private void TrySpreadFire() { BlockPos opos = Pos.AddCopy(fromFacing.Opposite); foreach (BlockFacing facing in BlockFacing.ALLFACES) { BlockPos npos = opos.AddCopy(facing); Block nBlock = Api.World.BlockAccessor.GetBlock(npos); if (canBurn(nBlock, npos)) { if (Api.World.BlockAccessor.GetBlock(npos.AddCopy(fromFacing)).BlockId == 0 && TrySpreadTo(npos.AddCopy(fromFacing), fromFacing)) { break; } bool dobreak = false; foreach (BlockFacing firefacing in BlockFacing.ALLFACES) { BlockPos nnpos = npos.AddCopy(firefacing); Block nnblock = Api.World.BlockAccessor.GetBlock(nnpos); if (canBurn(nnblock, nnpos) && TrySpreadTo(nnpos, firefacing)) { dobreak = true; break; } } if (dobreak) { break; } } } }
internal virtual bool IsAttached(IBlockAccessor blockAccessor, BlockPos pos) { for (int i = 0; i < AttachedToFaces.Length; i++) { BlockFacing face = AttachedToFaces[i]; Block block = blockAccessor.GetBlock(pos.AddCopy(face)); if (block.CanAttachBlockAt(blockAccessor, block, pos.AddCopy(face), face.GetOpposite())) { return(true); } } return(false); }
private void queueNeighborsForCheckDecay(BlockPos pos) { lock (checkDecayLock) { for (int i = 0; i < Vec3i.DirectAndIndirectNeighbours.Length; i++) { Vec3i vec = Vec3i.DirectAndIndirectNeighbours[i]; Block block = sapi.World.BlockAccessor.GetBlock(pos.X + vec.X, pos.Y + vec.Y, pos.Z + vec.Z); if (block.Id == 0) { continue; } if (canDecay(block)) { checkDecayQueue.Add(pos.AddCopy(vec)); // sapi.World.SpawnParticles(10, ColorUtil.ToRgba(255, 0, 255, 0), pos.AddCopy(vec).ToVec3d().Add(0.3, 0.3, 0.3), pos.AddCopy(vec).ToVec3d().Add(0.3, 0.35, 0.3), new Vec3f(), new Vec3f(), 1f, 0f, 1, EnumParticleModel.Cube); //Console.WriteLine("added " + vec); } else { // sapi.World.SpawnParticles(10, ColorUtil.ToRgba(255, 255, 0, 0), pos.AddCopy(vec).ToVec3d().Add(0.3, 0.3, 0.3), pos.AddCopy(vec).ToVec3d().Add(0.3, 0.35, 0.3), new Vec3f(), new Vec3f(), 1f, 0f, 1, EnumParticleModel.Cube); } } } }
public override void OnBlockBroken(IWorldAccessor world, BlockPos pos, IPlayer byPlayer, float dropQuantityMultiplier = 1f) { BEMPMultiblock be = world.BlockAccessor.GetBlockEntity(pos) as BEMPMultiblock; if (be == null || be.Principal == null) { // being broken by other game code (including on breaking the pulverizer base block): standard block breaking treatment base.OnBlockBroken(world, pos, byPlayer, dropQuantityMultiplier); return; } // being broken by player: break the main block instead BlockPos principalPos = be.Principal; Block principalBlock = world.BlockAccessor.GetBlock(principalPos); principalBlock.OnBlockBroken(world, principalPos, byPlayer, dropQuantityMultiplier); // Need to trigger neighbourchange on client side only (because it's normally in the player block breaking code) if (api.Side == EnumAppSide.Client) { foreach (BlockFacing facing in BlockFacing.HORIZONTALS) { BlockPos npos = principalPos.AddCopy(facing); world.BlockAccessor.GetBlock(npos).OnNeighbourBlockChange(world, npos, principalPos); } } base.OnBlockBroken(world, pos, byPlayer, dropQuantityMultiplier); }
private void CmdGenHouse(IServerPlayer player, int groupId, CmdArgs args) { IBlockAccessor blockAccessor = api.WorldManager.GetBlockAccessorBulkUpdate(true, true); int blockID = api.WorldManager.GetBlockId(new AssetLocation("log-placed-oak-ud")); BlockPos pos = player.Entity.Pos.AsBlockPos; for (int dx = -3; dx <= 3; dx++) { for (int dz = -3; dz <= 3; dz++) { for (int dy = 0; dy <= 3; dy++) { if (Math.Abs(dx) != 3 && Math.Abs(dz) != 3 && dy < 3) { continue; // Hollow } if (dx == -3 && dz == 0 && dy < 2) { continue; // Door } blockAccessor.SetBlock(blockID, pos.AddCopy(dx, dy, dz)); } } } blockAccessor.Commit(); }
bool CanTorchStay(IBlockAccessor blockAccessor, BlockPos pos) { BlockFacing facing = BlockFacing.FromCode(LastCodePart()); Block block = blockAccessor.GetBlock(blockAccessor.GetBlockId(pos.AddCopy(facing.GetOpposite()))); return(block.CanAttachBlockAt(blockAccessor, this, pos, facing)); }
// Returns the block pos that is adjacent to a hole BlockPos FindHoleInPit() { smokeLocations.Clear(); HashSet <BlockPos> visitedPositions = new HashSet <BlockPos>(); Queue <BlockPos> bfsQueue = new Queue <BlockPos>(); bfsQueue.Enqueue(Pos); int firewoodBlockId = Api.World.GetBlock(new AssetLocation("firewoodpile")).BlockId; int charcoalPitBlockId = Api.World.GetBlock(new AssetLocation("charcoalpit")).BlockId; int maxHalfSize = 6; while (bfsQueue.Count > 0) { BlockPos bpos = bfsQueue.Dequeue(); BlockPos bposGround = bpos.Copy(); bposGround.Y = 0; int yMax = 0; smokeLocations.TryGetValue(bposGround, out yMax); smokeLocations[bposGround] = Math.Max(yMax, bpos.Y); foreach (BlockFacing facing in BlockFacing.ALLFACES) { BlockPos npos = bpos.AddCopy(facing); IWorldChunk chunk = Api.World.BlockAccessor.GetChunkAtBlockPos(npos); if (chunk == null) { continue; // Maybe at the endge of the loaded chunk } Block nBlock = chunk.GetLocalBlockAtBlockPos(Api.World, npos); if (!nBlock.SideSolid[facing.Opposite.Index] && nBlock.BlockId != firewoodBlockId && nBlock.BlockId != charcoalPitBlockId) { return(bpos); } // Only traverse inside the firewood pile if (nBlock.BlockId != firewoodBlockId) { continue; } // Only traverse within a 12x12x12 block cube bool inCube = Math.Abs(npos.X - Pos.X) <= maxHalfSize && Math.Abs(npos.Y - Pos.Y) <= maxHalfSize && Math.Abs(npos.Z - Pos.Z) <= maxHalfSize; if (inCube && !visitedPositions.Contains(npos)) { bfsQueue.Enqueue(npos); visitedPositions.Add(npos); } } } return(null); }
public override bool ShouldReceiveServerGameTicks(IWorldAccessor world, BlockPos pos, Random offThreadRandom, out object extra) { extra = null; if (!GlobalConstants.MeltingFreezingEnabled) { return(false); } if (freezable && offThreadRandom.NextDouble() < 0.6) { int rainY = world.BlockAccessor.GetRainMapHeightAt(pos); if (rainY <= pos.Y) { for (int i = 0; i < BlockFacing.HORIZONTALS.Length; i++) { BlockFacing facing = BlockFacing.HORIZONTALS[i]; if (world.BlockAccessor.GetBlock(pos.AddCopy(facing)).Replaceable < 6000) { ClimateCondition conds = world.BlockAccessor.GetClimateAt(pos, EnumGetClimateMode.NowValues); if (conds != null && conds.Temperature < -4) { return(true); } } } } } return(false); }
void TreeLineup(IServerPlayer player, CmdArgs arguments) { if (arguments.Length < 2) { player.SendMessage(groupId, "/wgen treelineup {treeWorldPropertyCode} [0.1 - 3]", EnumChatType.CommandError); return; } EntityPos pos = player.Entity.Pos; BlockPos center = pos.HorizontalAheadCopy(25).AsBlockPos; IBlockAccessor blockAccessor = api.WorldManager.GetBlockAccessorBulkUpdate(true, true, true); int size = 12; for (int dx = -2 * size; dx < 2 * size; dx++) { for (int dz = -size; dz < size; dz++) { for (int dy = 0; dy < 2 * size; dy++) { blockAccessor.SetBlock(0, center.AddCopy(dx, dy, dz)); } } } treeGenerators.ReloadTreeGenerators(); treeGenerators.RunGenerator(new AssetLocation(arguments[1]), blockAccessor, center.AddCopy(0, -1, 0)); treeGenerators.RunGenerator(new AssetLocation(arguments[1]), blockAccessor, center.AddCopy(-9, -1, 0)); treeGenerators.RunGenerator(new AssetLocation(arguments[1]), blockAccessor, center.AddCopy(9, -1, 0)); blockAccessor.Commit(); }
protected override void Open(IWorldAccessor world, IPlayer byPlayer, BlockPos position) { float breakChance = Attributes["breakOnTriggerChance"].AsFloat(0); if (world.Side == EnumAppSide.Server && world.Rand.NextDouble() < breakChance && byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative) { world.BlockAccessor.BreakBlock(position, byPlayer); world.PlaySoundAt(new AssetLocation("sounds/effect/toolbreak"), position.X + 0.5, position.Y + 0.5, position.Z + 0.5, null); return; } AssetLocation newCode = CodeWithVariant("state", IsOpened() ? "closed" : "opened"); Block newBlock = world.BlockAccessor.GetBlock(newCode); AssetLocation otherNewCode = newBlock.CodeWithVariant("part", IsUpperHalf() ? "down" : "up"); world.BlockAccessor.ExchangeBlock(newBlock.BlockId, position); world.BlockAccessor.MarkBlockDirty(position); BlockPos otherPos = position.AddCopy(0, IsUpperHalf() ? -1 : 1, 0); Block otherPart = world.BlockAccessor.GetBlock(otherPos); if (otherPart is BlockDoor && ((BlockDoor)otherPart).IsUpperHalf() != IsUpperHalf()) { world.BlockAccessor.ExchangeBlock(world.BlockAccessor.GetBlock(otherNewCode).BlockId, otherPos); world.BlockAccessor.MarkBlockDirty(otherPos); } }
bool CanVineStay(IWorldAccessor world, BlockPos pos) { BlockPos apos = pos.AddCopy(VineFacing.Opposite); Block block = world.BlockAccessor.GetBlock(world.BlockAccessor.GetBlockId(apos)); return(block.CanAttachBlockAt(world.BlockAccessor, this, apos, VineFacing) || world.BlockAccessor.GetBlock(pos.UpCopy()) is BlockVines); }
public void LightHighlight(BlockPos pos = null, EnumLightLevelType type = EnumLightLevelType.OnlyBlockLight) { pos = pos ?? capi.World.Player.Entity.LocalPos.AsBlockPos.UpCopy(); int rad = config.LightRadius; Dictionary <BlockPos, int> colors = new Dictionary <BlockPos, int>(); for (int x = -rad; x <= rad; x++) { for (int y = -rad; y <= rad; y++) { for (int z = -rad; z <= rad; z++) { BlockPos iPos = pos.AddCopy(x, y, z); Block block = capi.World.BlockAccessor.GetBlock(iPos); BlockPos cPos = config.LUShowAbove ? iPos.UpCopy() : iPos; int level = capi.World.BlockAccessor.GetLightLevel(cPos, type); bool rep = config.LUSpawning ? capi.World.BlockAccessor.GetBlock(iPos.UpCopy()).IsReplacableBy(block) : true; bool opq = config.LUOpaque ? block.AllSidesOpaque : true; if (block.BlockId != 0 && rep && opq && (x * x + y * y + z * z) <= (rad * rad)) { float fLevel = level / 32.0f; int alpha = (int)Math.Round(config.LightLevelAlpha * 255); int c = level > config.LightLevelRed ? ColorUtil.ToRgba(alpha, 0, (int)(fLevel * 255), 0) : ColorUtil.ToRgba(alpha, 0, 0, (int)(Math.Max(fLevel, 0.2) * 255)); colors.Add(iPos, c); } } } } capi.World.HighlightBlocks(capi.World.Player, config.MinLLID, colors.Keys.ToList(), colors.Values.ToList(), EnumHighlightBlocksMode.Absolute, EnumHighlightShape.Arbitrary); }
OrderedDictionary <BlockPos, float> GetNearblyMultibreakables(IWorldAccessor world, BlockPos pos, Vec3d hitPos) { OrderedDictionary <BlockPos, float> positions = new OrderedDictionary <BlockPos, float>(); for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { for (int dz = -1; dz <= 1; dz++) { if (dx == 0 && dy == 0 && dz == 0) { continue; } BlockPos dpos = pos.AddCopy(dx, dy, dz); if (CanMultiBreak(world.BlockAccessor.GetBlock(dpos))) { positions.Add(dpos, hitPos.SquareDistanceTo(dpos.X + 0.5, dpos.Y + 0.5, dpos.Z + 0.5)); } } } } return(positions); }
bool TryAttachTo(IWorldAccessor world, IPlayer byPlayer, BlockPos blockpos, Vec3d hitPosition, BlockFacing onBlockFace, ItemStack itemstack) { BlockPos attachingBlockPos = blockpos.AddCopy(onBlockFace.Opposite); Block attachingBlock = world.BlockAccessor.GetBlock(world.BlockAccessor.GetBlockId(attachingBlockPos)); BlockFacing onFace = onBlockFace; Block hereBlock = world.BlockAccessor.GetBlock(blockpos); Cuboidi attachmentArea = null; attachmentAreas?.TryGetValue(onBlockFace.Code, out attachmentArea); if (hereBlock.Replaceable >= 6000 && attachingBlock.CanAttachBlockAt(world.BlockAccessor, block, attachingBlockPos, onFace, attachmentArea)) { Block orientedBlock = world.BlockAccessor.GetBlock(block.CodeWithVariant(facingCode, onBlockFace.Code)); orientedBlock.DoPlaceBlock(world, byPlayer, new BlockSelection() { Position = blockpos, HitPosition = hitPosition, Face = onFace }, itemstack); return(true); } return(false); }
public override void FromTreeAttributes(ITreeAttribute tree, IWorldAccessor worldAccessForResolve) { base.FromTreeAttributes(tree, worldAccessForResolve); remainingBurnDuration = tree.GetFloat("remainingBurnDuration"); startDuration = tree.GetFloat("startDuration"); // pre v1.15-pre.3 fire if (!tree.HasAttribute("fireposX")) { BlockFacing fromFacing = BlockFacing.ALLFACES[tree.GetInt("fromFacing", 0)]; FirePos = Blockentity.Pos.Copy(); FuelPos = FirePos.AddCopy(fromFacing); } else { FirePos = new BlockPos(tree.GetInt("fireposX"), tree.GetInt("fireposY"), tree.GetInt("fireposZ")); FuelPos = new BlockPos(tree.GetInt("fuelposX"), tree.GetInt("fuelposY"), tree.GetInt("fuelposZ")); } bool wasBurning = IsBurning; bool nowBurning = tree.GetBool("isBurning", true); if (nowBurning && !wasBurning) { startBurning(); } if (!nowBurning && wasBurning) { KillFire(remainingBurnDuration <= 0); IsBurning = nowBurning; } startedByPlayerUid = tree.GetString("startedByPlayerUid"); }
private void TrySpreadHorizontal(Block ourblock, IWorldAccessor world, BlockPos pos) { foreach (BlockFacing facing in BlockFacing.HORIZONTALS) { TrySpreadIntoBlock(ourblock, pos.AddCopy(facing), world); } }
public override bool OnBlockInteractStart(IWorldAccessor world, IPlayer byPlayer, BlockSelection blockSel) { if (blockSel != null) { BlockPos pos = blockSel.Position; if (LastCodePart(1) == "feet") { BlockFacing facing = BlockFacing.FromCode(LastCodePart()).Opposite; pos = pos.AddCopy(facing); } BlockEntityTrough betr = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityTrough; bool ok = betr?.OnInteract(byPlayer, blockSel) == true; if (ok && world.Side == EnumAppSide.Client) { (byPlayer as IClientPlayer).TriggerFpAnimation(EnumHandInteract.HeldItemInteract); return(true); } return(ok); } return(base.OnBlockInteractStart(world, byPlayer, blockSel)); }
/// <summary> /// Returns the location to place the chest if the given world coordinates is a tree, null if it's not a tree. /// </summary> private BlockPos TryGetChestLocation(BlockPos pos) { var block = _chunkGenBlockAccessor.GetBlock(pos); if (IsTreeLog(block)) { for (var posY = pos.Y; posY >= 0; posY--) { while (pos.Y-- > 0) { var underBlock = _chunkGenBlockAccessor.GetBlock(pos); if (IsTreeLog(underBlock)) { continue; } foreach (var facing in BlockFacing.HORIZONTALS) { var adjacentPos = pos.AddCopy(facing).Up(); if (_chunkGenBlockAccessor.GetBlock(adjacentPos).Id == 0) { return(adjacentPos); } } } } } return(null); }
BlockPos GetControllerBlockPositionOrNull(BlockPos pos) { if (!ControllerBlock && IsCompleteCoffin(pos)) { return(pos.AddCopy(Orientation.Opposite)); } return(null); }
private BlockFacing getOpenedEndedFace(BlockFacing[] dirFacings, IWorldAccessor world, BlockPos blockPos) { Block block = world.BlockAccessor.GetBlock(blockPos.AddCopy(dirFacings[0])); if (!(block is BlockRails)) { return(dirFacings[0]); } block = world.BlockAccessor.GetBlock(blockPos.AddCopy(dirFacings[1])); if (!(block is BlockRails)) { return(dirFacings[1]); } return(null); }
private void NotifyNeighborsOfBlockChange(BlockPos pos) { foreach (BlockFacing facing in BlockFacing.ALLFACES) { BlockPos npos = pos.AddCopy(facing); Block neib = World.BlockAccessor.GetBlock(npos); neib.OnNeighourBlockChange(World, npos, pos); } }
public override void OnNeighbourBlockChange(IWorldAccessor world, BlockPos pos, BlockPos neibpos) { //Drop any adjacent angled gears if no longer supported BlockPos npos = pos.AddCopy(orientation); if (world.BlockAccessor.GetBlock(npos) is BlockAngledGears ag && ag.Facings.Contains(orientation.Opposite) && ag.Facings.Length == 1) { world.BlockAccessor.BreakBlock(npos, null); } npos = pos.AddCopy(orientation.Opposite); ag = world.BlockAccessor.GetBlock(npos) as BlockAngledGears; if (ag != null && ag.Facings.Contains(orientation) && ag.Facings.Length == 1) { world.BlockAccessor.BreakBlock(npos, null); } base.OnNeighbourBlockChange(world, pos, neibpos); }
private bool TryAttachPlaceToHoriontal(IWorldAccessor world, IPlayer byPlayer, BlockPos position, BlockFacing toFacing, BlockFacing targetFacing) { Block neibBlock = world.BlockAccessor.GetBlock(position.AddCopy(toFacing)); if (!(neibBlock is BlockRails)) { return(false); } BlockFacing fromFacing = toFacing.GetOpposite(); BlockFacing[] neibDirFacings = getFacingsFromType(neibBlock.Variant["type"]); // Already attached, do default placement behavior if (neibDirFacings[0] == fromFacing || neibDirFacings[1] == fromFacing) { return(false); } BlockFacing neibFreeFace = getOpenedEndedFace(neibDirFacings, world, position.AddCopy(toFacing)); // Already fully attached, don't bend rail if (neibFreeFace == null) { return(false); } Block blockToPlace = getRailBlock(world, "curved_", fromFacing, targetFacing); if (blockToPlace != null) { if (!placeIfSuitable(blockToPlace, world, position)) { return(false); } } string dirs = neibBlock.Variant["type"].Split('_')[1]; BlockFacing neibKeepFace = (dirs[0] == neibFreeFace.Code[0]) ? BlockFacing.FromFirstLetter(dirs[1]) : BlockFacing.FromFirstLetter(dirs[0]); Block block = getRailBlock(world, "curved_", neibKeepFace, fromFacing); block.DoPlaceBlock(world, position.AddCopy(toFacing), BlockFacing.UP, null); return(false); }
public virtual bool IsAttached(IBlockAccessor blockAccessor, BlockPos pos) { for (int i = 0; i < AttachedToFaces.Length; i++) { BlockFacing face = AttachedToFaces[i]; Block block = blockAccessor.GetBlock(pos.AddCopy(face)); Cuboidi attachmentArea = null; attachmentAreas?.TryGetValue(face.Code, out attachmentArea); if (block.CanAttachBlockAt(blockAccessor, this.block, pos.AddCopy(face), face.Opposite, attachmentArea)) { return(true); } } return(false); }
bool CanBlockStay(IWorldAccessor world, BlockPos pos) { string[] parts = Code.Path.Split('-'); BlockFacing facing = BlockFacing.FromCode(parts[parts.Length - 1]); int blockId = world.BlockAccessor.GetBlockId(pos.AddCopy(facing)); Block block = world.BlockAccessor.GetBlock(blockId); return(block.CanAttachBlockAt(world.BlockAccessor, this, pos, facing.GetOpposite())); }
public bool ShouldConnectAt(IWorldAccessor world, BlockPos ownPos, BlockFacing side) { Block block = world.BlockAccessor.GetBlock(ownPos.AddCopy(side)); if (ownFirstCodePart == block.FirstCodePart()) { return(true); } return(block.SideSolid[side.GetOpposite().Index]); //test if neighbor face is solid }
private void LowerLiquidLevelAndNotifyNeighbors(Block block, BlockPos pos, IWorldAccessor world) { SpreadLiquid(GetLessLiquidBlockId(world, block), pos, world); for (int i = 0; i < BlockFacing.ALLFACES.Length; i++) { BlockPos npos = pos.AddCopy(BlockFacing.ALLFACES[i]); world.BlockAccessor.GetBlock(npos).OnNeighourBlockChange(world, npos, pos); } }
public override void OnBlockRemoved(IWorldAccessor world, BlockPos pos, ref EnumHandling handling) { cardinal = cardinal ?? AreaMethods.SphericalOffsetList(1).ToArray(); //if for whatever reason it's null offset = offset ?? AreaMethods.AreaBelowOffsetList().ToArray(); if (world.Side.IsServer()) { for (int i = 0; i < cardinal.Length; i++) { if (world.BlockAccessor.GetBlock(pos.AddCopy(cardinal[i])).Id != 0) { world.BlockAccessor.GetBlock(pos.AddCopy(cardinal[i])).GetBehavior <AlteredBlockPhysics>()?.TryCollapse(world, pos.AddCopy(cardinal[i])); world.BlockAccessor.GetBlock(pos.AddCopy(cardinal[i])).OnNeighourBlockChange(world, pos.AddCopy(cardinal[i]), pos); } } TryCollapse(world, pos); } base.OnBlockRemoved(world, pos, ref handling); }
public bool ShouldConnectAt(IWorldAccessor world, BlockPos ownPos, BlockFacing side) { Block block = world.BlockAccessor.GetBlock(ownPos.AddCopy(side)); return ((block.FirstCodePart() == FirstCodePart() || block.FirstCodePart() == FirstCodePart() + "gate") || block.SideSolid[side.GetOpposite().Index]); ; }
public bool TrySpreadTo(BlockPos pos) { // 1. Replaceable test var block = Api.World.BlockAccessor.GetBlock(pos); if (block.Replaceable < 6000) { return(false); } BlockEntity be = Api.World.BlockAccessor.GetBlockEntity(pos); if (be?.GetBehavior <BEBehaviorBurning>() != null) { return(false); } // 2. fuel test bool hasFuel = false; BlockPos npos = null; foreach (BlockFacing firefacing in BlockFacing.ALLFACES) { npos = pos.AddCopy(firefacing); block = Api.World.BlockAccessor.GetBlock(npos); if (canBurn(npos) && Api.World.BlockAccessor.GetBlockEntity(npos)?.GetBehavior <BEBehaviorBurning>() == null) { hasFuel = true; break; } } if (!hasFuel) { return(false); } // 3. Land claim test IPlayer player = Api.World.PlayerByUid(startedByPlayerUid); if (player != null && Api.World.Claims.TestAccess(player, pos, EnumBlockAccessFlags.BuildOrBreak) != EnumWorldAccessResponse.Granted) { return(false); } Api.World.BlockAccessor.SetBlock(fireBlock.BlockId, pos); //Api.World.Logger.Debug(string.Format("Fire @{0}: Spread to {1}.", FirePos, pos)); BlockEntity befire = Api.World.BlockAccessor.GetBlockEntity(pos); befire.GetBehavior <BEBehaviorBurning>()?.OnFirePlaced(pos, npos, startedByPlayerUid); return(true); }