Пример #1
0
        private static BoxTransition ComputeTransitions(
            ChunkManager Data,
            VoxelHandle V,
            VoxelType Type)
        {
            if (Type.Transitions == VoxelType.TransitionType.Horizontal)
            {
                var value = ComputeTransitionValueOnPlane(
                    VoxelHelpers.EnumerateManhattanNeighbors2D(V.Coordinate)
                    .Select(c => new VoxelHandle(Data, c)), Type);

                return(new BoxTransition()
                {
                    Top = (TransitionTexture)value
                });
            }
            else
            {
                var transitionFrontBack = ComputeTransitionValueOnPlane(VoxelHelpers.EnumerateManhattanNeighbors2D_Z(V.Coordinate)
                                                                        .Select(c => new VoxelHandle(Data, c)),
                                                                        Type);

                var transitionLeftRight = ComputeTransitionValueOnPlane(VoxelHelpers.EnumerateManhattanNeighbors2D_X(V.Coordinate)
                                                                        .Select(c => new VoxelHandle(Data, c)),
                                                                        Type);

                return(new BoxTransition()
                {
                    Front = (TransitionTexture)transitionFrontBack,
                    Back = (TransitionTexture)transitionFrontBack,
                    Left = (TransitionTexture)transitionLeftRight,
                    Right = (TransitionTexture)transitionLeftRight
                });
            }
        }
Пример #2
0
        public IEnumerable <Status> TeleportFunction()
        {
            GameComponent closestItem = Creature.AI.Blackboard.GetData <GameComponent>(ObjectBlackboardName);

            if (closestItem != null)
            {
                var location = TeleportOffset + closestItem.BoundingBox.Center();
                if (CheckForOcclusion)
                {
                    VoxelHandle voxAt       = new VoxelHandle(Agent.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(location));
                    bool        gotLocation = false;
                    if (!voxAt.IsValid || !voxAt.IsEmpty)
                    {
                        // If we can't go to the preferred location, just try any free neighbor.
                        voxAt = new VoxelHandle(Agent.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(closestItem.BoundingBox.Center()));
                        foreach (var neighbor in VoxelHelpers.EnumerateManhattanNeighbors2D(voxAt.Coordinate))
                        {
                            VoxelHandle newVox = new VoxelHandle(Agent.World.ChunkManager, neighbor);

                            if (newVox.IsValid && newVox.IsEmpty)
                            {
                                location    = newVox.WorldPosition + new Vector3(0.5f, Agent.Physics.BoundingBox.Extents().Y, 0.5f);
                                gotLocation = true;
                                break;
                            }
                        }

                        // If there's no free neighbor, just teleport directly to the object.
                        if (!gotLocation)
                        {
                            location = closestItem.BoundingBox.Center();
                        }
                    }
                }
                TeleportAct act = new TeleportAct(Creature.AI)
                {
                    Location = location
                };
                act.Initialize();
                foreach (Act.Status status in act.Run())
                {
                    yield return(status);
                }
            }

            yield return(Status.Fail);
        }
Пример #3
0
        public virtual void OrientToWalls()
        {
            Orient(0);
            var curr = new VoxelHandle(Manager.World.ChunkManager, GlobalVoxelCoordinate.FromVector3(LocalTransform.Translation));

            if (curr.IsValid)
            {
                foreach (var n in VoxelHelpers.EnumerateManhattanNeighbors2D(curr.Coordinate))
                {
                    var v = new VoxelHandle(World.ChunkManager, n);
                    if (v.IsValid && !v.IsEmpty)
                    {
                        Vector3 diff = n.ToVector3() - curr.WorldPosition;
                        Orient((float)Math.Atan2(diff.X, diff.Z));
                        break;
                    }
                }
            }
        }
Пример #4
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var grass = Library.GetGrassType(voxel.GrassType);

                            if (grass.NeedsSunlight && !voxel.Sunlight)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (grass.Decay)
                            {
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = Library.GetGrassType(grass.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                                else
                                {
                                    voxel.GrassDecay -= 1;
                                }
                            }
                        }
//#if false
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            // Don't spread if there's an entity here.
                            var entityPresent = chunk.Manager.World.EnumerateIntersectingObjects(
                                new BoundingBox(voxel.WorldPosition + new Vector3(0.1f, 1.1f, 0.1f), voxel.WorldPosition + new Vector3(0.9f, 1.9f, 0.9f)),
                                CollisionType.Static).Any();
                            if (entityPresent)
                            {
                                continue;
                            }

                            if (chunk.Manager.World.Overworld.Map.GetBiomeAt(voxel.Coordinate.ToVector3(), chunk.Manager.World.Overworld.InstanceSettings.Origin).HasValue(out var biome))
                            {
                                var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                      .Select(c => new VoxelHandle(voxel.Chunk.Manager, c))
                                                      .Where(v => v.IsValid && v.GrassType != 0)
                                                      .Where(v => Library.GetGrassType(v.GrassType).Spreads)
                                                      .Where(v =>
                                {
                                    if (chunk.Manager.World.Overworld.Map.GetBiomeAt(v.Coordinate.ToVector3(), chunk.Manager.World.Overworld.InstanceSettings.Origin).HasValue(out var otherBiome))
                                    {
                                        return(biome == otherBiome);
                                    }
                                    return(false);
                                })
                                                      .ToList();

                                if (grassyNeighbors.Count > 0)
                                {
                                    if (MathFunctions.RandEvent(0.1f))
                                    {
                                        addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                    }
                                }
                            }
                        }
//#endif
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = Library.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && !l.Sunlight)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }
Пример #5
0
        public static bool IsValidPlacement(
            VoxelHandle Location,
            ResourceType CraftType,
            WorldManager World,
            GameComponent PreviewBody,
            String Verb,
            String PastParticple)
        {
            if (CraftType == null)
            {
                return(false);
            }

            switch (CraftType.Placement_PlacementRequirement)
            {
            case ResourceType.PlacementRequirement.NearWall:
            {
                var neighborFound = VoxelHelpers.EnumerateManhattanNeighbors2D(Location.Coordinate)
                                    .Select(c => new VoxelHandle(World.ChunkManager, c))
                                    .Any(v => v.IsValid && !v.IsEmpty);

                if (!neighborFound)
                {
                    World.UserInterface.ShowTooltip("Must be " + PastParticple + " next to wall!");
                    return(false);
                }

                break;
            }

            case ResourceType.PlacementRequirement.OnGround:
            {
                var below = VoxelHelpers.GetNeighbor(Location, new GlobalVoxelOffset(0, -1, 0));

                if (!below.IsValid || below.IsEmpty)
                {
                    World.UserInterface.ShowTooltip("Must be " + PastParticple + " on solid ground!");
                    return(false);
                }
                break;
            }
            }

            if (PreviewBody != null)
            {
                // Just check for any intersecting body in octtree.

                var previewBox = PreviewBody.GetRotatedBoundingBox();
                var sensorBox  = previewBox;

                GenericVoxelListener sensor;
                if (PreviewBody.GetComponent <GenericVoxelListener>().HasValue(out sensor))
                {
                    sensorBox = sensor.GetRotatedBoundingBox();
                }

                if (Debugger.Switches.DrawToolDebugInfo)
                {
                    Drawer3D.DrawBox(sensorBox, Color.Yellow, 0.1f, false);
                }

                foreach (var intersectingObject in World.EnumerateIntersectingObjects(sensorBox, CollisionType.Static))
                {
                    if (Object.ReferenceEquals(intersectingObject, sensor))
                    {
                        continue;
                    }
                    var objectRoot = intersectingObject.GetRoot() as GameComponent;
                    if (objectRoot is WorkPile)
                    {
                        continue;
                    }
                    if (objectRoot == PreviewBody)
                    {
                        continue;
                    }
                    if (objectRoot.IsDead)
                    {
                        continue;
                    }
                    if (objectRoot != null && objectRoot.GetRotatedBoundingBox().Intersects(previewBox))
                    {
                        World.UserInterface.ShowTooltip("Can't " + Verb + " here: intersects " + objectRoot.Name);
                        return(false);
                    }
                }

                bool intersectsWall = VoxelHelpers.EnumerateCoordinatesInBoundingBox
                                          (PreviewBody.GetRotatedBoundingBox().Expand(-0.1f)).Any(
                    v =>
                {
                    var tvh = new VoxelHandle(World.ChunkManager, v);
                    return(tvh.IsValid && !tvh.IsEmpty);
                });

                var  current    = new VoxelHandle(World.ChunkManager, GlobalVoxelCoordinate.FromVector3(PreviewBody.Position));
                bool underwater = current.IsValid && current.LiquidType != LiquidType.None;

                if (underwater)
                {
                    World.UserInterface.ShowTooltip("Can't " + Verb + " here: underwater or in lava.");
                    return(false);
                }

                if (intersectsWall && CraftType.Placement_PlacementRequirement != ResourceType.PlacementRequirement.NearWall)
                {
                    World.UserInterface.ShowTooltip("Can't " + Verb + " here: intersects wall.");
                    return(false);
                }
            }
            World.UserInterface.ShowTooltip("");
            return(true);
        }
Пример #6
0
        public static bool IsValidPlacement(
            VoxelHandle Location,
            CraftItem CraftType,
            GameMaster Player,
            Body PreviewBody,
            String Verb,
            String PastParticple)
        {
            if (CraftType == null)
            {
                return(false);
            }

            if (!String.IsNullOrEmpty(CraftType.CraftLocation) &&
                Player.Faction.FindNearestItemWithTags(CraftType.CraftLocation, Location.WorldPosition, false, null) == null)
            {
                Player.World.ShowTooltip("Can't " + Verb + ", need " + CraftType.CraftLocation);
                return(false);
            }

            foreach (var req in CraftType.Prerequisites)
            {
                switch (req)
                {
                case CraftItem.CraftPrereq.NearWall:
                {
                    var neighborFound = VoxelHelpers.EnumerateManhattanNeighbors2D(Location.Coordinate)
                                        .Select(c => new VoxelHandle(Player.World.ChunkManager.ChunkData, c))
                                        .Any(v => v.IsValid && !v.IsEmpty);

                    if (!neighborFound)
                    {
                        Player.World.ShowTooltip("Must be " + PastParticple + " next to wall!");
                        return(false);
                    }

                    break;
                }

                case CraftItem.CraftPrereq.OnGround:
                {
                    var below = VoxelHelpers.GetNeighbor(Location, new GlobalVoxelOffset(0, -1, 0));

                    if (!below.IsValid || below.IsEmpty)
                    {
                        Player.World.ShowTooltip("Must be " + PastParticple + " on solid ground!");
                        return(false);
                    }
                    break;
                }
                }
            }

            if (PreviewBody != null)
            {
                // Just check for any intersecting body in octtree.

                var previewBox = PreviewBody.GetRotatedBoundingBox();
                var sensorBox  = previewBox;
                var sensor     = PreviewBody.GetComponent <GenericVoxelListener>();
                if (sensor != null)
                {
                    sensorBox = sensor.GetRotatedBoundingBox();
                }
                if (Debugger.Switches.DrawToolDebugInfo)
                {
                    Drawer3D.DrawBox(sensorBox, Color.Yellow, 0.1f, false);
                }

                foreach (var intersectingObject in Player.World.EnumerateIntersectingObjects(sensorBox, CollisionType.Static))
                {
                    if (Object.ReferenceEquals(intersectingObject, sensor))
                    {
                        continue;
                    }
                    var objectRoot = intersectingObject.GetRoot() as Body;
                    if (objectRoot is WorkPile)
                    {
                        continue;
                    }
                    if (objectRoot != null && objectRoot.GetRotatedBoundingBox().Intersects(previewBox))
                    {
                        Player.World.ShowTooltip("Can't " + Verb + " here: intersects " + objectRoot.Name);
                        return(false);
                    }
                }

                bool intersectsWall = VoxelHelpers.EnumerateCoordinatesInBoundingBox
                                          (PreviewBody.GetRotatedBoundingBox().Expand(-0.1f)).Any(
                    v =>
                {
                    var tvh = new VoxelHandle(Player.World.ChunkManager.ChunkData, v);
                    return(tvh.IsValid && !tvh.IsEmpty);
                });
                var  current    = new VoxelHandle(Player.World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(PreviewBody.Position));
                bool underwater = current.IsValid && current.LiquidType != LiquidType.None;
                if (underwater)
                {
                    Player.World.ShowTooltip("Can't " + Verb + " here: underwater or in lava.");
                    return(false);
                }
                if (intersectsWall && !CraftType.Prerequisites.Contains(CraftItem.CraftPrereq.NearWall))
                {
                    Player.World.ShowTooltip("Can't " + Verb + " here: intersects wall.");
                    return(false);
                }
            }
            Player.World.ShowTooltip("");
            return(true);
        }
Пример #7
0
        public bool IsValid(CraftDesignation designation)
        {
            if (!designation.Valid)
            {
                return(false);
            }

            if (IsDesignation(designation.Location))
            {
                World.ShowToolPopup("Something is already being built there!");
                return(false);
            }

            if (!String.IsNullOrEmpty(designation.ItemType.CraftLocation) &&
                Faction.FindNearestItemWithTags(designation.ItemType.CraftLocation, designation.Location.WorldPosition, false) ==
                null)
            {
                World.ShowToolPopup("Can't build, need " + designation.ItemType.CraftLocation);
                return(false);
            }

            if (!Faction.HasResources(designation.ItemType.RequiredResources))
            {
                string neededResources = "";

                foreach (Quantitiy <Resource.ResourceTags> amount in designation.ItemType.RequiredResources)
                {
                    neededResources += "" + amount.NumResources + " " + amount.ResourceType.ToString() + " ";
                }

                World.ShowToolPopup("Not enough resources! Need " + neededResources + ".");
                return(false);
            }

            foreach (var req in designation.ItemType.Prerequisites)
            {
                switch (req)
                {
                case CraftItem.CraftPrereq.NearWall:
                {
                    var neighborFound = VoxelHelpers.EnumerateManhattanNeighbors2D(designation.Location.Coordinate)
                                        .Select(c => new VoxelHandle(World.ChunkManager.ChunkData, c))
                                        .Any(v => v.IsValid && !v.IsEmpty);

                    if (!neighborFound)
                    {
                        World.ShowToolPopup("Must be built next to wall!");
                        return(false);
                    }

                    break;
                }

                case CraftItem.CraftPrereq.OnGround:
                {
                    var below = VoxelHelpers.GetNeighbor(designation.Location, new GlobalVoxelOffset(0, -1, 0));

                    if (!below.IsValid || below.IsEmpty)
                    {
                        World.ShowToolPopup("Must be built on solid ground!");
                        return(false);
                    }
                    break;
                }
                }
            }

            if (CurrentCraftBody != null)
            {
                var intersectsAnyOther = Faction.OwnedObjects.FirstOrDefault(
                    o => o != null &&
                    o != CurrentCraftBody &&
                    o.GetRotatedBoundingBox().Intersects(CurrentCraftBody.GetRotatedBoundingBox().Expand(-0.1f)));

                var intersectsBuildObjects = Faction.Designations.EnumerateEntityDesignations(DesignationType.Craft)
                                             .Any(d => d.Body != CurrentCraftBody && d.Body.GetRotatedBoundingBox().Intersects(
                                                      CurrentCraftBody.GetRotatedBoundingBox().Expand(-0.1f)));

                bool intersectsWall = VoxelHelpers.EnumerateCoordinatesInBoundingBox
                                          (CurrentCraftBody.GetRotatedBoundingBox().Expand(-0.1f)).Any(
                    v =>
                {
                    var tvh = new VoxelHandle(World.ChunkManager.ChunkData, v);
                    return(tvh.IsValid && !tvh.IsEmpty);
                });

                if (intersectsAnyOther != null)
                {
                    World.ShowToolPopup("Can't build here: intersects " + intersectsAnyOther.Name);
                }
                else if (intersectsBuildObjects)
                {
                    World.ShowToolPopup("Can't build here: intersects something else being built");
                }
                else if (intersectsWall && !designation.ItemType.Prerequisites.Contains(CraftItem.CraftPrereq.NearWall))
                {
                    World.ShowToolPopup("Can't build here: intersects wall.");
                }

                return(intersectsAnyOther == null && !intersectsBuildObjects &&
                       (!intersectsWall || designation.ItemType.Prerequisites.Contains(CraftItem.CraftPrereq.NearWall)));
            }
            return(true);
        }
Пример #8
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var decal = GrassLibrary.GetGrassType(voxel.GrassType);

                            if (decal.NeedsSunlight && voxel.SunColor < 255)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (decal.Decay)
                            {
                                voxel.GrassDecay -= 1;
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = GrassLibrary.GetGrassType(decal.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                            }
                        }
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            var biome = Overworld.GetBiomeAt(voxel.Coordinate.ToVector3());

                            var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                  .Select(c => new VoxelHandle(voxel.Chunk.Manager.ChunkData, c))
                                                  .Where(v => v.IsValid && v.GrassType != 0)
                                                  .Where(v => biome == Overworld.GetBiomeAt(v.Coordinate.ToVector3()))
                                                  .ToList();

                            if (grassyNeighbors.Count > 0)
                            {
                                if (MathFunctions.RandEvent(0.1f))
                                {
                                    addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                }
                            }
                        }
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = GrassLibrary.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && l.SunColor != 255)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }