示例#1
0
        public PartyTurnActor()
        {
            MoveAction     moveAction     = new MoveAction(m_activeActions);
            RotateAction   rotateAction   = new RotateAction(m_activeActions);
            RestAction     restAction     = new RestAction();
            InteractAction interactAction = new InteractAction();
            SelectNextInteractiveObjectAction selectNextInteractiveObjectAction = new SelectNextInteractiveObjectAction();

            m_actions = new BaseAction[4][];
            for (Int32 i = 0; i < m_actions.Length; i++)
            {
                m_actions[i]     = new BaseAction[11];
                m_actions[i][0]  = moveAction;
                m_actions[i][1]  = rotateAction;
                m_actions[i][6]  = restAction;
                m_actions[i][2]  = interactAction;
                m_actions[i][10] = selectNextInteractiveObjectAction;
                m_actions[i][3]  = new MeleeAttackAction(i);
                m_actions[i][4]  = new RangedAttackAction(i);
                m_actions[i][9]  = new CastSpellAction(i);
                m_actions[i][5]  = new ConsumeItemAction(i);
                m_actions[i][8]  = new DefendAction(i);
                m_actions[i][7]  = new EquipAction(i);
            }
        }
示例#2
0
 public override void FindNextState()
 {
     if (currentAction is WaitAction)
     {
         currentAction = new WalkAction(owner, TargetType.PLAYER);
     }
     else if (currentAction is WalkAction)
     {
         GameObject nearestPlayer = FindNearestPlayer();
         if ((nearestPlayer.transform.position - owner.transform.position).sqrMagnitude <= Mathf.Pow(0.22f, 2f))
         {
             currentAction = new AttackPrepareAction(owner, nearestPlayer, 0.4f);
         }
     }
     else if (currentAction is AttackPrepareAction)
     {
         if (currentAction.isOver)
         {
             AttackPrepareAction prevAction = currentAction as AttackPrepareAction;
             currentAction = new MeleeAttackAction(owner, prevAction.targetPosition, 1f, 2f);
         }
     }
     else if (currentAction is MeleeAttackAction)
     {
         if (currentAction.isOver)
         {
             owner.animator.SetTrigger("Idle");
             currentAction = new WaitAction();
         }
     }
 }
示例#3
0
        private List <EncounterAction> MoveAndAttack(EncounterState state, int dx, int dy)
        {
            var positionComponent = state.Player.GetComponent <PositionComponent>();
            var oldPos            = positionComponent.EncounterPosition;
            var newPos            = new EncounterPosition(oldPos.X + dx, oldPos.Y + dy);

            // TODO: maybe not hostile?
            var hostiles = AIUtils.HostilesInPosition(state, FactionName.PLAYER, newPos.X, newPos.Y);

            if (hostiles.Count > 0)
            {
                var attackAction = new MeleeAttackAction(state.Player.EntityId, hostiles[state.EncounterRand.Next(hostiles.Count)]);
                return(new List <EncounterAction>()
                {
                    attackAction
                });
            }
            else
            {
                var moveAction = new MoveAction(state.Player.EntityId, newPos);
                return(new List <EncounterAction>()
                {
                    moveAction
                });
            }
        }
示例#4
0
    public Action GetAction(EntityMap entityMap, GroundMap groundMap)
    {
        Action action;
        var    aStar        = new AStar(groundMap, entityMap);
        var    target       = entityMap.GetPlayer();
        var    actionResult = new ActionResult();

        if (target == null)
        {
            // If no target, the pathfinding doesn't know what to do, so wait instead and send a message up
            action = BuildWaitAction(actionResult, entityMap, groundMap);
        }

        // Right now enemies will only act if the player can see them
        else if (groundMap.isTileVisible(owner.position))
        {
            // Attempt to move towards the AIs target (this doesn't have to be the player!)
            if (owner.DistanceTo(target) >= 2)
            {
                var moveTile = aStar.FindPathToTarget((owner.position.x, owner.position.y), (target.position.x, target.position.y));
                if (moveTile == null)
                {
                    // No path found I guess
                    action = BuildWaitAction(actionResult, entityMap, groundMap);
                }
                else
                {
                    action = new WalkAction(owner.actor, new CellPosition(moveTile.x, moveTile.y));
                }
            }
            else
            {
                // If we're in melee range, attack instead of move
                if (owner.GetComponent <Fighter>() == null)
                {
                    // Can't fight though... ha
                    action = BuildWaitAction(actionResult, entityMap, groundMap);
                }
                else
                {
                    action = new MeleeAttackAction(owner.actor, target.position);
                }
            }
        }
        else
        {
            // Nothing to do, not visible, just wait
            action = BuildWaitAction(actionResult, entityMap, groundMap, logMessage: false);
        }

        return(action);
    }
示例#5
0
        public void DoRoundOfCombat(List <Character.Character> characters)
        {
            RoundCount++;
            foreach (var character in TurnOrder)
            {
                CurrentCharacter = character;

                //TODO DetermineAction()
                AbstractAction chosenAction = new MeleeAttackAction();
                //ToDO DetermineTarget()
                var target = characters.FirstOrDefault(x => x.Team != CurrentCharacter.Team); //simple for now.

                chosenAction.DoAction(CurrentCharacter, target);
            }
        }
示例#6
0
        private static bool ResolveMeleeAttack(MeleeAttackAction action, EncounterState state)
        {
            Entity attacker = state.GetEntityById(action.ActorId);
            Entity defender = action.TargetEntity;

            var attackerComponent         = attacker.GetComponent <AttackerComponent>();
            var attackerDefenderComponent = attacker.GetComponent <DefenderComponent>();
            var defenderComponent         = defender.GetComponent <DefenderComponent>();

            if (defenderComponent.IsInvincible)
            {
                var logMessage = string.Format("[b]{0}[/b] hits [b]{1}[/b], but the attack has no effect!",
                                               attacker.EntityName, defender.EntityName);
                LogAttack(attacker, defender, defenderComponent, logMessage, state);
            }
            else
            {
                bool isPlayer = attacker == state.Player;
                bool hit      = false;
                bool killed   = false;

                var attackReport = AttackHits(state.EncounterRand, attackerComponent.MeleeAttack, attackerDefenderComponent.FootingPenalty,
                                              defenderComponent.MeleeDefense, defenderComponent.FootingPenalty);
                attackerDefenderComponent.NotifyParentHasAttacked();
                if (!attackReport.Item3)
                {
                    var logMessage = string.Format("[b]{0}[/b] attacks [b]{1}[/b], but misses! ({2}% chance to hit)",
                                                   attacker.EntityName, defender.EntityName, attackReport.Item1);
                    LogAttack(attacker, defender, defenderComponent, logMessage, state);
                    return(true);
                }

                // We don't allow underflow damage, though that could be a pretty comical mechanic...
                int weaponDamage      = Math.Max(0, attackerComponent.Power - defenderComponent.Defense);
                int shieldedByFooting = (int)Math.Floor(weaponDamage * defenderComponent.PercentageFooting);
                int hpDamage          = weaponDamage - shieldedByFooting;
                int footingDamage     = shieldedByFooting * 3;

                hit = true;
                defenderComponent.RemoveHp(hpDamage);
                defenderComponent.RemoveFooting(footingDamage);

                if (defenderComponent.CurrentHp <= 0)
                {
                    killed = true;
                    var logMessage = string.Format("[b]{0}[/b] hits [b]{1}[/b] for {2} damage, killing it! ({3}% chance to hit)",
                                                   attacker.EntityName, defender.EntityName, hpDamage, attackReport.Item1);

                    // Assign XP to the entity that fired the projectile
                    var attackerId       = state.GetEntityById(attackerComponent.SourceEntityId);
                    var xpValueComponent = defender.GetComponent <XPValueComponent>();
                    if (attackerId != null && xpValueComponent != null && attackerId.GetComponent <XPTrackerComponent>() != null)
                    {
                        attackerId.GetComponent <XPTrackerComponent>().AddXP(xpValueComponent.XPValue, attackerComponent, defenderComponent, state);
                        logMessage += String.Format(" [b]{0}[/b] gains {1} XP!", attackerId.EntityName, xpValueComponent.XPValue);
                    }

                    LogAttack(attacker, defender, defenderComponent, logMessage, state);
                    ResolveAction(new DestroyAction(defender.EntityId), state);
                }
                else
                {
                    var logMessage = string.Format("[b]{0}[/b] hits [b]{1}[/b] for {2} HP damage and {3} footing damage! ({4}% chance to hit)",
                                                   attacker.EntityName, defender.EntityName, hpDamage, shieldedByFooting, attackReport.Item1);
                    LogAttack(attacker, defender, defenderComponent, logMessage, state);
                }

                // Finally, assign player prestige
                if (isPlayer && killed)
                {
                    var logMessage = string.Format("Your allies witness you slaying the [b]{0}[/b]. [b]You gain 5 prestige![/b]", defender.EntityName);
                    attacker.GetComponent <PlayerComponent>().AddPrestige(5, state, logMessage, PrestigeSource.DEFEATING_FOES);
                }
                else if (isPlayer && hit)
                {
                    var logMessage = string.Format("Your allies will remember that injured the [b]{0}[/b]. [b]You gain 1 prestige![/b]", defender.EntityName);
                    attacker.GetComponent <PlayerComponent>().AddPrestige(1, state, logMessage, PrestigeSource.LANDING_HITS);
                }
            }
            return(true);
        }