public override IEnumerable <Act.Status> Run() { List <ResourceAmount> foods = Agent.Creature.Inventory.GetResources(new Quantitiy <Resource.ResourceTags>(Resource.ResourceTags.Edible), Inventory.RestockType.Any); if (foods.Count == 0 && Agent.Creature.Faction == Agent.World.PlayerFaction) { yield return(Act.Status.Fail); yield break; } FoodBody = null; Timer eatTimer = new Timer(3.0f, true); foreach (ResourceAmount resourceAmount in foods) { if (resourceAmount.NumResources > 0) { List <Body> bodies = Agent.Creature.Inventory.RemoveAndCreate(new ResourceAmount(resourceAmount.ResourceType, 1), Inventory.RestockType.Any); var resource = ResourceLibrary.GetResourceByName(resourceAmount.ResourceType); Agent.Creature.NoiseMaker.MakeNoise("Chew", Agent.Creature.AI.Position); if (bodies.Count == 0) { yield return(Act.Status.Fail); } else { FoodBody = bodies[0]; while (!eatTimer.HasTriggered) { eatTimer.Update(DwarfTime.LastTime); Matrix rot = Agent.Creature.Physics.LocalTransform; rot.Translation = Vector3.Zero; FoodBody.LocalTransform = Agent.Creature.Physics.LocalTransform; Vector3 foodPosition = Agent.Creature.Physics.Position + Vector3.Up * 0.05f + Vector3.Transform(Vector3.Forward, rot) * 0.5f; FoodBody.LocalPosition = foodPosition; FoodBody.PropogateTransforms(); FoodBody.Active = false; Agent.Creature.Physics.Velocity = Vector3.Zero; Agent.Creature.CurrentCharacterMode = CharacterMode.Sitting; if (MathFunctions.RandEvent(0.05f)) { Agent.Creature.World.ParticleManager.Trigger("crumbs", foodPosition, Color.White, 3); } yield return(Act.Status.Running); } Agent.Creature.Status.Hunger.CurrentValue += resource.FoodContent; Agent.Creature.AddThought(Thought.ThoughtType.AteFood); if (resource.Tags.Contains(Resource.ResourceTags.Alcohol)) { Agent.Creature.AddThought(Thought.ThoughtType.HadAle); } FoodBody.GetRoot().Delete(); yield return(Act.Status.Success); } yield break; } } }
public bool RemoveResources(List <ResourceAmount> resources, Vector3 position, bool createItems = true) { Dictionary <ResourceType, ResourceAmount> amounts = new Dictionary <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.Values)) { return(false); } List <Stockpile> stockpilesCopy = new List <Stockpile>(Stockpiles.Where(s => resources.All(r => s.IsAllowed(r.ResourceType)))); 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.GetRoot().GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; newEntity.AnimationQueue.Add(toss); newEntity.UpdateRate = 1; toss.OnComplete += () => toss_OnComplete(newEntity); } } } return(true); }
public bool Perform(Creature performer, Body other, DwarfTime time, float bonus, Vector3 pos, string faction) { switch (TriggerMode) { case AttackTrigger.Timer: RechargeTimer.Update(time); if (!RechargeTimer.HasTriggered) { HasTriggered = false; return(false); } break; case AttackTrigger.Animation: if (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame != TriggerFrame) { HasTriggered = false; return(false); } break; } if (HasTriggered) { return(true); } HasTriggered = true; switch (Mode) { case AttackMode.Melee: case AttackMode.Dogfight: { DoDamage(performer, other, bonus); break; } case AttackMode.Area: { BoundingBox box = new BoundingBox(performer.AI.Position - Vector3.One * Range, performer.AI.Position + Vector3.One * Range); foreach (var body in performer.World.EnumerateIntersectingObjects(box, CollisionType.Both)) { var creature = body.GetRoot().GetComponent <CreatureAI>(); if (creature == null) { var health = body.GetRoot().GetComponent <Health>(); if (health != null) { DoDamage(performer, body, bonus); } continue; } if (creature.Faction == performer.Faction) { continue; } var alliance = performer.World.Diplomacy.GetPolitics(creature.Faction, performer.Faction).GetCurrentRelationship() != Relationship.Hateful; if (alliance) { continue; } DoDamage(performer, body, bonus); } break; } case AttackMode.Ranged: { PlayNoise(other.GlobalTransform.Translation); LaunchProjectile(pos, other.Position, other); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { var creature = other.GetRoot().GetComponent <Creature>(); if (creature != null) { creature.AcquireDisease(injury.Name); } } break; } } return(true); }
public bool Perform(Creature performer, Body other, DwarfTime time, float bonus, Vector3 pos, string faction) { switch (TriggerMode) { case AttackTrigger.Timer: RechargeTimer.Update(time); if (!RechargeTimer.HasTriggered) { HasTriggered = false; return(false); } break; case AttackTrigger.Animation: if (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame != TriggerFrame) { HasTriggered = false; return(false); } break; } if (HasTriggered) { return(true); } HasTriggered = true; switch (Mode) { case AttackMode.Melee: case AttackMode.Dogfight: { var otherCreature = other.GetRoot().GetComponent <Creature>(); if (otherCreature != null && !String.IsNullOrEmpty(DiseaseToSpread)) { var disease = DiseaseLibrary.GetDisease(DiseaseToSpread); if (MathFunctions.RandEvent(disease.LikelihoodOfSpread)) { otherCreature.AcquireDisease(DiseaseToSpread); } } var health = other.GetRoot().EnumerateAll().OfType <Health>().FirstOrDefault(); if (health != null) { health.Damage(DamageAmount + bonus); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { var creature = other.GetRoot().GetComponent <Creature>(); if (creature != null) { creature.AcquireDisease(injury.Name); } } 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)); } } PlayNoise(other.GlobalTransform.Translation); if (HitParticles != "") { performer.Manager.World.ParticleManager.Trigger(HitParticles, other.LocalTransform.Translation, Color.White, 5); } if (HitAnimation != null) { IndicatorManager.DrawIndicator(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 - pos; if (force.LengthSquared() > 0.01f) { force.Normalize(); physics.ApplyForce(force * Knockback, 1.0f); } } break; } case AttackMode.Ranged: { PlayNoise(other.GlobalTransform.Translation); LaunchProjectile(pos, other.Position, other); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { var creature = other.GetRoot().GetComponent <Creature>(); if (creature != null) { creature.AcquireDisease(injury.Name); } } break; } } return(true); }
public void DoDamage(Creature performer, Body other, float bonus) { if (!String.IsNullOrEmpty(DiseaseToSpread)) { var otherCreature = other.GetRoot().GetComponent <Creature>(); if (otherCreature != null) { var disease = DiseaseLibrary.GetDisease(DiseaseToSpread); if (MathFunctions.RandEvent(disease.LikelihoodOfSpread)) { otherCreature.AcquireDisease(DiseaseToSpread); } } } var health = other.GetRoot().EnumerateAll().OfType <Health>().FirstOrDefault(); if (health != null) { health.Damage(DamageAmount + bonus); var injury = DiseaseLibrary.GetRandomInjury(); if (MathFunctions.RandEvent(injury.LikelihoodOfSpread)) { var creature = other.GetRoot().GetComponent <Creature>(); if (creature != null) { creature.AcquireDisease(injury.Name); } } 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 (HitParticles != "") { performer.Manager.World.ParticleManager.Trigger(HitParticles, other.LocalTransform.Translation, Color.White, 5); if (ShootLaser) { performer.Manager.World.ParticleManager.TriggerRay(HitParticles, performer.AI.Position, other.LocalTransform.Translation); } } if (HitAnimation != null) { IndicatorManager.DrawIndicator(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 * Knockback, 1.0f); } } }