Ejemplo n.º 1
0
        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;
                }
            }
        }
Ejemplo n.º 2
0
 public bool InitializePath()
 {
     // ERROR CHECKS / INITIALIZING
     Creature.CurrentCharacterMode  = Creature.CharacterMode.Walking;
     Creature.OverrideCharacterMode = false;
     Agent.Physics.Orientation      = Physics.OrientMode.RotateY;
     ActionTimes = new List <float>();
     Path        = GetPath();
     if (Path == null)
     {
         SetPath(null);
         Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
         return(false);
     }
     if (Path.Count > 0)
     {
         RandomPositionOffsets = new List <Vector3>();
         int   i    = 0;
         float dt   = 0;
         float time = 0;
         foreach (Creature.MoveAction action in Path)
         {
             RandomPositionOffsets.Add(MathFunctions.RandVector3Box(-0.1f, 0.1f, 0.0f, 0.0f, -0.1f, 0.1f));
             dt = GetActionTime(action, i);
             ActionTimes.Add(dt);
             time += dt;
             i++;
         }
         RandomPositionOffsets[0] = Agent.Position - (Path[0].Voxel.Position + Vector3.One * 0.5f);
         TrajectoryTimer          = new Timer(time, true);
         return(true);
     }
     return(true);
 }
Ejemplo n.º 3
0
        public override IEnumerable <Status> Run()
        {
            if (Zone == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);

                yield break;
            }

            if (Resource.Count <= 0)
            {
                yield return(Status.Success);

                yield break;
            }

            List <GameComponent> createdItems = Creature.Inventory.RemoveAndCreate(Resource, Inventory.RestockType.RestockResource);

            if (createdItems.Count == 0)
            {
                yield return(Status.Success);
            }

            foreach (GameComponent b in createdItems)
            {
                if (Zone.AddItem(b))
                {
                    Creature.Stats.NumItemsGathered++;
                }
                else
                {
                    Creature.Inventory.AddResource(new ResourceAmount(Resource.Type, 1), Inventory.RestockType.RestockResource);
                    b.Delete();
                }
            }

            Creature.NoiseMaker.MakeNoise("Stockpile", Creature.AI.Position);
            Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode;
            Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);
            Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode);
            while (!Creature.Sprite.AnimPlayer.IsDone())
            {
                yield return(Status.Running);
            }

            var resource = Library.GetResourceType(Resource.Type);

            if (resource.Tags.Contains(DwarfCorp.Resource.ResourceTags.Corpse))
            {
                Creature.AddThought("I laid a friend to rest.", new TimeSpan(0, 8, 0, 0), 10.0f);
            }

            yield return(Status.Running);

            Creature.CurrentCharacterMode = CharacterMode.Idle;
            yield return(Status.Success);
        }
Ejemplo n.º 4
0
 public void Converse(CreatureAI other)
 {
     if (SpeakTimer.HasTriggered)
     {
         AddThought(Thought.ThoughtType.Talked);
         Creature.DrawIndicator(IndicatorManager.StandardIndicators.Dots);
         Creature.Physics.Face(other.Position);
         SpeakTimer.Reset(SpeakTimer.TargetTimeSeconds);
     }
 }
Ejemplo n.º 5
0
        public override IEnumerable <Status> Run()
        {
            var zone     = Agent.Blackboard.GetData <Zone>(StockpileName);
            var resource = Agent.Blackboard.GetData <Resource>(ResourceName);

            if (zone == null || !(zone is Stockpile) || resource == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);

                yield break;
            }

            var createdItems = Creature.Inventory.RemoveAndCreate(resource, Inventory.RestockType.RestockResource);

            if ((zone as Stockpile).AddResource(resource))
            {
                var toss = new TossMotion(1.0f, 2.5f, createdItems.LocalTransform, zone.GetBoundingBox().Center() + new Vector3(0.5f, 0.5f, 0.5f));

                if (createdItems.GetRoot().GetComponent <Physics>().HasValue(out var physics))
                {
                    physics.CollideMode = Physics.CollisionMode.None;
                }

                createdItems.AnimationQueue.Add(toss);
                toss.OnComplete += createdItems.Die;

                Creature.Stats.NumItemsGathered++;
            }
            else
            {
                Creature.Inventory.AddResource(resource, Inventory.RestockType.RestockResource);
                createdItems.Delete();
            }

            Creature.NoiseMaker.MakeNoise("Stockpile", Creature.AI.Position);
            Creature.CurrentCharacterMode = Creature.Stats.CurrentClass.AttackMode;
            Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);
            Creature.Sprite.PlayAnimations(Creature.Stats.CurrentClass.AttackMode);

            while (!Creature.Sprite.AnimPlayer.IsDone())
            {
                yield return(Status.Running);
            }

            if (Library.GetResourceType(resource.TypeName).HasValue(out var res) && res.Tags.Contains("Corpse"))
            {
                Creature.AddThought("I laid a friend to rest.", new TimeSpan(0, 8, 0, 0), 10.0f);
            }

            yield return(Status.Running);

            Creature.CurrentCharacterMode = CharacterMode.Idle;
            yield return(Status.Success);
        }
Ejemplo n.º 6
0
        public override IEnumerable <Status> Run()
        {
            if (Zone == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);

                yield break;
            }

            if (Resource.NumResources <= 0)
            {
                yield return(Status.Success);

                yield break;
            }

            List <Body> createdItems = Creature.Inventory.RemoveAndCreate(Resource, Inventory.RestockType.RestockResource);

            if (createdItems.Count == 0)
            {
                yield return(Status.Success);
            }

            foreach (Body b in createdItems)
            {
                if (Zone.AddItem(b))
                {
                    Creature.Stats.NumItemsGathered++;
                }
            }

            Creature.NoiseMaker.MakeNoise("Stockpile", Creature.AI.Position);
            Creature.CurrentCharacterMode = Creature.AttackMode;
            Creature.Sprite.ResetAnimations(Creature.AttackMode);
            Creature.Sprite.PlayAnimations(Creature.AttackMode);
            while (!Creature.Sprite.AnimPlayer.IsDone())
            {
                yield return(Status.Running);
            }

            var resource = ResourceLibrary.GetResourceByName(Resource.ResourceType);

            if (resource.Tags.Contains(DwarfCorp.Resource.ResourceTags.Corpse))
            {
                Creature.AddThought(Thought.ThoughtType.BuriedDead);
            }

            yield return(Status.Running);

            Creature.CurrentCharacterMode = CharacterMode.Idle;
            yield return(Status.Success);
        }
Ejemplo n.º 7
0
        public override IEnumerable <Status> Run()
        {
            if (Zone == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);

                yield break;
            }

            if (Resource.NumResources <= 0)
            {
                yield return(Status.Success);

                yield break;
            }

            List <Body> createdItems = Creature.Inventory.RemoveAndCreate(Resource);

            if (createdItems.Count == 0)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);
            }

            foreach (Body b in createdItems)
            {
                if (Zone.AddItem(b))
                {
                    Creature.NoiseMaker.MakeNoise("Hurt", Creature.AI.Position);
                    Creature.Stats.NumItemsGathered++;
                    Creature.AI.AddXP(1);
                    Creature.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                    Creature.Sprite.ResetAnimations(Creature.CharacterMode.Attacking);
                    Creature.Sprite.PlayAnimations(Creature.CharacterMode.Attacking);

                    while (!Creature.Sprite.CurrentAnimation.IsDone())
                    {
                        yield return(Status.Running);
                    }

                    yield return(Status.Running);
                }
                else
                {
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
                    yield return(Status.Fail);
                }
            }
            Creature.CurrentCharacterMode = Creature.CharacterMode.Idle;
            yield return(Status.Success);
        }
Ejemplo n.º 8
0
        public static IEnumerable <Act.Status> EatStockedFood(this Creature agent)
        {
            List <ResourceAmount> foods = agent.Faction.ListResourcesWithTag(Resource.ResourceTags.Edible);

            if (foods.Count == 0)
            {
                if (agent.Allies == "Dwarf")
                {
                    agent.Manager.World.MakeAnnouncement("We're out of food!", "Our stockpiles don't have any food. Our employees will starve!");
                }
                yield return(Act.Status.Fail);

                yield break;
            }
            else
            {
                foreach (ResourceAmount resourceAmount in foods)
                {
                    if (resourceAmount.NumResources > 0)
                    {
                        Resource resource = ResourceLibrary.GetResourceByName(resourceAmount.ResourceType);
                        bool     removed  = agent.Faction.RemoveResources(new List <ResourceAmount>()
                        {
                            new ResourceAmount(resourceAmount.ResourceType, 1)
                        }, agent.AI.Position);
                        agent.Status.Hunger.CurrentValue += resource.FoodContent;
                        agent.NoiseMaker.MakeNoise("Chew", agent.AI.Position);
                        if (!removed)
                        {
                            yield return(Act.Status.Fail);
                        }
                        else
                        {
                            agent.DrawIndicator(resource.Image, resource.Tint);
                            agent.AI.AddThought(Thought.ThoughtType.AteFood);
                            yield return(Act.Status.Success);
                        }
                        yield break;
                    }
                }

                if (agent.Allies == "Dwarf")
                {
                    agent.Manager.World.MakeAnnouncement("We're out of food!", "Our stockpiles don't have any food. Our employees will starve!");
                }

                yield return(Act.Status.Fail);

                yield break;
            }
        }
Ejemplo n.º 9
0
        public override IEnumerable <Status> Run()
        {
            if (Zone == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);

                yield break;
            }

            if (Money <= 0)
            {
                yield return(Status.Success);

                yield break;
            }

            DwarfBux moneyPut = 0m;

            if (Zone.AddMoney(Creature.AI.Position, Money, ref moneyPut))
            {
                Creature.AI.AddMoney(-Money);
                Creature.NoiseMaker.MakeNoise("Stockpile", Creature.AI.Position);
                Creature.Stats.NumItemsGathered++;
                Creature.AI.AddXP(1);
                Creature.CurrentCharacterMode = CharacterMode.Attacking;
                Creature.Sprite.ResetAnimations(CharacterMode.Attacking);
                Creature.Sprite.PlayAnimations(CharacterMode.Attacking);

                while (!Creature.Sprite.AnimPlayer.IsDone())
                {
                    yield return(Status.Running);
                }

                yield return(Status.Running);
            }
            else
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                Creature.CurrentCharacterMode = CharacterMode.Idle;
                Creature.AI.GatherManager.StockMoneyOrders.Add(new GatherManager.StockMoneyOrder()
                {
                    Destination = null,
                    Money       = Money - moneyPut
                });
                yield return(Status.Fail);
            }
            Creature.CurrentCharacterMode = CharacterMode.Idle;
            yield return(Status.Success);
        }
Ejemplo n.º 10
0
        public override IEnumerable <Status> Run()
        {
            bool validTargetFound = false;

            List <Zone> sortedPiles;

            if (ResourceLibrary.GetResourceByName(this.Item.ResourceType).Tags.Contains(Resource.ResourceTags.Money))
            {
                sortedPiles = new List <Zone>(Creature.Faction.Treasurys);
                sortedPiles.Sort(CompareTreasurys);
            }
            else
            {
                sortedPiles =
                    new List <Zone>(Creature.Faction.Stockpiles.Where(pile => pile.IsAllowed(Item.ResourceType)));
                sortedPiles.Sort(CompareStockpiles);
            }

            foreach (Zone s in sortedPiles)
            {
                if (s.IsFull())
                {
                    continue;
                }

                var v = s.GetNearestVoxel(Creature.Physics.GlobalTransform.Translation);

                if (!v.IsValid || v.IsEmpty)
                {
                    continue;
                }

                Voxel     = v;
                Stockpile = s;

                validTargetFound = true;
                break;
            }

            if (validTargetFound)
            {
                yield return(Status.Success);
            }
            else
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);
            }
        }
Ejemplo n.º 11
0
        public override IEnumerable <Status> Run()
        {
            InitializePath();
            if (TrajectoryTimer == null)
            {
                yield break;
            }
            while (!TrajectoryTimer.HasTriggered)
            {
                TrajectoryTimer.Update(DwarfTime.LastTime);
                ValidPathTimer.Update(DwarfTime.LastTime);
                foreach (Status status in PerformCurrentAction())
                {
                    if (status == Status.Fail)
                    {
                        yield return(Status.Fail);
                    }
                    else if (status == Status.Success)
                    {
                        break;
                    }
                    yield return(Status.Running);
                }

                if (Agent.DrawPath)
                {
                    List <Vector3> points =
                        Path.Select(
                            (v, i) => v.Voxel.Position + new Vector3(0.5f, 0.5f, 0.5f) + RandomPositionOffsets[i])
                        .ToList();
                    Drawer3D.DrawLineList(points, Color.Red, 0.1f);
                }


                // Check if the path has been made invalid
                if (ValidPathTimer.HasTriggered && !IsPathValid(Path))
                {
                    Creature.OverrideCharacterMode = false;
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    yield return(Status.Fail);
                }
                yield return(Status.Running);
            }
            Creature.OverrideCharacterMode = false;
            SetPath(null);
            yield return(Status.Success);
        }
Ejemplo n.º 12
0
        public override IEnumerable <Status> Run()
        {
            // Todo: Re-add random offsets?
            Creature.CurrentCharacterMode  = CharacterMode.Walking;
            Creature.OverrideCharacterMode = false;
            Agent.Physics.Orientation      = Physics.OrientMode.RotateY;
            if (Path == null || Path.Count == 0)
            {
                Path = null;
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Act.Status.Success);
            }

            foreach (var step in Path)
            {
                if (Agent.MinecartActive && (step.MoveType != MoveType.RideVehicle && step.MoveType != MoveType.EnterVehicle && step.MoveType != MoveType.ExitVehicle))
                {
                    var x = 5;
                }

                foreach (var status in PerformStep(step))
                {
                    //Agent.Physics.PropogateTransforms();
                    DeltaTime += (float)DwarfTime.LastTime.ElapsedGameTime.TotalSeconds;
                    Creature.Physics.CollisionType = CollisionType.Dynamic;

                    if (status == Status.Fail)
                    {
                        CleanupMinecart();
                        yield return(Status.Fail);
                    }
                    else
                    {
                        DrawDebugPath();
                        yield return(Status.Running);
                    }
                }
            }

            Creature.OverrideCharacterMode = false;
            Path = null;
            Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, true);
            CleanupMinecart();
            yield return(Status.Success);
        }
Ejemplo n.º 13
0
        public override IEnumerable <Status> Run()
        {
            if (Zone == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);

                yield break;
            }

            if (Resource.NumResources <= 0)
            {
                yield return(Status.Success);

                yield break;
            }

            List <Body> createdItems = Creature.Inventory.RemoveAndCreate(Resource);

            if (createdItems.Count == 0)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);
            }

            foreach (Body b in createdItems)
            {
                if (Zone.AddItem(b))
                {
                    Creature.NoiseMaker.MakeNoise("Hurt", Creature.AI.Position);
                    Creature.Stats.NumItemsGathered++;
                    Creature.AI.AddXP(1);
                    yield return(Status.Running);
                }
                else
                {
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    yield return(Status.Fail);
                }
            }

            yield return(Status.Success);
        }
Ejemplo n.º 14
0
        public override IEnumerable <Status> Run()
        {
            bool validTargetFound = false;

            List <Stockpile> sortedPiles = new List <Stockpile>(Creature.Faction.Stockpiles);

            sortedPiles.Sort(CompareStockpiles);

            foreach (Stockpile s in sortedPiles)
            {
                if (s.IsFull())
                {
                    continue;
                }

                Voxel v = s.GetNearestVoxel(Creature.Physics.GlobalTransform.Translation);

                if (v.IsEmpty)
                {
                    continue;
                }

                Voxel     = v;
                Stockpile = s;
                if (Voxel == null)
                {
                    continue;
                }

                validTargetFound = true;
                break;
            }

            if (validTargetFound)
            {
                yield return(Status.Success);
            }
            else
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);
            }
        }
        public override IEnumerable <Status> Run()
        {
            if (TargetZone == null)
            {
                yield return(Status.Fail);
            }
            else
            {
                Voxel v = TargetZone.GetNearestVoxel(Agent.Position);

                if (!v.IsEmpty)
                {
                    Agent.Blackboard.SetData(OutputVoxel, v);
                    yield return(Status.Success);
                }
                else
                {
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    yield return(Status.Fail);
                }
            }
        }
Ejemplo n.º 16
0
        public override IEnumerable <Status> Run()
        {
            bool validTargetFound = false;

            var sortedPiles = Creature.World.EnumerateZones().OfType <Stockpile>().Where(pile => pile.IsAllowed(Item.TypeName)).ToList();

            sortedPiles.Sort(CompareStockpiles);

            foreach (var s in sortedPiles)
            {
                if (s.IsFull())
                {
                    continue;
                }

                var v = s.GetNearestVoxel(Creature.Physics.GlobalTransform.Translation);

                if (!v.IsValid || v.IsEmpty)
                {
                    continue;
                }

                Agent.Blackboard.SetData <VoxelHandle>(VoxelBlackboardName, v);
                Agent.Blackboard.SetData <Zone>(StockpileBlackboardName, s);

                validTargetFound = true;
                break;
            }

            if (validTargetFound)
            {
                yield return(Status.Success);
            }
            else
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);
            }
        }
Ejemplo n.º 17
0
        public override IEnumerable <Status> Run()
        {
            Body grabbed = Creature.Hands.GetFirstGrab();

            if (grabbed == null)
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return(Status.Fail);
            }
            else
            {
                Creature.Hands.UnGrab(grabbed);
                Matrix m = Matrix.Identity;
                m.Translation = Creature.Physics.GlobalTransform.Translation;
                Agent.Blackboard.SetData <object>("HeldObject", null);
                grabbed.LocalTransform = m;
                grabbed.HasMoved       = true;
                grabbed.IsActive       = true;

                yield return(Status.Success);
            }
        }
Ejemplo n.º 18
0
        public override IEnumerable<Status> Run()
        {
            bool validTargetFound = false;

            List<Zone> sortedPiles;

                sortedPiles =
                    new List<Zone>(Creature.World.EnumerateZones().Where(pile => pile is Stockpile && (pile as Stockpile).IsAllowed(Item.Type)));
                sortedPiles.Sort(CompareStockpiles);

            foreach (Zone s in sortedPiles)
            {
                if(s.IsFull())
                {
                    continue;
                }

                var v = s.GetNearestVoxel(Creature.Physics.GlobalTransform.Translation);

                if(!v.IsValid || v.IsEmpty)
                    continue;

                Voxel = v;
                Stockpile = s;

                validTargetFound = true;
                break;
            }

            if(validTargetFound)
            {
                yield return Status.Success;
            }
            else
            {
                Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                yield return Status.Fail;
            }
        }
Ejemplo n.º 19
0
        public static IEnumerable <Act.Status> Dig(this Creature agent, string voxel, float energyLoss)
        {
            Vector3 LocalTarget = agent.AI.Position;

            agent.Sprite.ResetAnimations(Creature.CharacterMode.Attacking);
            while (true)
            {
                agent.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                Voxel blackBoardVoxel = agent.AI.Blackboard.GetData <Voxel>(voxel);

                if (blackBoardVoxel == null)
                {
                    agent.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    yield return(Act.Status.Fail);

                    break;
                }

                Voxel vox = blackBoardVoxel;
                if (vox.Health <= 0.0f || !agent.Faction.IsDigDesignation(vox))
                {
                    agent.AI.AddXP(Math.Max((int)(VoxelLibrary.GetVoxelType(blackBoardVoxel.TypeName).StartingHealth / 4), 1));
                    if (vox.Health <= 0.0f)
                    {
                        vox.Kill();
                    }
                    agent.Stats.NumBlocksDestroyed++;
                    agent.CurrentCharacterMode = Creature.CharacterMode.Idle;
                    yield return(Act.Status.Success);

                    break;
                }
                agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                agent.Physics.Velocity *= 0.9f;
                agent.Attacks[0].Perform(agent.Physics.Position, vox, DwarfTime.LastTime, agent.Stats.BaseDigSpeed, agent.Faction.Name);
                yield return(Act.Status.Running);
            }
        }
Ejemplo n.º 20
0
        public override IEnumerable <Status> Run()
        {
            Path     = null;
            Timeouts = 0;
            PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
            var     lastId  = -1;
            Vector3 goalPos = Vector3.Zero;

            Agent.Blackboard.SetData <bool>("NoPath", false);
            while (true)
            {
                if (Path != null)
                {
                    yield return(Status.Success);

                    break;
                }

                if (Timeouts > MaxTimeouts)
                {
                    Agent.Blackboard.SetData <bool>("NoPath", true);
                    yield return(Status.Fail);

                    break;
                }
                if (WaitingOnResponse && Debugger.Switches.DrawPaths)
                {
                    Drawer3D.DrawLine(Creature.AI.Position, goalPos, Color.Blue, 0.25f);
                }
                PlannerTimer.Update(DwarfTime.LastTime);

                ChunkManager chunks = Creature.Manager.World.ChunkManager;
                if (PlannerTimer.HasTriggered || Timeouts == 0)
                {
                    if (!Target.IsValid && Type != PlanType.Edge)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        Agent.Blackboard.SetData <bool>("NoPath", true);
                        yield return(Status.Fail);

                        break;
                    }

                    var voxUnder = VoxelHelpers.FindValidVoxelNear(chunks, Agent.Position);

                    if (!voxUnder.IsValid)
                    {
                        if (Debugger.Switches.DrawPaths)
                        {
                            Creature.World.UserInterface.MakeWorldPopup(String.Format("Invalid request"), Creature.Physics, -10, 1);
                        }
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        Agent.Blackboard.SetData <bool>("NoPath", true);
                        yield return(Status.Fail);

                        break;
                    }

                    Path = null;
                    AstarPlanRequest aspr = new AstarPlanRequest
                    {
                        Subscriber      = Agent.PlanSubscriber,
                        Start           = voxUnder,
                        MaxExpansions   = MaxExpansions,
                        Sender          = Agent,
                        HeuristicWeight = Weights[Timeouts]
                    };

                    lastId          = aspr.ID;
                    aspr.GoalRegion = GetGoal();
                    goalPos         = GetGoal().GetVoxel().GetBoundingBox().Center();
                    Agent.PlanSubscriber.Clear();
                    if (!Agent.PlanSubscriber.SendRequest(aspr, aspr.ID))
                    {
                        yield return(Status.Fail);

                        yield break;
                    }
                    PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
                    WaitingOnResponse = true;
                    yield return(Status.Running);


                    Timeouts++;
                }
                else
                {
                    Status statusResult = Status.Running;

                    while (Agent.PlanSubscriber.Responses.Count > 0)
                    {
                        AStarPlanResponse response;
                        if (!Agent.PlanSubscriber.Responses.TryDequeue(out response))
                        {
                            yield return(Status.Running);

                            continue;
                        }
                        LastResult = response.Result;

                        if (response.Success && response.Request.ID == lastId)
                        {
                            Path = response.Path;
                            WaitingOnResponse = false;

                            statusResult = Status.Success;
                        }
                        else if (response.Request.ID != lastId && response.Path != null && response.Path.Count > 0)
                        {
                            var goal = GetGoal();

                            bool obeysGoal = goal == null ? false : (response.Success && (goal.IsInGoalRegion(response.Path.Last().DestinationVoxel)));

                            if (Debugger.Switches.DrawPaths)
                            {
                                if (obeysGoal)
                                {
                                    Creature.World.UserInterface.MakeWorldPopup(String.Format("Using Old Path", response.Result), Creature.Physics, -10, 1);
                                }
                                else
                                {
                                    Creature.World.UserInterface.MakeWorldPopup(String.Format("Old Path Dropped", response.Result), Creature.Physics, -10, 1);
                                }
                            }

                            if (obeysGoal)
                            {
                                Path = response.Path;
                                WaitingOnResponse = false;
                                statusResult      = Status.Success;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else if (response.Result == AStarPlanner.PlanResultCode.Invalid || response.Result == AStarPlanner.PlanResultCode.NoSolution ||
                                 response.Result == AStarPlanner.PlanResultCode.Cancelled || response.Result == AStarPlanner.PlanResultCode.Invalid)
                        {
                            if (Debugger.Switches.DrawPaths)
                            {
                                Creature.World.UserInterface.MakeWorldPopup(String.Format("Path: {0}", response.Result), Creature.Physics, -10, 1);
                            }
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            Agent.Blackboard.SetData <bool>("NoPath", true);
                            statusResult = Status.Fail;
                            yield return(Status.Fail);
                        }
                        else if (Timeouts <= MaxTimeouts)
                        {
                            Timeouts++;
                            yield return(Status.Running);
                        }
                        else
                        {
                            if (Debugger.Switches.DrawPaths)
                            {
                                Creature.World.UserInterface.MakeWorldPopup(String.Format("Max timeouts reached", response.Result), Creature.Physics, -10, 1);
                            }
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            Agent.Blackboard.SetData <bool>("NoPath", true);
                            statusResult = Status.Fail;
                        }
                    }
                    yield return(statusResult);
                }
            }
        }
Ejemplo n.º 21
0
        public override IEnumerable <Status> Run()
        {
            Path     = null;
            Timeouts = 0;
            PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
            Voxel voxUnder = new Voxel();

            while (true)
            {
                if (Path != null)
                {
                    yield return(Status.Success);

                    break;
                }

                if (Timeouts > MaxTimeouts)
                {
                    yield return(Status.Fail);

                    break;
                }

                PlannerTimer.Update(DwarfTime.LastTime);

                ChunkManager chunks = PlayState.ChunkManager;
                if (PlannerTimer.HasTriggered || Timeouts == 0)
                {
                    if (!chunks.ChunkData.GetVoxel(Agent.Position, ref voxUnder))
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }


                    if (Target == null && Type != PlanType.Edge)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    if (voxUnder != null)
                    {
                        Path = null;
                        AstarPlanRequest aspr = new AstarPlanRequest
                        {
                            Subscriber      = PlanSubscriber,
                            Start           = voxUnder,
                            MaxExpansions   = MaxExpansions,
                            Sender          = Agent,
                            HeuristicWeight = Weights[Timeouts]
                        };

                        switch (Type)
                        {
                        case PlanType.Radius:
                            aspr.GoalRegion = new SphereGoalRegion(Target, Radius);
                            break;

                        case PlanType.Into:
                            aspr.GoalRegion = new VoxelGoalRegion(Target);
                            break;

                        case PlanType.Adjacent:
                            aspr.GoalRegion = new AdjacentVoxelGoalRegion2D(Target);
                            break;

                        case PlanType.Edge:
                            aspr.GoalRegion = new EdgeGoalRegion();
                            break;
                        }

                        PlanSubscriber.SendRequest(aspr);
                        PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
                        WaitingOnResponse = true;
                        yield return(Status.Running);
                    }
                    else
                    {
                        Path = null;
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    Timeouts++;
                }
                else
                {
                    if (Target != null && Creature.AI.DrawAIPlan)
                    {
                        Drawer3D.DrawLine(Creature.AI.Position, Target.Position, Color.Blue, 0.25f);
                    }
                    Status statusResult = Status.Running;

                    while (PlanSubscriber.Responses.Count > 0)
                    {
                        AStarPlanResponse response;
                        PlanSubscriber.Responses.TryDequeue(out response);

                        if (response.Success)
                        {
                            Path = response.Path;

                            if (Type == PlanType.Adjacent && Path.Count > 0)
                            {
                                Path.RemoveAt(Path.Count - 1);
                            }
                            WaitingOnResponse = false;

                            statusResult = Status.Success;
                        }
                        else
                        {
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            statusResult = Status.Fail;
                        }
                    }
                    yield return(statusResult);
                }
            }
        }
Ejemplo n.º 22
0
        public override IEnumerable <Status> Run()
        {
            if (Target == null)
            {
                yield return(Status.Fail);
            }

            switch (PickType)
            {
            case (PickUpType.Room):
            case (PickUpType.Stockpile):
            {
                if (Zone == null)
                {
                    yield return(Status.Fail);

                    break;
                }
                bool removed = Zone.Resources.RemoveResource(new ResourceAmount(Target.Tags[0]));

                if (removed)
                {
                    if (Creature.Inventory.Pickup(Target))
                    {
                        Agent.Blackboard.SetData(StashedItemOut, new ResourceAmount(Target));
                        SoundManager.PlaySound(ContentPaths.Audio.dig, Agent.Position);
                        yield return(Status.Success);
                    }
                    else
                    {
                        yield return(Status.Fail);
                    }
                }
                else
                {
                    yield return(Status.Fail);
                }
                break;
            }

            case (PickUpType.None):
            {
                if (!Creature.Inventory.Pickup(Target))
                {
                    yield return(Status.Fail);
                }

                if (Creature.Faction.GatherDesignations.Contains(Target))
                {
                    Creature.Faction.GatherDesignations.Remove(Target);
                }

                ResourceAmount resource = new ResourceAmount(Target);
                Agent.Blackboard.SetData(StashedItemOut, resource);
                Creature.DrawIndicator(resource.ResourceType.Image);
                SoundManager.PlaySound(ContentPaths.Audio.dig, Agent.Position);
                yield return(Status.Success);

                break;
            }
            }
        }
Ejemplo n.º 23
0
        public override IEnumerable <Status> Run()
        {
            InitializePath();
            if (Path == null || Path.Count == 0)
            {
                yield return(Act.Status.Success);
            }
            if (TrajectoryTimer == null)
            {
                yield break;
            }
            while (!TrajectoryTimer.HasTriggered)
            {
                TrajectoryTimer.Update(DwarfTime.LastTime);
                ValidPathTimer.Update(DwarfTime.LastTime);
                foreach (Status status in PerformCurrentAction())
                {
                    if (status == Status.Fail)
                    {
                        yield return(Status.Fail);
                    }
                    else if (status == Status.Success)
                    {
                        break;
                    }
                    yield return(Status.Running);
                }

                if (Agent.DrawPath)
                {
                    List <Vector3> points =
                        Path.Select(
                            (v, i) => v.SourceVoxel.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f) + RandomPositionOffsets[i])
                        .ToList();
                    points.Add(Path[Path.Count - 1].DestinationVoxel.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f));

                    List <Color> colors =
                        Path.Select((v, i) =>
                    {
                        switch (v.MoveType)
                        {
                        case MoveType.Climb:
                            return(Color.Cyan);

                        case MoveType.ClimbWalls:
                            return(Color.DarkCyan);

                        case MoveType.DestroyObject:
                            return(Color.Orange);

                        case MoveType.Fall:
                            return(Color.LightBlue);

                        case MoveType.Fly:
                            return(Color.Green);

                        case MoveType.Jump:
                            return(Color.Yellow);

                        case MoveType.Swim:
                            return(Color.Blue);

                        case MoveType.Walk:
                            return(Color.Red);
                        }
                        return(Color.White);
                    })
                        .ToList();
                    colors.Add(Color.White);
                    Drawer3D.DrawLineList(points, colors, 0.1f);
                }


                // Check if the path has been made invalid
                if (ValidPathTimer.HasTriggered && !IsPathValid(Path))
                {
                    Creature.OverrideCharacterMode = false;
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    yield return(Status.Fail);
                }
                yield return(Status.Running);
            }
            Creature.OverrideCharacterMode = false;
            SetPath(null);
            yield return(Status.Success);
        }
Ejemplo n.º 24
0
        public override IEnumerable <Status> Run()
        {
            InitializePath();
            if (Path == null || Path.Count == 0)
            {
                yield return(Act.Status.Success);
            }
            if (TrajectoryTimer == null)
            {
                yield break;
            }
            while (!TrajectoryTimer.HasTriggered)
            {
                Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, true);
                TrajectoryTimer.Update(DwarfTime.LastTime);
                ValidPathTimer.Update(DwarfTime.LastTime);
                foreach (Status status in PerformCurrentAction())
                {
                    if (status == Status.Fail)
                    {
                        CleanupMinecart();
                        yield return(Status.Fail);
                    }
                    else if (status == Status.Success)
                    {
                        break;
                    }
                    Creature.Physics.AnimationQueue.Clear();
                    yield return(Status.Running);
                }

                if (Debugger.Switches.DrawPaths)
                {
                    List <Vector3> points =
                        Path.Select(
                            (v, i) => v.SourceVoxel.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f) + RandomPositionOffsets[i])
                        .ToList();
                    points.Add(Path[Path.Count - 1].DestinationVoxel.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f));

                    List <Color> colors =
                        Path.Select((v, i) =>
                    {
                        switch (v.MoveType)
                        {
                        case MoveType.Climb:
                            return(Color.Cyan);

                        case MoveType.ClimbWalls:
                            return(Color.DarkCyan);

                        case MoveType.DestroyObject:
                            return(Color.Orange);

                        case MoveType.Fall:
                            return(Color.LightBlue);

                        case MoveType.Fly:
                            return(Color.Green);

                        case MoveType.Jump:
                            return(Color.Yellow);

                        case MoveType.Swim:
                            return(Color.Blue);

                        case MoveType.Walk:
                            return(Color.Red);
                        }
                        return(Color.White);
                    })
                        .ToList();
                    colors.Add(Color.White);
                    Drawer3D.DrawLineList(points, colors, 0.1f);
                }

                float      t            = 0;
                int        currentIndex = 0;
                MoveAction action       = new MoveAction();
                if (GetCurrentAction(ref action, ref t, ref currentIndex))
                {
                    // Check if the path has been made invalid
                    if (ValidPathTimer.HasTriggered && !IsPathValid(Path, currentIndex))
                    {
                        Creature.OverrideCharacterMode = false;
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        CleanupMinecart();
                        Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, true);
                        yield return(Status.Fail);
                    }
                }
                Creature.Physics.AnimationQueue.Clear();
                yield return(Status.Running);
            }
            Creature.OverrideCharacterMode = false;
            SetPath(null);
            Agent.GetRoot().SetFlagRecursive(GameComponent.Flag.Visible, true);
            CleanupMinecart();
            yield return(Status.Success);
        }
Ejemplo n.º 25
0
        public override IEnumerable <Status> Run()
        {
            Path     = null;
            Timeouts = 0;
            PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
            Voxel voxUnder = new Voxel();

            while (true)
            {
                if (Path != null)
                {
                    yield return(Status.Success);

                    break;
                }

                if (Timeouts > MaxTimeouts)
                {
                    yield return(Status.Fail);

                    break;
                }

                PlannerTimer.Update(DwarfTime.LastTime);

                ChunkManager chunks = PlayState.ChunkManager;
                if (PlannerTimer.HasTriggered || Timeouts == 0)
                {
                    if (!chunks.ChunkData.GetVoxel(Agent.Position, ref voxUnder))
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }


                    if (Target == null)
                    {
                        if (Creature.Faction == PlayState.Master.Faction)
                        {
                            PlayState.AnnouncementManager.Announce(Creature.Stats.FullName + " (" + Creature.Stats.CurrentLevel.Name + ")" + " got lost.",
                                                                   Creature.Stats.FullName + "'s target was lost.", () => Agent.ZoomToMe());
                        }
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    if (voxUnder != null)
                    {
                        Path = null;



                        AstarPlanRequest aspr = new AstarPlanRequest
                        {
                            Subscriber    = PlanSubscriber,
                            Start         = voxUnder,
                            MaxExpansions = MaxExpansions,
                            Sender        = Agent
                        };

                        if (Type == PlanType.Radius)
                        {
                            aspr.GoalRegion = new SphereGoalRegion(Target, Radius);
                        }
                        else if (Type == PlanType.Into)
                        {
                            aspr.GoalRegion = new VoxelGoalRegion(Target);
                        }
                        else if (Type == PlanType.Adjacent)
                        {
                            aspr.GoalRegion = new AdjacentVoxelGoalRegion2D(Target);
                        }


                        PlanSubscriber.SendRequest(aspr);
                        PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
                        WaitingOnResponse = true;
                        yield return(Status.Running);
                    }
                    else
                    {
                        Path = null;
                        if (Creature.Faction == PlayState.Master.Faction)
                        {
                            PlayState.AnnouncementManager.Announce(Creature.Stats.FullName + " got lost.",
                                                                   Creature.Stats.FullName + " couldn't find a path. The target was invalid.", () => Agent.ZoomToMe());
                        }
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    Timeouts++;
                }
                else
                {
                    Status statusResult = Status.Running;

                    while (PlanSubscriber.Responses.Count > 0)
                    {
                        AStarPlanResponse response;
                        PlanSubscriber.Responses.TryDequeue(out response);

                        if (response.Success)
                        {
                            Path = response.Path;

                            if (Type == PlanType.Adjacent && Path.Count > 0)
                            {
                                Path.RemoveAt(Path.Count - 1);
                            }
                            WaitingOnResponse = false;

                            statusResult = Status.Success;
                        }
                        else
                        {
                            if (Creature.Faction == PlayState.Master.Faction)
                            {
                                PlayState.AnnouncementManager.Announce(Creature.Stats.FullName + " got lost.",
                                                                       Creature.Stats.FullName + " couldn't find a path in time.", Agent.ZoomToMe);
                            }
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            statusResult = Status.Fail;
                        }
                    }
                    yield return(statusResult);
                }
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// This is the underlying Dig behavior that dwarves follow while digging.
        /// </summary>
        /// <param name="agent">The agent.</param>
        /// <param name="voxel">The voxel.</param>
        /// <param name="energyLoss">The energy loss the dwarf gets per block mined.</param>
        /// <returns>Success when the block is mined, fail if it fails to be mined, and running otherwise.</returns>
        public static IEnumerable <Act.Status> Dig(this Creature agent, string voxel, float energyLoss)
        {
            agent.Sprite.ResetAnimations(Creature.CharacterMode.Attacking);

            // Block since we're in a coroutine.
            while (true)
            {
                // Get the voxel stored in the agent's blackboard.
                Voxel blackBoardVoxel = agent.AI.Blackboard.GetData <Voxel>(voxel);

                // Somehow, there wasn't a voxel to mine.
                if (blackBoardVoxel == null)
                {
                    agent.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    yield return(Act.Status.Fail);

                    break;
                }

                Voxel vox = blackBoardVoxel;

                // If the voxel has already been destroyed, just ignore it and return.
                if (vox.Health <= 0.0f || !agent.Faction.IsDigDesignation(vox))
                {
                    agent.CurrentCharacterMode = Creature.CharacterMode.Idle;
                    yield return(Act.Status.Success);

                    break;
                }

                // Look at the block and slow your velocity down.
                agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                agent.Physics.Velocity *= 0.9f;

                // Play the attack animations.
                agent.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                agent.Sprite.ResetAnimations(agent.CurrentCharacterMode);
                agent.Sprite.PlayAnimations(agent.CurrentCharacterMode);

                // Wait until an attack was successful...
                foreach (var status in
                         agent.Attacks[0].Perform(agent,
                                                  agent.Physics.Position,
                                                  vox, DwarfTime.LastTime,
                                                  agent.Stats.BaseDigSpeed,
                                                  agent.Faction.Name))
                {
                    if (status == Act.Status.Running)
                    {
                        agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                        agent.Physics.Velocity *= 0.9f;

                        // Debug drawing.
                        if (agent.AI.DrawPath)
                        {
                            Drawer3D.DrawLine(vox.Position, agent.AI.Position, Color.Green, 0.25f);
                        }
                        yield return(Act.Status.Running);
                    }
                }

                // If the voxel has been destroyed by you, gather it.
                if (vox.Health <= 0.0f)
                {
                    List <Body> items = vox.Kill();

                    if (items != null)
                    {
                        foreach (Body item in items)
                        {
                            agent.Gather(item);
                        }
                    }
                    agent.AI.AddXP(Math.Max((int)(VoxelLibrary.GetVoxelType(blackBoardVoxel.TypeName).StartingHealth / 4), 1));
                    agent.Stats.NumBlocksDestroyed++;
                }

                // Wait until the animation is done playing before continuing.
                while (!agent.Sprite.CurrentAnimation.IsDone() && agent.Sprite.CurrentAnimation.IsPlaying)
                {
                    agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                    agent.Physics.Velocity *= 0.9f;
                    yield return(Act.Status.Running);
                }

                // Pause the animation and wait for a recharge timer.
                agent.Sprite.PauseAnimations(agent.CurrentCharacterMode);


                // Wait for a recharge timer to trigger.
                agent.Attacks[0].RechargeTimer.Reset();
                while (!agent.Attacks[0].RechargeTimer.HasTriggered)
                {
                    agent.Attacks[0].RechargeTimer.Update(DwarfTime.LastTime);
                    agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                    agent.Physics.Velocity *= 0.9f;
                    yield return(Act.Status.Running);
                }

                agent.CurrentCharacterMode = Creature.CharacterMode.Idle;

                yield return(Act.Status.Running);
            }
        }
Ejemplo n.º 27
0
        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);
        }
Ejemplo n.º 28
0
        public override IEnumerable <Status> Run()
        {
            Creature.Sprite.ResetAnimations(Creature.AttackMode);

            // Block since we're in a coroutine.
            while (true)
            {
                var vox = OwnerTask.Voxel;

                // Somehow, there wasn't a voxel to mine.
                if (!vox.IsValid)
                {
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    Agent.SetMessage("Failed to dig. Invalid voxel.");
                    yield return(Act.Status.Fail);

                    break;
                }

                // If the voxel has already been destroyed, just ignore it and return.
                if (OwnerTask.VoxelHealth <= 0 || (CheckOwnership && !Creature.Faction.Designations.IsVoxelDesignation(vox, DesignationType.Dig)))
                {
                    Creature.CurrentCharacterMode = CharacterMode.Idle;
                    yield return(Act.Status.Success);

                    break;
                }

                // Look at the block and slow your velocity down.
                Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                Creature.Physics.Velocity *= 0.01f;

                // Play the attack animations.
                Creature.CurrentCharacterMode  = Creature.AttackMode;
                Creature.OverrideCharacterMode = true;
                Creature.Sprite.ResetAnimations(Creature.CurrentCharacterMode);
                Creature.Sprite.PlayAnimations(Creature.CurrentCharacterMode);

                // Wait until an attack was successful...
                foreach (var status in
                         Creature.Attacks[0].PerformOnVoxel(Creature,
                                                            Creature.Physics.Position,
                                                            OwnerTask, DwarfTime.LastTime,
                                                            Creature.Stats.BaseDigSpeed,
                                                            Creature.Faction.Name))
                {
                    if (status == Act.Status.Running)
                    {
                        Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                        Creature.Physics.Velocity *= 0.01f;

                        // Debug drawing.
                        //if (agent.AI.DrawPath)
                        //    Drawer3D.DrawLine(vox.WorldPosition, agent.AI.Position, Color.Green, 0.25f);
                        yield return(Act.Status.Running);
                    }
                }

                Creature.OverrideCharacterMode = false;

                // If the voxel has been destroyed by you, gather it.
                if (OwnerTask.VoxelHealth <= 0.0f)
                {
                    var voxelType = VoxelLibrary.GetVoxelType(vox.Type.Name);
                    if (MathFunctions.RandEvent(0.5f))
                    {
                        Creature.AI.AddXP(Math.Max((int)(voxelType.StartingHealth / 4), 1));
                    }
                    Creature.Stats.NumBlocksDestroyed++;
                    Creature.World.GoalManager.OnGameEvent(new Goals.Triggers.DigBlock(voxelType, Creature));

                    var items = Creature.World.ChunkManager.KillVoxel(vox);

                    if (items != null)
                    {
                        foreach (Body item in items)
                        {
                            Creature.Gather(item);
                        }
                    }

                    yield return(Act.Status.Success);
                }

                // Wait until the animation is done playing before continuing.
                while (!Creature.Sprite.AnimPlayer.IsDone() && Creature.Sprite.AnimPlayer.IsPlaying)
                {
                    Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                    Creature.Physics.Velocity *= 0.01f;
                    yield return(Act.Status.Running);
                }

                // Pause the animation and wait for a recharge timer.
                Creature.Sprite.PauseAnimations(Creature.CurrentCharacterMode);


                // Wait for a recharge timer to trigger.
                Creature.Attacks[0].RechargeTimer.Reset();
                while (!Creature.Attacks[0].RechargeTimer.HasTriggered)
                {
                    Creature.Attacks[0].RechargeTimer.Update(DwarfTime.LastTime);
                    Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                    Creature.Physics.Velocity *= 0.01f;
                    yield return(Act.Status.Running);
                }

                Creature.CurrentCharacterMode = CharacterMode.Idle;
                yield return(Act.Status.Running);
            }
        }
Ejemplo n.º 29
0
        public override IEnumerable <Status> Run()
        {
            Path     = null;
            Timeouts = 0;
            PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);

            while (true)
            {
                if (Path != null)
                {
                    yield return(Status.Success);

                    break;
                }

                if (Timeouts > MaxTimeouts)
                {
                    yield return(Status.Fail);

                    break;
                }

                PlannerTimer.Update(DwarfTime.LastTime);

                ChunkManager chunks = Creature.Manager.World.ChunkManager;
                if (PlannerTimer.HasTriggered || Timeouts == 0)
                {
                    if (!Target.IsValid && Type != PlanType.Edge)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    var voxUnder = new VoxelHandle(chunks.ChunkData,
                                                   GlobalVoxelCoordinate.FromVector3(Agent.Position));

                    if (!voxUnder.IsValid)
                    {
                        Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                        yield return(Status.Fail);

                        break;
                    }

                    Path = null;
                    AstarPlanRequest aspr = new AstarPlanRequest
                    {
                        Subscriber      = Agent.PlanSubscriber,
                        Start           = voxUnder,
                        MaxExpansions   = MaxExpansions,
                        Sender          = Agent,
                        HeuristicWeight = Weights[Timeouts]
                    };


                    aspr.GoalRegion = GetGoal();

                    if (!Agent.PlanSubscriber.SendRequest(aspr))
                    {
                        yield return(Status.Fail);

                        yield break;
                    }
                    PlannerTimer.Reset(PlannerTimer.TargetTimeSeconds);
                    WaitingOnResponse = true;
                    yield return(Status.Running);


                    Timeouts++;
                }
                else
                {
                    //if (Target.IsValid && Creature.AI.DrawAIPlan)
                    //    Drawer3D.DrawLine(Creature.AI.Position, Target.WorldPosition, Color.Blue, 0.25f);
                    Status statusResult = Status.Running;

                    while (Agent.PlanSubscriber.Responses.Count > 0)
                    {
                        AStarPlanResponse response;
                        if (!Agent.PlanSubscriber.Responses.TryDequeue(out response))
                        {
                            yield return(Status.Running);

                            continue;
                        }
                        LastResult = response.Result;

                        if (response.Success)
                        {
                            Path = response.Path;
                            WaitingOnResponse = false;

                            statusResult = Status.Success;
                        }
                        else if (response.Result == AStarPlanner.PlanResultCode.Invalid || response.Result == AStarPlanner.PlanResultCode.NoSolution ||
                                 response.Result == AStarPlanner.PlanResultCode.Cancelled || response.Result == AStarPlanner.PlanResultCode.Invalid)
                        {
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            statusResult = Status.Fail;
                            yield return(Status.Fail);
                        }
                        else if (Timeouts <= MaxTimeouts)
                        {
                            Timeouts++;
                            yield return(Status.Running);
                        }
                        else
                        {
                            Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                            statusResult = Status.Fail;
                        }
                    }
                    yield return(statusResult);
                }
            }
        }
Ejemplo n.º 30
0
        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;
                }
            }
        }
Ejemplo n.º 31
0
        public override IEnumerable <Status> Run()
        {
            Creature.Sprite.ResetAnimations(Creature.Stats.CurrentClass.AttackMode);

            // Block since we're in a coroutine.
            while (true)
            {
                var vox = OwnerTask.Voxel;

                // Somehow, there wasn't a voxel to mine.
                if (!vox.IsValid)
                {
                    Creature.DrawIndicator(IndicatorManager.StandardIndicators.Question);
                    Agent.SetTaskFailureReason("Failed to dig. Invalid voxel.");
                    yield return(Act.Status.Fail);

                    break;
                }

                // If the voxel has already been destroyed, just ignore it and return.
                if (OwnerTask.VoxelHealth <= 0 || (CheckOwnership && !Creature.World.PersistentData.Designations.IsVoxelDesignation(vox, DesignationType.Dig)))
                {
                    Creature.CurrentCharacterMode = CharacterMode.Idle;
                    yield return(Act.Status.Success);

                    break;
                }

                // Look at the block and slow your velocity down.
                Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                Creature.Physics.Velocity *= 0.01f;

                // Play the attack animations.
                Creature.CurrentCharacterMode  = Creature.Stats.CurrentClass.AttackMode;
                Creature.OverrideCharacterMode = true;
                Creature.Sprite.ResetAnimations(Creature.CurrentCharacterMode);
                Creature.Sprite.PlayAnimations(Creature.CurrentCharacterMode);

                // Wait until an attack was successful...
                foreach (var status in
                         PerformOnVoxel(Creature,
                                        Creature.Physics.Position,
                                        OwnerTask, DwarfTime.LastTime,
                                        Creature.Stats.BaseDigSpeed,
                                        Creature.Faction.ParentFaction.Name))
                {
                    if (status == Act.Status.Running)
                    {
                        Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                        Creature.Physics.Velocity *= 0.01f;
                        yield return(Act.Status.Running);
                    }
                }

                Creature.OverrideCharacterMode = false;

                // If the voxel has been destroyed by you, gather it.
                if (OwnerTask.VoxelHealth <= 0.0f)
                {
                    if (Library.GetVoxelType(vox.Type.Name).HasValue(out VoxelType voxelType))
                    {
                        Creature.AI.AddXP(Math.Max((int)(voxelType.StartingHealth / 4), 1));
                        Creature.Stats.NumBlocksDestroyed++;
                        ActHelper.ApplyWearToTool(Creature.AI, GameSettings.Current.Wear_Dig);

                        var items = VoxelHelpers.KillVoxel(Creature.World, vox);

                        if (items != null)
                        {
                            foreach (GameComponent item in items)
                            {
                                Creature.Gather(item, TaskPriority.Eventually);
                            }
                        }

                        yield return(Act.Status.Success);
                    }
                }

                // Wait until the animation is done playing before continuing.
                while (!Creature.Sprite.AnimPlayer.IsDone() && Creature.Sprite.AnimPlayer.IsPlaying)
                {
                    Creature.Physics.Face(vox.WorldPosition + Vector3.One * 0.5f);
                    Creature.Physics.Velocity *= 0.01f;
                    yield return(Act.Status.Running);
                }

                // Pause the animation and wait for a recharge timer.
                Creature.Sprite.PauseAnimations(Creature.CurrentCharacterMode);

                Creature.CurrentCharacterMode = CharacterMode.Idle;
                yield return(Act.Status.Running);
            }
        }