Beispiel #1
0
        private void DamageNearbyBlocks(IPlayer player, BlockSelection blockSel, float damage, int leftDurability)
        {
            Block block = player.Entity.World.BlockAccessor.GetBlock(blockSel.Position);

            if (!CanMultiBreak(block))
            {
                return;
            }

            Vec3d hitPos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition);
            OrderedDictionary <BlockPos, float> dict = GetNearblyMultibreakables(player.Entity.World, blockSel.Position, hitPos);
            var orderedPositions = dict.OrderBy(x => x.Value).Select(x => x.Key);

            int q = Math.Min(MultiBreakQuantity, leftDurability);

            foreach (var pos in orderedPositions)
            {
                if (q == 0)
                {
                    break;
                }
                BlockFacing facing = BlockFacing.FromNormal(player.Entity.ServerPos.GetViewVector()).GetOpposite();

                if (!player.Entity.World.Claims.TryAccess(player, blockSel.Position, EnumBlockAccessFlags.BuildOrBreak))
                {
                    continue;
                }

                player.Entity.World.BlockAccessor.DamageBlock(pos, facing, damage);
                q--;
            }
        }
Beispiel #2
0
        private bool RequiresStand(BlockPos pos, Vec3i vector)
        {
            BlockMPBase block = Api.World.BlockAccessor.GetBlock(pos.X + vector.X, pos.Y + vector.Y, pos.Z + vector.Z) as BlockMPBase;

            if (block == null)
            {
                return(true);
            }
            BlockPos         sidePos = new BlockPos(pos.X + vector.X, pos.Y + vector.Y, pos.Z + vector.Z);
            BEBehaviorMPBase bemp    = Api.World.BlockAccessor.GetBlockEntity(sidePos)?.GetBehavior <BEBehaviorMPBase>();

            if (bemp == null)
            {
                return(true);
            }
            BEBehaviorMPAxle bempaxle = bemp as BEBehaviorMPAxle;

            if (bempaxle == null)
            {
                if (bemp is BEBehaviorMPBrake || bemp is BEBehaviorMPCreativeRotor)
                {
                    BlockFacing side = BlockFacing.FromNormal(vector);
                    if (side != null && block.HasMechPowerConnectorAt(Api.World, sidePos, side.Opposite))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            if (IsAttachedToBlock(Api.World.BlockAccessor, block, sidePos))
            {
                return(false);
            }
            return(bempaxle.RequiresStand(sidePos, vector));
        }
        private void initSoundsAndTicking()
        {
            fuelBlock = Api.World.BlockAccessor.GetBlock(FuelPos);

            l1 = Blockentity.RegisterGameTickListener(OnTick, 25);
            if (Api.Side == EnumAppSide.Server)
            {
                l2 = Blockentity.RegisterGameTickListener(OnSlowServerTick, 1000);
            }

            wsys = Api.ModLoader.GetModSystem <WeatherSystemBase>();

            if (ambientSound == null && Api.Side == EnumAppSide.Client)
            {
                ambientSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams()
                {
                    Location        = new AssetLocation("sounds/environment/fire.ogg"),
                    ShouldLoop      = true,
                    Position        = FirePos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                    DisposeOnFinish = false,
                    Volume          = 1f
                });

                if (ambientSound != null)
                {
                    ambientSound.PlaybackPosition = ambientSound.SoundLengthSeconds * (float)Api.World.Rand.NextDouble();
                    ambientSound.Start();
                }
            }

            particleFacing = BlockFacing.FromNormal(new Vec3i(FirePos.X - FuelPos.X, FirePos.Y - FuelPos.Y, FirePos.Z - FuelPos.Z));
        }
        public void OnNeighbourBlockChange(BlockPos neibpos)
        {
            var bh = GetBehavior <FruitTreeGrowingBranchBH>();

            if (bh != null)
            {
                bh.OnNeighbourBlockChange(BlockFacing.FromNormal((neibpos - Pos).ToVec3i()));
            }
        }
Beispiel #5
0
    public override bool TryPlaceBlock(IWorldAccessor world, IPlayer byPlayer, ItemStack itemstack, BlockSelection blockSel, ref string failureCode)
    {
        if (!CanPlaceBlock(world, byPlayer, blockSel, ref failureCode))
        {
            return(false);
        }

        foreach (BlockFacing face in BlockFacing.ALLFACES)
        {
            BlockPos pos = blockSel.Position.AddCopy(face);
            IMechanicalPowerBlock block = world.BlockAccessor.GetBlock(pos) as IMechanicalPowerBlock;
            if (block != null)
            {
                if (block.HasMechPowerConnectorAt(world, pos, face.Opposite))
                {
                    //Prevent rotor back-to-back placement
                    if (block is IMPPowered)
                    {
                        return(false);
                    }

                    Block toPlaceBlock = world.GetBlock(CodeWithParts(face.Opposite.Code));
                    world.BlockAccessor.SetBlock(toPlaceBlock.BlockId, blockSel.Position);

                    block.DidConnectAt(world, pos, face.Opposite);
                    WasPlaced(world, blockSel.Position, face);

                    powerOutFacing = face;
                    return(true);
                }
            }
        }

        if (byPlayer != null && byPlayer.Entity != null)
        {
            Vec3f       vec          = new Vec3d().Ahead(1f, byPlayer.Entity.Pos.Pitch, byPlayer.Entity.Pos.Yaw).ToVec3f();
            BlockFacing face         = BlockFacing.FromNormal(vec);
            Block       toPlaceBlock = world.GetBlock(CodeWithParts(face.Opposite.Code));
            world.BlockAccessor.SetBlock(toPlaceBlock.BlockId, blockSel.Position);
            WasPlaced(world, blockSel.Position, null);
            powerOutFacing = face;
            return(true);
        }

        bool ok = base.TryPlaceBlock(world, byPlayer, itemstack, blockSel, ref failureCode);

        if (ok)
        {
            WasPlaced(world, blockSel.Position, null);
        }
        return(ok);
    }
Beispiel #6
0
    public override bool TryPlaceBlock(IWorldAccessor world, IPlayer byPlayer, ItemStack itemstack, BlockSelection blockSel, ref EnumHandling handling, ref string failureCode)
    {
        handling = EnumHandling.PreventDefault;
        Vec3f         vec           = new Vec3d().Ahead(1f, byPlayer.Entity.Pos.Pitch, byPlayer.Entity.Pos.Yaw).ToVec3f();
        BlockFacing   face          = BlockFacing.FromNormal(vec).Opposite;
        AssetLocation blockCode     = block.CodeWithVariant("side", face.Code);
        Block         orientedBlock = world.BlockAccessor.GetBlock(blockCode);

        if (orientedBlock.CanPlaceBlock(world, byPlayer, blockSel, ref failureCode))
        {
            orientedBlock.DoPlaceBlock(world, byPlayer, blockSel, itemstack);
            return(true);
        }
        return(false);
    }
Beispiel #7
0
        private bool RequiresStand(BlockPos pos, Vec3i vector)
        {
            try
            {
                BlockMPBase block = Api.World.BlockAccessor.GetBlock(pos.X + vector.X, pos.Y + vector.Y, pos.Z + vector.Z) as BlockMPBase;
                if (block == null)
                {
                    return(true);
                }

                BlockPos         sidePos = new BlockPos(pos.X + vector.X, pos.Y + vector.Y, pos.Z + vector.Z);
                BEBehaviorMPBase bemp    = Api.World.BlockAccessor.GetBlockEntity(sidePos)?.GetBehavior <BEBehaviorMPBase>();
                if (bemp == null)
                {
                    return(true);
                }

                BEBehaviorMPAxle bempaxle = bemp as BEBehaviorMPAxle;
                if (bempaxle == null)
                {
                    if (bemp is BEBehaviorMPBrake || bemp is BEBehaviorMPCreativeRotor)
                    {
                        BlockFacing side = BlockFacing.FromNormal(vector);
                        if (side != null && block.HasMechPowerConnectorAt(Api.World, sidePos, side.Opposite))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }

                if (IsAttachedToBlock(Api.World.BlockAccessor, block, sidePos))
                {
                    return(false);
                }
                return(bempaxle.RequiresStand(sidePos, vector));
            }
            catch (Exception e)
            {
#if DEBUG
                throw (e);
#else
                Api.Logger.Error("Exception thrown in RequiresStand, will log exception but silently ignore it");
                Api.Logger.Error("{0}", e);
                return(false);
#endif
            }
        }
Beispiel #8
0
        /// <summary>
        /// Loads the meta information for each block in the schematic.
        /// </summary>
        /// <param name="blockAccessor"></param>
        /// <param name="worldForResolve"></param>
        /// <param name="fileNameForLogging"></param>
        public void LoadMetaInformationAndValidate(IBlockAccessor blockAccessor, IWorldAccessor worldForResolve, string fileNameForLogging)
        {
            List <BlockPos>  undergroundPositions = new List <BlockPos>();
            Queue <BlockPos> pathwayPositions     = new Queue <BlockPos>();

            HashSet <AssetLocation> missingBlocks = new HashSet <AssetLocation>();

            for (int i = 0; i < Indices.Count; i++)
            {
                uint index         = Indices[i];
                int  storedBlockid = BlockIds[i];

                int dx = (int)(index & 0x1ff);
                int dy = (int)((index >> 20) & 0x1ff);
                int dz = (int)((index >> 10) & 0x1ff);

                AssetLocation blockCode = BlockCodes[storedBlockid];
                Block         newBlock  = blockAccessor.GetBlock(blockCode);

                if (newBlock == null)
                {
                    missingBlocks.Add(blockCode);
                }

                if (newBlock != pathwayBlock && newBlock != undergroundBlock)
                {
                    continue;
                }

                BlockPos pos = new BlockPos(dx, dy, dz);

                if (newBlock == pathwayBlock)
                {
                    pathwayPositions.Enqueue(pos);
                }
                else
                {
                    undergroundPositions.Add(pos);
                }
            }

            if (missingBlocks.Count > 0)
            {
                worldForResolve.Logger.Warning("Block schematic file {0} uses blocks that could no longer be found. These will turn into air blocks! (affected: {1})", fileNameForLogging, string.Join(",", missingBlocks));
            }

            HashSet <AssetLocation> missingItems = new HashSet <AssetLocation>();

            foreach (var val in ItemCodes)
            {
                if (worldForResolve.GetItem(val.Value) == null)
                {
                    missingItems.Add(val.Value);
                }
            }

            if (missingItems.Count > 0)
            {
                worldForResolve.Logger.Warning("Block schematic file {0} uses items that could no longer be found. These will turn into unknown items! (affected: {1})", fileNameForLogging, string.Join(",", missingItems));
            }


            UndergroundCheckPositions = undergroundPositions.ToArray();


            List <List <BlockPos> > pathwayslist = new List <List <BlockPos> >();

            if (pathwayPositions.Count == 0)
            {
                this.PathwayStarts  = new BlockPos[0];
                this.PathwayOffsets = new BlockPos[0][];
                this.PathwaySides   = new BlockFacing[0];
                return;
            }


            while (pathwayPositions.Count > 0)
            {
                List <BlockPos> pathway = new List <BlockPos>()
                {
                    pathwayPositions.Dequeue()
                };
                pathwayslist.Add(pathway);

                int i = pathwayPositions.Count;

                while (i-- > 0)
                {
                    BlockPos pos   = pathwayPositions.Dequeue();
                    bool     found = false;

                    for (int j = 0; j < pathway.Count; j++)
                    {
                        BlockPos ppos     = pathway[j];
                        int      distance = Math.Abs(pos.X - ppos.X) + Math.Abs(pos.Y - ppos.Y) + Math.Abs(pos.Z - ppos.Z);

                        if (distance == 1)
                        {
                            found = true;
                            pathway.Add(pos);
                            break;
                        }
                    }

                    if (!found)
                    {
                        pathwayPositions.Enqueue(pos);
                    }
                    else
                    {
                        i = pathwayPositions.Count;
                    }
                }
            }



            PathwayStarts  = new BlockPos[pathwayslist.Count];
            PathwayOffsets = new BlockPos[pathwayslist.Count][];
            PathwaySides   = new BlockFacing[pathwayslist.Count];


            for (int i = 0; i < PathwayStarts.Length; i++)
            {
                // Concept to determine on which side the door is:
                // 1. Iterate over every pathway block
                // 2. Calculate the vector between the schematic center point an the pathway block
                // 3. Get the average vector by summing up + divide by count
                // => this is now basically the centerpoint of the door!
                // 4. This final vector can now be used to determine the block facing

                Vec3f dirToMiddle = new Vec3f();

                List <BlockPos> pathway = pathwayslist[i];

                for (int j = 0; j < pathway.Count; j++)
                {
                    BlockPos pos = pathway[j];
                    dirToMiddle.X += pos.X - SizeX / 2f;
                    dirToMiddle.Y += pos.Y - SizeY / 2f;
                    dirToMiddle.Z += pos.Z - SizeZ / 2f;
                }

                dirToMiddle.Normalize();

                PathwaySides[i] = BlockFacing.FromNormal(dirToMiddle);
                BlockPos start = PathwayStarts[i] = pathwayslist[i][0].Copy();

                PathwayOffsets[i] = new BlockPos[pathwayslist[i].Count];

                for (int j = 0; j < pathwayslist[i].Count; j++)
                {
                    PathwayOffsets[i][j] = pathwayslist[i][j].Sub(start);
                }
            }
        }