public IEnumerable <Act.Status> AddAnimal(Body animal, Faction faction) { Animals.Add(animal); BoundingBox animalBounds = GetBoundingBox(); animalBounds = animalBounds.Expand(-0.25f); animalBounds.Max.Y += 2; animalBounds.Min.Y -= 0.25f; animal.GetComponent <Physics>().ReservedFor = null;; animal.GetComponent <CreatureAI>().PositionConstraint = animalBounds; faction.Designations.RemoveEntityDesignation(animal.GetComponent <Physics>(), DesignationType.Wrangle); yield return(Act.Status.Success); }
public IEnumerable <Act.Status> RemoveAnimal(Body animal) { if (!Animals.Contains(animal)) { yield return(Act.Status.Fail); yield break; } Animals.Remove(animal); animal.GetComponent <CreatureAI>().ResetPositionConstraint(); Species = animal.GetComponent <Creature>().Species; yield return(Act.Status.Success); }
public override bool ShouldRetry(Creature agent) { return(EntityToGather != null && !EntityToGather.IsDead && !agent.AI.GatherManager.ItemsToGather.Contains(EntityToGather) && PlanAct.PathExists(EntityToGather.GetComponent <Physics>().CurrentVoxel, agent.Physics.CurrentVoxel, agent.AI)); }
public override bool AddItem(Body component) { bool worked = base.AddItem(component); HandleBoxes(); TossMotion toss = new TossMotion(1.0f, 2.5f, component.LocalTransform, Boxes[Boxes.Count - 1].LocalTransform.Translation + new Vector3(0.5f, 0.5f, 0.5f)); component.GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; component.AnimationQueue.Add(toss); toss.OnComplete += component.Die; return(worked); }
public bool RemoveResources(List <ResourceAmount> resources, Vector3 position, bool createItems = true) { Dictionary <ResourceLibrary.ResourceType, ResourceAmount> amounts = new Dictionary <ResourceLibrary.ResourceType, ResourceAmount>(); foreach (ResourceAmount resource in resources) { if (!amounts.ContainsKey(resource.ResourceType)) { amounts.Add(resource.ResourceType, new ResourceAmount(resource)); } else { amounts[resource.ResourceType].NumResources += resource.NumResources; } } if (!HasResources(amounts)) { return(false); } List <Stockpile> stockpilesCopy = new List <Stockpile>(Stockpiles); stockpilesCopy.Sort((a, b) => CompareZones(a, b, position)); foreach (ResourceAmount resource in resources) { int count = 0; List <Vector3> positions = new List <Vector3>(); foreach (Stockpile stock in stockpilesCopy) { int num = stock.Resources.RemoveMaxResources(resource, resource.NumResources - count); stock.HandleBoxes(); if (stock.Boxes.Count > 0) { for (int i = 0; i < num; i++) { positions.Add(stock.Boxes[stock.Boxes.Count - 1].LocalTransform.Translation); } } count += num; if (count >= resource.NumResources) { break; } } if (createItems) { foreach (Vector3 vec in positions) { Body newEntity = EntityFactory.CreateEntity <Body>(resource.ResourceType + " Resource", vec + MathFunctions.RandVector3Cube() * 0.5f); TossMotion toss = new TossMotion(1.0f + MathFunctions.Rand(0.1f, 0.2f), 2.5f + MathFunctions.Rand(-0.5f, 0.5f), newEntity.LocalTransform, position); newEntity.GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; newEntity.AnimationQueue.Add(toss); toss.OnComplete += () => toss_OnComplete(newEntity); } } } 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 override IEnumerable <Status> Run() { if (!Creature.Faction.WallBuilder.IsDesignation(Voxel)) { yield return(Status.Fail); yield break; } foreach (Status status in Creature.HitAndWait(1.0f, true, Voxel.Position)) { if (status == Status.Running) { yield return(status); } } Body grabbed = Creature.Inventory.RemoveAndCreate(Resource).FirstOrDefault(); if (grabbed == null) { yield return(Status.Fail); yield break; } else { if (Creature.Faction.WallBuilder.IsDesignation(Voxel)) { // If the creature intersects the box, find a voxel adjacent to it that is free, and jump there to avoid getting crushed. if (Creature.Physics.BoundingBox.Intersects(Voxel.GetBoundingBox())) { List <Voxel> neighbors = Voxel.Chunk.GetNeighborsEuclidean(Voxel); Voxel closest = null; float closestDist = float.MaxValue; foreach (Voxel voxel in neighbors) { float dist = (voxel.Position - Creature.Physics.Position).LengthSquared(); if (dist < closestDist && voxel.IsEmpty) { closestDist = dist; closest = voxel; } } if (closest != null) { TossMotion teleport = new TossMotion(0.5f, 1.0f, Creature.Physics.GlobalTransform, closest.Position + Vector3.One * 0.5f); Creature.Physics.AnimationQueue.Add(teleport); } } TossMotion motion = new TossMotion(1.0f, 2.0f, grabbed.LocalTransform, Voxel.Position + new Vector3(0.5f, 0.5f, 0.5f)); motion.OnComplete += grabbed.Die; grabbed.GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; grabbed.AnimationQueue.Add(motion); WallBuilder put = Creature.Faction.WallBuilder.GetDesignation(Voxel); put.Put(Creature.Manager.World.ChunkManager); Creature.Faction.WallBuilder.Designations.Remove(put); Creature.Stats.NumBlocksPlaced++; Creature.AI.AddXP(1); yield return(Status.Success); } else { Creature.Inventory.Resources.AddItem(grabbed); grabbed.Die(); yield return(Status.Fail); } } }