Beispiel #1
0
    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)));
    }
Beispiel #2
0
    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;
            }
        }
    }
Beispiel #4
0
        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);
        }
Beispiel #5
0
    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);
            }
        }
    }
Beispiel #6
0
 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)]);
 }
Beispiel #7
0
    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)]);
    }
Beispiel #8
0
        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);
        }
Beispiel #9
0
 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]);
 }
Beispiel #10
0
    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)]);
        }
    }
Beispiel #11
0
 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;
 }
Beispiel #12
0
 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;
     }
 }
Beispiel #13
0
        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);
        }
Beispiel #14
0
 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
    }
Beispiel #16
0
    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;
        }
    }
Beispiel #20
0
    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;
            }
        }
    }
Beispiel #21
0
    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;
                        }
                    }
                }
            }
        }
    }
Beispiel #22
0
    /// <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);
    }
Beispiel #23
0
        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)]);
        }
Beispiel #24
0
    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);
            }
        }
    }