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(), }); }
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"); }
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(), }); }
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(), }); }
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() } }); }
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" } }); }
public static BlockPos[] Cardinal(BlockPos Pos) { return(new BlockPos[] { Pos.NorthCopy(), Pos.SouthCopy(), Pos.EastCopy(), Pos.WestCopy(), }); }
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; } }
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); }
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); }
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); } }
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); }
// 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); }
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); }
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; }