예제 #1
0
        public DigAct(CreatureAI creature, KillVoxelTask OwnerTask) :
            base(creature)
        {
            Name       = "Dig!";
            EnergyLoss = 10.0f;

            this.OwnerTask = OwnerTask;
        }
예제 #2
0
        public bool CheckIsDigDesignation(CreatureAI creature, KillVoxelTask OwnerTask)
        {
            if (OwnerTask.Voxel.IsValid)
            {
                return(creature.World.PersistentData.Designations.IsVoxelDesignation(OwnerTask.Voxel, DesignationType.Dig));
            }

            return(false);
        }
예제 #3
0
 public IEnumerable <Act.Status> Cleanup(CreatureAI creature, KillVoxelTask OwnerTask)
 {
     if (creature.Blackboard.GetData <bool>("NoPath", false))
     {
         if (creature.Faction == creature.World.PlayerFaction)
         {
             creature.World.MakeAnnouncement(String.Format("{0} cancelled dig task because it is unreachable", creature.Stats.FullName));
             creature.World.TaskManager.CancelTask(OwnerTask);
         }
     }
     yield return(Act.Status.Success);
 }
예제 #4
0
 public KillVoxelAct(CreatureAI creature, KillVoxelTask OwnerTask) :
     base(creature)
 {
     Name = "Kill DestinationVoxel " + OwnerTask.Voxel.WorldPosition;
     Tree =
         new Domain(() => CheckIsDigDesignation(creature, OwnerTask),
                    new Sequence(
                        new GoToVoxelAct(OwnerTask.Voxel, PlanAct.PlanType.Radius, creature)
     {
         Radius = 2.0f
     },
                        new DigAct(Agent, OwnerTask)))
         | new Wrap(() => Cleanup(creature, OwnerTask));
 }
예제 #5
0
 public KillVoxelAct(CreatureAI creature, KillVoxelTask OwnerTask) :
     base(creature)
 {
     Name = "Kill DestinationVoxel " + OwnerTask.Voxel.WorldPosition;
     Tree = new Select(
         new Domain(() => CheckIsDigDesignation(creature, OwnerTask),
                    new Sequence(
                        ActHelper.CreateEquipmentCheckAct(creature, "Tool", ActHelper.EquipmentFallback.AllowDefault, "Pick"),
                        new GoToVoxelAct(OwnerTask.Voxel, PlanAct.PlanType.Radius, creature)
     {
         Radius = 2.0f
     },
                        new DigAct(Agent, OwnerTask))),
         new Wrap(() => Cleanup(creature, OwnerTask)));
 }
예제 #6
0
        public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button)
        {
            if (button == InputManager.MouseButton.Left)
            {
                Player.World.Tutorial("slice");
                List <Task> assignments = new List <Task>();
                foreach (var v in refs)
                {
                    if (!v.IsValid || (v.IsEmpty && v.IsExplored) || v.Type.IsInvincible)
                    {
                        continue;
                    }

                    var boundingBox = v.GetBoundingBox().Expand(-0.1f);
                    var entities    = Player.World.EnumerateIntersectingObjects(boundingBox, CollisionType.Static);
                    if (entities.OfType <IVoxelListener>().Any())
                    {
                        continue;
                    }

                    if (!Player.Faction.Designations.IsVoxelDesignation(v, DesignationType.Dig) && !(Player.Faction.RoomBuilder.IsInRoom(v) || Player.Faction.RoomBuilder.IsBuildDesignation(v)))
                    {
                        var task = new KillVoxelTask(v);
                        assignments.Add(task);
                    }
                }

                Player.TaskManager.AddTasks(assignments);
                List <CreatureAI> minions = Faction.FilterMinionsWithCapability(Player.SelectedMinions, Task.TaskCategory.Dig);
                OnConfirm(minions);
            }
            else
            {
                foreach (var r in refs)
                {
                    if (r.IsValid)
                    {
                        var designation = Player.Faction.Designations.GetVoxelDesignation(r, DesignationType.Dig);
                        if (designation != null && designation.Task != null)
                        {
                            Player.TaskManager.CancelTask(designation.Task);
                        }
                    }
                }
            }
        }
예제 #7
0
        public IEnumerable <Act.Status> PerformOnVoxel(Creature performer, Vector3 pos, KillVoxelTask DigAct, DwarfTime time, float bonus, string faction)
        {
            while (true)
            {
                if (!DigAct.Voxel.IsValid)
                {
                    performer.AI.SetMessage("Failed to dig. Voxel was not valid.");
                    yield return(Act.Status.Fail);

                    yield break;
                }

                Drawer2D.DrawLoadBar(performer.World.Renderer.Camera, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f, Color.White, Color.Black, 32, 1, (float)DigAct.VoxelHealth / DigAct.Voxel.Type.StartingHealth);

                switch (Weapon.TriggerMode)
                {
                case Weapon.AttackTrigger.Timer:
                    RechargeTimer.Update(time);
                    if (!RechargeTimer.HasTriggered)
                    {
                        yield return(Act.Status.Running);

                        continue;
                    }
                    break;

                case Weapon.AttackTrigger.Animation:
                    if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                        performer.Sprite.AnimPlayer.CurrentFrame < Weapon.TriggerFrame)
                    {
                        if (performer.Sprite.AnimPlayer.HasValidAnimation())
                        {
                            performer.Sprite.AnimPlayer.Play();
                        }
                        yield return(Act.Status.Running);

                        continue;
                    }
                    break;
                }

                DigAct.VoxelHealth -= (Weapon.DamageAmount + bonus);

                DigAct.Voxel.Type.HitSound.Play(DigAct.Voxel.WorldPosition);
                if (!String.IsNullOrEmpty(Weapon.HitParticles))
                {
                    performer.Manager.World.ParticleManager.Trigger(Weapon.HitParticles, DigAct.Voxel.WorldPosition, Color.White, 5);
                }

                if (Weapon.HitAnimation != null)
                {
                    IndicatorManager.DrawIndicator(Weapon.HitAnimation, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f,
                                                   10.0f, 1.0f, MathFunctions.RandVector2Circle() * 10, Weapon.HitColor, MathFunctions.Rand() > 0.5f);
                }

                yield return(Act.Status.Success);

                yield break;
            }
        }
예제 #8
0
        public List <Task> CreateTasks()
        {
            List <Task> tasks = new List <Task>();

            if (Faction.Stockpiles.Count > 0)
            {
                tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Hunger.IsUnhappy())
                {
                    Task g = new SatisfyHungerTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
                {
                    Task g = new SatisfyTirednessTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            List <Creature> threatsToRemove = new List <Creature>();

            foreach (Creature threat in Faction.Threats)
            {
                if (threat != null && !threat.IsDead)
                {
                    Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto);

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
                else
                {
                    threatsToRemove.Add(threat);
                }
            }

            foreach (Creature threat in threatsToRemove)
            {
                Faction.Threats.Remove(threat);
            }

            foreach (BuildOrder i in Faction.DigDesignations)
            {
                if (i == null || i.Vox == null || i.Vox.Health <= 0)
                {
                    continue;
                }

                VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position);

                if (chunk != null)
                {
                    if (chunk.IsCompletelySurrounded(i.Vox))
                    {
                        continue;
                    }
                }


                Task g = new KillVoxelTask(i.Vox);

                if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                {
                    tasks.Add(g);
                }
            }

            tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            if (Faction.Stockpiles.Count <= 0)
            {
                return(tasks);
            }

            foreach (WallBuilder put in Faction.WallBuilder.Designations)
            {
                if (Faction.HasResources(new List <ResourceAmount>()
                {
                    new ResourceAmount(put.Type.ResourceToRelease)
                }))
                {
                    Task g = (new BuildVoxelTask(put.Vox, put.Type));

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            return(tasks);
        }
예제 #9
0
        public List<Task> CreateTasks()
        {
            List<Task> tasks = new List<Task>();

            if(Faction.Stockpiles.Count > 0)
            {
                tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));
            }

            foreach(CreatureAI creature in Faction.Minions)
            {
                if(creature.Status.Hunger.IsUnhappy())
                {
                    Task g = new SatisfyHungerTask();

                    if(IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }

                }
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
                {
                    Task g = new SatisfyTirednessTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }

                }
            }

            List<Creature> threatsToRemove = new List<Creature>();
            foreach(Creature threat in Faction.Threats)
            {
                if(threat != null && !threat.IsDead)
                {
                    Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto);

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
                else
                {
                    threatsToRemove.Add(threat);
                }
            }

            foreach (Creature threat in threatsToRemove)
            {
                Faction.Threats.Remove(threat);
            }

            foreach(BuildOrder i in Faction.DigDesignations)
            {
                if (i == null || i.Vox == null || i.Vox.Health <= 0)
                {
                    continue;
                }

                VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position);

                if(chunk != null)
                {
                    if(chunk.IsCompletelySurrounded(i.Vox))
                    {
                        continue;
                    }
                }

                Task g = new KillVoxelTask(i.Vox);

                if(!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                {
                    tasks.Add(g);
                }
            }

            tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            if(Faction.Stockpiles.Count <= 0)
            {
                return tasks;
            }

            foreach(WallBuilder put in Faction.WallBuilder.Designations)
            {
                if(Faction.HasResources(new List<ResourceAmount>()
                {
                    new ResourceAmount(put.Type.ResourceToRelease)
                }))
                {

                    Task g = (new BuildVoxelTask(put.Vox, put.Type));

                    if(!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach(ShipOrder ship in Faction.ShipDesignations)
            {
                List<Body> componentsToShip = new List<Body>();
                int remaining = ship.GetRemainingNumResources();

                if(remaining == 0)
                {
                    continue;
                }

                foreach(Stockpile s in Faction.Stockpiles)
                {
                    for(int i = componentsToShip.Count; i < remaining; i++)
                    {
                        // TODO: Reimplement
                        /*
                        Body r = s.FindItemWithTag(ship.Resource.ResourceType.ResourceName, componentsToShip);

                        if(r != null)
                        {
                            componentsToShip.Add(r);
                        }
                         */
                    }
                }

                foreach(Body loc in componentsToShip)
                {
                    // TODO: Reimplement
                    /*
                    if(ship.Port.ContainsItem(loc))
                    {
                        continue;
                    }
                     */

                    Task g = new PutItemInZoneTask(Item.FindItem(loc), ship.Port);

                    if(TaskIsAssigned(g) || !IsFeasible(g, Faction.Minions))
                    {
                        continue;
                    }

                    ship.Assignments.Add(g);
                    tasks.Add(g);
                }
            }

            return tasks;
        }
예제 #10
0
        public List <Task> CreateTasks()
        {
            List <Task> tasks = new List <Task>();

            if (Faction.Stockpiles.Count > 0)
            {
                tasks.AddRange(Faction.GatherDesignations.Select(i => new GatherItemTask(i)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Hunger.IsUnhappy())
                {
                    Task g = new SatisfyHungerTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach (CreatureAI creature in Faction.Minions)
            {
                if (creature.Status.Energy.IsUnhappy() && PlayState.Time.IsNight())
                {
                    Task g = new SatisfyTirednessTask();

                    if (IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            List <Creature> threatsToRemove = new List <Creature>();

            foreach (Creature threat in Faction.Threats)
            {
                if (threat != null && !threat.IsDead)
                {
                    Task g = new KillEntityTask(threat.Physics, KillEntityTask.KillType.Auto);

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
                else
                {
                    threatsToRemove.Add(threat);
                }
            }

            foreach (Creature threat in threatsToRemove)
            {
                Faction.Threats.Remove(threat);
            }

            foreach (BuildOrder i in Faction.DigDesignations)
            {
                if (i == null || i.Vox == null || i.Vox.Health <= 0)
                {
                    continue;
                }

                VoxelChunk chunk = PlayState.ChunkManager.ChunkData.GetVoxelChunkAtWorldLocation(i.Vox.Position);

                if (chunk != null)
                {
                    if (chunk.IsCompletelySurrounded(i.Vox))
                    {
                        continue;
                    }
                }


                Task g = new KillVoxelTask(i.Vox);

                if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                {
                    tasks.Add(g);
                }
            }

            tasks.AddRange(Faction.GuardDesignations.Select(i => new GuardVoxelTask(i.Vox)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            tasks.AddRange(Faction.ChopDesignations.Select(i => new KillEntityTask(i, KillEntityTask.KillType.Chop)).Where(g => !TaskIsAssigned(g) && IsFeasible(g, Faction.Minions)));

            if (Faction.Stockpiles.Count <= 0)
            {
                return(tasks);
            }

            foreach (WallBuilder put in Faction.WallBuilder.Designations)
            {
                if (Faction.HasResources(new List <ResourceAmount>()
                {
                    new ResourceAmount(put.Type.ResourceToRelease)
                }))
                {
                    Task g = (new BuildVoxelTask(put.Vox, put.Type));

                    if (!TaskIsAssigned(g) && IsFeasible(g, Faction.Minions))
                    {
                        tasks.Add(g);
                    }
                }
            }

            foreach (ShipOrder ship in Faction.ShipDesignations)
            {
                List <Body> componentsToShip = new List <Body>();
                int         remaining        = ship.GetRemainingNumResources();

                if (remaining == 0)
                {
                    continue;
                }


                foreach (Stockpile s in Faction.Stockpiles)
                {
                    for (int i = componentsToShip.Count; i < remaining; i++)
                    {
                        // TODO: Reimplement

                        /*
                         * Body r = s.FindItemWithTag(ship.Resource.ResourceType.ResourceName, componentsToShip);
                         *
                         * if(r != null)
                         * {
                         *  componentsToShip.Add(r);
                         * }
                         */
                    }
                }

                foreach (Body loc in componentsToShip)
                {
                    // TODO: Reimplement

                    /*
                     * if(ship.Port.ContainsItem(loc))
                     * {
                     *  continue;
                     * }
                     */

                    Task g = new PutItemInZoneTask(Item.FindItem(loc), ship.Port);

                    if (TaskIsAssigned(g) || !IsFeasible(g, Faction.Minions))
                    {
                        continue;
                    }

                    ship.Assignments.Add(g);
                    tasks.Add(g);
                }
            }

            return(tasks);
        }
예제 #11
0
        private IEnumerable <Act.Status> PerformOnVoxel(Creature performer, Vector3 pos, KillVoxelTask DigAct, DwarfTime time, float bonus, string faction)
        {
            var tool = ActHelper.GetEquippedItem(performer, "Tool");

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

            while (true)
            {
                if (!DigAct.Voxel.IsValid)
                {
                    performer.AI.SetTaskFailureReason("Failed to dig. Voxel was not valid.");
                    yield return(Act.Status.Fail);

                    yield break;
                }

                Drawer2D.DrawLoadBar(performer.World.Renderer.Camera, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f, Color.White, Color.Black, 32, 1, (float)DigAct.VoxelHealth / DigAct.Voxel.Type.StartingHealth);

                while (!performer.Sprite.AnimPlayer.HasValidAnimation() || performer.Sprite.AnimPlayer.CurrentFrame < tool.Tool_AttackTriggerFrame)
                {
                    if (performer.Sprite.AnimPlayer.HasValidAnimation())
                    {
                        performer.Sprite.AnimPlayer.Play();
                    }
                    yield return(Act.Status.Running);
                }

                DigAct.VoxelHealth -= (tool.Tool_AttackDamage + bonus);
                DigAct.Voxel.Type.HitSound.Play(DigAct.Voxel.WorldPosition);
                if (!String.IsNullOrEmpty(tool.Tool_AttackHitParticles))
                {
                    performer.Manager.World.ParticleManager.Trigger(tool.Tool_AttackHitParticles, DigAct.Voxel.WorldPosition, Color.White, 5);
                }

                if (!String.IsNullOrEmpty(tool.Tool_AttackHitEffect))
                {
                    IndicatorManager.DrawIndicator(Library.CreateSimpleAnimation(tool.Tool_AttackHitEffect), DigAct.Voxel.WorldPosition + Vector3.One * 0.5f,
                                                   10.0f, 1.0f, MathFunctions.RandVector2Circle() * 10, tool.Tool_AttackHitColor, MathFunctions.Rand() > 0.5f);
                }

                yield return(Act.Status.Success);

                yield break;
            }
        }
예제 #12
0
        public IEnumerable <Act.Status> PerformOnVoxel(Creature performer, Vector3 pos, KillVoxelTask DigAct, DwarfTime time, float bonus, string faction)
        {
            while (true)
            {
                if (!DigAct.Voxel.IsValid)
                {
                    yield return(Act.Status.Fail);

                    yield break;
                }

                Drawer2D.DrawLoadBar(performer.World.Camera, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f, Color.White, Color.Black, 32, 1, (float)DigAct.VoxelHealth / DigAct.Voxel.Type.StartingHealth);

                switch (TriggerMode)
                {
                case AttackTrigger.Timer:
                    RechargeTimer.Update(time);
                    if (!RechargeTimer.HasTriggered)
                    {
                        yield return(Act.Status.Running);

                        continue;
                    }
                    break;

                case AttackTrigger.Animation:
                    if (!performer.Sprite.AnimPlayer.HasValidAnimation() ||
                        performer.Sprite.AnimPlayer.CurrentFrame < TriggerFrame)
                    {
                        if (performer.Sprite.AnimPlayer.HasValidAnimation())
                        {
                            performer.Sprite.AnimPlayer.Play();
                        }
                        yield return(Act.Status.Running);

                        continue;
                    }
                    break;
                }

                switch (Mode)
                {
                case AttackMode.Melee:
                {
                    DigAct.VoxelHealth -= (DamageAmount + bonus);

                    DigAct.Voxel.Type.HitSound.Play(DigAct.Voxel.WorldPosition);
                    if (HitParticles != "")
                    {
                        performer.Manager.World.ParticleManager.Trigger(HitParticles, DigAct.Voxel.WorldPosition, Color.White, 5);
                    }

                    if (HitAnimation != null)
                    {
                        IndicatorManager.DrawIndicator(HitAnimation, DigAct.Voxel.WorldPosition + Vector3.One * 0.5f,
                                                       10.0f, 1.0f, MathFunctions.RandVector2Circle() * 10, HitColor, MathFunctions.Rand() > 0.5f);
                    }

                    break;
                }

                case AttackMode.Ranged:
                {
                    throw new InvalidOperationException("Ranged attacks should never be used for digging.");
                    //LaunchProjectile(pos, DigAct.GetTargetVoxel().WorldPosition, null);
                    //break;
                }
                }
                yield return(Act.Status.Success);

                yield break;
            }
        }
예제 #13
0
        public override void OnVoxelsSelected(List <VoxelHandle> refs, InputManager.MouseButton button)
        {
            if (button == InputManager.MouseButton.Left)
            {
                int count = World.PersistentData.Designations.EnumerateDesignations(DesignationType.Dig).Count();

                World.Tutorial("slice");
                List <Task> assignments = new List <Task>();
                foreach (var v in refs)
                {
                    if (!v.IsValid || (v.IsEmpty && v.IsExplored) || v.Type.IsInvincible)
                    {
                        continue;
                    }

                    var boundingBox = v.GetBoundingBox().Expand(-0.1f);
                    var entities    = World.EnumerateIntersectingObjects(boundingBox, CollisionType.Static);
                    if (entities.OfType <IVoxelListener>().Any())
                    {
                        continue;
                    }

                    if (count >= GameSettings.Current.MaxVoxelDesignations)
                    {
                        World.UserInterface.ShowToolPopup("Too many dig designations!");
                        break;
                    }

                    // Todo: Should this be removed from the existing compound task and put in the new one?
                    if (!World.PersistentData.Designations.IsVoxelDesignation(v, DesignationType.Dig) && !(World.IsInZone(v) || World.IsBuildDesignation(v)))
                    {
                        var task = new KillVoxelTask(v);
                        task.Hidden = true;
                        assignments.Add(task);
                        count++;
                    }
                }

                if (assignments.Count > 0)
                {
                    World.TaskManager.AddTasks(assignments);

                    var compoundTask = new CompoundTask("DIG A HOLE", TaskCategory.Dig, TaskPriority.Medium);
                    compoundTask.AddSubTasks(assignments);
                    World.TaskManager.AddTask(compoundTask);

                    var minions = Faction.FilterMinionsWithCapability(World.PersistentData.SelectedMinions, TaskCategory.Dig);
                    OnConfirm(minions);
                }
            }
            else
            {
                foreach (var r in refs)
                {
                    if (r.IsValid)
                    {
                        if (World.PersistentData.Designations.GetVoxelDesignation(r, DesignationType.Dig).HasValue(out var designation) && designation.Task != null) // Todo: Is this necessary?
                        {
                            World.TaskManager.CancelTask(designation.Task);
                        }
                    }
                }
            }
        }
예제 #14
0
        // This hack exists to find orphaned tasks not assigned to any dwarf, and to then
        // put them on the task list.
        public void UpdateOrphanedTasks()
        {
            orphanedTaskRateLimiter.Update(DwarfTime.LastTime);
            if (orphanedTaskRateLimiter.HasTriggered)
            {
                List <Task> orphanedTasks = new List <Task>();
                foreach (var block in Faction.Designations.EnumerateDesignations())
                {
                    if (block.Type == DesignationType.Put)
                    {
                        var type = (short)(block.Tag);
                        var task = new BuildVoxelTask(block.Voxel, VoxelLibrary.GetVoxelType(type).Name);

                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }
                    else if (block.Type == DesignationType.Dig)
                    {
                        var task = new KillVoxelTask(block.Voxel);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }
                    // TODO... other tasks here ?
                }

                foreach (var ent in Faction.Designations.EnumerateEntityDesignations())
                {
                    if (ent.Type == DesignationType.Attack)
                    {
                        var task = new KillEntityTask(ent.Body, KillEntityTask.KillType.Attack);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }
                    else if (ent.Type == DesignationType.Chop)
                    {
                        var task = new KillEntityTask(ent.Body, KillEntityTask.KillType.Chop);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }
                    else if (ent.Type == DesignationType.Wrangle)
                    {
                        var task = new WrangleAnimalTask(ent.Body.GetRoot().GetComponent <Creature>());
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }
                    else if (ent.Type == DesignationType.Gather)
                    {
                        var task = new GatherItemTask(ent.Body);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }
                    else if (ent.Type == DesignationType.Craft)
                    {
                        var task = new CraftItemTask(ent.Tag as CraftDesignation);
                        if (!TaskManager.HasTask(task) &&
                            !Faction.Minions.Any(minion => minion.Tasks.Contains(task)))
                        {
                            orphanedTasks.Add(task);
                        }
                    }

                    /// TODO ... other entity task types
                }

                if (orphanedTasks.Count > 0)
                {
                    TaskManager.AssignTasksGreedy(orphanedTasks, Faction.Minions);
                }
            }
        }