示例#1
0
        protected override void copyExtendedProperties(ItemModel sourceItemModel)
        {
            EquipmentItemModel equipmentItemModel = sourceItemModel as EquipmentItemModel;

            if (equipmentItemModel == null)
            {
                throw new InvalidCastException("Invalid type.");
            }
            EquipmentType    = equipmentItemModel.EquipmentType;
            MaxHealthBoost   = equipmentItemModel.MaxHealthBoost;
            HealthRegenBoost = equipmentItemModel.HealthRegenBoost;
            MaxManaBoost     = equipmentItemModel.MaxManaBoost;
            ArmorBoost       = equipmentItemModel.ArmorBoost;
            SpellResistBoost = equipmentItemModel.SpellResistBoost;
            MeleeDamageBoost = equipmentItemModel.MeleeDamageBoost;
            MeleeCritBoost   = equipmentItemModel.MeleeCritBoost;
            SpellDamageBoost = equipmentItemModel.SpellDamageBoost;
            SpellCritBoost   = equipmentItemModel.SpellCritBoost;

            if (equipmentItemModel.AbilityItemModels == null)
            {
                AbilityItemModels = null;
            }
            else
            {
                AbilityItemModels = new AbilityItemModel[equipmentItemModel.AbilityItemModels.Length];
                for (int i = 0; i < AbilityItemModels.Length; i++)
                {
                    AbilityItemModels[i] = new AbilityItemModel();
                    AbilityItemModels[i].CopyFrom(equipmentItemModel.AbilityItemModels[i], true);
                }
            }
        }
        protected override void determineAbilityAndTargets(AbilityItemModel[] availableAbilityItemModels,
                                                           ref AbilityItemModel chosenAbilityItemModel, ref int chosenAbilityIndex, ref List <CombatantModel> chosenTargets)
        {
            chosenAbilityItemModel = null;
            for (int i = 0; i < availableAbilityItemModels.Length; i++)
            {
                if (availableAbilityItemModels[i] == null)
                {
                    continue;
                }

                if (availableAbilityItemModels[i].AbilityTargetType == AbilityTargetType.EnemySingle)
                {
                    chosenAbilityItemModel = availableAbilityItemModels[i];
                    chosenAbilityIndex     = i;
                }
            }

            if (chosenAbilityItemModel != null)
            {
                for (int i = 0; i < enemies.Count; i++)
                {
                    if (enemies[i].IsAlive())
                    {
                        chosenTargets.Add(enemies[0]);
                        return;
                    }
                }
            }
        }
示例#3
0
        private AbilityItemModel[] getRandomNPCAbilities(int numAbilities, int level)
        {
            List <AbilityItemModel> randomAbilitiesList = new List <AbilityItemModel>();
            List <ItemModel>        allAbilities        = catalogModel.GetAllItemsOfType <AbilityItemModel>();

            for (int i = 0; i < numAbilities; i++)
            {
                AbilityItemModel randomAbility = allAbilities[RandomGen.GetIntRange(0, allAbilities.Count - 1)] as AbilityItemModel;
                if (!randomAbilitiesList.Contains(randomAbility))
                {
                    randomAbilitiesList.Add(randomAbility);
                }
            }

            AbilityItemModel[] randomAbilitiesArray = new AbilityItemModel[randomAbilitiesList.Count];
            for (int j = 0; j < randomAbilitiesArray.Length; j++)
            {
                AbilityItemModel clone = new AbilityItemModel();
                clone.CopyFrom(randomAbilitiesList[j], false);
                clone.Level_ZeroBased   = level;
                randomAbilitiesArray[j] = clone;
            }

            return(randomAbilitiesArray);
        }
        /// <summary>
        /// Merges equippedAbilities with any abilities provided by specified equipment.
        /// </summary>
        /// <param name="equippedAbilities">Abilities the CombatantModel has equipped</param>
        /// <param name="equipmentItemModels">Any equipment the CombatantModel is wearing</param>
        /// <returns></returns>
        private static AbilityItemModel[] mergeAbilities(AbilityItemModel[] equippedAbilities, EquipmentItemModel[] equipmentItemModels)
        {
            int equippedAbilitiesCount  = equippedAbilities == null ? 0 : equippedAbilities.Length;
            int equipmentAbilitiesCount = 0;

            for (int i = 0; i < equipmentItemModels.Length; i++)
            {
                if (equipmentItemModels[i].AbilityItemModels != null)
                {
                    equipmentAbilitiesCount += equipmentItemModels[i].AbilityItemModels.Length;
                }
            }

            AbilityItemModel[] mergedAbilities = new AbilityItemModel[equippedAbilitiesCount + equipmentAbilitiesCount];
            int mergeIndex = 0;

            for (mergeIndex = 0; mergeIndex < equippedAbilitiesCount; mergeIndex++)
            {
                mergedAbilities[mergeIndex] = equippedAbilities[mergeIndex];
            }
            mergeIndex++;

            for (int e = 0; e < equipmentItemModels.Length; e++)
            {
                if (equipmentItemModels[e].AbilityItemModels != null)
                {
                    for (int ea = 0; ea < equipmentItemModels[e].AbilityItemModels.Length; ea++)
                    {
                        mergedAbilities[mergeIndex++] = equipmentItemModels[e].AbilityItemModels[ea];
                    }
                }
            }

            return(mergedAbilities);
        }
        public int GetStatModifiedAbilityTotalCastTurns(int abilityIndex)
        {
            AbilityItemModel abilityItemModel = AbilityItemModels[abilityIndex];
            float            deltaRatio       = 1f + (float)StatModifiersDeltas.AbilityCastTurnsPercentModifierDelta * .01f;
            int modifiedCastTurns             = (int)(((float)abilityItemModel.CastTurns) * deltaRatio);

            return(modifiedCastTurns < 1 ? 1 : modifiedCastTurns);
        }
        private static AbilityItemModel parseAbilityItemModel(string customData, IJsonParser jsonParser)
        {
            AbilityItemModel    abilityItemModel    = new AbilityItemModel();
            AbilityItemModelRaw abilityItemModelRaw = jsonParser.DeserializeObject <AbilityItemModelRaw>(customData);

            abilityItemModelRaw.ApplyToAbilityItemModel(abilityItemModel, jsonParser);
            return(abilityItemModel);
        }
示例#7
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;
                }
            }
        }
 public void ApplyToDurationData(AbilityDurationData abilityDurationData, AbilityItemModel parentAbility)
 {
     abilityDurationData.OriginAbilityID   = parentAbility.ID;
     abilityDurationData.PerTickAmount     = int.Parse(PerTickAmount);
     abilityDurationData.TurnsPerTick      = int.Parse(TurnsPerTick);
     abilityDurationData.MaxTicks          = int.Parse(MaxTicks);
     abilityDurationData.AbilityEffectType = parentAbility.AbilityEffectType;
     abilityDurationData.AbilityTargetType = parentAbility.AbilityTargetType;
 }
示例#9
0
        private void onPlayerCombatAction(OperationRequest operationRequest, IClientConnection clientConnection, SendParameters sendParameters)
        {
            PlayerCombatActionRequest playerCombatActionRequest = PlayerCombatActionRequest.FromOperationRequest(operationRequest);

            ServerPlayerModel serverPlayerModel = clientConnectionToServerPlayerModel[clientConnection];
            AbilityItemModel  abilityItemModel  = serverPlayerModel.CombatantModel.GetAbilityByID(playerCombatActionRequest.AbilityID);

            clientConnectionToServerPlayerModel[clientConnection].PlayerCombatBehaviour.QueueAbility(
                abilityItemModel, playerCombatActionRequest.TargetCombatantIDs);
        }
示例#10
0
        public int GetStatModifiedAbilityCoolDownTurnsRemaining(int abilityIndex)
        {
            AbilityItemModel abilityItemModel = AbilityItemModels[abilityIndex];

            float deltaRatio         = 1f + (float)StatModifiersDeltas.AbilityCoolDownTurnsPercentModifier * 0.01f;
            int   totalCoolDownTurns = (int)(((float)abilityItemModel.CoolDownTurns) * deltaRatio);
            int   turnsRemaining     = totalCoolDownTurns - abilityItemModel.CoolDownTurnsElapsed;

            return(turnsRemaining < 0 ? 0 : turnsRemaining);
        }
示例#11
0
        public void Clear()
        {
            allies.Clear();
            enemies.Clear();
            combatantIDsToModels.Clear();
            if (castingAbilityItemModel != null)
            {
                castingAbilityItemModel.NumCastTurnsElapsed = 0;
                if (castingAbilityItemModel.AbilityDurationData != null)
                {
                    castingAbilityItemModel.AbilityDurationData.NumTurnsElapsed = 0;
                }
                castingAbilityItemModel = null;
            }

            targetCombatantModels.Clear();
            ownerCombatantModel = null;
        }
示例#12
0
        public void ApplyToAbilityItemModel(AbilityItemModel abilityItemModel, IJsonParser jsonParser)
        {
            abilityItemModel.AbilityEffectType   = (AbilityEffectType)int.Parse(AbilityEffectType);
            abilityItemModel.AbilityTargetType   = (AbilityTargetType)int.Parse(AbilityTargetType);
            abilityItemModel.AbilityDurationType = (AbilityDurationType)int.Parse(AbilityDurationType);
            abilityItemModel.CastTurns           = int.Parse(CastTurns);
            abilityItemModel.CoolDownTurns       = int.Parse(CoolDownTurns);
            abilityItemModel.ImmediateAmout      = int.Parse(ImmediateAmout);
            abilityItemModel.IsSpellBased        = int.Parse(IsSpellBased) == 1;

            AbilityDurationDataRaw abilityDurationDataRaw = string.IsNullOrEmpty(AbilityDurationData) ? null :
                                                            jsonParser.DeserializeObject <AbilityDurationDataRaw>(AbilityDurationData);

            if (abilityDurationDataRaw != null)
            {
                abilityItemModel.AbilityDurationData = new AbilityDurationData();
                abilityDurationDataRaw.ApplyToDurationData(abilityItemModel.AbilityDurationData, abilityItemModel);
            }
        }
示例#13
0
        protected override void determineAbilityAndTargets(AbilityItemModel[] availableAbilityItemModels,
                                                           ref AbilityItemModel chosenAbilityItemModel, ref int chosenAbilityIndex, ref List <CombatantModel> chosenTargets)
        {
            if (nextAbilityItemModel == null)
            {
                return;
            }

            chosenAbilityItemModel = nextAbilityItemModel;
            nextAbilityItemModel   = null;

            bool isAbilityValid = false;

            for (int a = 0; a < availableAbilityItemModels.Length; a++)
            {
                if (availableAbilityItemModels[a] == null)
                {
                    continue;
                }

                if (chosenAbilityItemModel.ID == availableAbilityItemModels[a].ID)
                {
                    isAbilityValid     = true;
                    chosenAbilityIndex = a;
                    break;
                }
            }

            if (!isAbilityValid)
            {
                Logging.Log.Info("Player specified invalid ID.  CombatantID: " + ownerCombatantModel.ID + ", AbilityID: " + chosenAbilityItemModel.ID);
                chosenAbilityItemModel = null;
                return;
            }

            for (int i = 0; i < nextTargetCombatants.Count; i++)
            {
                chosenTargets.Add(nextTargetCombatants[i]);
            }
            nextTargetCombatants.Clear();
        }
示例#14
0
        public void FromObjectArray(object[] properties)
        {
            int i = 0;

            ID                        = (int)properties[i++];
            Level                     = (int)properties[i++];
            CurrentHealth             = (int)properties[i++];
            MaxHealth                 = (int)properties[i++];
            HealthRegenPerTurn        = (int)properties[i++];
            CurrentMana               = (int)properties[i++];
            MaxMana                   = (int)properties[i++];
            ManaRegenPerTurn          = (int)properties[i++];
            Armor                     = (int)properties[i++];
            SpellResist               = (int)properties[i++];
            MeleeDamage               = (int)properties[i++];
            MeleeCritChanceNormalized = (float)properties[i++];
            SpellDamage               = (int)properties[i++];
            SpellCritChanceNormalized = (float)properties[i++];
            TeamID                    = (int)properties[i++];

            object[] statModifierAbDurs = properties[i++] as object[];
            StatModifierAbilityDurations.FromObjectArray(statModifierAbDurs);

            object[] regenOverTimeAbDurs = properties[i++] as object[];
            RegenOverTimeAbilityDurations.FromObjectArray(regenOverTimeAbDurs);

            object[] damageOverTimeAbDurs = properties[i++] as object[];
            DamageOverTimeAbilityDurations.FromObjectArray(damageOverTimeAbDurs);

            object[]           serializedAbilities = properties[i++] as object[];
            AbilityItemModel[] parsedAbilities     = new AbilityItemModel[serializedAbilities.Length];
            for (int j = 0; j < parsedAbilities.Length; j++)
            {
                parsedAbilities[j] = new AbilityItemModel();
                parsedAbilities[j].FromObjectArray(serializedAbilities[j] as object[]);
            }
            AbilityItemModels = parsedAbilities;
        }
示例#15
0
        protected override void getPlayerModelByID(PlayerAuthenticationModel playerAuthModel, PlayerCombatBehaviourBase playerCombatBehaviourBase,
                                                   Action <ServerPlayerModel> onSuccessHandler, Action onFailureHandler)
        {
            if (playerAuthModel.UserID == "testFail")
            {
                onFailureHandler();
                return;
            }

            ServerPlayerModel playerModel = new ServerPlayerModel(playerCombatBehaviourBase);

            playerModel.PlayerID = playerAuthModel.UserID;
            playerModel.Name     = playerAuthModel.UserName;

            AbilityItemModel[] mockAbilities = new AbilityItemModel[]
            {
                MockCatalogService.FIREBALL_ABILITY
            };

            playerModel.CombatantModel = new CombatantModel(1, 100, 1, 100, 1, 1, 1, 10, 0f, 10, 0f, PlayerModel.DEFAULT_TEAM_ID, mockAbilities);

            Task.Delay(100).ContinueWith(t => { onSuccessHandler(playerModel); });
        }
        private void parseEquipmentAndCombatantModel(ServerPlayerModel serverPlayerModel)
        {
            if (catalogModel == null)
            {
                catalogModel = DIContainer.GetInstanceByContextID <CatalogModel>(InstanceServerApplication.CONTEXT_ID);
            }

            // Parse equipment
            parseItemModel <EquipmentItemModel>(ref serverPlayerModel.EquippedWeaponItemModel, ref serverPlayerModel.EquippedWeapon);
            parseItemModel <EquipmentItemModel>(ref serverPlayerModel.EquippedOffHandItemModel, ref serverPlayerModel.EquippedOffHand);
            parseItemModel <EquipmentItemModel>(ref serverPlayerModel.EquippedArmorItemModel, ref serverPlayerModel.EquippedArmor);
            List <EquipmentItemModel> allEquipment = new List <EquipmentItemModel>();

            if (serverPlayerModel.EquippedWeaponItemModel != null)
            {
                allEquipment.Add(serverPlayerModel.EquippedWeaponItemModel);
            }
            if (serverPlayerModel.EquippedOffHandItemModel != null)
            {
                allEquipment.Add(serverPlayerModel.EquippedOffHandItemModel);
            }
            if (serverPlayerModel.EquippedArmorItemModel != null)
            {
                allEquipment.Add(serverPlayerModel.EquippedArmorItemModel);
            }

            // Player must have at least 1 Ability
            AbilityItemModel[] equippedAbilityItemModels = new AbilityItemModel[serverPlayerModel.EquippedAbilities.Length];
            for (int i = 0; i < equippedAbilityItemModels.Length; i++)
            {
                parseItemModel <AbilityItemModel>(ref equippedAbilityItemModels[i], ref serverPlayerModel.EquippedAbilities[i]);
            }

            serverPlayerModel.CombatantModel =
                BuildCombatantSCMD.Execute(serverPlayerModel.Level_ZeroBased, PlayerModel.DEFAULT_TEAM_ID, equippedAbilityItemModels,
                                           RarityType.Common, allEquipment.Count == 0 ? null : allEquipment.ToArray());
        }
        private void processCombatantBehaviour(CombatantModel combatantModel)
        {
            // Advance all ability cooldowns
            for (int i = 0; i < combatantModel.AbilityItemModels.Length; i++)
            {
                combatantModel.AbilityItemModels[i].CoolDownTurnsElapsed++;
            }

            AbilityItemModel combatAbility = null;

            targets.Clear();
            CombatActionModel combatActionModel = combatantModelToBehaviour[combatantModel].GetCombatAction(out combatAbility, ref targets);

            // If waiting, return
            if (combatActionModel.CombatActionType == CombatActionType.Wait)
            {
                return;
            }

            // if starting or canceling cast, append CombatActionModel and return
            if (combatActionModel.CombatActionType == CombatActionType.StartCastingAbility ||
                combatActionModel.CombatActionType == CombatActionType.CancelCastingAbility)
            {
                combatActionsCollection[combatantModel.ID].Add(combatActionModel);
                return;
            }

            if (combatActionModel.CombatActionType != CombatActionType.ApplyAbility)
            {
                throw new Exception("Unexpected CombatActionType: " + combatActionModel.CombatActionType.ToString());
            }

            // Append cast completion CombatActionModel
            combatActionsCollection[combatantModel.ID].Add(combatActionModel);

            // Restart ability cooldown
            combatAbility.CoolDownTurnsElapsed = 0;

            // Apply ability to targets and keep track of CombatActionModels
            bool isAbilityFriendly = combatAbility.IsFriendly();

            for (int t = 0; t < targets.Count; t++)
            {
                CombatActionModel combatActionOnTarget;

                if (combatAbility.AbilityDurationType == AbilityDurationType.Immediate) // Handle ability with IMMEDIATE effect.
                {
                    bool isCrit;
                    int  immediateAmountWithStatMods = getAbilityAmountWithStatMods(combatantModel, combatAbility.ImmediateAmout,
                                                                                    combatAbility.IsSpellBased, out isCrit);

                    if (isAbilityFriendly)
                    {
                        combatActionOnTarget = applyRegenAbilityEffectToCombatant(combatAbility.AbilityEffectType, combatAbility.ID, combatantModel.ID,
                                                                                  immediateAmountWithStatMods, targets[t], 0, isCrit);
                    }
                    else
                    {
                        combatActionOnTarget = applyDamageAbilityEffectToCombatant(combatAbility.AbilityEffectType, combatAbility.ID, combatantModel.ID,
                                                                                   immediateAmountWithStatMods, targets[t], 0, isCrit);
                    }
                }
                else // Handle ability with DURATION effect
                {
                    AbilityDurationData abilityDurationDataClone = combatAbility.AbilityDurationData.Clone(true);

                    if (combatAbility.IsStatModifier())
                    {
                        // Stat modifiers don't consider other stat modifiers. Ex: (if target has spell effect/damage debuff from
                        // another modifier, we dont want another spell dmg debuff to cause exponential damage).
                        targets[t].StatModifiersDeltas.AddModifier(abilityDurationDataClone.PerTickAmount, abilityDurationDataClone.AbilityEffectType);
                        targets[t].StatModifierAbilityDurations.Add(abilityDurationDataClone);
                        CombatActionType combatActionType = isAbilityFriendly ? CombatActionType.StatIncreasedByDurationAbility : CombatActionType.StatDecreasedByDurationAbility;
                        combatActionOnTarget = new CombatActionModel(
                            combatantModel.ID, combatActionType, combatAbility.ID, targets[t].ID,
                            abilityDurationDataClone.PerTickAmount, abilityDurationDataClone.NumTurnsRemaining, false);
                    }
                    else
                    {
                        // Update clone's per tick value to consider the caster's spell/melee buffs/debuffs
                        bool isCrit;
                        int  perTickAmountWithStatMods = getAbilityAmountWithStatMods(
                            combatantModel, abilityDurationDataClone.PerTickAmount, combatAbility.IsSpellBased, out isCrit);
                        abilityDurationDataClone.PerTickAmount = perTickAmountWithStatMods;
                        abilityDurationDataClone.IsCrit        = isCrit;

                        AbilityDurationDataCollection abilityDurationCollection = isAbilityFriendly ?
                                                                                  targets[t].RegenOverTimeAbilityDurations : targets[t].DamageOverTimeAbilityDurations;
                        abilityDurationCollection.Add(abilityDurationDataClone);
                        combatActionOnTarget = new CombatActionModel(
                            combatantModel.ID, CombatActionType.AffectedByDurationAbility, combatAbility.ID, targets[t].ID,
                            0, abilityDurationDataClone.NumTurnsRemaining, isCrit);
                    }
                }

                combatActionsCollection[targets[t].ID].Add(combatActionOnTarget);

                // If target has died then append death CombatActionModel
                if (!targets[t].IsAlive())
                {
                    combatActionsCollection[targets[t].ID].Add(
                        new CombatActionModel(combatantModel.ID, CombatActionType.Death, combatAbility.ID, targets[t].ID, 0, 0, false));
                }
            }
        }
示例#18
0
 public override void QueueAbility(AbilityItemModel abilityItemModel, int[] combatantIDs)
 {
     throw new NotImplementedException();
 }
示例#19
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));
        }
示例#20
0
 protected abstract void determineAbilityAndTargets(AbilityItemModel[] availableAbilityItemModels,
                                                    ref AbilityItemModel chosenAbilityItemModel, ref int chosenAbilityIndex, ref List <CombatantModel> chosenTargets);
 public abstract void QueueAbility(AbilityItemModel abilityItemModel, int[] combatantIDs);