Пример #1
0
        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);
        }
Пример #2
0
        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();
                    }
                }
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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
            });
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
                }
            }
        }
Пример #9
0
        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;
                }
            }
        }