public List <Task> CreateTasks() { List <Task> tasks = new List <Task>(); if (Faction.Stockpiles.Count > 0) { tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); } foreach (CreatureAI creature in Faction.Minions) { if (creature.Status.Hunger.IsUnhappy()) { Task g = new SatisfyHungerTask(); if (IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } foreach (CreatureAI creature in Faction.Minions) { if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight()) { Task g = new SatisfyTirednessTask(); if (IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } List <Creature> threatsToRemove = new List <Creature>(); foreach (Creature threat in Faction.Threats) { if (threat != null && !threat.IsDead) { Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } else { threatsToRemove.Add(threat); } } foreach (Creature threat in threatsToRemove) { Faction.Threats.Remove(threat); } foreach (BuildOrder i in Faction.DigDesignations) { if (i == null || i.Vox == null || i.Vox.Health <= 0) { continue; } VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position); if (chunk != null) { if (chunk.IsCompletelySurrounded(i.Vox)) { continue; } } Task g = new KillVoxelTask(i.Vox); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); if (Faction.Stockpiles.Count <= 0) { return(tasks); } foreach (WallBuilder put in Faction.WallBuilder.Designations) { if (Faction.HasResources(new List <ResourceAmount>() { new ResourceAmount(put.Type.ResourceToRelease) })) { Task g = (new BuildVoxelTask(put.Vox, put.Type)); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } return(tasks); }
public List<Task> CreateTasks() { List<Task> tasks = new List<Task>(); if(Faction.Stockpiles.Count > 0) { tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); } foreach(CreatureAI creature in Faction.Minions) { if(creature.Status.Hunger.IsUnhappy()) { Task g = new SatisfyHungerTask(); if(IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } foreach (CreatureAI creature in Faction.Minions) { if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight()) { Task g = new SatisfyTirednessTask(); if (IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } List<Creature> threatsToRemove = new List<Creature>(); foreach(Creature threat in Faction.Threats) { if(threat != null && !threat.IsDead) { Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } else { threatsToRemove.Add(threat); } } foreach (Creature threat in threatsToRemove) { Faction.Threats.Remove(threat); } foreach(BuildOrder i in Faction.DigDesignations) { if (i == null || i.Vox == null || i.Vox.Health <= 0) { continue; } VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position); if(chunk != null) { if(chunk.IsCompletelySurrounded(i.Vox)) { continue; } } Task g = new KillVoxelTask(i.Vox); if(!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); if(Faction.Stockpiles.Count <= 0) { return tasks; } foreach(WallBuilder put in Faction.WallBuilder.Designations) { if(Faction.HasResources(new List<ResourceAmount>() { new ResourceAmount(put.Type.ResourceToRelease) })) { Task g = (new BuildVoxelTask(put.Vox, put.Type)); if(!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } foreach(ShipOrder ship in Faction.ShipDesignations) { List<Body> componentsToShip = new List<Body>(); int remaining = ship.GetRemainingNumResources(); if(remaining == 0) { continue; } foreach(Stockpile s in Faction.Stockpiles) { for(int i = componentsToShip.Count; i < remaining; i++) { // TODO: Reimplement /* Body r = s.FindItemWithTag(ship.Resource.ResourceType.ResourceName, componentsToShip); if(r != null) { componentsToShip.Add(r); } */ } } foreach(Body loc in componentsToShip) { // TODO: Reimplement /* if(ship.Port.ContainsItem(loc)) { continue; } */ Task g = new PutItemInZoneTask(Item.FindItem(loc), ship.Port); if(TaskIsAssigned(g) || !IsFeasible(g, Faction.Minions)) { continue; } ship.Assignments.Add(g); tasks.Add(g); } } return tasks; }
public List <Task> CreateTasks() { List <Task> tasks = new List <Task>(); if (Faction.Stockpiles.Count > 0) { tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); } foreach (CreatureAI creature in Faction.Minions) { if (creature.Status.Hunger.IsUnhappy()) { Task g = new SatisfyHungerTask(); if (IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } foreach (CreatureAI creature in Faction.Minions) { if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight()) { Task g = new SatisfyTirednessTask(); if (IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } List <Creature> threatsToRemove = new List <Creature>(); foreach (Creature threat in Faction.Threats) { if (threat != null && !threat.IsDead) { Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } else { threatsToRemove.Add(threat); } } foreach (Creature threat in threatsToRemove) { Faction.Threats.Remove(threat); } foreach (BuildOrder i in Faction.DigDesignations) { if (i == null || i.Vox == null || i.Vox.Health <= 0) { continue; } VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position); if (chunk != null) { if (chunk.IsCompletelySurrounded(i.Vox)) { continue; } } Task g = new KillVoxelTask(i.Vox); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))); if (Faction.Stockpiles.Count <= 0) { return(tasks); } foreach (WallBuilder put in Faction.WallBuilder.Designations) { if (Faction.HasResources(new List <ResourceAmount>() { new ResourceAmount(put.Type.ResourceToRelease) })) { Task g = (new BuildVoxelTask(put.Vox, put.Type)); if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)) { tasks.Add(g); } } } foreach (ShipOrder ship in Faction.ShipDesignations) { List <Body> componentsToShip = new List <Body>(); int remaining = ship.GetRemainingNumResources(); if (remaining == 0) { continue; } foreach (Stockpile s in Faction.Stockpiles) { for (int i = componentsToShip.Count; i < remaining; i++) { // TODO: Reimplement /* * Body r = s.FindItemWithTag(ship.Resource.ResourceType.ResourceName, componentsToShip); * * if(r != null) * { * componentsToShip.Add(r); * } */ } } foreach (Body loc in componentsToShip) { // TODO: Reimplement /* * if(ship.Port.ContainsItem(loc)) * { * continue; * } */ Task g = new PutItemInZoneTask(Item.FindItem(loc), ship.Port); if (TaskIsAssigned(g) || !IsFeasible(g, Faction.Minions)) { continue; } ship.Assignments.Add(g); tasks.Add(g); } } return(tasks); }
public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { IdleTimer.Update(gameTime); SpeakTimer.Update(gameTime); OrderEnemyAttack(); DeleteBadTasks(); PreEmptTasks(); if (Status.Energy.IsUnhappy() && PlayState.Time.IsNight()) { Task toReturn = new SatisfyTirednessTask(); toReturn.SetupScript(Creature); if (!Tasks.Contains(toReturn)) { Tasks.Add(toReturn); } } if (Status.Hunger.IsUnhappy() && Faction.CountResourcesWithTag(Resource.ResourceTags.Food) > 0) { Task toReturn = new SatisfyHungerTask(); toReturn.SetupScript(Creature); if (!Tasks.Contains(toReturn)) { Tasks.Add(toReturn); } } if (CurrentTask != null && CurrentAct != null) { Act.Status status = CurrentAct.Tick(); bool retried = false; if (status == Act.Status.Fail) { if (CurrentTask.ShouldRetry(Creature)) { if (!Tasks.Contains(CurrentTask)) { CurrentTask.Priority = Task.PriorityType.Eventually; Tasks.Add(CurrentTask); CurrentTask.SetupScript(Creature); retried = true; } } } if (status != Act.Status.Running && !retried) { CurrentTask = null; } } else { bool tantrum = false; if (Status.Happiness.IsUnhappy()) { tantrum = MathFunctions.Rand(0, 1) < 0.25f; } Task goal = GetEasiestTask(Tasks); if (goal != null) { if (tantrum) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Sad); if (Creature.Allies == "Dwarf") { PlayState.AnnouncementManager.Announce(Stats.FullName + " (" + Stats.CurrentLevel.Name + ")" + " refuses to work!", "Our employee is unhappy, and would rather not work!", ZoomToMe); } CurrentTask = null; } else { IdleTimer.Reset(IdleTimer.TargetTimeSeconds); goal.SetupScript(Creature); CurrentTask = goal; Tasks.Remove(goal); } } else { CurrentTask = ActOnIdle(); } } PlannerTimer.Update(gameTime); UpdateThoughts(); UpdateXP(); base.Update(gameTime, chunks, camera); }
public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { IdleTimer.Update(gameTime); SpeakTimer.Update(gameTime); OrderEnemyAttack(); DeleteBadTasks(); PreEmptTasks(); if (Status.Energy.IsUnhappy() && PlayState.Time.IsNight()) { Task toReturn = new SatisfyTirednessTask(); toReturn.SetupScript(Creature); if (!Tasks.Contains(toReturn)) Tasks.Add(toReturn); } if (Status.Hunger.IsUnhappy() && Faction.CountResourcesWithTag(Resource.ResourceTags.Food) > 0) { Task toReturn = new SatisfyHungerTask(); toReturn.SetupScript(Creature); if (!Tasks.Contains(toReturn)) Tasks.Add(toReturn); } if(CurrentTask != null && CurrentAct != null) { Act.Status status = CurrentAct.Tick(); bool retried = false; if(status == Act.Status.Fail) { if(CurrentTask.ShouldRetry(Creature)) { if (!Tasks.Contains(CurrentTask)) { CurrentTask.Priority = Task.PriorityType.Eventually; Tasks.Add(CurrentTask); CurrentTask.SetupScript(Creature); retried = true; } } } if(status != Act.Status.Running && !retried) { CurrentTask = null; } } else { bool tantrum = false; if (Status.Happiness.IsUnhappy()) { tantrum = MathFunctions.Rand(0, 1) < 0.25f; } Task goal = GetEasiestTask(Tasks); if (goal != null) { if (tantrum) { Creature.DrawIndicator(IndicatorManager.StandardIndicators.Sad); if (Creature.Allies == "Dwarf") { PlayState.AnnouncementManager.Announce(Stats.FullName + " (" + Stats.CurrentLevel.Name + ")" + " refuses to work!", "Our employee is unhappy, and would rather not work!", ZoomToMe); } CurrentTask = null; } else { IdleTimer.Reset(IdleTimer.TargetTimeSeconds); goal.SetupScript(Creature); CurrentTask = goal; Tasks.Remove(goal); } } else { CurrentTask = ActOnIdle(); } } PlannerTimer.Update(gameTime); UpdateThoughts(); UpdateXP(); base.Update(gameTime, chunks, camera); }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { //base.Update(gameTime, chunks, camera); if (!Active) { return; } Creature.NoiseMaker.BasePitch = Stats.VoicePitch; AutoGatherTimer.Update(gameTime); IdleTimer.Update(gameTime); SpeakTimer.Update(gameTime); if (AutoGatherTimer.HasTriggered) { foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0)) { Creature.GatherImmediately(body, Inventory.RestockType.RestockResource); } OrderEnemyAttack(); } DeleteBadTasks(); PreEmptTasks(); if (CurrentTask != null) { Stats.Boredom.CurrentValue -= (float)(CurrentTask.BoredomIncrease * gameTime.ElapsedGameTime.TotalSeconds); if (Stats.Boredom.IsCritical()) { Creature.AddThought("I have been overworked recently.", new TimeSpan(0, 4, 0, 0), -2.0f); } Stats.Energy.CurrentValue += (float)(CurrentTask.EnergyDecrease * gameTime.ElapsedGameTime.TotalSeconds); } // Heal thyself if (Stats.Health.IsDissatisfied()) { Task toReturn = new GetHealedTask(); if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } // Try to go to sleep if we are low on energy and it is night time. if (Stats.Energy.IsCritical()) { Task toReturn = new SatisfyTirednessTask(); if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } // Try to find food if we are hungry. if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag(Resource.ResourceTags.Edible) > 0) { Task toReturn = new SatisfyHungerTask() { MustPay = true }; if (Stats.Hunger.IsCritical()) { toReturn.Priority = TaskPriority.Urgent; } if (!Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } if (Stats.Boredom.IsDissatisfied()) { if (!Tasks.Any(task => task.BoredomIncrease < 0)) { Task toReturn = SatisfyBoredom(); if (toReturn != null && !Tasks.Contains(toReturn) && CurrentTask != toReturn) { AssignTask(toReturn); } } } restockTimer.Update(DwarfTime.LastTime); if (restockTimer.HasTriggered && Creature.Inventory.Resources.Count > 10) { Creature.RestockAllImmediately(); } if (CurrentTask == null) // We need something to do. { if (Stats.Happiness.IsSatisfied()) // We're happy, so make sure we aren't on strike. { Stats.IsOnStrike = false; UnhappinessTime = 0.0f; } if (Stats.IsOnStrike) // We're on strike, so track how long this job has sucked. { UnhappinessTime += gameTime.ElapsedGameTime.TotalMinutes; if (UnhappinessTime > GameSettings.Default.HoursUnhappyBeforeQuitting) // If we've been unhappy long enough, quit. { var thoughts = GetRoot().GetComponent <DwarfThoughts>(); Manager.World.MakeAnnouncement( // Can't use a popup because the dwarf will soon not exist. Also - this is a serious event! Message: String.Format("{0} has quit!{1}", Stats.FullName, (thoughts == null ? "" : (" The last straw: " + thoughts.Thoughts.Last(t => t.HappinessModifier < 0.0f).Description))), ClickAction: null, logEvent: true, eventDetails: (thoughts == null ? "So sick of this place!" : String.Join("\n", thoughts.Thoughts.Where(t => t.HappinessModifier < 0.0f).Select(t => t.Description))) ); LeaveWorld(); GetRoot().GetComponent <Inventory>().Die(); GetRoot().GetComponent <SelectionCircle>().Die(); if (thoughts != null) { thoughts.Thoughts.Clear(); } Faction.Minions.Remove(this); World.PersistentData.SelectedMinions.Remove(this); return; } } else if (Stats.Happiness.IsDissatisfied()) // We aren't on strike, but we hate this place. { if (MathFunctions.Rand(0, 1) < 0.25f) // We hate it so much that we might just go on strike! This can probably be tweaked. As it stands, // dorfs go on strike almost immediately every time. { Manager.World.UserInterface.MakeWorldPopup(String.Format("{0} ({1}) refuses to work!", Stats.FullName, Stats.CurrentClass.Name), Creature.Physics, -10, 10); Manager.World.Tutorial("happiness"); SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_gui_negative_generic, 0.25f); Stats.IsOnStrike = true; } } if (!Stats.IsOnStrike) // We aren't on strike, so find a new task. { var goal = GetEasiestTask(Tasks); if (goal == null) { goal = World.TaskManager.GetBestTask(this); } if (goal != null) { IdleTimer.Reset(IdleTimer.TargetTimeSeconds); ChangeTask(goal); } else { var newTask = ActOnIdle(); if (newTask != null) { ChangeTask(newTask); } } } else { ChangeTask(ActOnIdle()); } } else { if (CurrentAct == null) // Should be impossible to have a current task and no current act. { // Try and recover the correct act. // <blecki> I always run with a breakpoint set here... just in case. ChangeAct(CurrentTask.CreateScript(Creature)); // This is a bad situation! if (CurrentAct == null) { ChangeTask(null); } } if (CurrentAct != null) { var status = CurrentAct.Tick(); bool retried = false; if (CurrentAct != null && CurrentTask != null) { if (status == Act.Status.Fail) { LastFailedAct = CurrentAct.Name; if (!FailedTasks.Any(task => task.TaskFailure.Equals(CurrentTask))) { FailedTasks.Add(new FailedTask() { TaskFailure = CurrentTask, FailedTime = World.Time.CurrentDate }); } if (CurrentTask.ShouldRetry(Creature)) { if (!Tasks.Contains(CurrentTask)) { ReassignCurrentTask(); retried = true; } } } } if (CurrentTask != null && CurrentTask.IsComplete(World)) { ChangeTask(null); } else if (status != Act.Status.Running && !retried) { ChangeTask(null); } } } // With a small probability, the creature will drown if its under water. if (MathFunctions.RandEvent(0.01f)) { var above = VoxelHelpers.GetVoxelAbove(Physics.CurrentVoxel); var below = VoxelHelpers.GetVoxelBelow(Physics.CurrentVoxel); bool shouldDrown = (above.IsValid && (!above.IsEmpty || above.LiquidLevel > 0)); if ((Physics.IsInLiquid || (!Movement.CanSwim && (below.IsValid && (below.LiquidLevel > 5)))) && (!Movement.CanSwim || shouldDrown)) { Creature.Damage(Movement.CanSwim ? 1.0f : 30.0f, Health.DamageType.Normal); } } if (PositionConstraint.Contains(Physics.LocalPosition) == ContainmentType.Disjoint) { Physics.LocalPosition = MathFunctions.Clamp(Physics.Position, PositionConstraint); Physics.PropogateTransforms(); } }