public CreatureAI(Creature creature, string name, EnemySensor sensor, PlanService planService) : base(name, creature.Physics) { Movement = new CreatureMovement(); GatherManager = new GatherManager(this); Blackboard = new Blackboard(); Creature = creature; CurrentPath = null; DrawPath = false; PlannerTimer = new Timer(0.1f, false); LocalControlTimeout = new Timer(5, false); WanderTimer = new Timer(1, false); Creature.Faction.Minions.Add(this); DrawAIPlan = false; WaitingOnResponse = false; PlanSubscriber = new PlanSubscriber(planService); ServiceTimeout = new Timer(2, false); Sensor = sensor; Sensor.OnEnemySensed += Sensor_OnEnemySensed; Sensor.Creature = this; CurrentTask = null; Tasks = new List<Task>(); Thoughts = new List<Thought>(); IdleTimer = new Timer(15.0f, true); SpeakTimer = new Timer(5.0f, true); XPEvents = new List<int>(); }
public NecromancerAI(Creature creature, string name, EnemySensor sensor, PlanService planService) : base(creature, name, sensor, planService) { Skeletons = new List<Skeleton>(); MaxSkeletons = 5; SummonTimer = new Timer(5, false); WanderTimer = new Timer(1, false); AttackTimer = new Timer(3, false); SummonTimer.HasTriggered = true; AttackRange = 10; }
public static float GetDistance(Voxel a, Voxel b, Creature.MoveType action, ChunkManager chunks) { if(!b.IsEmpty) { return 100000; } else { float score = (a.Position - b.Position).LengthSquared() * ActionCost(action); return score; } }
public override float ComputeCost(Creature agent) { if(VoxelToKill == null) { return 1000; } Voxel vox = VoxelToKill; if (vox == null) { return 10000; } int surroundedValue = 0; if(vox.Chunk.IsCompletelySurrounded(VoxelToKill)) { surroundedValue = 10000; } return (agent.AI.Position - VoxelToKill.Position).LengthSquared() + 100 * Math.Abs(agent.AI.Position.Y - VoxelToKill.Position.Y) + surroundedValue; }
public override Act CreateScript(Creature agent) { return new FindBedAndSleepAct(agent.AI); }
public static CompositeAnimation CreateCompositeAnimation(Creature.CharacterMode mode, Orientation orient, string composite, float frameHz, List<SpriteSheet> layers, List<Color> tints, params int[][] frames ) { return new CompositeAnimation(composite, layers, tints, frames) { FrameHZ = frameHz, Name = mode.ToString() + OrientationStrings[(int) orient], Loops = true, CurrentFrame = 0 }; }
public override Feasibility IsFeasible(Creature agent) { return(agent.World.GetResourcesWithTag("Potion").Count > 0 ? Feasibility.Feasible : Feasibility.Infeasible); }
public override Act CreateScript(Creature creature) { return null; //return new MoveItemAct(creature.AI, Item, Zone); }
public override Act CreateScript(Creature agent) { return(new GoToZoneAct(agent.AI, TradePort) | new Wrap(() => RecallEnvoyOnFail(Envoy))); }
public override float ComputeCost(Creature agent, bool alreadyCheckedFeasible = false) { return(!Voxel.IsValid ? 1000 : 0.01f * (agent.AI.Position - Voxel.WorldPosition).LengthSquared() + (Voxel.Coordinate.Y)); }
public override bool ShouldRetry(Creature agent) { return Voxel != null && agent.Faction.WallBuilder.IsDesignation(Voxel); }
public static Animation CreateAnimation(Creature.CharacterMode mode, Orientation orient, SpriteSheet texture, float frameHz, int frameWidth, int frameHeight, int row, params int[] cols) { return CreateAnimation(mode, orient, texture, frameHz, frameWidth, frameHeight, row, cols.ToList()); }
public override IEnumerable <Status> Run() { return(Creature.Dig(TargetVoxelName, EnergyLoss)); }
override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { base.Update(gameTime, chunks, camera); if (!Active) { return; } Creature.NoiseMaker.BasePitch = Stats.VoicePitch; // Non-dwarves are always at full energy. Stats.Energy.CurrentValue = 100.0f; BehaviorTimer.Update(gameTime); if (BehaviorTimer.HasTriggered) { if (Faction.Race.HasValue(out var race)) { if (!String.IsNullOrEmpty(race.BecomeWhenEvil) && MathFunctions.RandEvent(0.01f)) { Faction.Minions.Remove(this); Faction = World.Factions.Factions[race.BecomeWhenEvil]; Faction.AddMinion(this); } else if (!String.IsNullOrEmpty(race.BecomeWhenNotEvil) && MathFunctions.RandEvent(0.01f)) { Faction.Minions.Remove(this); Faction = World.Factions.Factions[race.BecomeWhenNotEvil]; Faction.AddMinion(this); } foreach (var body in World.EnumerateIntersectingObjects(Physics.BoundingBox.Expand(3.0f)).OfType <ResourceEntity>().Where(r => r.Active && r.AnimationQueue.Count == 0)) { if (Library.GetResourceType(body.Resource.TypeName).HasValue(out var resource) && resource.Tags.Contains("Edible")) { if ((race.EatsMeat && resource.Tags.Contains("AnimalProduct")) || (race.EatsPlants && !resource.Tags.Contains("AnimalProduct"))) { Creature.GatherImmediately(body); AssignTask(new ActWrapperTask(new EatFoodAct(this, false))); } } } } OrderEnemyAttack(); } DeleteBadTasks(); PreEmptTasks(); HandleReproduction(); // Try to find food if we are hungry. Wait - doesn't this rob the player? if (Stats.Hunger.IsDissatisfied() && World.CountResourcesWithTag("Edible") > 0) { var eatTask = new SatisfyHungerTask(); if (Stats.Hunger.IsCritical()) { eatTask.Priority = TaskPriority.Urgent; } if (!Tasks.Contains(eatTask) && CurrentTask.HasValue(out var task) && task != eatTask) // Really should just leave the current task in the task list. { AssignTask(eatTask); } } if (CurrentTask.HasValue(out var currentTask)) { if (!CurrentAct.HasValue()) // 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.HasValue()) { ChangeTask(null); } } if (CurrentAct.HasValue(out Act currentAct)) { var status = currentAct.Tick(); bool retried = false; if (CurrentAct.HasValue(out Act newCurrentAct) && currentTask != null) { if (status == Act.Status.Fail) { LastFailedAct = newCurrentAct.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); } } } else { var goal = GetEasiestTask(Tasks); if (goal != null) { ChangeTask(goal); } else { var newTask = ActOnIdle(); if (newTask != null) { ChangeTask(newTask); } } } // With a small probability, the creature will drown if its under water. if (MathFunctions.RandEvent(GameSettings.Current.DrownChance)) { 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(); } }
public override Feasibility IsFeasible(Creature agent) { return(agent.World.ListResourcesWithTag(Resource.ResourceTags.Potion).Count > 0 ? Feasibility.Feasible : Feasibility.Infeasible); }
public override bool ShouldRetry(Creature agent) { return(EntityToKill != null && !EntityToKill.IsDead); }
public virtual bool IsRelevant(Creature creature) { return(true); }
public Animation GetAnimation(Creature.CharacterMode mode, Orientation orient) { if (HasAnimation(mode, orient)) { return Animations[mode.ToString() + OrientationStrings[(int) orient]]; } else { return null; } }
public override Act CreateScript(Creature creature) { return new KillEntityAct(EntityToKill, creature.AI, Mode); }
public bool HasAnimation(Creature.CharacterMode mode, Orientation orient) { return Animations.ContainsKey(mode.ToString() + OrientationStrings[(int) orient]); }
public override float ComputeCost(Creature agent) { return agent.Status.Hunger.IsUnhappy() ? 0.0f : 1e13f; }
public override bool IsFeasible(Creature agent) { return Voxel != null && agent.Faction.WallBuilder.IsDesignation(Voxel); }
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. { if (GetRoot().GetComponent <DwarfThoughts>().HasValue(out var thoughts)) { 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! The last straw: {1}", Stats.FullName, thoughts.Thoughts.Last(t => t.HappinessModifier < 0.0f).Description), ClickAction: null, logEvent: true, eventDetails: String.Join("\n", thoughts.Thoughts.Where(t => t.HappinessModifier < 0.0f).Select(t => t.Description))); thoughts.Thoughts.Clear(); } else { 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!", Stats.FullName), ClickAction: null, logEvent: true, eventDetails: "So sick of this place!"); } LeaveWorld(); if (GetRoot().GetComponent <Inventory>().HasValue(out var inv)) { inv.Die(); } if (GetRoot().GetComponent <SelectionCircle>().HasValue(out var sel)) { sel.Die(); } 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.HasValue()) // 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.HasValue()) { ChangeTask(null); } } if (CurrentAct.HasValue(out Act currentAct)) { var status = currentAct.Tick(); bool retried = false; if (CurrentAct.HasValue(out Act newCurrentAct) && CurrentTask != null) { if (status == Act.Status.Fail) { LastFailedAct = newCurrentAct.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(); } }
public override float ComputeCost(Creature agent) { return Voxel == null ? 1000 : 0.01f * (agent.AI.Position - Voxel.Position).LengthSquared() + (Voxel.Position.Y); }
public override Feasibility IsFeasible(Creature agent) { return(agent.AI != Ally && !Ally.IsDead && !Ally.Status.Health.IsSatisfied() && agent.Stats.CurrentLevel.HealingPower > 0 ? Feasibility.Feasible : Feasibility.Infeasible); }
public override bool ShouldDelete(Creature agent) { if (EntityToKill == null || EntityToKill.IsDead) { return true; } switch (Mode) { case KillType.Attack: { if (!agent.Faction.AttackDesignations.Contains(EntityToKill)) return true; return false; break; } case KillType.Chop: { if (!agent.Faction.ChopDesignations.Contains(EntityToKill)) { return true; } return false; break; } case KillType.Auto: { return false; } } return false; }
public override Act CreateScript(Creature agent) { return(new MagicHealAllyAct(agent.AI, Ally)); }
public override bool IsFeasible(Creature agent) { return agent.Sensors.Enemies.Count == 0; }
public override Feasibility IsFeasible(Creature agent) { return(agent.AI != Ally && !Ally.IsDead && Ally.Status.Health.IsDissatisfied() ? Feasibility.Feasible : Feasibility.Infeasible); }
public bool Perform(Creature performer, GameComponent other, DwarfTime time, float bonus, Vector3 pos, string faction) { if (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame != Weapon.TriggerFrame) { HasTriggered = false; return(false); } if (HasTriggered) { return(true); } HasTriggered = true; switch (Weapon.Mode) { case Weapon.AttackMode.Melee: case Weapon.AttackMode.Dogfight: { DoDamage(performer, other, bonus); break; } case Weapon.AttackMode.Area: { var box = new BoundingBox(performer.AI.Position - Vector3.One * Weapon.Range, performer.AI.Position + Vector3.One * Weapon.Range); foreach (var body in performer.World.EnumerateIntersectingObjects(box, CollisionType.Both).Where(b => b.IsRoot())) { if (body.GetRoot().GetComponent <CreatureAI>().HasValue(out var creature)) { if (creature.Faction == performer.Faction) { continue; } if (performer.World.Overworld.GetPolitics(creature.Faction.ParentFaction, performer.Faction.ParentFaction).GetCurrentRelationship() != Relationship.Hateful) { continue; } DoDamage(performer, body, bonus); } else { if (body.GetRoot().GetComponent <Health>().HasValue(out var health)) { DoDamage(performer, body, bonus); } continue; } } break; } case Weapon.AttackMode.Ranged: { PlayNoise(other.GlobalTransform.Translation); LaunchProjectile(pos, other.Position, other); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature)) { creature.Stats.AcquireDisease(injury); } } break; } } return(true); }
public override Act CreateScript(Creature agent) { return(new HealOtherDwarfAct(agent.AI, Ally)); }
public override Act CreateScript(Creature agent) { return(new GetHealedAct(agent.AI)); }
public override Feasibility IsFeasible(Creature agent) { GameComponent closestItem = agent.Faction.FindNearestItemWithTags("Bed", agent.AI.Position, true, agent.AI); return((closestItem != null && agent.AI.Stats.Health.IsDissatisfied()) || agent.AI.Stats.Health.IsCritical() ? Feasibility.Feasible : Feasibility.Infeasible); }
public override Act CreateScript(Creature creature) { return null; //return new GetItemWithTagsAct(creature.AI, Tags); }
public override float ComputeCost(Creature agent, bool alreadyCheckedFeasible = false) { return(0.0f); }
public static Animation CreateAnimation(Creature.CharacterMode mode, Orientation orient, SpriteSheet texture, float frameHz, int frameWidth, int frameHeight, int row, List<int> cols) { List<Point> frames = new List<Point>(); int numCols = texture.Width / frameWidth; if (cols.Count == 0) { for (int i = 0; i < numCols; i++) { frames.Add(new Point(i, row)); } } else { frames.AddRange(cols.Select(c => new Point(c, row))); } return new Animation(GameState.Game.GraphicsDevice, texture, mode.ToString() + OrientationStrings[(int)orient], frameWidth, frameHeight, frames, true, Color.White, frameHz, (float)frameWidth / 35.0f, (float)frameHeight / 35.0f, false); }
public override bool ShouldRetry(Creature agent) { return(false); }
public void AddAnimation(Creature.CharacterMode mode, Orientation orient, SpriteSheet texture, float frameHz, int frameWidth, int frameHeight, int row, params int[] cols) { List<int> ints = new List<int>(); ints.AddRange(cols); Animation animation = CreateAnimation(mode, orient, texture, frameHz, frameWidth, frameHeight, row, ints); Animations[mode.ToString() + OrientationStrings[(int) orient]] = animation; animation.Play(); }
public override IEnumerable <Status> Run() { float startingHealth = Creature.Status.Health.CurrentValue; PreTeleport = Creature.AI.Position; if (Type == SleepType.Sleep) { while (!Creature.Status.Energy.IsSatisfied() && Creature.Manager.World.Time.IsNight()) { Creature.Physics.AllowPhysicsSleep = true; Creature.Physics.IsSleeping = true; if (Teleport) { Creature.AI.Position = TeleportLocation; Creature.Physics.Velocity = Vector3.Zero; Creature.Physics.LocalPosition = TeleportLocation; Creature.Physics.IsSleeping = true; } Creature.CurrentCharacterMode = CharacterMode.Sleeping; Creature.Status.Energy.CurrentValue += DwarfTime.Dt * RechargeRate; if (Creature.Status.Health.CurrentValue < startingHealth) { Creature.Status.IsAsleep = false; Creature.CurrentCharacterMode = CharacterMode.Idle; Creature.OverrideCharacterMode = false; yield return(Status.Fail); } Creature.Status.IsAsleep = true; Creature.OverrideCharacterMode = false; yield return(Status.Running); } if (Teleport) { Creature.AI.Position = PreTeleport; Creature.Physics.Velocity = Vector3.Zero; Creature.Physics.LocalPosition = TeleportLocation; Creature.Physics.IsSleeping = false; Creature.Physics.AllowPhysicsSleep = false; } Creature.AI.AddThought(Thought.ThoughtType.Slept); Creature.Status.IsAsleep = false; Creature.Physics.IsSleeping = false; Creature.Physics.AllowPhysicsSleep = false; yield return(Status.Success); } else { while (Creature.Status.Health.IsDissatisfied() || Creature.Buffs.Any(buff => buff is Disease)) { if (Teleport) { Creature.AI.Position = TeleportLocation; Creature.Physics.Velocity = Vector3.Zero; Creature.Physics.LocalPosition = TeleportLocation; Creature.Physics.IsSleeping = true; Creature.Physics.AllowPhysicsSleep = true; } Creature.CurrentCharacterMode = CharacterMode.Sleeping; Creature.Status.Energy.CurrentValue += DwarfTime.Dt * RechargeRate; Creature.Heal(DwarfTime.Dt * HealRate); Creature.Status.IsAsleep = true; Creature.OverrideCharacterMode = false; yield return(Status.Running); } if (Teleport) { Creature.AI.Position = PreTeleport; Creature.Physics.Velocity = Vector3.Zero; Creature.Physics.LocalPosition = TeleportLocation; Creature.Physics.IsSleeping = false; Creature.Physics.AllowPhysicsSleep = false; } Creature.AI.AddThought(Thought.ThoughtType.Slept); Creature.Status.IsAsleep = false; Creature.Physics.IsSleeping = false; Creature.Physics.AllowPhysicsSleep = false; yield return(Status.Success); } }
public List<Animation> GetAnimations(Creature.CharacterMode mode) { return OrientationStrings.Where((t, i) => HasAnimation(mode, (Orientation) i)) .Select(t => Animations[mode.ToString() + t]) .ToList(); }
public override MaybeNull <Act> CreateScript(Creature creature) { return(new StockResourceAct(creature.AI, ResourceToStock)); }
public void ResetAnimations(Creature.CharacterMode mode) { List<Animation> animations = GetAnimations(mode); foreach (Animation a in animations) { a.Reset(); } }
public override float ComputeCost(Creature agent, bool alreadyCheckedFeasible = false) { return(IsFeasible(agent) == Feasibility.Feasible ? 1.0f : 1000.0f); }
public override Act CreateScript(Creature creature) { return new Wrap(() => AddBuildOrder(creature)); }
public override Act CreateScript(Creature creature) { return(new GatherItemAct(creature.AI, EntityToGather)); }
public override bool ShouldDelete(Creature agent) { return Voxel == null || !agent.Faction.WallBuilder.IsDesignation(Voxel); }
public override bool ShouldDelete(Creature agent) { return(IsFeasible(agent) == Feasibility.Infeasible); }
public IEnumerable<Act.Status> AddBuildOrder(Creature creature) { creature.AI.GatherManager.AddVoxelOrder(new GatherManager.BuildVoxelOrder() { Type = VoxType, Voxel = Voxel }); yield return Act.Status.Success; }
public override bool ShouldRetry(Creature agent) { return(EntityToGather != null && EntityToGather.Active && !EntityToGather.IsDead); }
public override bool IsFeasible(Creature agent) { if(EntityToKill == null) { return false; } else { if (EntityToKill.IsDead) return false; Creature ai = EntityToKill.GetChildrenOfTypeRecursive<Creature>().FirstOrDefault(); switch (Mode) { case KillType.Attack: { if (!agent.Faction.AttackDesignations.Contains(EntityToKill)) return false; return true; break; } case KillType.Chop: { if (!agent.Faction.ChopDesignations.Contains(EntityToKill)) { return false; } return true; break; } case KillType.Auto: { return true; } } if(ai == null) { return true; } Relationship relation = Alliance.Relationships[new Alliance.AlliancePair {AllianceA = ai.Allies, AllianceB = agent.Allies}]; return relation == Relationship.Hates || relation == Relationship.Indifferent; } }
public override float ComputeCost(Creature agent, bool alreadyCheckedFeasible = false) { return(EntityToGather == null || EntityToGather.IsDead ? 1000 : (agent.AI.Position - EntityToGather.GlobalTransform.Translation).LengthSquared()); }
public override bool IsFeasible(Creature agent) { if(EntityToKill == null) { return false; } else { if (EntityToKill.IsDead) return false; Creature ai = EntityToKill.GetChildrenOfTypeRecursive<Creature>().FirstOrDefault(); switch (Mode) { case KillType.Attack: { if (!agent.Faction.AttackDesignations.Contains(EntityToKill)) return false; return true; break; } case KillType.Chop: { if (!agent.Faction.ChopDesignations.Contains(EntityToKill)) { return false; } return true; break; } case KillType.Auto: { return true; } } if(ai == null) { return true; } Relationship relation = PlayState.Diplomacy.GetPolitics(ai.Faction, agent.Faction).GetCurrentRelationship(); return relation == Relationship.Hates || relation == Relationship.Indifferent; } }
public static IEnumerable <Act.Status> RestockAll(this Creature agent) { AssignRestockAllTasks(agent, TaskPriority.Medium, false); yield return(Act.Status.Success); }
public override float ComputeCost(Creature agent) { if (agent == null || EntityToKill == null) { return 10000; } else return (agent.AI.Position - EntityToKill.LocalTransform.Translation).LengthSquared() * 0.01f; }
public override float ComputeCost(Creature agent, bool alreadyCheckedFeasible = false) { return((agent.AI.Position - Animal.Physics.Position).LengthSquared()); }
public override Act CreateScript(Creature agent) { return new FindAndEatFoodAct(agent.AI); }
public void DoDamage(Creature performer, GameComponent other, float bonus) { if (!String.IsNullOrEmpty(Weapon.DiseaseToSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var otherCreature)) { var disease = DiseaseLibrary.GetDisease(Weapon.DiseaseToSpread); if (disease != null) { if (MathFunctions.RandEvent(disease.LikelihoodOfSpread)) { otherCreature.Stats.AcquireDisease(disease); } } } } var health = other.GetRoot().EnumerateAll().OfType <Health>().FirstOrDefault(); if (health != null) { health.Damage(Weapon.DamageAmount + bonus); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { if (other.GetRoot().GetComponent <Creature>().HasValue(out var creature)) { creature.Stats.AcquireDisease(injury); } } Vector3 knock = other.Position - performer.Physics.Position; knock.Normalize(); knock *= 0.2f; if (other.AnimationQueue.Count == 0) { other.AnimationQueue.Add(new KnockbackAnimation(0.15f, other.LocalTransform, knock)); } } else { other.GetRoot().Die(); } PlayNoise(other.GlobalTransform.Translation); if (Weapon.HitParticles != "") { performer.Manager.World.ParticleManager.Trigger(Weapon.HitParticles, other.LocalTransform.Translation, Color.White, 5); if (Weapon.ShootLaser) { performer.Manager.World.ParticleManager.TriggerRay(Weapon.HitParticles, performer.AI.Position, other.LocalTransform.Translation); } } if (Weapon.HitAnimation != null) { IndicatorManager.DrawIndicator(Weapon.HitAnimation, other.BoundingBox.Center(), 10.0f, 1.0f, MathFunctions.RandVector2Circle(), Color.White, MathFunctions.Rand() > 0.5f); } Physics physics = other as Physics; if (physics != null) { Vector3 force = other.Position - performer.AI.Position; if (force.LengthSquared() > 0.01f) { force.Normalize(); physics.ApplyForce(force * Weapon.Knockback, 1.0f); } } }
public void Update(Creature creature, DwarfTime gameTime, ChunkManager chunks, Camera camera) { float dt = (float)gameTime.ElapsedGameTime.TotalSeconds; Hunger.CurrentValue -= dt * creature.Stats.HungerGrowth; Health.CurrentValue = (creature.Hp - creature.MinHealth) / (creature.MaxHealth - creature.MinHealth); if(creature.Stats.CanSleep) Energy.CurrentValue = (float) (100*Math.Sin(PlayState.Time.GetTotalHours()*Math.PI / 24.0f)); else { Energy.CurrentValue = 100.0f; } if(Energy.IsUnhappy()) { creature.DrawIndicator(IndicatorManager.StandardIndicators.Sleepy); } if(creature.Stats.CanEat && Hunger.IsUnhappy()) { creature.DrawIndicator(IndicatorManager.StandardIndicators.Hungry); if(Hunger.CurrentValue <= 1e-12 && (DateTime.Now - LastHungerDamageTime).TotalSeconds > HungerDamageRate) { creature.Damage(1.0f / (creature.Stats.HungerResistance) * HungerDamageRate); LastHungerDamageTime = DateTime.Now; } } }
public override bool ShouldRetry(Creature agent) { return(Voxel.IsValid && agent.World.PersistentData.Designations.IsVoxelDesignation(Voxel, DesignationType.Put)); }