コード例 #1
0
        public override void QueueAbility(AbilityItemModel abilityItemModel, int[] combatantIDs)
        {
            if (castingAbilityItemModel != null || nextAbilityItemModel != null)
            {
                // Ignore if ability is already queued
                Logging.Log.Info("An ability is already queued for player with combatant ID: " + ownerCombatantModel.ID + ", ignoring.");
                return;
            }

            nextAbilityItemModel = abilityItemModel;
            int abilityIndex = ownerCombatantModel.GetAbilityIndex(abilityItemModel.ID);

            nextTargetCombatants.Clear();
            for (int i = 0; i < combatantIDs.Length; i++)
            {
                CombatantModel targetCombatantModel = null;
                if (combatantIDsToModels.TryGetValue(combatantIDs[i], out targetCombatantModel))
                {
                    // Ignore if ability is still cooling down
                    if (ownerCombatantModel.GetStatModifiedAbilityCoolDownTurnsRemaining(abilityIndex) > 0)
                    {
                        Logging.Log.Info("Ability with ID: " + abilityItemModel.ID + " is cooling down, ignoring.");
                        continue;
                    }

                    // Ignore if combatant is already dead
                    if (!targetCombatantModel.IsAlive())
                    {
                        Logging.Log.Info("Specified target with combatant ID: " + targetCombatantModel.ID + " is dead, ignoring");
                        continue;
                    }

                    bool isAbilityFriendly = abilityItemModel.IsFriendly();

                    // Ignore if attempting to cast friendly ability on enemy
                    if (isAbilityFriendly && !allies.Contains(targetCombatantModel))
                    {
                        Logging.Log.Info("Can't apply friendly ability with ID " + abilityItemModel.ID + " to an enemy, ignoring.");
                        continue;
                    }

                    // Ignore if attempting to cast offensive ability on ally
                    if (!isAbilityFriendly && !enemies.Contains(targetCombatantModel))
                    {
                        Logging.Log.Info("Can't apply offensive ability with ID " + abilityItemModel.ID + " to an ally, ignoring.");
                        continue;
                    }

                    nextTargetCombatants.Add(targetCombatantModel);
                }
                else
                {
                    // Ignore if invalid combatant ID specified.
                    Logging.Log.Info("Invalid combatant ID specified:  " + combatantIDs[i] + ", ignoring.");
                    continue;
                }
            }
        }
コード例 #2
0
        private void onTurnElapsed()
        {
            // Update combatActionsCollection turn number
            combatActionsCollection.TurnNumber = TurnDispatcher.TurnNumber;
            Logging.Log.Info(">>>>>>> CoOpInstanceCombatController START TURN " + combatActionsCollection.TurnNumber);

            // If we're delaying, decrement delay turns and return
            if (delayStartTurns > 0)
            {
                Logging.Log.Info("CoOpInstanceCombatController delaying start for " + delayStartTurns + " turns...");
                delayStartTurns--;
                return;
            }

            // Clear all CombatActionModels for all combatants
            for (int c = 0; c < allCombatants.Count; c++)
            {
                combatActionsCollection[allCombatants[c].ID].Clear();
            }

            foreach (var kvp in teamIDToCombatantModel)
            {
                List <CombatantModel> teamCombatants = kvp.Value;
                for (int i = 0; i < teamCombatants.Count; i++)
                {
                    CombatantModel combatantModel = teamCombatants[i];
                    if (!combatantModel.IsAlive())
                    {
                        continue;
                    }

                    // Advance and apply regen duration abilities and keep track of CombatActionModels
                    combatantModel.RegenOverTimeAbilityDurations.AdvanceAbilityDurations(tickedRegenAbilities);
                    for (int r = 0; r < tickedRegenAbilities.Length && tickedRegenAbilities[r] != null; r++)
                    {
                        AbilityDurationData tickedRegenAbilityDuration = tickedRegenAbilities[r];
                        combatActionsCollection[combatantModel.ID].Add(
                            applyRegenAbilityEffectToCombatant(
                                tickedRegenAbilityDuration.AbilityEffectType, tickedRegenAbilityDuration.OriginAbilityID,
                                tickedRegenAbilityDuration.OwnerCombatantID, tickedRegenAbilityDuration.PerTickAmount,
                                combatantModel, tickedRegenAbilityDuration.NumTurnsRemaining, tickedRegenAbilityDuration.IsCrit));
                    }

                    // Clean up any expired regen abilities and keep track of CombatActionModels
                    combatantModel.RegenOverTimeAbilityDurations.RemoveAndResetExpired(expiredRegenAbilities);
                    for (int rx = 0; rx < expiredRegenAbilities.Length && expiredRegenAbilities[rx] != null; rx++)
                    {
                        combatActionsCollection[combatantModel.ID].Add(new CombatActionModel(expiredRegenAbilities[rx].OwnerCombatantID,
                                                                                             CombatActionType.ExpireAbility, expiredRegenAbilities[rx].OriginAbilityID, combatantModel.ID, 0, 0, false));
                    }

                    // Advance and apply damage duration abilities and keep track of CombatActionModels
                    combatantModel.DamageOverTimeAbilityDurations.AdvanceAbilityDurations(tickedDamageAbilities);
                    for (int d = 0; d < tickedDamageAbilities.Length && tickedDamageAbilities[d] != null; d++)
                    {
                        AbilityDurationData tickedDamageAbilityDuration = tickedDamageAbilities[d];
                        combatActionsCollection[combatantModel.ID].Add(
                            applyDamageAbilityEffectToCombatant(
                                tickedDamageAbilityDuration.AbilityEffectType, tickedDamageAbilityDuration.OriginAbilityID,
                                tickedDamageAbilityDuration.OwnerCombatantID, tickedDamageAbilityDuration.PerTickAmount,
                                combatantModel, tickedDamageAbilityDuration.NumTurnsRemaining, tickedDamageAbilityDuration.IsCrit));

                        // If target has died then append CombatActionModel and break;
                        if (!combatantModel.IsAlive())
                        {
                            combatActionsCollection[combatantModel.ID].Add(new CombatActionModel(tickedDamageAbilities[d].OwnerCombatantID,
                                                                                                 CombatActionType.Death, tickedDamageAbilities[d].OriginAbilityID, combatantModel.ID, 0, 0, false));
                            break;
                        }
                    }
                    if (!combatantModel.IsAlive())
                    {
                        continue;
                    }

                    // Clean up any expired damage abilities and keep track of CombatActionModels
                    combatantModel.DamageOverTimeAbilityDurations.RemoveAndResetExpired(expiredDamageAbilities);
                    for (int dx = 0; dx < expiredDamageAbilities.Length && expiredDamageAbilities[dx] != null; dx++)
                    {
                        combatActionsCollection[combatantModel.ID].Add(new CombatActionModel(expiredDamageAbilities[dx].OwnerCombatantID,
                                                                                             CombatActionType.ExpireAbility, expiredDamageAbilities[dx].OriginAbilityID, combatantModel.ID, 0, 0, false));
                    }

                    // Advance stat modifier duration abilities
                    // NOTE: no need to output per tick amount as stat modifiers only report their delta on application.
                    combatantModel.StatModifierAbilityDurations.AdvanceAbilityDurations(tickedStatAbilities);
                    // Expire and remove any stat modifier abilities and keep track of CombatActionModels
                    combatantModel.StatModifierAbilityDurations.RemoveAndResetExpired(expiredStatAbilities);
                    for (int sx = 0; sx < expiredStatAbilities.Length && expiredStatAbilities[sx] != null; sx++)
                    {
                        combatantModel.StatModifiersDeltas.RemoveModifier(
                            expiredStatAbilities[sx].PerTickAmount, expiredStatAbilities[sx].AbilityEffectType);
                        combatActionsCollection[combatantModel.ID].Add(
                            new CombatActionModel(expiredStatAbilities[sx].OwnerCombatantID, CombatActionType.ExpireAbility,
                                                  expiredStatAbilities[sx].OriginAbilityID, combatantModel.ID, 0, 0, false));
                    }

                    // Process Combatant's behaviour
                    processCombatantBehaviour(combatantModel);
                }
            }

            if (combatActionsCollection.HasEntries())
            {
                CombatTurnCompleted(combatActionsCollection);
            }
        }
コード例 #3
0
        public CombatActionModel GetCombatAction(out AbilityItemModel abilityItemModel, ref List <CombatantModel> targets)
        {
            if (!ownerCombatantModel.IsAlive())
            {
                throw new Exception("Dead CombatantModel can't perform actions.");
            }

            // If already casting.
            if (castingAbilityItemModel != null)
            {
                castingAbilityItemModel.NumCastTurnsElapsed++;
                abilityItemModel = castingAbilityItemModel;

                bool allTargetsDead = true;
                for (int a = 0; a < targetCombatantModels.Count; a++)
                {
                    if (targetCombatantModels[a].IsAlive())
                    {
                        allTargetsDead = false;
                        break;
                    }
                }

                // If all targets died during cast, then cancel cast
                if (allTargetsDead)
                {
                    castingAbilityItemModel.NumCastTurnsElapsed = 0;
                    castingAbilityItemModel = null;
                    return(new CombatActionModel(
                               ownerCombatantModel.ID, CombatActionType.CancelCastingAbility, abilityItemModel.ID, -1, 0, 0, false));
                }

                // Determine number of total cast turns considering cast time stat modifiers
                int modifiedTotalCastTurns = ownerCombatantModel.GetStatModifiedAbilityTotalCastTurns(castingAbilityIndex);

                // Handle cast completion (>= insteand of == as expired cast time debuffs can cause user to cast beyond the unmodified amount)
                if (castingAbilityItemModel.NumCastTurnsElapsed >= modifiedTotalCastTurns)
                {
                    // Reset ability cast turns and clear reference
                    castingAbilityItemModel.NumCastTurnsElapsed = 0;
                    castingAbilityItemModel = null;

                    // Output alive targets only.
                    for (int t = 0; t < targetCombatantModels.Count; t++)
                    {
                        if (targetCombatantModels[t].IsAlive())
                        {
                            targets.Add(targetCombatantModels[t]);
                        }
                    }

                    int abilityDurationTurnsRemaining = abilityItemModel.AbilityDurationType == AbilityDurationType.Immediate ? 0 :
                                                        abilityItemModel.AbilityDurationData.NumTurnsRemaining;

                    // -1 target id signifies multiple targets.
                    return(new CombatActionModel(
                               ownerCombatantModel.ID, CombatActionType.ApplyAbility, abilityItemModel.ID,
                               targets.Count == 1 ? targets[0].ID : -1, 0, abilityDurationTurnsRemaining, false));
                }

                // Still casting, so perform wait.
                return(new CombatActionModel(ownerCombatantModel.ID, CombatActionType.Wait, -1, -1, 0, 0, false));
            }

            // Determine which abilities are available (not on cooldown)
            bool abilityAvailable = false;

            for (int i = 0; i < ownerCombatantModel.AbilityItemModels.Length; i++)
            {
                if (ownerCombatantModel.GetStatModifiedAbilityCoolDownTurnsRemaining(i) > 0)
                {
                    availableAbilities[i] = null;
                }
                else
                {
                    abilityAvailable      = true;
                    availableAbilities[i] = ownerCombatantModel.AbilityItemModels[i];
                }
            }

            // If all abilities on cooldown, return wait.
            if (!abilityAvailable)
            {
                abilityItemModel = null;
                return(new CombatActionModel(ownerCombatantModel.ID, CombatActionType.Wait, -1, -1, 0, 0, false));
            }

            targetCombatantModels.Clear();
            castingAbilityIndex = -1;
            determineAbilityAndTargets(availableAbilities, ref castingAbilityItemModel, ref castingAbilityIndex, ref targetCombatantModels);
            abilityItemModel = castingAbilityItemModel;

            // If we were unable to determine an AbilityItemModel or find valid targets this turn, perform wait.
            if (castingAbilityItemModel == null || targetCombatantModels.Count == 0)
            {
                return(new CombatActionModel(ownerCombatantModel.ID, CombatActionType.Wait, -1, -1, 0, 0, false));
            }

            // Start casting
            return(new CombatActionModel(ownerCombatantModel.ID, CombatActionType.StartCastingAbility, abilityItemModel.ID,
                                         targetCombatantModels.Count == 1 ? targetCombatantModels[0].ID : -1, 0, abilityItemModel.CastTurns, false));
        }