public override bool AddItem(GameComponent component) { if (component.Tags.Count == 0) { return(false); } var resourceType = component.Tags[0]; if (!IsAllowed(resourceType)) { return(false); } bool worked = base.AddItem(component); HandleBoxes(); if (Boxes.Count > 0) { 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.GetRoot().GetComponent <Physics>().CollideMode = Physics.CollisionMode.None; component.AnimationQueue.Add(toss); toss.OnComplete += component.Die; } else { component.Die(); } World.RecomputeCachedResourceState(); return(worked); }
private void ClampBody(GameComponent body) { bool inZone = Voxels.Any(v => VoxelHelpers.GetVoxelAbove(v).GetBoundingBox().Contains(body.Position) == ContainmentType.Contains); if (!inZone) { float minDist = float.MaxValue; VoxelHandle minVoxel = VoxelHandle.InvalidHandle; foreach (var voxel in Voxels) { float dist = (voxel.GetBoundingBox().Center() - body.Position).LengthSquared(); if (dist < minDist) { minDist = dist; minVoxel = voxel; } } if (minDist < float.MaxValue) { body.LocalPosition = body.LocalPosition * 0.5f + (minVoxel.WorldPosition + Vector3.Up + Vector3.One) * 0.5f; var creature = body.GetRoot().GetComponent <CreatureAI>(); if (creature != null) { creature.CancelCurrentTask(); } } } }
public bool Pickup(GameComponent item, RestockType restockType) { if (item == null || item.IsDead) { return(false); } if (item is ResourceEntity) { var entity = item as ResourceEntity; Resources.Add(new InventoryItem() { MarkedForRestock = restockType == RestockType.RestockResource, MarkedForUse = restockType != RestockType.RestockResource, Resource = entity.Resource }); } else { throw new InvalidOperationException(); } item.SetFlag(Flag.Active, false); var toss = new BodyTossMotion(0.5f + MathFunctions.Rand(0.05f, 0.08f), 1.0f, item.GlobalTransform, Parent); item.AnimationQueue.Add(toss); toss.OnComplete += () => item.GetRoot().Delete(); return(true); }
public bool RemoveResourcesWithToss(ResourceAmount resources, Vector3 position, Zone Zone) // Todo: Kill this one. { if (!Zone.Resources.HasResource(resources)) { return(false); } if (!(Zone is Stockpile)) { return(false); } var stock = Zone as Stockpile; // Todo: Stockpile deals with it's own boxes. var resourceType = Library.GetResourceType(resources.Type); var num = stock.Resources.RemoveMaxResources(resources, resources.Count); stock.HandleBoxes(); foreach (var tag in resourceType.Tags) { if (PersistentData.CachedResourceTagCounts.ContainsKey(tag)) // Move cache into worldmanager... { PersistentData.CachedResourceTagCounts[tag] -= num; Trace.Assert(PersistentData.CachedResourceTagCounts[tag] >= 0); } } for (int i = 0; i < num; i++) { // Make a toss from the last crate to the agent. var startPosition = stock.Voxels.Count > 0 ? stock.Voxels.First().Center + new Vector3(0.0f, 1.0f, 0.0f) : Vector3.Zero; if (stock.Boxes.Count > 0) { startPosition = stock.Boxes.Last().Position + MathFunctions.RandVector3Cube() * 0.5f; } GameComponent newEntity = EntityFactory.CreateEntity <GameComponent>(resources.Type + " Resource", startPosition); TossMotion toss = new TossMotion(1.0f + MathFunctions.Rand(0.1f, 0.2f), 2.5f + MathFunctions.Rand(-0.5f, 0.5f), newEntity.LocalTransform, position); if (newEntity.GetRoot().GetComponent <Physics>().HasValue(out var newPhysics)) { newPhysics.CollideMode = Physics.CollisionMode.None; } newEntity.AnimationQueue.Add(toss); toss.OnComplete += () => newEntity.Die(); } RecomputeCachedVoxelstate(); return(true); }
public override MaybeNull <Act> CreateScript(Creature creature) { if (creature.IsDead || creature.AI.IsDead) { return(null); } if (EntityToKill.GetRoot().GetComponent <Creature>().HasValue(out var otherCreature)) { if (!otherCreature.IsDead && otherCreature.AI != null) { // Flee if the other creature is too scary. if (otherCreature != null && (creature.AI.Position - EntityToKill.Position).Length() < 10 && creature.AI.FightOrFlight(otherCreature.AI) == CreatureAI.FightOrFlightResponse.Flee) { Name = "Flee Entity: " + EntityToKill.Name + " " + EntityToKill.GlobalID; ReassignOnDeath = false; IndicatorManager.DrawIndicator(IndicatorManager.StandardIndicators.Exclaim, creature.AI.Position, 1.0f, 1.0f, Vector2.UnitY * -32); return(new FleeEntityAct(creature.AI) { Entity = EntityToKill, PathLength = 20 }); } // Make the other creature defend itself. var otherKill = new KillEntityTask(creature.Physics, KillType.Auto) { AutoRetry = true, ReassignOnDeath = false }; if (!otherCreature.AI.HasTaskWithName(otherKill)) { otherCreature.AI.AssignTask(otherKill); } } } float radius = this.Mode == KillType.Auto ? 20.0f : 0.0f; return(new KillEntityAct(EntityToKill, creature.AI) { RadiusDomain = radius, Defensive = Mode == KillType.Auto }); }
public bool Pickup(GameComponent item, RestockType restockType) { if (item == null || item.IsDead) { return(false); } if (item is ResourceEntity) { ResourceEntity entity = item as ResourceEntity; for (int i = 0; i < entity.Resource.Count; i++) { Resources.Add(new InventoryItem() { MarkedForRestock = restockType == RestockType.RestockResource, MarkedForUse = restockType != RestockType.RestockResource, Resource = entity.Resource.Type }); } } else { Resources.Add(new InventoryItem() { MarkedForRestock = restockType == RestockType.RestockResource, MarkedForUse = restockType != RestockType.RestockResource, Resource = item.Tags[0] }); } item.SetFlag(Flag.Active, false); BodyTossMotion toss = new BodyTossMotion(0.5f + MathFunctions.Rand(0.05f, 0.08f), 1.0f, item.GlobalTransform, Parent as GameComponent); item.AnimationQueue.Add(toss); toss.OnComplete += () => item.GetRoot().Delete(); return(true); }
public bool Perform(Creature performer, GameComponent other, DwarfTime time, float bonus, Vector3 pos, string faction) { switch (Weapon.TriggerMode) { case Weapon.AttackTrigger.Timer: RechargeTimer.Update(time); if (!RechargeTimer.HasTriggered) { HasTriggered = false; return(false); } break; case Weapon.AttackTrigger.Animation: if (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame != Weapon.TriggerFrame) { HasTriggered = false; return(false); } break; } 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 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 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) { Agent.SetMessage("Failed to eat. No food in inventory."); yield return(Act.Status.Fail); yield break; } FoodBody = null; Timer eatTimer = new Timer(3.0f, true); foreach (ResourceAmount resourceAmount in foods) { if (resourceAmount.Count > 0) { List <GameComponent> bodies = Agent.Creature.Inventory.RemoveAndCreate(new ResourceAmount(resourceAmount.Type, 1), Inventory.RestockType.Any); var resource = Library.GetResourceType(resourceAmount.Type); Agent.Creature.NoiseMaker.MakeNoise("Chew", Agent.Creature.AI.Position); if (bodies.Count == 0) { Agent.SetMessage("Failed to eat. No food in inventory."); 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.Stats.Hunger.CurrentValue += resource.FoodContent; if (resource.Tags.Contains(Resource.ResourceTags.Alcohol)) { Agent.Creature.AddThought("I had good ale recently.", new TimeSpan(0, 8, 0, 0), 10.0f); } else { Agent.Creature.AddThought("I ate good food recently.", new TimeSpan(0, 8, 0, 0), 5.0f); } FoodBody.GetRoot().Delete(); if (MustPay) { var depositAct = new DepositMoney(Agent, resource.MoneyValue); foreach (var result in depositAct.Run()) { if (result == Status.Running) { yield return(result); } } } yield return(Act.Status.Success); } yield break; } } }