예제 #1
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);
            }
        }
예제 #2
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);
            }
        }
예제 #3
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);
            }
        }
예제 #4
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)
            {
                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));
                    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.CurrentCharacterMode = Creature.CharacterMode.Attacking;
                agent.Sprite.ResetAnimations(agent.CurrentCharacterMode);
                agent.Sprite.PlayAnimations(agent.CurrentCharacterMode);

                while (!agent.Attacks[0].Perform(agent, agent.Physics.Position, vox, DwarfTime.LastTime, agent.Stats.BaseDigSpeed, agent.Faction.Name))
                {
                    agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                    agent.Physics.Velocity *= 0.9f;

                    yield return(Act.Status.Running);
                }

                if (vox.Health <= 0.0f)
                {
                    List <Body> items = vox.Kill();

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

                while (!agent.Sprite.CurrentAnimation.IsDone())
                {
                    agent.Physics.Face(vox.Position + Vector3.One * 0.5f);
                    agent.Physics.Velocity *= 0.9f;
                    yield return(Act.Status.Running);
                }
                agent.Sprite.PauseAnimations(agent.CurrentCharacterMode);


                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);
            }
        }