示例#1
0
    public void OldBuild(World world, BlockPos chunkPos, BlockPos pos, OldTerrainGen gen)
    {
        int leaves = gen.GetNoise(pos.x, 0, pos.z, 1f, 2, 1) + 1;
        pos = pos.Add(chunkPos);

        for (int x = -leaves; x <= leaves; x++)
        {
            for (int y = 3; y <= 6; y++)
            {
                for (int z = -leaves; z <= leaves; z++)
                {
                    if (Chunk.InRange(pos.x + x - chunkPos.x) && Chunk.InRange(pos.z + z - chunkPos.z))
                    {
                        Block block = "leaves";
                        block.modified = false;
                        world.SetBlock(pos.Add(x, y, z), block, false);
                    }
                }
            }
        }
        for (int y = 0; y <= 5; y++)
        {
            if (y < Config.Env.WorldMaxY)
            {
                Block block = "log";
                block.modified = false;
                world.SetBlock(pos.Add(0, y, 0), block, false);
            }
        }
    }
示例#2
0
    public PathFinder(BlockPos startLocation, BlockPos targetLocation, World world, int entityHeight=2)
    {
        this.startLocation = startLocation;
        this.targetLocation = targetLocation;
        distanceFromStartToTarget = Distance(startLocation, targetLocation);
        this.world = world;
        this.entityHeight = entityHeight;

        open.Add(startLocation, new Heuristics(0, distanceFromStartToTarget, startLocation));

        if (Config.Toggle.UseMultiThreading)
        {
            Thread thread = new Thread(() =>
           {
               while (path.Count == 0)
               {
                   update();
               }
           });
            thread.Start();
        }
        else
        {
            while (path.Count == 0)
            {
                update();
            }
        }
    }
示例#3
0
 public IBlock this[BlockPos pos]
 {
     get {
         var chunk = this[ChunkPos.FromBlockPos(pos)];
         return new TerrainBlock(this, chunk, pos);
     }
 }
示例#4
0
    //Instantiates a chunk at the supplied coordinates using the chunk prefab,
    //then runs terrain generation on it and loads the chunk's save file
    public void CreateChunk(BlockPos pos)
    {
        GameObject newChunkObject = Instantiate(
                        chunkPrefab, pos,
                        Quaternion.Euler(Vector3.zero)
                    ) as GameObject;

        newChunkObject.transform.parent = gameObject.transform;
        newChunkObject.transform.name = "Chunk (" + pos + ")";

        Chunk newChunk = newChunkObject.GetComponent<Chunk>();

        newChunk.pos = pos;
        newChunk.world = this;

        //Add it to the chunks dictionary with the position as the key
        chunks.Add(pos, newChunk);

        if (Config.Toggle.UseMultiThreading) {
            Thread thread = new Thread(() => { GenAndLoadChunk(newChunk); });
            thread.Start();
        }
        else
        {
            GenAndLoadChunk(newChunk);
        }
    }
示例#5
0
    static void LightAreaInner(World world, BlockPos pos)
    {
        List<BlockPos> chunksToUpdate = new List<BlockPos>();

        for (int x = pos.x - lightEffectRadius; x < pos.x + lightEffectRadius; x++)
        {
            for (int z = pos.z - lightEffectRadius; z < pos.z + lightEffectRadius; z++)
            {
                ResetLightColumn(world, x, z, chunksToUpdate);
            }
        }

        for (int x = pos.x - lightEffectRadius - 1; x < pos.x + lightEffectRadius + 1; x++)
        {
            for (int z = pos.z - lightEffectRadius - 1; z < pos.z + lightEffectRadius + 1; z++)
            {
                for (int y = Config.Env.WorldMaxY - 1; y >= Config.Env.WorldMinY; y--)
                {
                    FloodLight(world, x, y, z, chunksToUpdate);
                }
            }
        }

        world.GetChunk(pos).UpdateChunk();
        world.UpdateAdjacentChunks(pos);

        foreach (var chunkPos in chunksToUpdate)
        {
            world.GetChunk(chunkPos).UpdateChunk();
        }
    }
示例#6
0
    bool FindChunksAndLoad()
    {
        //Cycle through the array of positions
        for (int i = 0; i < Data.chunkLoadOrder.Length; i++)
        {
            //Get the position of this gameobject to generate around
            BlockPos playerPos = ((BlockPos)transform.position).ContainingChunkCoordinates();

            //translate the player position and array position into chunk position
            BlockPos newChunkPos = new BlockPos(
                Data.chunkLoadOrder[i].x * Config.Env.ChunkSize + playerPos.x,
                0,
                Data.chunkLoadOrder[i].z * Config.Env.ChunkSize + playerPos.z
                );

            //Get the chunk in the defined position
            Chunk newChunk = world.GetChunk(newChunkPos);

            //If the chunk already exists and it's already
            //rendered or in queue to be rendered continue
            if (newChunk != null && newChunk.GetFlag(Chunk.Flag.loaded))
                continue;

            LoadChunkColumn(newChunkPos);
            return true;
        }

        return false;
    }
 public static void BuildRenderer(Chunk chunk, BlockPos pos, MeshData meshData, Direction direction, Vector3 ModelSize, Vector3 ConnMeshSizeX, Vector3 ConnMeshSizeY, Vector3 ConnMeshSizeZ, Direction[] Dir)
 {
     MakeStickFace(chunk, pos, meshData, direction, false, ModelSize);
     Debug.Log(Dir.Length);
     if (Dir.Length > 0)
         MakeFenceFace(chunk, pos, meshData, direction, false, ModelSize, ConnMeshSizeX, ConnMeshSizeY, ConnMeshSizeZ, Dir);
 }
示例#8
0
 public BlockRegion(BlockPos start, BlockPos end)
 {
     this.start = start;
     this.end = end;
     if ((width < 0) || (height < 0) || (depth < 0))
         throw new ArgumentException(string.Format(
             "End position must be larger or equal to start" +
             "position for all dimensions ({0} : {1})", start, end));
 }
示例#9
0
    public static Block GetBlock(BlockPos pos, World world = null)
    {
        if (!world)
            world = World.instance;

        Block block = world.GetBlock(pos);

        return block;
    }
示例#10
0
 public override void BuildFace(Chunk chunk, BlockPos pos, MeshData meshData, Direction direction, Block block)
 {
     BlockBuilder.BuildRenderer(chunk, pos, meshData, direction);
     BlockBuilder.BuildTexture(chunk, pos, meshData, direction, textures);
     BlockBuilder.BuildColors(chunk, pos, meshData, direction);
     if (Config.Toggle.UseCollisionMesh)
     {
         BlockBuilder.BuildCollider(chunk, pos, meshData, direction);
     }
 }
示例#11
0
    // On create set the height to 10 and schedule and update in 1 second
    public override Block OnCreate(Chunk chunk, BlockPos pos, Block block)
    {
        block.data2 = (byte)(64 + ((chunk.world.noiseGen.Generate(pos.x * 1000, pos.y * 1000, pos.z * 1000) + 1) * 96));
        int offset1 = (int)((chunk.world.noiseGen.Generate(pos.x* 1000, pos.y* 1000, pos.z * 1000) + 1) * 16);
        block.data3 = (byte)((block.data3 & 240) | (offset1 & 15));
        int offset2 = (int)((chunk.world.noiseGen.Generate(pos.x*1000, pos.y * 10000, pos.z * 1000) + 1) * 16);
        block.data3 = (byte)((offset2 << 4) | (block.data3 & 15));

        return block;
    }
示例#12
0
    /// <summary>
    /// Returns true if the block local block position is contained in the chunk boundaries
    /// </summary>
    /// <param name="localPos">A local block position</param>
    /// <returns>true or false depending on if the position is in range</returns>
    public static bool InRange(BlockPos localPos)
    {
        if (!InRange(localPos.x))
            return false;
        if (!InRange(localPos.y))
            return false;
        if (!InRange(localPos.z))
            return false;

        return true;
    }
示例#13
0
    public static void CrossMeshRenderer(Chunk chunk, BlockPos pos, MeshData meshData, TextureCollection texture, Block block)
    {
        float halfBlock = (Config.Env.BlockSize / 2) + Config.Env.BlockFacePadding;
        float colliderOffest = 0.05f * Config.Env.BlockSize;
        float blockHeight = halfBlock * 2 * (block.data2 / 255f);

        float offsetX = (halfBlock * 2 * ((byte)(block.data3 & 0x0F) / 32f)) - (halfBlock/2);
        float offsetZ = (halfBlock * 2 * ((byte)((block.data3 & 0xF0) >> 4) / 32f)) - (halfBlock/2);

        //Converting the position to a vector adjusts it based on block size and gives us real world coordinates for x, y and z
        Vector3 vPos = pos;
        Vector3 vPosCollider = pos;
        vPos += new Vector3(offsetX, 0, offsetZ);

        float blockLight = ( (block.data1/255f) * Config.Env.BlockLightStrength) + (0.8f*Config.Env.AOStrength);

        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z + halfBlock));
        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock));
        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock));
        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z - halfBlock));
        meshData.AddQuadTriangles();
        BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture);
        meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight);

        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z - halfBlock));
        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock));
        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock));
        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z + halfBlock));
        meshData.AddQuadTriangles();
        BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture);
        meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight);

        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z + halfBlock));
        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock));
        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock));
        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z - halfBlock));
        meshData.AddQuadTriangles();
        BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture);
        meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight);

        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock, vPos.z - halfBlock));
        meshData.AddVertex(new Vector3(vPos.x - halfBlock, vPos.y - halfBlock + blockHeight, vPos.z - halfBlock));
        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock + blockHeight, vPos.z + halfBlock));
        meshData.AddVertex(new Vector3(vPos.x + halfBlock, vPos.y - halfBlock, vPos.z + halfBlock));
        meshData.AddQuadTriangles();
        BlockBuilder.BuildTexture(chunk, vPos, meshData, Direction.north, texture);
        meshData.AddColors(blockLight, blockLight, blockLight, blockLight, blockLight);

        meshData.AddVertex(new Vector3(vPosCollider.x - halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z + halfBlock), collisionMesh: true);
        meshData.AddVertex(new Vector3(vPosCollider.x + halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z + halfBlock), collisionMesh: true);
        meshData.AddVertex(new Vector3(vPosCollider.x + halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z - halfBlock), collisionMesh: true);
        meshData.AddVertex(new Vector3(vPosCollider.x - halfBlock, vPosCollider.y - halfBlock + colliderOffest, vPosCollider.z - halfBlock), collisionMesh: true);
        meshData.AddQuadTriangles(collisionMesh:true);
    }
示例#14
0
 public static void SetBlock(Chunk chunk, Block block, BlockPos pos, bool replaceBlocks = false)
 {
     if (Chunk.InRange(pos))
     {
         if (replaceBlocks || chunk.GetBlock(pos).type == Block.Air.type)
         {
             block.modified = false;
             chunk.SetBlock(pos, block, false);
         }
     }
 }
示例#15
0
    public static bool IsWalkable(World world, BlockPos pos)
    {
        if(!world.GetBlock(pos).controller.IsSolid(Direction.up))
            return false;

        for(int y = 1; y< characterHeight+1; y++){
            if (world.GetBlock(pos.Add(0,y,0)).GetType() != typeof(BlockAir))
                return false;
        }

        return true;
    }
示例#16
0
    public static void LightArea(World world, BlockPos pos)
    {

        if (Config.Toggle.UseMultiThreading)
        {
            Thread thread = new Thread(() => { LightAreaInner(world, pos); });
            thread.Start();
        }
        else
        {
            LightAreaInner(world, pos);
        }

    }
示例#17
0
    public void GenerateStructuresForChunk(BlockPos chunkPos)
    {
        for (int i = 0; i < layerOrder.Length; i++)
        {

            if (layerOrder[i] == null)
                continue;

            if (layerOrder[i].layerType == TerrainLayer.LayerType.Structure)
            {
                layerOrder[i].GenerateStructures(chunkPos, this);
            }
        }
    }
示例#18
0
    /// <summary>
    /// Gets and returns a block from a local position within the chunk 
    /// or fetches it from the world
    /// </summary>
    /// <param name="blockPos">A local block position</param>
    /// <returns>The block at the position</returns>
    public Block GetBlock(BlockPos blockPos)
    {
        Block returnBlock;

        if (InRange(blockPos))
        {
            returnBlock = blocks[blockPos.x, blockPos.y, blockPos.z];
        }
        else
        {
            returnBlock = world.GetBlock(blockPos + pos);
        }

        return returnBlock;
    }
示例#19
0
    void PathComplete(BlockPos lastTile)
    {
        Heuristics pos;
        closed.TryGetValue(lastTile, out pos);
        path.Clear();
        path.Add(lastTile);

        open.TryGetValue(lastTile, out pos);

        while (!pos.parent.Equals(startLocation))
        {
            path.Insert(0, pos.parent);
            if (!closed.TryGetValue(pos.parent, out pos))
                break;
        }
    }
示例#20
0
    public Save(Chunk chunk)
    {

        try
        {
            //Because existing saved blocks aren't marked as modified we have to add the
            //blocks already in the save fie if there is one. Then add 
            Dictionary<BlockPos, Block> blocksDictionary = AddSavedBlocks(chunk);

            for (int x = 0; x < Config.Env.ChunkSize; x++)
            {
                for (int y = 0; y < Config.Env.ChunkSize; y++)
                {
                    for (int z = 0; z < Config.Env.ChunkSize; z++)
                    {
                        BlockPos pos = new BlockPos(x, y, z);
                        if (chunk.GetBlock(pos).modified)
                        {
                            //remove any existing blocks in the dictionary as they're
                            //from the existing save and are overwritten
                            blocksDictionary.Remove(pos);
                            blocksDictionary.Add(pos, chunk.GetBlock(pos));
                            changed = true;
                        }
                    }
                }
            }

            blocks = new Block[blocksDictionary.Keys.Count];
            positions = new BlockPos[blocksDictionary.Keys.Count];

            int index = 0;

            foreach (var pair in blocksDictionary)
            {
                blocks[index] = pair.Value;
                positions[index] = pair.Key;
                index++;
            }

        }
        catch (Exception ex)
        {
            Debug.LogError(ex);
        }

    }
示例#21
0
 public override void BuildFace(Chunk chunk, BlockPos pos, MeshData meshData, BlockDirection blockDirection, Block block)
 {
     BlockBuilder.BuildRenderer(chunk, pos, meshData, blockDirection);
     BlockBuilder.BuildTexture(chunk, pos, meshData, blockDirection, new Tile[] {
         new Tile((int)textures[0].x, (int)textures[0].y),
         new Tile((int)textures[1].x, (int)textures[1].y),
         new Tile((int)textures[2].x, (int)textures[2].y),
         new Tile((int)textures[3].x, (int)textures[3].y),
         new Tile((int)textures[4].x, (int)textures[4].y),
         new Tile((int)textures[5].x, (int)textures[5].y)
     });
     BlockBuilder.BuildColors(chunk, pos, meshData, blockDirection);
     if (Config.Toggle.UseCollisionMesh)
     {
         BlockBuilder.BuildCollider(chunk, pos, meshData, blockDirection);
     }
 }
示例#22
0
    public bool IsWalkable(World world, BlockPos pos)
    {
        Block block = world.GetBlock(pos);

        if (!block.controller.CanBeWalkedOn(block))
            return false;

        for (int y = 1; y < entityHeight + 1; y++) {
            block = world.GetBlock(pos.Add(0, y, 0));

            if (!block.controller.CanBeWalkedThrough(block)) {
                return false;
            }
        }

        return true;
    }
示例#23
0
    public void Start(BlockPos start, BlockPos target, World world)
    {
        open.Clear();
        closed.Clear();

        startLocation = start;
        targetLocation = target;
        this.world = world;

        path.Clear();

        open.Add(start, new Heuristics(0,Distance(start, target), start));
        complete = false;
        noRoute = false;

        distanceFromStartToTarget = Distance(start, target);
    }
示例#24
0
    public static float Distance(BlockPos a, BlockPos b)
    {
        var x = a.x - b.x;
        var y = a.y - b.y;
        var z = a.z - b.z;

        if (x < 0)
            x *= -1;

        if (y < 0)
            y *= -1;

        if (z < 0)
            z *= -1;

        return x + y + z;
    }
示例#25
0
    public static bool SetBlock(BlockPos pos, Block block, World world = null)
    {
        if (!world)
            world = World.instance;

        Chunk chunk = world.GetChunk(pos);
        if (chunk == null)
            return false;

        chunk.world.SetBlock(pos, block, !Config.Toggle.BlockLighting);

        if (Config.Toggle.BlockLighting)
        {
            BlockLight.LightArea(world, pos);
        }

        return true;
    }
示例#26
0
 //On random update spread grass to any nearby dirt blocks on the surface
 public override void RandomUpdate(Chunk chunk, BlockPos pos, Block block)
 {
     for (int x = -1; x <= 1; x++)
     {
         for (int y = -1; y <= 1; y++)
         {
             for (int z = -1; z <= 1; z++)
             {
                 if (chunk.GetBlock(pos.Add(x, y, z) - chunk.pos) == dirt
                     && chunk.GetBlock(pos.Add(x, y + 1, z) - chunk.pos) == air)
                 {
                     chunk.SetBlock(pos.Add(x, y, z) - chunk.pos, "grass", false);
                     chunk.SetFlag(Chunk.Flag.updateSoon, true);
                 }
             }
         }
     }
 }
    public override void BuildFace(Chunk chunk, BlockPos pos, MeshData meshData, Direction direction, Block block)
    {
        List<Direction> dir = new List<Direction>();

        //East
        if (Block.Air != chunk.GetBlock(new BlockPos(pos.x + 1, pos.y, pos.z)) && dirE.east != false)
        {
            dir.Add(Direction.east);
        }
        //West
        if (Block.Air != chunk.GetBlock(new BlockPos(pos.x - 1, pos.y, pos.z)) && dirE.west != false)
        {
            dir.Add(Direction.west);
        }
        //North
        if (Block.Air != chunk.GetBlock(new BlockPos(pos.x, pos.y, pos.z + 1)) && dirE.north != false)
        {
            dir.Add(Direction.north);
        }
        //South
        if (Block.Air != chunk.GetBlock(new BlockPos(pos.x, pos.y, pos.z - 1)) && dirE.south != false)
        {
            dir.Add(Direction.south);
        }
        //Up
        if (Block.Air != chunk.GetBlock(new BlockPos(pos.x, pos.y + 1, pos.z)) && dirE.up != false)
        {
            dir.Add(Direction.up);
        }
        //Down
        if (Block.Air != chunk.GetBlock(new BlockPos(pos.x, pos.y - 1, pos.z)) && dirE.down != false)
        {
            dir.Add(Direction.down);
        }

        ConnectedBuilder.BuildRenderer(chunk, pos, meshData, direction, MeshSize, ConnMeshSizeX, ConnMeshSizeY, ConnMeshSizeZ, dir.ToArray());
        ConnectedBuilder.BuildTextures(chunk, pos, meshData, direction, textures, MeshSize, dir.ToArray());
        ConnectedBuilder.BuildColors(chunk, pos, meshData, direction, MeshSize, dir.ToArray());

        if (Config.Toggle.UseCollisionMesh)
        {
            BlockBuilder.BuildCollider(chunk, pos, meshData, direction);
        }
    }
示例#28
0
    public void SetBlock(BlockPos blockPos, Block block, bool updateChunk = true)
    {
        if (InRange(blockPos))
        {
            blocks[blockPos.x, blockPos.y, blockPos.z].controller.OnDestroy(this, pos, blocks[blockPos.x, blockPos.y, blockPos.z]);

            blocks[blockPos.x, blockPos.y, blockPos.z] = block;

            blocks[blockPos.x, blockPos.y, blockPos.z].controller.OnCreate(this, pos, blocks[blockPos.x, blockPos.y, blockPos.z]);

            if (updateChunk)
                UpdateChunk();
        }
        else
        {
            //if the block is out of range set it though world
            world.SetBlock(blockPos + pos, block, updateChunk);
        }
    }
示例#29
0
    public static void Build(Chunk chunk, BlockPos pos, TerrainGen terrainGen)
    {
        int leaves = terrainGen.GetNoise(pos.x + chunk.pos.x, 0, pos.z + chunk.pos.z, 1f, 2, 1) +1;

        for (int x = -leaves; x <= leaves; x++)
        {
            for (int y = 3; y <= 6; y++)
            {
                for (int z = -leaves; z <= leaves; z++)
                {
                    TerrainGen.SetBlock(chunk, "leaves", pos.Add(x,y,z), true);
                }
            }
        }
        for (int y = 0; y <= 5; y++)
        {
            TerrainGen.SetBlock(chunk, "log", pos.Add(0, y, 0), true);
        }
    }
示例#30
0
    public override void AddBlockData(Chunk chunk, BlockPos pos, MeshData meshData, Block block)
    {
        int initialVertCount = meshData.vertices.Count;

        foreach (var vert in verts)
        {
            meshData.AddVertex(vert + (Vector3)pos);

            if (uvs.Length == 0)
                meshData.uv.Add(new Vector2(0, 0));

            float lighting;
            if (Config.Toggle.BlockLighting)
            {
                lighting = block.data1 / 255f;
            }
            else
            {
                lighting = 1;
            }
            meshData.colors.Add(new Color(lighting, lighting, lighting, 1));
        }

        if (uvs.Length != 0)
        {
            Rect texture;
            if (collection != null)
                texture = collection.GetTexture(chunk, pos, Direction.down);
            else
                texture = new Rect();

            foreach (var uv in uvs)
            {
                meshData.uv.Add(new Vector2((uv.x * texture.width) + texture.x, (uv.y * texture.height) + texture.y));
            }
        }

        foreach (var tri in tris)
        {
            meshData.AddTriangle(tri + initialVertCount);
        }
    }
示例#31
0
        public override bool TryPlaceBlock(IWorldAccessor world, IPlayer byPlayer, ItemStack itemstack, BlockSelection blockSel, ref string failureCode)
        {
            Block blockExisting = world.BlockAccessor.GetBlock(blockSel.Position);

            if (!CanPlaceBlock(world, byPlayer, blockSel, ref failureCode, blockExisting))
            {
                return(false);
            }

            BlockFacing           firstFace     = null;
            BlockFacing           secondFace    = null;
            BlockMPMultiblockGear largeGearEdge = blockExisting as BlockMPMultiblockGear;
            bool validLargeGear = false;

            if (largeGearEdge != null)
            {
                BEMPMultiblock be = world.BlockAccessor.GetBlockEntity(blockSel.Position) as BEMPMultiblock;
                if (be != null)
                {
                    validLargeGear = be.Principal != null;
                }
            }

            foreach (BlockFacing face in BlockFacing.ALLFACES)
            {
                if (validLargeGear && (face == BlockFacing.UP || face == BlockFacing.DOWN))
                {
                    continue;
                }
                BlockPos pos = blockSel.Position.AddCopy(face);
                IMechanicalPowerBlock block = world.BlockAccessor.GetBlock(pos) as IMechanicalPowerBlock;
                if (block != null && block.HasMechPowerConnectorAt(world, pos, face.Opposite))
                {
                    if (firstFace == null)
                    {
                        firstFace = face;
                    }
                    else
                    {
                        if (face.IsAdjacent(firstFace))
                        {
                            secondFace = face;
                            break;
                        }
                    }
                }
            }

            if (firstFace != null)
            {
                BlockPos              firstPos  = blockSel.Position.AddCopy(firstFace);
                BlockEntity           be        = world.BlockAccessor.GetBlockEntity(firstPos);
                IMechanicalPowerBlock neighbour = be?.Block as IMechanicalPowerBlock;

                BEBehaviorMPAxle bempaxle = be?.GetBehavior <BEBehaviorMPAxle>();
                if (bempaxle != null && !BEBehaviorMPAxle.IsAttachedToBlock(world.BlockAccessor, neighbour as Block, firstPos))
                {
                    failureCode = "axlemusthavesupport";
                    return(false);
                }

                BlockEntity largeGearBE = validLargeGear ? largeGearEdge.GearPlaced(world, blockSel.Position) : null;

                Block toPlaceBlock = getGearBlock(world, validLargeGear, firstFace, secondFace);
                //world.BlockAccessor.RemoveBlockEntity(blockSel.Position);  //## needed in 1.12, but not with new chunk BlockEntity Dictionary in 1.13
                world.BlockAccessor.SetBlock(toPlaceBlock.BlockId, blockSel.Position);

                if (secondFace != null)
                {
                    BlockPos secondPos = blockSel.Position.AddCopy(secondFace);
                    IMechanicalPowerBlock neighbour2 = world.BlockAccessor.GetBlock(secondPos) as IMechanicalPowerBlock;
                    neighbour2?.DidConnectAt(world, secondPos, secondFace.Opposite);
                }

                BEBehaviorMPAngledGears beAngledGear = world.BlockAccessor.GetBlockEntity(blockSel.Position)?.GetBehavior <BEBehaviorMPAngledGears>();
                if (largeGearBE?.GetBehavior <BEBehaviorMPBase>() is BEBehaviorMPLargeGear3m largeGear)
                {
                    beAngledGear.AddToLargeGearNetwork(largeGear, firstFace);
                }

                //do this last even for the first face so that both neighbours are correctly set
                neighbour?.DidConnectAt(world, firstPos, firstFace.Opposite);
                beAngledGear.newlyPlaced = true;
                if (!beAngledGear.tryConnect(firstFace) && secondFace != null)
                {
                    beAngledGear.tryConnect(secondFace);
                }
                beAngledGear.newlyPlaced = false;

                return(true);
            }

            failureCode = "requiresaxle";

            return(false);
        }
示例#32
0
    void CheckAdjacent(BlockPos pos, Heuristics dist)
    {
        List <BlockPos> adjacentPositions = new List <BlockPos>();
        List <float>    distanceFromStart = new List <float>();

        //Cardinal directions
        adjacentPositions.Add(new BlockPos(pos.x, pos.y, pos.z + 1));
        distanceFromStart.Add(dist.g + 1);
        adjacentPositions.Add(new BlockPos(pos.x + 1, pos.y, pos.z));
        distanceFromStart.Add(dist.g + 1);
        adjacentPositions.Add(new BlockPos(pos.x, pos.y, pos.z - 1));
        distanceFromStart.Add(dist.g + 1);
        adjacentPositions.Add(new BlockPos(pos.x - 1, pos.y, pos.z));
        distanceFromStart.Add(dist.g + 1);

        //diagonal directions
        adjacentPositions.Add(new BlockPos(pos.x + 1, pos.y, pos.z + 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x + 1, pos.y, pos.z - 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x - 1, pos.y, pos.z - 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x - 1, pos.y, pos.z + 1));
        distanceFromStart.Add(dist.g + 1.414f);

        //climb up directions
        adjacentPositions.Add(new BlockPos(pos.x, pos.y + 1, pos.z + 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x + 1, pos.y + 1, pos.z));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x, pos.y + 1, pos.z - 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x - 1, pos.y + 1, pos.z));
        distanceFromStart.Add(dist.g + 1.414f);

        //climb down directions
        adjacentPositions.Add(new BlockPos(pos.x, pos.y - 1, pos.z + 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x + 1, pos.y - 1, pos.z));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x, pos.y - 1, pos.z - 1));
        distanceFromStart.Add(dist.g + 1.414f);
        adjacentPositions.Add(new BlockPos(pos.x - 1, pos.y - 1, pos.z));
        distanceFromStart.Add(dist.g + 1.414f);

        for (int i = 0; i < adjacentPositions.Count; i++)
        {
            if (!closed.ContainsKey(adjacentPositions[i]))
            {
                var h = new Heuristics(
                    distanceFromStart[i],
                    Distance(targetLocation,
                             adjacentPositions[i]),
                    pos);

                if (IsWalkable(world, adjacentPositions[i]))
                {
                    Heuristics existingTile;
                    if (open.TryGetValue(adjacentPositions[i], out existingTile))
                    {
                        if (existingTile.g > distanceFromStart[i])
                        {
                            open.Remove(adjacentPositions[i]);
                            open.Add(adjacentPositions[i], h);
                        }
                    }
                    else
                    {
                        open.Add(adjacentPositions[i], h);
                    }
                }
            }
        }
    }
示例#33
0
 public static ChunkPos FromWorldSpace(BlockPos pos) => FromWorldSpace(pos.X, pos.Z);
示例#34
0
 /// <summary>
 /// Called by the block info HUD for displaying additional information
 /// </summary>
 /// <param name="world"></param>
 /// <param name="pos"></param>
 /// <param name="forPlayer"></param>
 /// <returns></returns>
 public virtual string GetPlacedBlockInfo(IWorldAccessor world, BlockPos pos, IPlayer forPlayer)
 {
     return("");
 }
        /// <summary>
        /// For placement of ruins during worldgen, replaces the topsoil with the area specific soil (e.g. sand)
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="blocks"></param>
        /// <param name="startPos"></param>
        /// <param name="climateUpLeft"></param>
        /// <param name="climateUpRight"></param>
        /// <param name="climateBotLeft"></param>
        /// <param name="climateBotRight"></param>
        /// <param name="replaceblockids"></param>
        /// <returns></returns>
        public int PlaceRespectingBlockLayers(IBlockAccessor blockAccessor, IWorldAccessor worldForCollectibleResolve, BlockPos startPos, int climateUpLeft, int climateUpRight, int climateBotLeft, int climateBotRight, ushort[] replaceblockids, bool replaceMetaBlocks = true)
        {
            BlockPos curPos    = new BlockPos();
            int      placed    = 0;
            int      chunksize = blockAccessor.ChunkSize;


            for (int x = 0; x < SizeX; x++)
            {
                for (int z = 0; z < SizeZ; z++)
                {
                    curPos.Set(x + startPos.X, startPos.Y, z + startPos.Z);
                    IMapChunk mapchunk    = blockAccessor.GetMapChunkAtBlockPos(curPos);
                    int       rockblockid = mapchunk.TopRockIdMap[(curPos.Z % chunksize) * chunksize + curPos.X % chunksize];
                    int       depth       = 0;

                    int maxY = -1;

                    for (int y = SizeY - 1; y >= 0; y--)
                    {
                        curPos.Set(x + startPos.X, y + startPos.Y, z + startPos.Z);
                        Block newBlock = blocksByPos[x, y, z];
                        if (newBlock == null)
                        {
                            continue;
                        }

                        if (replaceMetaBlocks && newBlock == undergroundBlock)
                        {
                            continue;
                        }


                        if (newBlock.Replaceable < 1000)
                        {
                            if (replaceblockids.Length > depth && newBlock.BlockId == replaceblockids[depth])
                            {
                                int climate = GameMath.BiLerpRgbColor((float)x / chunksize, (float)z / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

                                newBlock = GetBlockLayerBlock((climate >> 8) & 0xff, (climate >> 16) & 0xff, startPos.Y, rockblockid, depth, newBlock, worldForCollectibleResolve.Blocks);
                            }
                            depth++;
                        }


                        Block oldBlock = blockAccessor.GetBlock(curPos);
                        int   p        = handler(blockAccessor, curPos, oldBlock, newBlock);
                        placed += p;

                        if (p > 0 && !newBlock.RainPermeable)
                        {
                            maxY = Math.Max(curPos.Y, maxY);
                        }


                        byte[] lightHsv = newBlock.GetLightHsv(blockAccessor, curPos);

                        if (lightHsv[2] > 0 && blockAccessor is IWorldGenBlockAccessor)
                        {
                            int chunkSize = blockAccessor.ChunkSize;
                            ((IWorldGenBlockAccessor)blockAccessor).ScheduleBlockLightUpdate(curPos.Copy(), oldBlock.BlockId, newBlock.BlockId);
                        }
                    }

                    // In the post pass the rain map does not update, so let's set it ourselves
                    if (maxY >= 0)
                    {
                        int lx = curPos.X % chunksize;
                        int lz = curPos.Z % chunksize;
                        mapchunk.RainHeightMap[lz * chunksize + lx] = (ushort)Math.Max(mapchunk.RainHeightMap[lz * chunksize + lx], maxY);
                    }
                }
            }

            PlaceEntitiesAndBlockEntities(blockAccessor, worldForCollectibleResolve, startPos);

            return(placed);
        }
示例#36
0
 public BlockPos Subtract(BlockPos pos)
 {
     return(new BlockPos(this.x - pos.x, this.y - pos.y, this.z - pos.z));
 }
示例#37
0
        public override void OnHeldInteractStart(IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandHandling handling)
        {
            IPlayer byPlayer = null;

            if (byEntity is IEntityPlayer)
            {
                byPlayer = byEntity.World.PlayerByUid(((IEntityPlayer)byEntity).PlayerUID);
            }


            if (byEntity.Controls.Sneak && blockSel != null)
            {
                IWorldAccessor world         = byEntity.World;
                Block          knappingBlock = world.GetBlock(new AssetLocation("knappingsurface"));
                if (knappingBlock == null)
                {
                    return;
                }

                Block block = world.BlockAccessor.GetBlock(blockSel.Position);
                if (!block.CanAttachBlockAt(byEntity.World.BlockAccessor, knappingBlock, blockSel.Position, BlockFacing.UP))
                {
                    return;
                }

                BlockPos pos = blockSel.Position.AddCopy(blockSel.Face);
                if (!world.BlockAccessor.GetBlock(pos).IsReplacableBy(knappingBlock))
                {
                    return;
                }

                BlockSelection placeSel = blockSel.Clone();
                placeSel.Position  = pos;
                placeSel.DidOffset = true;
                if (!knappingBlock.TryPlaceBlock(world, byPlayer, slot.Itemstack, placeSel))
                {
                    return;
                }

                if (knappingBlock.Sounds != null)
                {
                    world.PlaySoundAt(knappingBlock.Sounds.Place, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z);
                }

                BlockEntityKnappingSurface bec = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityKnappingSurface;
                if (bec != null)
                {
                    bec.BaseMaterial           = slot.Itemstack.Clone();
                    bec.BaseMaterial.StackSize = 1;

                    if (byEntity.World is IClientWorldAccessor)
                    {
                        bec.OpenDialog(world as IClientWorldAccessor, pos, slot.Itemstack);
                    }
                }

                slot.TakeOut(1);

                handling = EnumHandHandling.PreventDefaultAction;
                return;
            }

            base.OnHeldInteractStart(slot, byEntity, blockSel, entitySel, ref handling);
        }
        internal void CreateForestFloor(IBlockAccessor blockAccessor, TreeGenConfig config, BlockPos pos, LCGRandom rnd, int treesInChunkGenerated)
        {
            int grassLevelOffset = 0;
            // More grass coverage for jungles
            ClimateCondition climate = blockAccessor.GetClimateAt(pos, EnumGetClimateMode.WorldGenValues);

            if (climate.Temperature > 24 && climate.Rainfall > 160)
            {
                grassLevelOffset = 2;
            }

            short[] outline = outlineThreadSafe.Value;
            this.api = blockAccessor;

            float forestness = climate.ForestDensity * climate.ForestDensity * 4 * (climate.Fertility + 0.25f);


            // Only replace soil with forestFloor in certain climate conditions
            if (climate.Fertility <= 0.25 || forestness <= 0.4)
            {
                return;
            }

            // Otherwise adjust the strength of the effect according to forest density and fertility (fertility is higher for tropical forests)
            for (int i = 0; i < outline.Length; i++)
            {
                outline[i] = (short)(outline[i] * forestness + 0.3f);
            }

            // Blend the canopy outline outwards from the center in a way that ensures smoothness
            for (int pass = 0; pass < 7; pass++)
            {
                bool noChange = true;

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        if (x == 0 && z == 0)
                        {
                            continue;
                        }
                        int o = Math.Min((int)outline[(16 + z) * 33 + (16 + x)], 18 * 9);
                        if (o == 0)
                        {
                            continue;
                        }

                        int n1 = (17 + z) * 33 + (16 + x);
                        int n2 = (16 + z) * 33 + (17 + x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }

                        o  = Math.Min((int)outline[(16 - z) * 33 + (16 + x)], 18 * 9);
                        n1 = (15 - z) * 33 + (16 + x);
                        n2 = (16 - z) * 33 + (17 + x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }
                    }

                    for (int z = 0; z < 16; z++)
                    {
                        if (x == 0 && z == 0)
                        {
                            continue;
                        }
                        int o  = Math.Min((int)outline[(16 + z) * 33 + (16 - x)], 18 * 9);
                        int n1 = (17 + z) * 33 + (16 - x);
                        int n2 = (16 + z) * 33 + (15 - x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }

                        o  = Math.Min((int)outline[(16 - z) * 33 + (16 - x)], 18 * 9);
                        n1 = (15 - z) * 33 + (16 - x);
                        n2 = (16 - z) * 33 + (15 - x);
                        if (outline[n1] < o - 18)
                        {
                            outline[n1] = (short)(o - 18);
                            noChange    = false;
                        }
                        if (outline[n2] < o - 18)
                        {
                            outline[n2] = (short)(o - 18);
                            noChange    = false;
                        }
                    }
                }
                if (noChange)
                {
                    break;
                }
            }


            BlockPos currentPos = new BlockPos();

            for (int canopyIndex = 0; canopyIndex < outline.Length; canopyIndex++)
            {
                int intensity = outline[canopyIndex];
                if (intensity == 0)
                {
                    continue;
                }

                int dz = canopyIndex / 33 - 16;
                int dx = canopyIndex % 33 - 16;
                currentPos.Set(pos.X + dx, pos.Y, pos.Z + dz);
                currentPos.Y = blockAccessor.GetTerrainMapheightAt(currentPos);

                if (currentPos.Y - pos.Y < 4)  //Don't place forest floor above approximate height of the canopy of this tree
                {
                    CheckAndReplaceForestFloor(currentPos, intensity, grassLevelOffset);
                }
            }

            GenPatches(blockAccessor, pos, forestness, config.Treetype, rnd);
        }
示例#39
0
        public static MeshData CreateMesh(ICoreClientAPI coreClientAPI, List <uint> voxelCuboids, int[] materials, BlockPos posForRnd = null)
        {
            MeshData mesh = new MeshData(24, 36, false).WithColorMaps().WithRenderpasses().WithXyzFaces();

            if (voxelCuboids == null || materials == null)
            {
                return(mesh);
            }
            CuboidWithMaterial cwm = tmpCuboid;

            for (int i = 0; i < voxelCuboids.Count; i++)
            {
                FromUint(voxelCuboids[i], cwm);

                Block block = coreClientAPI.World.GetBlock(materials[cwm.Material]);

                float subPixelPaddingx = coreClientAPI.BlockTextureAtlas.SubPixelPaddingX;
                float subPixelPaddingy = coreClientAPI.BlockTextureAtlas.SubPixelPaddingY;

                int altNum = 0;

                if (block.HasAlternates && posForRnd != null)
                {
                    int altcount = 0;
                    foreach (var val in block.Textures)
                    {
                        BakedCompositeTexture bct = val.Value.Baked;
                        if (bct.BakedVariants == null)
                        {
                            continue;
                        }
                        altcount = Math.Max(altcount, bct.BakedVariants.Length);
                    }

                    altNum = block.RandomizeAxes == EnumRandomizeAxes.XYZ ? GameMath.MurmurHash3Mod(posForRnd.X, posForRnd.Y, posForRnd.Z, altcount) : GameMath.MurmurHash3Mod(posForRnd.X, 0, posForRnd.Z, altcount);
                }

                MeshData cuboidmesh = genCube(
                    cwm.X1, cwm.Y1, cwm.Z1,
                    cwm.X2 - cwm.X1, cwm.Y2 - cwm.Y1, cwm.Z2 - cwm.Z1,
                    coreClientAPI,
                    coreClientAPI.Tesselator.GetTexSource(block, altNum, true),
                    subPixelPaddingx,
                    subPixelPaddingy,
                    block
                    );

                mesh.AddMeshData(cuboidmesh);
            }

            return(mesh);
        }
示例#40
0
        public override void OnNeighbourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
        {
            string orients = Orientation;

            if (orients.Length == 2 && orients[0] == orients[1])
            {
                orients = "" + orients[0];
            }

            BlockFacing[] facings;
            facings = orients.Length == 1 ? new BlockFacing[] { BlockFacing.FromFirstLetter(orients[0]) } : new BlockFacing[] { BlockFacing.FromFirstLetter(orients[0]), BlockFacing.FromFirstLetter(orients[1]) };

            List <BlockFacing> lostFacings = new List <BlockFacing>();

            foreach (BlockFacing facing in facings)
            {
                BlockPos npos = pos.AddCopy(facing);
                IMechanicalPowerBlock nblock = world.BlockAccessor.GetBlock(npos) as IMechanicalPowerBlock;

                if (nblock == null || !nblock.HasMechPowerConnectorAt(world, npos, facing.Opposite) || world.BlockAccessor.GetBlockEntity(pos)?.GetBehavior <BEBehaviorMPBase>()?.disconnected == true)
                {
                    lostFacings.Add(facing);
                }
            }

            if (lostFacings.Count == orients.Length)
            {
                world.BlockAccessor.BreakBlock(pos, null);
                return;
            }

            if (lostFacings.Count > 0)
            {
                orients = orients.Replace("" + lostFacings[0].Code[0], "");
                Block toPlaceBlock = world.GetBlock(new AssetLocation(FirstCodePart() + "-" + orients));
                (toPlaceBlock as BlockMPBase).ExchangeBlockAt(world, pos);
                BlockEntity      be   = world.BlockAccessor.GetBlockEntity(pos);
                BEBehaviorMPBase bemp = be.GetBehavior <BEBehaviorMPBase>();
                bemp.LeaveNetwork();


                //check for connect to adjacent valid facings, similar to TryPlaceBlock
                BlockFacing           firstFace = BlockFacing.FromFirstLetter(orients[0]);
                BlockPos              firstPos  = pos.AddCopy(firstFace);
                BlockEntity           beNeib    = world.BlockAccessor.GetBlockEntity(firstPos);
                IMechanicalPowerBlock neighbour = beNeib?.Block as IMechanicalPowerBlock;

                BEBehaviorMPAxle bempaxle = beNeib?.GetBehavior <BEBehaviorMPAxle>();
                if (bempaxle != null && !BEBehaviorMPAxle.IsAttachedToBlock(world.BlockAccessor, neighbour as Block, firstPos))
                {
                    return;
                }
                neighbour?.DidConnectAt(world, firstPos, firstFace.Opposite);
                WasPlaced(world, pos, firstFace);
            }
        }
示例#41
0
        public override void OnHeldInteractStart(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, bool firstEvent, ref EnumHandHandling handHandling)
        {
            if (blockSel == null || byEntity?.World == null || !byEntity.Controls.Sneak)
            {
                return;
            }

            IWorldAccessor world = byEntity.World;

            BlockPos offsetedPos = blockSel.Position.AddCopy(blockSel.Face);
            BlockPos belowPos    = offsetedPos.DownCopy();

            Block targetedBlock = world.BlockAccessor.GetBlock(blockSel.Position);
            Block nextblock;


            AssetLocation loc           = new AssetLocation(this.Attributes["blockfirstcodepart"].AsString());
            string        firstcodepart = loc.Path;

            IPlayer player = byEntity.World.PlayerByUid((byEntity as EntityPlayer)?.PlayerUID);

            if (!byEntity.World.Claims.TryAccess(player, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak))
            {
                slot.MarkDirty();
                return;
            }

            if (targetedBlock.FirstCodePart() == firstcodepart)
            {
                int stage = 1;
                int.TryParse(targetedBlock.LastCodePart(), out stage);
                if (stage == 9)
                {
                    return;
                }

                nextblock = world.GetBlock(targetedBlock.CodeWithPart("" + (stage + 1), 1));

                world.BlockAccessor.SetBlock(nextblock.BlockId, blockSel.Position);
            }
            else
            {
                nextblock = byEntity.World.GetBlock(loc.WithPathAppendix("-1"));
                if (nextblock == null)
                {
                    return;
                }

                Block blockAtTargetPos = world.BlockAccessor.GetBlock(offsetedPos);
                if (!blockAtTargetPos.IsReplacableBy(nextblock))
                {
                    return;
                }
                if (!world.BlockAccessor.GetBlock(belowPos).SideSolid[BlockFacing.UP.Index])
                {
                    return;
                }

                world.BlockAccessor.SetBlock(nextblock.BlockId, offsetedPos);
            }

            slot.TakeOut(1);
            slot.MarkDirty();

            if (nextblock.Sounds != null)
            {
                IPlayer byPlayer = null;
                if (byEntity is EntityPlayer)
                {
                    byPlayer = byEntity.World.PlayerByUid(((EntityPlayer)byEntity).PlayerUID);
                }
                world.PlaySoundAt(nextblock.Sounds.Place, blockSel.Position.X, blockSel.Position.Y, blockSel.Position.Z, byPlayer);
            }

            handHandling = EnumHandHandling.PreventDefault;
        }
示例#42
0
 public override BlockDropItemStack[] GetDropsForHandbook(IWorldAccessor world, BlockPos pos, IPlayer byPlayer)
 {
     return(GetHandbookDropsFromBreakDrops(world, pos, byPlayer));
 }
示例#43
0
 public override Cuboidf[] GetSelectionBoxes(IBlockAccessor world, BlockPos pos)
 {
     return(selectionBoxes);
 }
示例#44
0
 public override bool CanAttachBlockAt(IBlockAccessor world, Block block, BlockPos pos, BlockFacing blockFace)
 {
     return(false);
 }
示例#45
0
        public override void OnNeighourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
        {
            string newFacingLetters = "";

            foreach (BlockFacing facing in ownFacings)
            {
                Block block = world.BlockAccessor.GetBlock(pos.X + facing.Normali.X, pos.Y + facing.Normali.Y, pos.Z + facing.Normali.Z);

                if (block.SideSolid[facing.GetOpposite().Index])
                {
                    newFacingLetters += facing.Code.Substring(0, 1);
                }
            }

            if (ownFacings.Length <= newFacingLetters.Length)
            {
                return;
            }

            if (newFacingLetters.Length == 0)
            {
                world.BlockAccessor.BreakBlock(pos, null);
                return;
            }

            int diff = newFacingLetters.Length - ownFacings.Length;

            for (int i = 0; i < diff; i++)
            {
                world.SpawnItemEntity(Drops[0].GetNextItemStack(), pos.ToVec3d().AddCopy(0.5, 0.5, 0.5));
            }

            Block newblock = world.GetBlock(CodeWithPath(FirstCodePart() + "-" + newFacingLetters));

            world.BlockAccessor.SetBlock(newblock.BlockId, pos);
        }
示例#46
0
 public override ItemStack OnPickBlock(IWorldAccessor world, BlockPos pos)
 {
     return(new ItemStack(world.GetBlock(new AssetLocation("angledgears-s"))));
 }
 public abstract void GenDeposit(IBlockAccessor blockAccessor, IServerChunk[] chunks, int originChunkX, int originChunkZ, BlockPos pos, ref Dictionary <BlockPos, DepositVariant> subDepositsToPlace);
示例#48
0
 public override void RemoveTileEntity(BlockPos pos)
 {
     GetChunk(pos.ChunkPos())?.RemoveTileEntity(ChunkPos.ToChunkLocal(pos));
 }
        private void GenPatches(IBlockAccessor blockAccessor, BlockPos pos, float forestNess, EnumTreeType treetype, LCGRandom rnd)
        {
            var bpc         = genPatchesSystem.bpc;
            int radius      = 5;
            int worldheight = blockAccessor.MapSizeY;

            int cnt = underTreePatches?.Count ?? 0;

            for (int i = 0; i < cnt; i++)
            {
                BlockPatch bPatch = underTreePatches[i];
                if (bPatch.TreeType != EnumTreeType.Any && bPatch.TreeType != treetype)
                {
                    continue;
                }

                float chance = 0.003f * forestNess * bPatch.Chance * bpc.ChanceMultiplier.nextFloat();

                //if (bPatch.blockCodes[0].Path.Contains("mushroom")) chance *= 20; - for debugging

                while (chance-- > rnd.NextDouble())
                {
                    int dx = rnd.NextInt(2 * radius) - radius;
                    int dz = rnd.NextInt(2 * radius) - radius;

                    tmpPos.Set(pos.X + dx, 0, pos.Z + dz);

                    int y = blockAccessor.GetTerrainMapheightAt(tmpPos);
                    if (y <= 0 || y >= worldheight - 8)
                    {
                        continue;
                    }

                    tmpPos.Y = y;

                    var climate = blockAccessor.GetClimateAt(tmpPos, EnumGetClimateMode.WorldGenValues);
                    if (climate == null)
                    {
                        continue;
                    }

                    if (bpc.IsPatchSuitableUnderTree(bPatch, worldheight, climate, y))
                    {
                        int regionX = pos.X / blockAccessor.RegionSize;
                        int regionZ = pos.Z / blockAccessor.RegionSize;
                        if (bPatch.MapCode != null && rnd.NextInt(255) > genPatchesSystem.GetPatchDensity(bPatch.MapCode, tmpPos.X, tmpPos.Z, blockAccessor.GetMapRegion(regionX, regionZ)))
                        {
                            continue;
                        }

                        int  firstBlockId = 0;
                        bool found        = true;

                        if (bPatch.BlocksByRockType != null)
                        {
                            found = false;
                            int dy = 1;
                            while (dy < 5 && y - dy > 0)
                            {
                                string lastCodePart = blockAccessor.GetBlock(tmpPos.X, y - dy, tmpPos.Z).LastCodePart();
                                if (genPatchesSystem.RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId))
                                {
                                    found = true; break;
                                }
                                dy++;
                            }
                        }

                        if (found)
                        {
                            bPatch.Generate(blockAccessor, rnd, tmpPos.X, tmpPos.Y, tmpPos.Z, firstBlockId);
                        }
                    }
                }
            }

            cnt = onTreePatches?.Count ?? 0;
            for (int i = 0; i < cnt; i++)
            {
                BlockPatch blockPatch = onTreePatches[i];

                float chance = 3 * forestNess * blockPatch.Chance * bpc.ChanceMultiplier.nextFloat();

                while (chance-- > rnd.NextDouble())
                {
                    int dx = 1 - rnd.NextInt(2) * 2;
                    int dy = rnd.NextInt(5);
                    int dz = 1 - rnd.NextInt(2) * 2;

                    tmpPos.Set(pos.X + dx, pos.Y + dy, pos.Z + dz);

                    var block = api.GetBlock(tmpPos);
                    if (block.Id != 0)
                    {
                        continue;
                    }
                    BlockFacing facing = null;

                    for (int j = 0; j < 4; j++)
                    {
                        var f      = BlockFacing.HORIZONTALS[j];
                        var nblock = api.GetBlock(tmpPos.X + f.Normali.X, tmpPos.Y, tmpPos.Z + f.Normali.Z);
                        if (nblock is BlockLog && nblock.Variant["type"] != "resin")
                        {
                            facing = f;
                            break;
                        }
                    }
                    if (facing == null)
                    {
                        break;
                    }

                    var climate = blockAccessor.GetClimateAt(tmpPos, EnumGetClimateMode.WorldGenValues);
                    if (climate == null)
                    {
                        continue;
                    }

                    if (bpc.IsPatchSuitableUnderTree(blockPatch, worldheight, climate, tmpPos.Y))
                    {
                        int regionX = pos.X / blockAccessor.RegionSize;
                        int regionZ = pos.Z / blockAccessor.RegionSize;
                        if (blockPatch.MapCode != null && rnd.NextInt(255) > genPatchesSystem.GetPatchDensity(blockPatch.MapCode, tmpPos.X, tmpPos.Z, blockAccessor.GetMapRegion(regionX, regionZ)))
                        {
                            continue;
                        }

                        int index = rnd.NextInt(blockPatch.Blocks.Length);
                        blockPatch.Blocks[index].TryPlaceBlockForWorldGen(blockAccessor, tmpPos, facing, rnd);
                    }
                }
            }
        }
示例#50
0
        public override void carvePiece(Chunk chunk, System.Random rnd)
        {
            BlockPos p1 = this.getPosMin();
            BlockPos p2 = this.getPosMax();
            int      chunkCoordX, chunkCoordY, chunkCoordZ, offsetX, offsetY, offsetZ;
            Block    b;
            byte     meta;

            for (int i = p1.x; i <= p2.x; i++)
            {
                for (int j = p1.y; j <= p2.y; j++)
                {
                    for (int k = p1.z; k <= p2.z; k++)
                    {
                        if (chunk.isInChunk(i, j, k))
                        {
                            b           = Block.air;
                            meta        = 0;
                            chunkCoordX = i - chunk.worldPos.x;
                            chunkCoordY = j - chunk.worldPos.y;
                            chunkCoordZ = k - chunk.worldPos.z;
                            offsetX     = i - this.orgin.x;
                            offsetY     = j - this.orgin.y;
                            offsetZ     = k - this.orgin.z;

                            // Columns
                            if (Mathf.Abs(offsetX) == 2 && Mathf.Abs(offsetZ) == 2)
                            {
                                b    = Block.wood;
                                meta = 1;
                            }
                            // Bottom floor, if it's there
                            else if (this.isBottom && offsetY == 0)
                            {
                                if (Random.Range(0, 2) == 0)
                                {
                                    b = Block.stone;
                                }
                                else
                                {
                                    b = Block.gravel;
                                }
                            }
                            // Ladder
                            else if (offsetX == -3 && offsetZ == 3)
                            {
                                b    = Block.ladder;
                                meta = 0;
                            }
                            // Floor
                            else if (!this.isBottom && offsetY == 0)
                            {
                                int absX = Mathf.Abs(offsetX);
                                int absZ = Mathf.Abs(offsetZ);
                                if (absX == 3 || absZ == 3)
                                {
                                    b = Block.plank;
                                }
                                else if (absX == 2 && absZ < 2)
                                {
                                    b    = Block.wood;
                                    meta = 2;
                                }
                                else if (absZ == 2 && absX < 2)
                                {
                                    b    = Block.wood;
                                    meta = 0;
                                }
                            }
                            // Railing
                            else if (!this.isBottom && offsetY == 1)
                            {
                                int absX = Mathf.Abs(offsetX);
                                int absZ = Mathf.Abs(offsetZ);
                                if (((absX == 2 && absZ < 2) || (absZ == 2 && absX < 2)) && rnd.Next(10) != 0)
                                {
                                    b = Block.fence;
                                }
                            }

                            chunk.setBlock(chunkCoordX, chunkCoordY, chunkCoordZ, b);
                            chunk.setMeta(chunkCoordX, chunkCoordY, chunkCoordZ, meta);
                        }
                    }
                }
            }
        }
示例#51
0
 public Cuboidf[] GetCollisionBoxes(IBlockAccessor blockAccessor, BlockPos pos)
 {
     return(selectionBoxes);
 }
示例#52
0
 public BlockPos Add(BlockPos pos)
 {
     return(new BlockPos(this.x + pos.x, this.y + pos.y, this.z + pos.z));
 }
示例#53
0
 public virtual void OnBlockExploded(IWorldAccessor world, BlockPos pos, BlockPos explosionCenter, EnumBlastType blastType, ref EnumHandling handling)
 {
     handling = EnumHandling.PassThrough;
 }
示例#54
0
        public List <Vec3d> FindPathAsWaypoints(BlockPos start, BlockPos end, int maxFallHeight, float stepHeight, Cuboidf entityCollBox, int searchDepth = 9999, bool allowReachAlmost = false)
        {
            List <PathNode> nodes = FindPath(start, end, maxFallHeight, stepHeight, entityCollBox, searchDepth, allowReachAlmost);

            return(nodes == null ? null : ToWaypoints(nodes));
        }
示例#55
0
 /// <summary>
 /// Step 4: Block was placed. Always called when a block has been placed through whatever method, except during worldgen or via ExchangeBlock()
 /// Be aware that the vanilla OnBlockPlaced block behavior is to spawn the block entity if any is associated with this block, so this code will not get executed if you set handled to PreventDefault or Last
 /// </summary>
 /// <param name="world"></param>
 /// <param name="blockPos"></param>
 /// <param name="handling"></param>
 public virtual void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ref EnumHandling handling)
 {
     handling = EnumHandling.PassThrough;
 }
示例#56
0
 public PieceSmallShaft(StructureMineshaft shaft, BlockPos orgin, int height, bool isBottom) : base(shaft, orgin)
 {
     this.height   = height;
     this.isBottom = isBottom;
     this.calculateBounds();
 }
示例#57
0
        protected virtual void UpdateCustomFloatBuffer()
        {
            Vec3d camera            = capi.World.Player.Entity.CameraPos;
            float windSpeed         = API.Config.GlobalConstants.CurrentWindSpeedClient.X;
            float windWaveIntensity = 1.0f;
            float div = 30 * 3.5f;  //weakwave

            DefaultShaderUniforms shUniforms = capi.Render.ShaderUniforms;

            float wwaveHighFreq = shUniforms.WindWaveCounterHighFreq;
            float counter       = shUniforms.WindWaveCounter;

            int i = 0;

            foreach (var fruit in positions)
            {
                Vec3d  pos  = fruit.Key;
                Vec3f  rot  = fruit.Value.rotation;
                double posX = pos.X;
                double posY = pos.Y;
                double posZ = pos.Z;
                float  rotY = rot.Y;
                float  rotX = rot.X;
                float  rotZ = rot.Z;

                if (onGround)
                {
                    BlockPos blockPos = fruit.Value.behavior.Blockentity.Pos;
                    posY  = blockPos.Y - 0.0625;
                    posX += 1.1 * (posX - blockPos.X - 0.5);  //fruit on ground positioned further out from the plant center
                    posZ += 1.1 * (posZ - blockPos.Z - 0.5);
                    rot   = noRotation;
                    rotY  = (float)((posX + posZ) * 40 % 90); //some random rotation
                }
                else
                {
                    // Apply windwave

                    // Precisely replicate the effects of vertexwarp.vsh ... except where noted in comments below!
                    double x          = posX;
                    double y          = posY;
                    double z          = posZ;
                    float  heightBend = 0.7f * (0.5f + (float)y - (int)y);
                    double strength   = windWaveIntensity * (1 + windSpeed) * (0.5 + (posY - fruit.Value.behavior.Blockentity.Pos.Y)) / 2.0; // reduce the strength for lower fruit

                    v.Set((float)x % 4096f / 10, (float)z % 4096f / 10, counter % 1024f / 4);
                    float bendNoise = windSpeed * 0.2f + 1.4f * gnoise(v);

                    float bend = windSpeed * (0.8f + bendNoise) * heightBend * windWaveIntensity;
                    bend = Math.Min(4, bend) * 0.2857143f / 2.8f;    //no idea why this reduction by a factor of approximately 10 is needed, but it looks right

                    x        += wwaveHighFreq;
                    y        += wwaveHighFreq;
                    z        += wwaveHighFreq;
                    strength *= 0.25f;  // reduced strength because it looks right (fruits are less wobbly and closer to the center of the plant, compared with the foliage texture vertex tips)
                    double dx = strength * (Math.Sin(x * 10) / 120 + (2 * Math.Sin(x / 2) + Math.Sin(x + y) + Math.Sin(0.5 + 4 * x + 2 * y) + Math.Sin(1 + 6 * x + 3 * y) / 3) / div);
                    double dz = strength * ((2 * Math.Sin(z / 4) + Math.Sin(z + 3 * y) + Math.Sin(0.5 + 4 * z + 2 * y) + Math.Sin(1 + 6 * z + y) / 3) / div);
                    posX += dx;
                    posY += strength * (Math.Sin(5 * y) / 15 + Math.Cos(10 * x) / 10 + Math.Sin(3 * z) / 2 + Math.Cos(x * 2) / 2.2) / div;
                    posZ += dz;

                    // Also apply a small wind effect to the rotation, otherwise the fruits look 'stiff' because they remain upright
                    rotX += (float)(dz * 6 + bend / 2);
                    rotZ += (float)(dx * 6 + bend / 2);
                    posX += bend;
                }

                //double precision subtraction is needed here (even though the desired result is a float).
                // It's needed to have enough significant figures in the result, as the integer size could be large e.g. 50000 but the difference should be small (can easily be less than 5)
                tmp.Set((float)(posX - camera.X), (float)(posY - camera.Y), (float)(posZ - camera.Z));

                UpdateLightAndTransformMatrix(matrixAndLightFloats.Values, i, tmp, fruit.Value.behavior.LightRgba, rotX, rotY, rotZ);
                i++;
            }
        }
示例#58
0
 public static BlockPos ToChunkLocal(BlockPos worldPos)
 {
     return(new BlockPos(MathUtil.ToLocal(worldPos.X, Chunk.ChunkSize), MathUtil.Clamp(worldPos.Y, 0, 255), MathUtil.ToLocal(worldPos.Z, Chunk.ChunkSize)));
 }
示例#59
0
 public Heuristics(float g, float h, BlockPos parent)
 {
     this.g      = g;
     this.h      = h;
     this.parent = parent;
 }
示例#60
0
        private void onCmdAStar(IServerPlayer player, int groupId, CmdArgs args)
        {
            string subcmd = args.PopWord();

            BlockPos       plrPos = player.Entity.ServerPos.XYZ.AsBlockPos;
            PathfindSystem pfs    = sapi.ModLoader.GetModSystem <PathfindSystem>();

            Cuboidf narrow = new Cuboidf(-0.45f, 0, -0.45f, 0.45f, 1.5f, 0.45f);
            Cuboidf wide   = new Cuboidf(-0.6f, 0, -0.6f, 0.6f, 1.5f, 0.6f);

            Cuboidf collbox       = narrow;
            int     maxFallHeight = 3;
            float   stepHeight    = 1.01f;


            switch (subcmd)
            {
            case "start":
                start = plrPos.Copy();
                sapi.World.HighlightBlocks(player, 26, new List <BlockPos>()
                {
                    start
                }, new List <int>()
                {
                    ColorUtil.ColorFromRgba(255, 255, 0, 128)
                }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                break;

            case "end":
                end = plrPos.Copy();
                sapi.World.HighlightBlocks(player, 27, new List <BlockPos>()
                {
                    end
                }, new List <int>()
                {
                    ColorUtil.ColorFromRgba(255, 0, 255, 128)
                }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                break;

            case "bench":
                if (start == null || end == null)
                {
                    return;
                }

                Stopwatch sw = new Stopwatch();
                sw.Start();

                for (int i = 0; i < 15; i++)
                {
                    List <PathNode> nodes = pfs.FindPath(start, end, maxFallHeight, stepHeight, collbox);
                }

                sw.Stop();
                float timeMs = (float)sw.ElapsedMilliseconds / 15f;

                player.SendMessage(groupId, string.Format("15 searches average: {0} ms", (int)timeMs), EnumChatType.Notification);
                return;

            case "clear":
                start = null;
                end   = null;

                sapi.World.HighlightBlocks(player, 2, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                sapi.World.HighlightBlocks(player, 26, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                sapi.World.HighlightBlocks(player, 27, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                break;
            }

            if (start == null || end == null)
            {
                sapi.World.HighlightBlocks(player, 2, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
            }
            if (start != null && end != null)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();


                List <PathNode> nodes = pfs.FindPath(start, end, maxFallHeight, stepHeight, collbox);
                sw.Stop();
                int timeMs = (int)sw.ElapsedMilliseconds;

                player.SendMessage(groupId, string.Format("Search took {0} ms, {1} nodes checked", timeMs, pfs.astar.NodesChecked), EnumChatType.Notification);

                if (nodes == null)
                {
                    player.SendMessage(groupId, "No path found", EnumChatType.CommandError);

                    sapi.World.HighlightBlocks(player, 2, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                    sapi.World.HighlightBlocks(player, 3, new List <BlockPos>(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
                    return;
                }

                List <BlockPos> poses = new List <BlockPos>();
                foreach (var node in nodes)
                {
                    poses.Add(node);
                }

                sapi.World.HighlightBlocks(player, 2, poses, new List <int>()
                {
                    ColorUtil.ColorFromRgba(128, 128, 128, 30)
                }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);


                List <Vec3d> wps = pfs.ToWaypoints(nodes);
                poses = new List <BlockPos>();
                foreach (var node in wps)
                {
                    poses.Add(node.AsBlockPos);
                }

                sapi.World.HighlightBlocks(player, 3, poses, new List <int>()
                {
                    ColorUtil.ColorFromRgba(128, 0, 0, 100)
                }, EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary);
            }
        }