示例#1
0
        public float GetHeatStrength(IWorldAccessor world, BlockPos heatSourcePos, BlockPos heatReceiverPos)
        {
            if (block.EntityClass != null)
            {
                var behs = world.BlockAccessor.GetBlockEntity(heatSourcePos) as IHeatSource;
                if (behs != null)
                {
                    return(behs.GetHeatStrength(world, heatSourcePos, heatReceiverPos) * GameMath.Clamp(1 - (heatSourcePos.DistanceTo(heatReceiverPos) - 1) / 3f, 0, 1));
                }
            }

            return(heatStrength * GameMath.Clamp(1 - (heatSourcePos.DistanceTo(heatReceiverPos) - 1) / 3f, 0, 1));
        }
示例#2
0
        public override void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ref EnumHandling handled)
        {
            testBlockPos.Clear();
            lworld = world;
            if (world.Side != EnumAppSide.Server)
            {
                return;
            }
            BlockPos pos = blockPos;

            targetPos = world.GetNearestEntity(pos.ToVec3d(), 64, 64).Pos.AsBlockPos;
            Vec3d    posv = pos.ToVec3d();
            Vec3d    tgtv = targetPos.ToVec3d();
            BlockPos mP   = ((posv.Add(tgtv)) / 2).AsBlockPos;
            int      sR   = (int)mP.DistanceTo(pos) + 4;
            var      grid = new CubeGrid(sR * 2, sR * 2, sR * 2);

            if (!grid.isInBounds(world, targetPos) || !grid.isPassable(world, targetPos) || !grid.isWalkable(world, targetPos))
            {
                return;
            }
            for (int x = mP.X - sR; x <= mP.X + sR; x++)
            {
                for (int y = mP.Y - sR; y <= mP.Y + sR; y++)
                {
                    for (int z = mP.Z - sR; z <= mP.Z + sR; z++)
                    {
                        BlockPos currentPos = new BlockPos(x, y, z);
                        if (grid.isInBounds(world, currentPos) && grid.isPassable(world, currentPos) && grid.isWalkable(world, currentPos))
                        {
                            grid.air.Add(currentPos);
                        }
                        else
                        {
                            grid.walls.Add(currentPos);
                        }
                    }
                }
            }
            var astar = new AStarSearch(world, grid, pos, targetPos);

            DrawGrid(world, astar, mP, sR);
            world.BlockAccessor.SetBlock(2278, pos);
            //world.BlockAccessor.SetBlock(2279, mP);
            world.BlockAccessor.SetBlock(2278, targetPos);
            testBlockPos.Add(targetPos);
            testBlockPos.Add(pos);
            //testBlockPos.Add(mP);
            return;
        }
示例#3
0
        public void GrowTree(IBlockAccessor blockAccessor, BlockPos pos, bool skipForestFloor, float sizeModifier = 1, float vineGrowthChance = 0, float otherBlockChance = 1, int treesInChunkGenerated = 0)
        {
            float f = otherBlockChance == 0 ? (3 + (float)rand.NextDouble() * 6) : (3 + (float)rand.NextDouble() * 4) * 3 * 3;

            int quantity = GameMath.RoundRandom(rand, f);

            BlockPos npos = pos.Copy();

            sizeModifier = GameMath.Mix(sizeModifier, 1, 0.5f);

            sizeModifier *= 1 + ((float)rand.NextDouble() * 0.5f);

            while (quantity-- > 0)
            {
                float dist = Math.Max(1, pos.DistanceTo(npos) - 2);

                GrowStalk(blockAccessor, npos.UpCopy(), dist, sizeModifier, vineGrowthChance);

                // Potentially grow another one nearby
                npos.Set(pos);
                npos.X += rand.Next(8) - 4;
                npos.Z += rand.Next(8) - 4;

                // Test up to 2 blocks up and down.
                bool foundSuitableBlock = false;
                for (int y = 2; y >= -2; y--)
                {
                    Block block = blockAccessor.GetBlock(npos.X, npos.Y + y, npos.Z);
                    if (block.Fertility > 0)
                    {
                        npos.Y             = npos.Y + y;
                        foundSuitableBlock = true;
                        break;
                    }
                }
                if (!foundSuitableBlock)
                {
                    break;
                }
            }
        }
示例#4
0
        public List <BlockPos> MakeGrid(IWorldAccessor world, BlockPos targetPos, BlockPos startPos)
        {
            BlockPos pos  = startPos;
            Vec3d    posv = pos.ToVec3d();
            Vec3d    tgtv = targetPos.ToVec3d();
            BlockPos mP   = ((posv.Add(tgtv)) / 2).AsBlockPos;
            int      sR   = (int)mP.DistanceTo(pos) + 4;
            var      grid = new CubeGrid(sR * 2, sR * 2, sR * 2);

            if (!grid.isInBounds(world, targetPos) || !grid.isPassable(world, targetPos) || !grid.isWalkable(world, targetPos))
            {
                return(new List <BlockPos> {
                    startPos
                });
            }
            for (int x = mP.X - sR; x <= mP.X + sR; x++)
            {
                for (int y = mP.Y - sR; y <= mP.Y + sR; y++)
                {
                    for (int z = mP.Z - sR; z <= mP.Z + sR; z++)
                    {
                        BlockPos currentPos = new BlockPos(x, y, z);
                        if (grid.isInBounds(world, currentPos) && grid.isPassable(world, currentPos) && grid.isWalkable(world, currentPos))
                        {
                            grid.air.Add(currentPos);
                        }
                        else
                        {
                            grid.walls.Add(currentPos);
                        }
                    }
                }
            }
            var astar = new AStarSearch(world, grid, pos, targetPos);

            return(CurrentPath(world, astar, mP, sR));
        }
示例#5
0
        public void CmdMeasuringTape(int groupId, CmdArgs args)
        {
            WaypointUtilSystem wUtil = capi.ModLoader.GetModSystem <WaypointUtilSystem>();
            string             arg   = args.PopWord();

            switch (arg)
            {
            case "start":
                if (capi.World.Player.CurrentBlockSelection != null)
                {
                    start = capi.World.Player.CurrentBlockSelection.Position;
                    //capi.ShowChatMessage("Okay, start set to: " + start);
                    MakeHighlights();
                }
                else
                {
                    capi.ShowChatMessage("Please look at a block.");
                }
                break;

            case "end":
                if (capi.World.Player.CurrentBlockSelection != null)
                {
                    end = capi.World.Player.CurrentBlockSelection.Position;
                    //capi.ShowChatMessage("Okay, end set to: " + end);
                    MakeHighlights();
                }
                else
                {
                    capi.ShowChatMessage("Please look at a block.");
                }
                break;

            case "startwp":
                int?swpID = args.PopInt();
                if (swpID != null)
                {
                    start = wUtil.Waypoints[(int)swpID].Position.AsBlockPos;
                    MakeHighlights();
                }
                else
                {
                    capi.ShowChatMessage("Please enter a waypoint id.");
                }
                break;

            case "endwp":
                int?ewpID = args.PopInt();
                if (ewpID != null)
                {
                    end = wUtil.Waypoints[(int)ewpID].Position.AsBlockPos;
                    MakeHighlights();
                }
                else
                {
                    capi.ShowChatMessage("Please enter a waypoint id.");
                }
                break;

            case "calc":
                string type = args.PopWord();
                switch (type)
                {
                case "block":
                    capi.ShowChatMessage("Block Distance: " + Math.Round(start.DistanceTo(end) + 1));
                    break;

                case "euclidian":
                    capi.ShowChatMessage("Euclidian Distance: " + start.DistanceTo(end));
                    break;

                case "manhattan":
                    capi.ShowChatMessage("Manhattan Distance: " + start.ManhattenDistance(end));
                    break;

                case "horizontal":
                    capi.ShowChatMessage("Horizontal Distance: " + Math.Sqrt(start.HorDistanceSqTo(end.X, end.Z)));
                    break;

                case "horizontalmanhattan":
                    capi.ShowChatMessage("Horizontal Manhattan Distance: " + start.HorizontalManhattenDistance(end));
                    break;

                default:
                    capi.ShowChatMessage("Syntax: .measure calc [block|euclidian|manhattan|horizontal|horizontalmanhattan]");
                    break;
                }
                break;

            default:
                capi.ShowChatMessage("Syntax: .measure [start|end|calc]");
                break;
            }
        }
示例#6
0
        //-- Creates a spherical crater where the meteor made contact with the ground --//
        private void CreateCrater(Vec3d meteorDirection, Vec3d shrapnelDirection)
        {
            List <LandClaim> claims       = serverAPI.World.Claims.All;
            List <BlockPos>  ashPositions = new List <BlockPos>();

            blockAccessor = serverAPI.World.GetBlockAccessorBulkUpdate(true, true);

            Vec3i centerPos = this.entity.ServerPos.XYZInt;

            BlockPos craterPos = new BlockPos();

            //-- Initial scan to see if the meteor crater should fill with liquid instead of air --//
            blockAccessor.SearchFluidBlocks(new BlockPos(centerPos.X - explosionRadius, centerPos.Y - explosionRadius, centerPos.Z - explosionRadius),
                                            new BlockPos(centerPos.X + explosionRadius, centerPos.Y + explosionRadius, centerPos.Z + explosionRadius), (block, bPos) =>
            {
                if (block.DrawType == EnumDrawType.Liquid)
                {
                    liquidAsset = new AssetLocation(block.Code.Domain, block.Code.Path);

                    fillWithLiquid = true;
                    fillHeight     = bPos.Y;

                    return(true);
                }

                return(false);
            });


            //-- Scans every block in a cube determined by the explosion radius and determines whether that block fits within the explosion sphere --//
            blockAccessor.WalkBlocks(new BlockPos(centerPos.X - explosionRadius, centerPos.Y - explosionRadius, centerPos.Z - explosionRadius),
                                     new BlockPos(centerPos.X + explosionRadius, centerPos.Y + explosionRadius, centerPos.Z + explosionRadius), (block, xPos, yPos, zPos) =>
            {
                BlockPos blockPos      = new BlockPos(xPos, yPos, zPos);
                float distanceToCenter = blockPos.DistanceTo(centerPos.ToBlockPos());

                if (distanceToCenter < explosionRadius)
                {
                    if (serverAPI.World.Config.GetBool("ClaimsProtected") == true)
                    {
                        bool isClaimed = false;

                        foreach (LandClaim claim in claims)
                        {
                            if (claim.PositionInside(blockPos))
                            {
                                isClaimed = true;
                            }
                        }

                        if (isClaimed == false)
                        {
                            ExplodeBlock(block, blockPos, shrapnelDirection);

                            if (fillWithLiquid == false)
                            {
                                if (centerPos.Y - blockPos.Y == explosionRadius - 1)
                                {
                                    if (explosionRand.Next(0, 100) < ashBlockChance)
                                    {
                                        ashPositions.Add(blockPos + new BlockPos(0, 1, 0));
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        ExplodeBlock(block, blockPos, shrapnelDirection);

                        if (fillWithLiquid == false)
                        {
                            if (centerPos.Y - blockPos.Y == explosionRadius - 1)
                            {
                                if (explosionRand.Next(0, 100) < ashBlockChance)
                                {
                                    ashPositions.Add(blockPos.Copy() + new BlockPos(0, 1, 0));
                                }
                            }
                        }
                    }
                }
            });

            PlaceMeteor(meteorDirection, shrapnelDirection, centerPos, explosionRadius, claims);
            PlaceAsh(ashPositions);

            blockAccessor.Commit();
        }