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 }); } }
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); }
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; } } } }
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; } }
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); }
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); }
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); }
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; } }