void LoadAndSendChunk(int x, int y, int z) { ClientSimple c = server.clients[clientId]; int pos = MapUtilCi.Index2d(x, y, server.MapSizeX / ServerSimple.ChunkSize); if (c.chunksseen[pos] == null) { c.chunksseen[pos] = new bool[server.MapSizeZ / ServerSimple.ChunkSize]; } c.chunksseen[pos][z] = true; int[] chunk = new int[32 * 32 * 32]; for (int i = 0; i < server.modsCount; i++) { server.mods[i].GenerateChunk(x, y, z, chunk); } byte[] chunkBytes = MiscCi.UshortArrayToByteArray(chunk, 32 * 32 * 32); IntRef compressedLength = new IntRef(); byte[] chunkCompressed = server.platform.GzipCompress(chunkBytes, 32 * 32 * 32 * 2, compressedLength); server.QueueMainThreadAction(SendPacketAction.Create(server, clientId, ServerPackets.ChunkPart(chunkCompressed))); server.QueueMainThreadAction(SendPacketAction.Create(server, clientId, ServerPackets.Chunk_(x * ServerSimple.ChunkSize, y * ServerSimple.ChunkSize, z * ServerSimple.ChunkSize, ServerSimple.ChunkSize))); }
void ApplyLightEmitting(int[] workportionArr, byte[] worklightArr, int[] dataLightRadius) { int[] radiusArr = dataLightRadius; const int portionsize = 16; const int portionsize3 = portionsize * portionsize * portionsize; Vector3IntRef p = new Vector3IntRef(); for (int pos = 0; pos < portionsize3; pos++) { if (workportionArr[pos] >= 10) //optimization { if (radiusArr[workportionArr[pos]] != 0) //optimization { if (radiusArr[workportionArr[pos]] > worklightArr[pos]) { MapUtilCi.PosInt(pos, portionsize, portionsize, p); int xx = p.X; int yy = p.Y; int zz = p.Z; int l = radiusArr[workportionArr[pos]]; lighttoflood.Push(xx); lighttoflood.Push(yy); lighttoflood.Push(zz); worklightArr[pos] = Game.IntToByte(MathCi.MaxInt(l, worklightArr[pos])); } } } } }
public override void Update(Server server, float dt) { int sizexchunks = server.mapsizexchunks(); int sizeychunks = server.mapsizeychunks(); int sizezchunks = server.mapsizezchunks(); for (int i = 0; i < 100; i++) { MapUtilCi.PosInt(CompressUnusedIteration, sizexchunks, sizeychunks, chunkpos); ServerChunk c = server.d_Map.GetChunkValid(chunkpos.X, chunkpos.Y, chunkpos.Z); bool stop = false; if (c != null) { var globalpos = new Vector3i(chunkpos.X * Server.chunksize, chunkpos.Y * Server.chunksize, chunkpos.Z * Server.chunksize); bool unload = true; foreach (var k in server.clients) { if (k.Value.IsBot) { // don't hold chunks in memory for bots continue; } // unload distance = view distance + 60% (prevents chunks from being unloaded too early (square loading vs. circular unloading)) int viewdist = (int)(server.chunkdrawdistance * Server.chunksize * 1.8f); if (server.DistanceSquared(server.PlayerBlockPosition(k.Value), globalpos) <= viewdist * viewdist) { //System.Console.WriteLine("No Unload: {0},{1},{2}", chunkpos.X, chunkpos.Y, chunkpos.Z); unload = false; } } if (unload) { // unload if chunk isn't seen by anyone if (c.DirtyForSaving) { // save changes to disk if necessary server.DoSaveChunk(chunkpos.X, chunkpos.Y, chunkpos.Z, c); } server.d_Map.SetChunkValid(chunkpos.X, chunkpos.Y, chunkpos.Z, null); foreach (var client in server.clients) { // mark chunks unseen for all players server.ClientSeenChunkRemove(client.Key, chunkpos.X, chunkpos.Y, chunkpos.Z); } stop = true; } } CompressUnusedIteration++; if (CompressUnusedIteration >= sizexchunks * sizeychunks * sizezchunks) { CompressUnusedIteration = 0; } if (stop) { // only unload one chunk at a time return; } } }
public void SetBlockNotMakingDirty(int x, int y, int z, int tileType) { ServerChunk chunk = GetChunk(x, y, z); chunk.data[MapUtilCi.Index3d(x % chunksize, y % chunksize, z % chunksize, chunksize, chunksize)] = (ushort)tileType; chunk.DirtyForSaving = true; UpdateColumnHeight(x, y); }
public void FloodLight(int[] chunk, byte[] light, int startx, int starty, int startz, int[] dataLightRadius, bool[] dataTransparent) { int start = Index3d(startx, starty, startz, 16, 16); if (light[start] == minlight) { return; } q.Clear(); q.Push(start); for (; ;) { if (q.Count == 0) { break; } int vPos = q.Pop(); int vLight = light[vPos]; if (vLight == minlight) { continue; } int vBlock = chunk[vPos]; if (!dataTransparent[vBlock] && dataLightRadius[vBlock] == 0) { continue; } int x = MapUtilCi.PosX(vPos, 16, 16); int y = MapUtilCi.PosY(vPos, 16, 16); int z = MapUtilCi.PosZ(vPos, 16, 16); if (x < 15) { Push(q, light, vLight, vPos + XPlus); } if (x > 0) { Push(q, light, vLight, vPos + XMinus); } if (y < 15) { Push(q, light, vLight, vPos + YPlus); } if (y > 0) { Push(q, light, vLight, vPos + YMinus); } if (z < 15) { Push(q, light, vLight, vPos + ZPlus); } if (z > 0) { Push(q, light, vLight, vPos + ZMinus); } } }
static int GetLightHeight(Game game, int cx, int cy, int xx, int yy) { int[] chunk = game.d_Heightmap.chunks[MapUtilCi.Index2d(cx, cy, game.map.MapSizeX / Game.chunksize)]; if (chunk == null) { return(0); } return(chunk[MapUtilCi.Index2d(xx % Game.chunksize, yy % Game.chunksize, Game.chunksize)]); }
static int Texture2d(GamePlatform platform, int[] pixelsArgb, float x, float y) { int px = platform.FloatToInt(x * (textureSize - 1)); int py = platform.FloatToInt(y * (textureSize - 1)); px = positive_modulo(px, (textureSize - 1)); py = positive_modulo(py, (textureSize - 1)); return(pixelsArgb[MapUtilCi.Index2d(px, py, textureSize)]); }
public override void SetBlock(int x, int y, int z, int tileType) { ServerChunk chunk = GetChunk(x, y, z); chunk.data[MapUtilCi.Index3d(x % chunksize, y % chunksize, z % chunksize, chunksize, chunksize)] = (ushort)tileType; chunk.LastChange = d_CurrentTime.GetSimulationCurrentFrame(); chunk.DirtyForSaving = true; UpdateColumnHeight(x, y); }
public ServerChunk GetChunkValid(int cx, int cy, int cz) { ServerChunk[] column = chunks[MapUtilCi.Index2d(cx, cy, MapSizeX / chunksize)]; if (column == null) { return(null); } return(column[cz]); }
public override int GetBlock(int x, int y, int z) { ServerChunk chunk = GetChunk(x, y, z); //return chunk.data[MapUtilCi.Index3d(x % chunksize, y % chunksize, z % chunksize, chunksize, chunksize)]; unchecked { return(chunk.data[MapUtilCi.Index3d(moduloChunk(x), moduloChunk(y), moduloChunk(z), chunksize, chunksize)]); } }
public void SetChunkValid(int cx, int cy, int cz, ServerChunk chunk) { ServerChunk[] column = chunks[MapUtilCi.Index2d(cx, cy, MapSizeX / chunksize)]; if (column == null) { column = new ServerChunk[MapSizeZ / chunksize]; chunks[MapUtilCi.Index2d(cx, cy, MapSizeX / chunksize)] = column; } column[cz] = chunk; }
public void SetChunkValid(int cx, int cy, int cz, ServerChunk chunk) { unchecked { ServerChunk[] column = chunks[MapUtilCi.Index2d(cx, cy, invertChunk(MapSizeX))]; if (column == null) { column = new ServerChunk[invertChunk(MapSizeZ)]; chunks[MapUtilCi.Index2d(cx, cy, invertChunk(MapSizeX))] = column; } column[cz] = chunk; } }
int GetColumnHeightInChunk(ushort[] chunk, int xx, int yy) { int height = chunksize - 1; for (int i = chunksize - 1; i >= 0; i--) { height = i; if (!Server.IsTransparentForLight(server.BlockTypes[chunk[MapUtilCi.Index3d(xx, yy, i, chunksize, chunksize)]])) { break; } } return(height); }
public unsafe ushort[] GetHeightmapChunk(int x, int y) { //TODO: don't copy ushort[] chunk2d = d_Heightmap.GetChunk(x, y); ushort[] chunk = new ushort[chunksize * chunksize]; for (int xx = 0; xx < chunksize; xx++) { for (int yy = 0; yy < chunksize; yy++) { chunk[MapUtilCi.Index2d(xx, yy, chunksize)] = chunk2d[MapUtilCi.Index2d(xx, yy, chunksize)]; } } //TODO: ushort[] return(chunk); }
void RedrawChunk(int x, int y, int z) { #if !CITO unchecked { #endif Chunk c = game.map.chunks[MapUtilCi.Index3d(x, y, z, mapsizexchunks(), mapsizeychunks())]; if (c == null) { return; } if (c.rendered == null) { c.rendered = new RenderedChunk(); } c.rendered.dirty = false; chunkupdates++; GetExtendedChunk(x, y, z); TerrainRendererRedraw r = new TerrainRendererRedraw(); r.c = c; VerticesIndicesToLoad[] a = null; IntRef retCount = new IntRef(); if (!IsSolidChunk(currentChunk, (bufferedChunkSize) * (bufferedChunkSize) * (bufferedChunkSize))) { CalculateShadows(x, y, z); a = game.d_TerrainChunkTesselator.MakeChunk(x, y, z, currentChunk, currentChunkShadows, game.mLightLevels, retCount); } r.data = new VerticesIndicesToLoad[retCount.value]; for (int i = 0; i < retCount.value; i++) { r.data[i] = VerticesIndicesToLoadClone(a[i]); } r.dataCount = retCount.value; redraw[redrawCount++] = r; #if !CITO } #endif }
void LightEmitting(int[] workportion, byte[] worklight, int[] dataLightRadius, bool[] dataTransparent) { const int portionsize = 16; const int portionsize3 = portionsize * portionsize * portionsize; for (int pos = 0; pos < portionsize3; pos++) { if (workportion[pos] >= 10) //optimization { if (dataLightRadius[workportion[pos]] != 0) //optimization { if (dataLightRadius[workportion[pos]] > worklight[pos]) { int xx = MapUtilCi.PosX(pos, portionsize, portionsize); int yy = MapUtilCi.PosY(pos, portionsize, portionsize); int zz = MapUtilCi.PosZ(pos, portionsize, portionsize); int l = dataLightRadius[workportion[pos]]; worklight[pos] = Game.IntToByte(MathCi.MaxInt(l, worklight[pos])); flood.FloodLight(workportion, worklight, xx, yy, zz, dataLightRadius, dataTransparent); } } } } }
void ChunkUpdate(Server server, Vector3i p, long lastupdate) { if (server.config.Monsters) { AddMonsters(server, p); } ServerChunk chunk = server.d_Map.GetChunk(p.x, p.y, p.z); for (int xx = 0; xx < Server.chunksize; xx++) { for (int yy = 0; yy < Server.chunksize; yy++) { for (int zz = 0; zz < Server.chunksize; zz++) { int block = chunk.data[MapUtilCi.Index3d(xx, yy, zz, Server.chunksize, Server.chunksize)]; for (int i = 0; i < server.modEventHandlers.blockticks.Count; i++) { server.modEventHandlers.blockticks[i](p.x + xx, p.y + yy, p.z + zz); } } } } }
public void Update(EntityPosition_ stateplayerposition, Controls move, float dt, BoolRef soundnow, Vector3Ref push, float modelheight) { if (game.stopPlayerMove) { movedz = 0; game.stopPlayerMove = false; } // No air control if (!isplayeronground) { acceleration.acceleration1 = 0.99f; acceleration.acceleration2 = 0.2f; acceleration.acceleration3 = 70; } // Trampoline { int blockunderplayer = game.BlockUnderPlayer(); if (blockunderplayer != -1 && blockunderplayer == game.d_Data.BlockIdTrampoline() && (!isplayeronground) && !game.controls.shiftkeydown) { game.controls.wantsjump = true; jumpstartacceleration = 20.666f * constGravity; } } // Slippery walk on ice and when swimming { int blockunderplayer = game.BlockUnderPlayer(); if ((blockunderplayer != -1 && game.d_Data.IsSlipperyWalk()[blockunderplayer]) || game.SwimmingBody()) { acceleration.acceleration1 = 0.99f; acceleration.acceleration2 = 0.2f; acceleration.acceleration3 = 70; } } soundnow.value = false; Vector3Ref diff1ref = new Vector3Ref(); VectorTool.ToVectorInFixedSystem (move.movedx * movespeednow * dt, 0, move.movedy * movespeednow * dt, stateplayerposition.rotx, stateplayerposition.roty, diff1ref); Vector3Ref diff1 = new Vector3Ref(); diff1.X = diff1ref.X; diff1.Y = diff1ref.Y; diff1.Z = diff1ref.Z; if (MiscCi.Vec3Length(push.X, push.Y, push.Z) > 0.01f) { push.Normalize(); push.X *= 5; push.Y *= 5; push.Z *= 5; } diff1.X += push.X * dt; diff1.Y += push.Y * dt; diff1.Z += push.Z * dt; bool loaded = false; int cx = game.platform.FloatToInt(game.player.position.x / Game.chunksize); int cy = game.platform.FloatToInt(game.player.position.z / Game.chunksize); int cz = game.platform.FloatToInt(game.player.position.y / Game.chunksize); if (game.map.IsValidChunkPos(cx, cy, cz)) { if (game.map.chunks[MapUtilCi.Index3d(cx, cy, cz, game.map.MapSizeX / Game.chunksize, game.map.MapSizeY / Game.chunksize)] != null) { loaded = true; } } else { loaded = true; } if ((!(move.freemove)) && loaded) { if (!game.SwimmingBody()) { movedz += -constGravity;//gravity } else { movedz += -constGravity * constWaterGravityMultiplier; //more gravity because it's slippery. } } game.movedz = movedz; if (constEnableAcceleration) { curspeed.X *= acceleration.acceleration1; curspeed.Y *= acceleration.acceleration1; curspeed.Z *= acceleration.acceleration1; curspeed.X = MakeCloserToZero(curspeed.X, acceleration.acceleration2 * dt); curspeed.Y = MakeCloserToZero(curspeed.Y, acceleration.acceleration2 * dt); curspeed.Z = MakeCloserToZero(curspeed.Z, acceleration.acceleration2 * dt); diff1.Y += move.moveup ? 2 * movespeednow * dt : 0; diff1.Y -= move.movedown ? 2 * movespeednow * dt : 0; curspeed.X += diff1.X * acceleration.acceleration3 * dt; curspeed.Y += diff1.Y * acceleration.acceleration3 * dt; curspeed.Z += diff1.Z * acceleration.acceleration3 * dt; if (curspeed.Length() > movespeednow) { curspeed.Normalize(); curspeed.X *= movespeednow; curspeed.Y *= movespeednow; curspeed.Z *= movespeednow; } } else { if (MiscCi.Vec3Length(diff1.X, diff1.Y, diff1.Z) > 0) { diff1.Normalize(); } curspeed.X = diff1.X * movespeednow; curspeed.Y = diff1.Y * movespeednow; curspeed.Z = diff1.Z * movespeednow; } Vector3Ref newposition = Vector3Ref.Create(0, 0, 0); if (!(move.freemove)) { newposition.X = stateplayerposition.x + curspeed.X; newposition.Y = stateplayerposition.y + curspeed.Y; newposition.Z = stateplayerposition.z + curspeed.Z; if (!game.SwimmingBody()) { newposition.Y = stateplayerposition.y; } // Fast move when looking at the ground float diffx = newposition.X - stateplayerposition.x; float diffy = newposition.Y - stateplayerposition.y; float diffz = newposition.Z - stateplayerposition.z; float difflength = MiscCi.Vec3Length(diffx, diffy, diffz); if (difflength > 0) { diffx /= difflength; diffy /= difflength; diffz /= difflength; diffx *= curspeed.Length(); diffy *= curspeed.Length(); diffz *= curspeed.Length(); } newposition.X = stateplayerposition.x + diffx * dt; newposition.Y = stateplayerposition.y + diffy * dt; newposition.Z = stateplayerposition.z + diffz * dt; } else { newposition.X = stateplayerposition.x + (curspeed.X) * dt; newposition.Y = stateplayerposition.y + (curspeed.Y) * dt; newposition.Z = stateplayerposition.z + (curspeed.Z) * dt; } newposition.Y += movedz * dt; Vector3Ref previousposition = Vector3Ref.Create(stateplayerposition.x, stateplayerposition.y, stateplayerposition.z); if (!move.noclip) { float[] v = WallSlide( Vec3.FromValues(stateplayerposition.x, stateplayerposition.y, stateplayerposition.z), Vec3.FromValues(newposition.X, newposition.Y, newposition.Z), modelheight); stateplayerposition.x = v[0]; stateplayerposition.y = v[1]; stateplayerposition.z = v[2]; } else { stateplayerposition.x = newposition.X; stateplayerposition.y = newposition.Y; stateplayerposition.z = newposition.Z; } if (!(move.freemove)) { if ((isplayeronground) || game.SwimmingBody()) { jumpacceleration = 0; movedz = 0; } if ((move.wantsjump || move.wantsjumphalf) && (((jumpacceleration == 0 && isplayeronground) || game.SwimmingBody()) && loaded) && (!game.SwimmingEyes())) { jumpacceleration = move.wantsjumphalf ? jumpstartaccelerationhalf : jumpstartacceleration; soundnow.value = true; } if (jumpacceleration > 0) { isplayeronground = false; jumpacceleration = jumpacceleration / 2; } //if (!this.reachedceiling) { movedz += jumpacceleration * constJump; } } else { isplayeronground = true; } game.isplayeronground = isplayeronground; }
void ProcessInBackground(Packet_Server packet) { switch (packet.Id) { case Packet_ServerIdEnum.ChunkPart: byte[] arr = packet.ChunkPart.CompressedChunkPart; int arrLength = game.platform.ByteArrayLength(arr); // todo for (int i = 0; i < arrLength; i++) { CurrentChunk[CurrentChunkCount++] = arr[i]; } break; case Packet_ServerIdEnum.Chunk_: { Packet_ServerChunk p = packet.Chunk_; if (CurrentChunkCount != 0) { game.platform.GzipDecompress(CurrentChunk, CurrentChunkCount, decompressedchunk); { int i = 0; for (int zz = 0; zz < p.SizeZ; zz++) { for (int yy = 0; yy < p.SizeY; yy++) { for (int xx = 0; xx < p.SizeX; xx++) { int block = (decompressedchunk[i + 1] << 8) + decompressedchunk[i]; if (block < GlobalVar.MAX_BLOCKTYPES) { receivedchunk[Index3d(xx, yy, zz, p.SizeX, p.SizeY)] = block; } i += 2; } } } } } else { int size = p.SizeX * p.SizeY * p.SizeZ; for (int i = 0; i < size; i++) { receivedchunk[i] = 0; } } { game.map.SetMapPortion(p.X, p.Y, p.Z, receivedchunk, p.SizeX, p.SizeY, p.SizeZ); for (int xx = 0; xx < 2; xx++) { for (int yy = 0; yy < 2; yy++) { for (int zz = 0; zz < 2; zz++) { //d_Shadows.OnSetChunk(p.X + 16 * xx, p.Y + 16 * yy, p.Z + 16 * zz);//todo } } } } game.ReceivedMapLength += CurrentChunkCount; // lengthPrefixLength + packetLength; CurrentChunkCount = 0; } break; case Packet_ServerIdEnum.HeightmapChunk: { Packet_ServerHeightmapChunk p = packet.HeightmapChunk; game.platform.GzipDecompress(p.CompressedHeightmap, game.platform.ByteArrayLength(p.CompressedHeightmap), decompressedchunk); int[] decompressedchunk1 = Game.ByteArrayToUshortArray(decompressedchunk, p.SizeX * p.SizeY * 2); for (int xx = 0; xx < p.SizeX; xx++) { for (int yy = 0; yy < p.SizeY; yy++) { int height = decompressedchunk1[MapUtilCi.Index2d(xx, yy, p.SizeX)]; game.d_Heightmap.SetBlock(p.X + xx, p.Y + yy, height); } } } break; } }
public override void OnReadOnlyBackgroundThread(Game game_, float dt) { game = game_; chunksize = Game.chunksize; mapsizexchunks = game.map.MapSizeX / chunksize; mapsizeychunks = game.map.MapSizeY / chunksize; mapsizezchunks = game.map.MapSizeZ / chunksize; int px = game.platform.FloatToInt(game.player.position.x) / chunksize; int py = game.platform.FloatToInt(game.player.position.z) / chunksize; int pz = game.platform.FloatToInt(game.player.position.y) / chunksize; int chunksxy = this.mapAreaSize() / chunksize / 2; int chunksz = this.mapAreaSizeZ() / chunksize / 2; int startx = px - chunksxy; int endx = px + chunksxy; int starty = py - chunksxy; int endy = py + chunksxy; int startz = pz - chunksz; int endz = pz + chunksz; if (startx < 0) { startx = 0; } if (starty < 0) { starty = 0; } if (startz < 0) { startz = 0; } if (endx >= mapsizexchunks) { endx = mapsizexchunks - 1; } if (endy >= mapsizeychunks) { endy = mapsizeychunks - 1; } if (endz >= mapsizezchunks) { endz = mapsizezchunks - 1; } int mapsizexchunks_ = mapsizexchunks; int mapsizeychunks_ = mapsizeychunks; int mapsizezchunks_ = mapsizezchunks; int count; if (game.platform.IsFastSystem()) { count = 1000; } else { count = 250; } for (int i = 0; i < count; i++) { unloadIterationXy++; if (unloadIterationXy >= mapsizexchunks_ * mapsizeychunks_ * mapsizezchunks_) { unloadIterationXy = 0; } MapUtilCi.PosInt(unloadIterationXy, mapsizexchunks_, mapsizeychunks_, unloadxyztemp); int x = unloadxyztemp.X; int y = unloadxyztemp.Y; int z = unloadxyztemp.Z; int pos = MapUtilCi.Index3d(x, y, z, mapsizexchunks_, mapsizeychunks_); bool unloaded = false; Chunk c = game.map.chunks[pos]; if (c == null || c.rendered == null || c.rendered.ids == null) { continue; } if (x < startx || y < starty || z < startz || x > endx || y > endy || z > endz) { int unloadChunkPos = pos; UnloadRendererChunksCommit commit = new UnloadRendererChunksCommit(); commit.game = game; commit.unloadChunkPos = unloadChunkPos; game.QueueActionCommit(commit); } unloaded = true; if (unloaded) { break; } } }
void NearestDirty(int clientid, int playerx, int playery, int playerz, int[] retNearest) { int nearestdist = intMaxValue; retNearest[0] = -1; retNearest[1] = -1; retNearest[2] = -1; int px = (playerx) / ServerSimple.ChunkSize; int py = (playery) / ServerSimple.ChunkSize; int pz = (playerz) / ServerSimple.ChunkSize; int chunksxy = this.mapAreaSize() / ServerSimple.ChunkSize / 2; int chunksz = this.mapAreaSizeZ() / ServerSimple.ChunkSize / 2; int startx = px - chunksxy; int endx = px + chunksxy; int starty = py - chunksxy; int endy = py + chunksxy; int startz = pz - chunksz; int endz = pz + chunksz; if (startx < 0) { startx = 0; } if (starty < 0) { starty = 0; } if (startz < 0) { startz = 0; } if (endx >= mapsizexchunks()) { endx = mapsizexchunks() - 1; } if (endy >= mapsizeychunks()) { endy = mapsizeychunks() - 1; } if (endz >= mapsizezchunks()) { endz = mapsizezchunks() - 1; } ClientSimple client = server.clients[clientid]; for (int x = startx; x <= endx; x++) { for (int y = starty; y <= endy; y++) { int pos = MapUtilCi.Index2d(x, y, server.MapSizeX / ServerSimple.ChunkSize); if (client.chunksseen[pos] == null) { client.chunksseen[pos] = new bool[server.MapSizeZ / ServerSimple.ChunkSize]; } for (int z = startz; z <= endz; z++) { bool[] column = client.chunksseen[pos]; if (column[z]) { continue; } { int dx = px - x; int dy = py - y; int dz = pz - z; int dist = dx * dx + dy * dy + dz * dz; if (dist < nearestdist) { nearestdist = dist; retNearest[0] = x; retNearest[1] = y; retNearest[2] = z; } } } } } }
/// <summary> /// Creates a bitmap from a given string /// </summary> /// <param name="t">The <see cref="Text_"/> object to create an image from</param> /// <returns>A <see cref="BitmapCi"/> containing the rendered text</returns> internal BitmapCi CreateTextTexture(Text_ t) { IntRef partsCount = new IntRef(); TextPart[] parts = DecodeColors(t.text, t.color, partsCount); float totalwidth = 0; float totalheight = 0; int[] sizesX = new int[partsCount.value]; int[] sizesY = new int[partsCount.value]; for (int i = 0; i < partsCount.value; i++) { IntRef outWidth = new IntRef(); IntRef outHeight = new IntRef(); platform.TextSize(parts[i].text, t.font, outWidth, outHeight); sizesX[i] = outWidth.value; sizesY[i] = outHeight.value; totalwidth += outWidth.value; totalheight = MathCi.MaxFloat(totalheight, outHeight.value); } int size2X = NextPowerOfTwo(platform.FloatToInt(totalwidth) + 1); int size2Y = NextPowerOfTwo(platform.FloatToInt(totalheight) + 1); BitmapCi bmp2 = platform.BitmapCreate(size2X, size2Y); int[] bmp2Pixels = new int[size2X * size2Y]; float currentwidth = 0; for (int i = 0; i < partsCount.value; i++) { int sizeiX = sizesX[i]; int sizeiY = sizesY[i]; if (sizeiX == 0 || sizeiY == 0) { continue; } Text_ partText = new Text_(); partText.text = parts[i].text; partText.color = parts[i].color; partText.font = t.font; BitmapCi partBmp = platform.CreateTextTexture(partText); int partWidth = platform.FloatToInt(platform.BitmapGetWidth(partBmp)); int partHeight = platform.FloatToInt(platform.BitmapGetHeight(partBmp)); int[] partBmpPixels = new int[partWidth * partHeight]; platform.BitmapGetPixelsArgb(partBmp, partBmpPixels); for (int x = 0; x < partWidth; x++) { for (int y = 0; y < partHeight; y++) { if (x + currentwidth >= size2X) { continue; } if (y >= size2Y) { continue; } int c = partBmpPixels[MapUtilCi.Index2d(x, y, partWidth)]; if (Game.ColorA(c) > 0) { bmp2Pixels[MapUtilCi.Index2d(platform.FloatToInt(currentwidth) + x, y, size2X)] = c; } } } currentwidth += sizeiX; } platform.BitmapSetPixelsArgb(bmp2, bmp2Pixels); return(bmp2); }
public override int GetBlock(int x, int y, int z) { ServerChunk chunk = GetChunk(x, y, z); return(chunk.data[MapUtilCi.Index3d(x % chunksize, y % chunksize, z % chunksize, chunksize, chunksize)]); }
public static void FloodLight_(FastQueueInt q, int[] portion, byte[] light, int startx, int starty, int startz, int[] dataLightRadius, bool[] dataTransparent) { const int portionsize = 16; int pos = Index3d(startx, starty, startz, portionsize, portionsize); if (light[pos] == minlight) { return; } int lightradius = dataLightRadius[portion[pos]]; if (lightradius != 0) { light[pos] = Game.IntToByte(lightradius); } //if (light[pos + 1] == light[pos] // && light[pos - 1] == light[pos] // && light[pos + portionsize] == light[pos] // && light[pos - portionsize] == light[pos] // && light[pos + portionsize * portionsize] == light[pos] // && light[pos - portionsize * portionsize] == light[pos]) //{ // return; //} q.Clear(); int start = Index3d(startx, starty, startz, portionsize, portionsize); q.Push(start); for (; ;) { if (q.Count == 0) { break; } int vpos = q.Pop(); int vlight = light[vpos]; if (vlight == minlight) { continue; } int vblock = portion[vpos]; if (!dataTransparent[vblock] && dataLightRadius[vblock] == 0) { continue; } int x = MapUtilCi.PosX(vpos, 16, 16); int y = MapUtilCi.PosY(vpos, 16, 16); int z = MapUtilCi.PosZ(vpos, 16, 16); if (x < 15) { Push(q, light, vlight, vpos + XPlus); } if (x > 0) { Push(q, light, vlight, vpos + XMinus); } if (y < 15) { Push(q, light, vlight, vpos + YPlus); } if (y > 0) { Push(q, light, vlight, vpos + YMinus); } if (z < 15) { Push(q, light, vlight, vpos + ZPlus); } if (z > 0) { Push(q, light, vlight, vpos + ZMinus); } } }