示例#1
0
 public static BlockPos[] AreaAround(BlockPos Pos)
 {
     return(new BlockPos[]
     {
         Pos,
         Pos.NorthCopy(),
         Pos.SouthCopy(),
         Pos.EastCopy(),
         Pos.WestCopy(),
         Pos.NorthCopy().EastCopy(),
         Pos.SouthCopy().WestCopy(),
         Pos.EastCopy().SouthCopy(),
         Pos.WestCopy().NorthCopy(),
     });
 }
示例#2
0
        private string getCode(IWorldAccessor world, BlockPos pos)
        {
            var code = "";

            // This is really screwy, and I don't feel like figuring out why. It works, don't mess with it.
            // (It probably has something to do with the block rotation)
            // Also, I can't use SideSolid or it won't connect to lanterns and signs.
            if (world.BlockAccessor.GetBlock(pos.WestCopy()).Id != 0)
            {
                code += "n";
            }
            if (world.BlockAccessor.GetBlock(pos.NorthCopy()).Id != 0)
            {
                code += "e";
            }
            if (world.BlockAccessor.GetBlock(pos.EastCopy()).Id != 0)
            {
                code += "s";
            }
            if (world.BlockAccessor.GetBlock(pos.SouthCopy()).Id != 0)
            {
                code += "w";
            }

            // Now hande the "no connections" case.
            if (code == "")
            {
                code = "empty";
            }
            return(code);
        }
        public override void OnAsyncClientParticleTick(IAsyncParticleManager manager, BlockPos pos, float windAffectednessAtPos, float secondsTicking)
        {
            double rand = random.NextDouble() * 50d;

            if (rand > 1d)
            {
                return;
            }

            double rainLevel = ((WeatherSystemClient)weatherSystem).GetActualRainLevel(pos, true);

            IBlockAccessor accessor = manager.BlockAccess;
            double         count    = 1d;

            count += accessor.GetBlock(pos.NorthCopy()) is BlockSticksLayer ? 0.25 : 0;
            count += accessor.GetBlock(pos.SouthCopy()) is BlockSticksLayer ? 0.25 : 0;
            count += accessor.GetBlock(pos.WestCopy()) is BlockSticksLayer ? 0.25 : 0;
            count += accessor.GetBlock(pos.EastCopy()) is BlockSticksLayer ? 0.25 : 0;
            // Reduced drips if similar blocks adjacent, otherwise there can be a lot of drops on a large roof

            if (rainLevel > rand * count)
            {
                waterParticles.MinPos.Set(pos.X, pos.Y - 0.05, pos.Z);
                manager.Spawn(waterParticles);
            }
        }
        private string getCode(IWorldAccessor world, BlockPos pos, string dir)
        {
            bool solid;

            switch (dir)
            {
            case "north":
                solid = world.BlockAccessor.GetBlock(pos.EastCopy()).Id != 0;
                break;

            case "south":
                solid = world.BlockAccessor.GetBlock(pos.WestCopy()).Id != 0;
                break;

            case "east":
                solid = world.BlockAccessor.GetBlock(pos.SouthCopy()).Id != 0;
                break;

            case "west":
                solid = world.BlockAccessor.GetBlock(pos.NorthCopy()).Id != 0;
                break;

            default:
                // Should be impossible.
                solid = false;
                break;
            }
            return(solid ? "long" : "short");
        }
示例#5
0
        public static BlockPos[] AreaBelow(BlockPos Pos)
        {
            BlockPos aPos = Pos.DownCopy();

            return(new BlockPos[]
            {
                aPos,
                aPos.NorthCopy(),
                aPos.SouthCopy(),
                aPos.EastCopy(),
                aPos.WestCopy(),
                aPos.NorthCopy().EastCopy(),
                aPos.SouthCopy().WestCopy(),
                aPos.EastCopy().SouthCopy(),
                aPos.WestCopy().NorthCopy(),
            });
        }
示例#6
0
        public static BlockPos[] AreaAbove(BlockPos Pos)
        {
            BlockPos aPos = Pos.UpCopy();

            return(new BlockPos[]
            {
                aPos,
                aPos.NorthCopy(),
                aPos.SouthCopy(),
                aPos.EastCopy(),
                aPos.WestCopy(),
                aPos.NorthCopy().EastCopy(),
                aPos.SouthCopy().WestCopy(),
                aPos.EastCopy().SouthCopy(),
                aPos.WestCopy().NorthCopy(),
            });
        }
示例#7
0
 public static Dictionary <string, BlockPos> DirectionDict(BlockPos pos)
 {
     return(new Dictionary <string, BlockPos>
     {
         { "north", pos.NorthCopy() },
         { "south", pos.SouthCopy() },
         { "east", pos.EastCopy() },
         { "west", pos.WestCopy() }
     });
 }
示例#8
0
 public static Dictionary <BlockPos, string> CardinalDict(BlockPos pos)
 {
     return(new Dictionary <BlockPos, string>
     {
         { pos.NorthCopy(), "north" },
         { pos.SouthCopy(), "south" },
         { pos.EastCopy(), "east" },
         { pos.WestCopy(), "west" }
     });
 }
示例#9
0
 public static BlockPos[] Cardinal(BlockPos Pos)
 {
     return(new BlockPos[]
     {
         Pos.NorthCopy(),
         Pos.SouthCopy(),
         Pos.EastCopy(),
         Pos.WestCopy(),
     });
 }
示例#10
0
 public static BlockPos[] FullCardinal(BlockPos pos)
 {
     return(new BlockPos[]
     {
         pos.UpCopy(),
         pos.DownCopy(),
         pos.NorthCopy(),
         pos.SouthCopy(),
         pos.EastCopy(),
         pos.WestCopy(),
     });
 }
        //-- If the block that this crystal is butting up against is broken...the crystal should break, too --//
        public override void OnNeighbourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos)
        {
            string codeLastPart = LastCodePart(0);

            switch (codeLastPart)
            {
            case "ore_up":
                if (world.BlockAccessor.GetBlockId(pos.UpCopy(1)) == 0)
                {
                    world.BlockAccessor.BreakBlock(pos, null);
                }
                break;

            case "ore_down":
                if (world.BlockAccessor.GetBlockId(pos.DownCopy(1)) == 0)
                {
                    world.BlockAccessor.BreakBlock(pos, null);
                }
                break;

            case "ore_north":
                if (world.BlockAccessor.GetBlockId(pos.NorthCopy(1)) == 0)
                {
                    world.BlockAccessor.BreakBlock(pos, null);
                }
                break;

            case "ore_south":
                if (world.BlockAccessor.GetBlockId(pos.SouthCopy(1)) == 0)
                {
                    world.BlockAccessor.BreakBlock(pos, null);
                }
                break;

            case "ore_east":
                if (world.BlockAccessor.GetBlockId(pos.EastCopy(1)) == 0)
                {
                    world.BlockAccessor.BreakBlock(pos, null);
                }
                break;

            case "ore_west":
                if (world.BlockAccessor.GetBlockId(pos.WestCopy(1)) == 0)
                {
                    world.BlockAccessor.BreakBlock(pos, null);
                }
                break;

            default:
                break;
            }
        }
示例#12
0
        public static AssetLocation[] GetCardinal(IWorldAccessor world, BlockPos pos)
        {
            var bA = world.BlockAccessor;

            AssetLocation[] cardinal =
            {
                bA.GetBlock(pos.NorthCopy()).Code,
                bA.GetBlock(pos.SouthCopy()).Code,
                bA.GetBlock(pos.EastCopy()).Code,
                bA.GetBlock(pos.WestCopy()).Code,
            };
            return(cardinal);
        }
示例#13
0
        protected virtual BlockFacing OrientForPlacement(IBlockAccessor world, IPlayer player, BlockSelection bs)
        {
            BlockFacing[] facings   = SuggestedHVOrientation(player, bs);
            BlockFacing   suggested = facings.Length > 0 ? facings[0] : null;
            BlockPos      pos       = bs.Position;

            // Logic waterfall for smart placement:
            // 1. if adjacent Sticks Layer horizontally, snap to it (if there are two orthogonally, no decision; if three, take the majority)
            // 2. If air (or similar) below and the block below has any supporting blocks horizontally, orient to span the gap
            // 3. Respect SuggestedHV

            // 1
            Block westBlock    = world.GetBlock(pos.WestCopy());
            Block eastBlock    = world.GetBlock(pos.EastCopy());
            Block northBlock   = world.GetBlock(pos.NorthCopy());
            Block southBlock   = world.GetBlock(pos.SouthCopy());
            int   westConnect  = (westBlock is BlockSticksLayer wb) && wb.Orientation == BlockFacing.EAST ? 1 : 0;
            int   eastConnect  = (eastBlock is BlockSticksLayer eb) && eb.Orientation == BlockFacing.EAST ? 1 : 0;
            int   northConnect = (northBlock is BlockSticksLayer nb) && nb.Orientation == BlockFacing.NORTH ? 1 : 0;
            int   southConnect = (southBlock is BlockSticksLayer sb) && sb.Orientation == BlockFacing.NORTH ? 1 : 0;

            if (westConnect + eastConnect - northConnect - southConnect > 0)
            {
                return(BlockFacing.EAST);
            }
            if (northConnect + southConnect - westConnect - eastConnect > 0)
            {
                return(BlockFacing.NORTH);
            }

            // 2
            BlockPos down = pos.DownCopy();

            if (!CanSupportThis(world, down, null))
            {
                int westSolid  = CanSupportThis(world, down.WestCopy(), BlockFacing.EAST) ? 1 : 0;
                int eastSolid  = CanSupportThis(world, down.EastCopy(), BlockFacing.WEST) ? 1 : 0;
                int northSolid = CanSupportThis(world, down.NorthCopy(), BlockFacing.SOUTH) ? 1 : 0;
                int southSolid = CanSupportThis(world, down.SouthCopy(), BlockFacing.NORTH) ? 1 : 0;
                if (westSolid + eastSolid == 2 && northSolid + southSolid < 2)
                {
                    return(BlockFacing.EAST);
                }
                if (westSolid + eastSolid < 2 && northSolid + southSolid == 2)
                {
                    return(BlockFacing.NORTH);
                }
            }

            return(suggested);
        }
示例#14
0
        public override bool CanPlaceBlock(IWorldAccessor world, IPlayer byPlayer, BlockSelection bs, ref string failureCode)
        {
            BlockPos       pos         = bs.Position;
            BlockPos       down        = pos.DownCopy();
            IBlockAccessor blockAccess = world.BlockAccessor;

            //TODO: in future wattle walls directly below can also support this
            if (!CanSupportThis(blockAccess, down, null))
            {
                // Can always place against other Layers of sticks
                bool oneSolid = blockAccess.GetBlock(pos.WestCopy()) is BlockSticksLayer;
                if (!oneSolid)
                {
                    oneSolid = blockAccess.GetBlock(pos.EastCopy()) is BlockSticksLayer;
                }
                if (!oneSolid)
                {
                    oneSolid = blockAccess.GetBlock(pos.NorthCopy()) is BlockSticksLayer;
                }
                if (!oneSolid)
                {
                    oneSolid = blockAccess.GetBlock(pos.SouthCopy()) is BlockSticksLayer;
                }

                // Can place if any of the 4 surrounding supporting blocks has a solid top face or a shape which supports this
                if (!oneSolid)
                {
                    oneSolid = CanSupportThis(blockAccess, down.WestCopy(), BlockFacing.EAST);
                }
                if (!oneSolid)
                {
                    oneSolid = CanSupportThis(blockAccess, down.EastCopy(), BlockFacing.WEST);
                }
                if (!oneSolid)
                {
                    oneSolid = CanSupportThis(blockAccess, down.NorthCopy(), BlockFacing.SOUTH);
                }
                if (!oneSolid)
                {
                    oneSolid = CanSupportThis(blockAccess, down.SouthCopy(), BlockFacing.NORTH);
                }
                if (!oneSolid)
                {
                    failureCode = "requiresolidground";
                    return(false);
                }
            }
            return(base.CanPlaceBlock(world, byPlayer, bs, ref failureCode));
        }
        public static void OnGearDestroyed(IWorldAccessor world, BlockPos pos, char orient)
        {
            BlockPos posCentre;

            switch (orient)
            {
            case 's':
                posCentre = pos.NorthCopy();
                break;

            case 'w':
                posCentre = pos.EastCopy();
                break;

            case 'e':
                posCentre = pos.WestCopy();
                break;

            case 'n':
            default:
                posCentre = pos.SouthCopy();
                break;
            }
            if (world.BlockAccessor.GetBlockEntity(posCentre) is IGearAcceptor beg)
            {
                beg.RemoveGearAt(pos);
                Block toPlaceBlock = world.GetBlock(new AssetLocation("mpmultiblockwood"));
                world.BlockAccessor.SetBlock(toPlaceBlock.BlockId, pos);
                if (world.BlockAccessor.GetBlockEntity(pos) is BEMPMultiblock be)
                {
                    be.Centre = posCentre;
                }
            }
            else
            {
                world.Logger.Notification("no LG found at " + posCentre + " from " + pos);
            }
        }
示例#16
0
        protected virtual BlockFacing OrientForPlacement(IBlockAccessor world, IPlayer player, BlockSelection bs)
        {
            BlockFacing[] facings   = SuggestedHVOrientation(player, bs);
            BlockFacing   suggested = facings.Length > 0 ? facings[0] : null;
            BlockPos      pos       = bs.Position;

            // Logic waterfall for smart placement:
            // 1. if adjacent pane vertically, snap to it (if there are two orthogonally, no decision)
            // 2. if adjacent pane horizontally, snap to it (if there are two orthogonally, no decision; if three, take the majority)
            // 3. If any blocks horizontally, orient towards clear-through direction
            // 4. Respect SuggestedHV

            //1
            Block upBlock     = world.GetBlock(pos.UpCopy()); //##TODO maybe an IBlockAccessor.getNeighbours() method?  if going to be coding like this a lot?
            Block downBlock   = world.GetBlock(pos.DownCopy());
            int   upConnect   = (upBlock is BlockGlassPane ub) ? (ub.Orientation == BlockFacing.EAST ? 1 : -1) : 0;
            int   downConnect = (downBlock is BlockGlassPane db) ? (db.Orientation == BlockFacing.EAST ? 1 : -1) : 0;
            int   vertConnect = upConnect + downConnect;

            if (vertConnect > 0)
            {
                return(BlockFacing.EAST);
            }
            if (vertConnect < 0)
            {
                return(BlockFacing.NORTH);
            }

            //2
            Block westBlock    = world.GetBlock(pos.WestCopy());
            Block eastBlock    = world.GetBlock(pos.EastCopy());
            Block northBlock   = world.GetBlock(pos.NorthCopy());
            Block southBlock   = world.GetBlock(pos.SouthCopy());
            int   westConnect  = (westBlock is BlockGlassPane wb) && wb.Orientation == BlockFacing.NORTH ? 1 : 0;
            int   eastConnect  = (eastBlock is BlockGlassPane eb) && eb.Orientation == BlockFacing.NORTH ? 1 : 0;
            int   northConnect = (northBlock is BlockGlassPane nb) && nb.Orientation == BlockFacing.EAST ? 1 : 0;
            int   southConnect = (southBlock is BlockGlassPane sb) && sb.Orientation == BlockFacing.EAST ? 1 : 0;

            if (westConnect + eastConnect - northConnect - southConnect > 0)
            {
                return(BlockFacing.NORTH);
            }
            if (northConnect + southConnect - westConnect - eastConnect > 0)
            {
                return(BlockFacing.EAST);
            }

            //3
            int westLight  = westBlock.GetLightAbsorption(world, pos.WestCopy()) + eastBlock.GetLightAbsorption(world, pos.EastCopy());
            int northLight = northBlock.GetLightAbsorption(world, pos.NorthCopy()) + southBlock.GetLightAbsorption(world, pos.SouthCopy());

            if (westLight < northLight)
            {
                return(BlockFacing.EAST);
            }
            if (westLight > northLight)
            {
                return(BlockFacing.NORTH);
            }

            return(suggested);
        }
示例#17
0
        // Spread method
        public bool TrySpreading(IWorldAccessor world, BlockPos pos)
        {
            // Stack value

            int layers = 0;

            int.TryParse(block.LastCodePart(0), out layers);

            List <KeyValuePair <BlockPos, int> > neighbors       = new List <KeyValuePair <BlockPos, int> >();
            List <KeyValuePair <BlockPos, int> > spreadNeighbors = new List <KeyValuePair <BlockPos, int> >();


            neighbors.Add(CanSpreadTo(world, pos.SouthCopy()));
            neighbors.Add(CanSpreadTo(world, pos.WestCopy()));
            neighbors.Add(CanSpreadTo(world, pos.NorthCopy()));
            neighbors.Add(CanSpreadTo(world, pos.EastCopy()));

            neighbors.Sort((pair1, pair2) =>
            {
                return(pair1.Value.CompareTo(pair2.Value));
            });

            int smallest = neighbors[0].Value;

            while (layers > smallest + 1)
            {
                neighbors.Sort((pair1, pair2) =>
                {
                    return(pair1.Value.CompareTo(pair2.Value));
                });

                smallest = neighbors[0].Value;

                KeyValuePair <BlockPos, int> item = neighbors.Find((entry) =>
                {
                    return(entry.Value == smallest);
                });

                if (item.Value != smallest)
                {
                    break;
                }

                int index = neighbors.FindIndex((entry) =>
                {
                    return(entry.Key == item.Key);
                });

                neighbors[index] = new KeyValuePair <BlockPos, int>(item.Key, item.Value + 1);
                layers--;
            }


            // Block type
            string basecode = block.CodeWithoutParts(1);

            neighbors.ForEach((entry) =>
            {
                if (entry.Value <= 0 || entry.Value >= 8)
                {
                    return;
                }
                ;
                Block newBlock = world.BlockAccessor.GetBlock(block.CodeWithPath(basecode + "-" + (entry.Value)));
                world.BlockAccessor.SetBlock(newBlock.BlockId, entry.Key);
            });

            Block originBlock = world.BlockAccessor.GetBlock(block.CodeWithPath(basecode + "-" + layers));

            world.BlockAccessor.SetBlock(originBlock.BlockId, pos);

            return(false);
        }
示例#18
0
        protected virtual BlockFacing[] OrientForPlacement(IBlockAccessor worldmap, IPlayer player, BlockSelection bs)
        {
            BlockFacing[] facings    = SuggestedHVOrientation(player, bs);
            BlockPos      pos        = bs.Position;
            BlockFacing   horizontal = null;
            BlockFacing   face       = bs.Face.Opposite;
            BlockFacing   vert       = null;

            //If player is placing against a block horizontally, check that one and all other horizontals for connectors
            if (face.IsHorizontal)
            {
                if (HasConnector(worldmap, pos.AddCopy(face), bs.Face, out vert))
                {
                    horizontal = face;
                }
                else
                {
                    face = face.GetCW();
                    if (HasConnector(worldmap, pos.AddCopy(face), face.Opposite, out vert))
                    {
                        horizontal = face;
                    }
                    else if (HasConnector(worldmap, pos.AddCopy(face.Opposite), face, out vert))
                    {
                        horizontal = face.Opposite;
                    }
                    else if (HasConnector(worldmap, pos.AddCopy(bs.Face), bs.Face.Opposite, out vert))
                    {
                        horizontal = bs.Face;
                    }
                }
                //Special case: the 3way has two connectors but the directional attribute covers only one of them
                if (Type == "3way" && horizontal != null)
                {
                    face = horizontal.GetCW();
                    BlockFacing unused = null;
                    if (HasConnector(worldmap, pos.AddCopy(face), face.Opposite, out unused) && !HasConnector(worldmap, pos.AddCopy(face.Opposite), face, out unused))
                    {
                        horizontal = face;
                    }
                }
            }
            else
            {
                //Player is placing against a block vertically, use that as the vertical connection and check all horizontals for connectors
                vert = face;
                bool moreThanOne = false;
                horizontal = HasConnector(worldmap, pos.EastCopy(), BlockFacing.WEST, out vert) ? BlockFacing.EAST : null;
                if (HasConnector(worldmap, pos.WestCopy(), BlockFacing.EAST, out vert))
                {
                    moreThanOne = horizontal != null;
                    horizontal  = BlockFacing.WEST;
                }
                if (HasConnector(worldmap, pos.NorthCopy(), BlockFacing.SOUTH, out vert))
                {
                    moreThanOne = horizontal != null;
                    horizontal  = BlockFacing.NORTH;
                }
                if (HasConnector(worldmap, pos.SouthCopy(), BlockFacing.NORTH, out vert))
                {
                    moreThanOne = horizontal != null;
                    horizontal  = BlockFacing.SOUTH;
                }
                if (moreThanOne)
                {
                    horizontal = null;
                }
            }
            if (vert == null)
            {
                //If vertical orientation not already chosen, see whether there is an existing open connector up or down
                BlockFacing unused = null;
                bool        up     = HasConnector(worldmap, pos.UpCopy(), BlockFacing.DOWN, out unused);
                bool        down   = HasConnector(worldmap, pos.DownCopy(), BlockFacing.UP, out unused);
                if (up && !down)
                {
                    vert = BlockFacing.UP;
                }
                else if (down && !up)
                {
                    vert = BlockFacing.DOWN;
                }
            }
            if (vert != null)
            {
                facings[1] = vert;
            }
            facings[0] = horizontal ?? facings[0].Opposite;
            return(facings);
        }
示例#19
0
        private void OnEvery250Ms(float dt)
        {
            // Random checks for breaking this block if heavy entity above and unsupported below

            IWorldAccessor world = Api.World;
            Vec3d          pos3d = center.AddCopy(Pos);
            BlockPos       down  = Pos.DownCopy();

            // If this block is unsupported, do an entity weight + block breaking check
            if (!CheckSupport(world.BlockAccessor, down))
            {
                Entity[] entities = world.GetEntitiesAround(pos3d, 1.0f, 1.5f, (e) => (e?.Properties.Weight > WEIGHTLIMIT));
                for (int i = 0; i < entities.Length; i++)
                {
                    Entity    entity = entities[i];
                    Cuboidd   eBox   = new Cuboidd();
                    EntityPos pos    = entity.Pos;
                    eBox.Set(entity.SelectionBox).Translate(pos.X, pos.Y, pos.Z);

                    Cuboidf bBox = new Cuboidf();
                    bBox.Set(this.Block.CollisionBoxes[0]);
                    bBox.Translate(Pos.X, Pos.Y, Pos.Z);

                    // Check entity yPos actually intersects with this block (approximately)
                    if (eBox.MinY <= bBox.MaxY + 0.01 && eBox.MinY >= bBox.MinY - 0.01)
                    {
                        // Check whether supported enough on any surrounding side
                        bool checkSouth = eBox.MaxZ > bBox.Z2;
                        bool checkNorth = eBox.MinZ < bBox.Z1;
                        bool checkWest  = eBox.MinX < bBox.X1;
                        bool checkEast  = eBox.MinZ > bBox.X2;

                        bool           supported = false;
                        IBlockAccessor access    = world.BlockAccessor;
                        if (checkEast)
                        {
                            supported |= CheckSupport(access, down.EastCopy());
                        }
                        if (checkEast && checkNorth)
                        {
                            supported |= CheckSupport(access, down.EastCopy().North());
                        }
                        if (checkEast && checkSouth)
                        {
                            supported |= CheckSupport(access, down.EastCopy().South());
                        }
                        if (checkWest)
                        {
                            supported |= CheckSupport(access, down.WestCopy());
                        }
                        if (checkWest && checkNorth)
                        {
                            supported |= CheckSupport(access, down.WestCopy().North());
                        }
                        if (checkWest && checkSouth)
                        {
                            supported |= CheckSupport(access, down.WestCopy().South());
                        }
                        if (checkNorth)
                        {
                            supported |= CheckSupport(access, down.NorthCopy());
                        }
                        if (checkSouth)
                        {
                            supported |= CheckSupport(access, down.SouthCopy());
                        }

                        if (!supported)
                        {
                            // Break the block and the entity will fall :)

                            // ## TODO
                        }
                    }
                }
            }

            return;
        }