예제 #1
0
        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;
                    }
                }
            }
        }
예제 #2
0
        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);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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));
        }
예제 #7
0
        // 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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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();
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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");
        }
예제 #16
0
 private void TrySpreadHorizontal(Block ourblock, IWorldAccessor world, BlockPos pos)
 {
     foreach (BlockFacing facing in BlockFacing.HORIZONTALS)
     {
         TrySpreadIntoBlock(ourblock, pos.AddCopy(facing), world);
     }
 }
예제 #17
0
        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);
        }
예제 #19
0
 BlockPos GetControllerBlockPositionOrNull(BlockPos pos)
 {
     if (!ControllerBlock && IsCompleteCoffin(pos))
     {
         return(pos.AddCopy(Orientation.Opposite));
     }
     return(null);
 }
예제 #20
0
        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);
        }
예제 #21
0
 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);
     }
 }
예제 #22
0
        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);
        }
예제 #23
0
        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);
        }
예제 #24
0
        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()));
        }
예제 #26
0
        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);
            }
        }
예제 #28
0
        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);
        }
예제 #29
0
        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);
        }