예제 #1
0
        public void FromObjectArray(object[] properties)
        {
            int i = 0;

            PlayerID    = (string)properties[i++];
            Name        = (string)properties[i++];
            IsRejoining = bool.Parse(properties[i++] as string);

            object[] serializedWeapon = properties[i++] as object[];
            if (serializedWeapon.Length > 0)
            {
                EquippedWeaponItemModel = new EquipmentItemModel();
                EquippedWeaponItemModel.FromObjectArray(serializedWeapon);
            }

            object[] serializedOffhand = properties[i++] as object[];
            if (serializedOffhand.Length > 0)
            {
                EquippedOffHandItemModel = new EquipmentItemModel();
                EquippedOffHandItemModel.FromObjectArray(serializedOffhand);
            }

            object[] serializedArmor = properties[i++] as object[];
            if (serializedArmor.Length > 0)
            {
                EquippedArmorItemModel = new EquipmentItemModel();
                EquippedArmorItemModel.FromObjectArray(serializedArmor);
            }

            CombatantModel = new CombatantModel();
            CombatantModel.FromObjectArray(properties[i] as object[]);
        }
예제 #2
0
        public void AddOtherCombatant(CombatantModel otherCombatantModel)
        {
            if (ownerCombatantModel == null)
            {
                throw new Exception("Owner CombatantModel must be set before specifying others.");
            }

            if (combatantIDsToModels.ContainsKey(otherCombatantModel.ID))
            {
                Log.Warning("Other Combatant with ID: " + otherCombatantModel.ID + " is already being considered.");
                return;
            }

            if (otherCombatantModel.ID == ownerCombatantModel.ID)
            {
                Log.Warning("Other Combatant with ID: " + otherCombatantModel.ID + " can't be owner.");
                return;
            }

            if (otherCombatantModel.TeamID == ownerCombatantModel.TeamID)
            {
                allies.Add(otherCombatantModel);
            }
            else
            {
                enemies.Add(otherCombatantModel);
            }
            combatantIDsToModels.Add(otherCombatantModel.ID, otherCombatantModel);
        }
예제 #3
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;
                }
            }
        }
예제 #4
0
 public NpcModel(string id, string name, NpcRole npcRole, NpcRace npcRace, NpcSize npcSize, RarityType rarityType,
                 CombatantModel combatantModel, string[] alwaysDroppedItemIDs = null)
 {
     this.ID                   = id;
     this.Name                 = name;
     this.NpcRole              = npcRole;
     this.NpcRace              = npcRace;
     this.NpcSize              = npcSize;
     this.RarityType           = rarityType;
     this.CombatantModel       = combatantModel;
     this.AlwaysDroppedItemIDs = alwaysDroppedItemIDs;
 }
 /// <summary>
 /// Applies any boosts from equipment to a CombatantModel's existing stats.
 /// </summary>
 /// <param name="combatantModel">The CombatantModel</param>
 /// <param name="equipmentItemModels">Any equipment being worn.</param>
 private static void boostCombatantStatsFromEquipment(CombatantModel combatantModel, EquipmentItemModel[] equipmentItemModels)
 {
     for (int i = 0; i < equipmentItemModels.Length; i++)
     {
         EquipmentItemModel equipmentItemModel = equipmentItemModels[i];
         combatantModel.MaxHealth          += equipmentItemModel.MaxHealthBoost;
         combatantModel.HealthRegenPerTurn += equipmentItemModel.HealthRegenBoost;
         combatantModel.MaxMana            += equipmentItemModel.MaxManaBoost;
         combatantModel.ManaRegenPerTurn   += equipmentItemModel.ManaRegenBoost;
         combatantModel.Armor       += equipmentItemModel.ArmorBoost;
         combatantModel.SpellResist += equipmentItemModel.SpellResistBoost;
         combatantModel.MeleeDamage += equipmentItemModel.MeleeDamageBoost;
         combatantModel.MeleeCritChanceNormalized += equipmentItemModel.MeleeCritBoost;
         combatantModel.SpellDamage += equipmentItemModel.SpellDamageBoost;
         combatantModel.SpellCritChanceNormalized += equipmentItemModel.SpellCritBoost;
     }
 }
예제 #6
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;
        }
        /// <summary>
        /// Builds a CombatantModel from the specified core stats.
        /// </summary>
        /// <param name="level">Combatant's level</param>
        /// <param name="teamID">Combatant's team ID</param>
        /// <param name="equippedAbilities">Combatant's main abilities</param>
        /// <param name="rarityModifier">Combatant's rarity (Common if Player). Higher rarity increases stats.</param>
        /// <param name="equipmentItemModels">Any equipment being worn</param>
        /// <returns></returns>
        public static CombatantModel Execute(int level, int teamID, AbilityItemModel[] equippedAbilities,
                                             RarityType rarityModifier = RarityType.Common, EquipmentItemModel[] equipmentItemModels = null)
        {
            // Make sure equipment stats have been built before considering them in CombatantModel creation.
            if (equipmentItemModels != null)
            {
                for (int e = 0; e < equipmentItemModels.Length; e++)
                {
                    if (!equipmentItemModels[e].HasBuiltStatsFromLevel)
                    {
                        throw new Exception("Equipment stats not built (invalid level): " + equipmentItemModels[e].ID + ", " + equipmentItemModels[e].Name);
                    }
                }
            }

            // Make sure ability stats have been built before assigning them to CombatantModel
            for (int i = 0; i < equippedAbilities.Length; i++)
            {
                if (!equippedAbilities[i].HasBuiltStatsFromLevel)
                {
                    throw new Exception("Ability " + equippedAbilities[i].ID + "(" + equippedAbilities[i].Name + ")" + " stats not built (invalid level)");
                }
            }

            // Build combatant model considering level and rarity for core stats.
            CombatantModel combatantModel = buildCombatantModel(rarityModifier, level, teamID);

            if (equipmentItemModels != null)
            {
                // If the combatant is wearing equipment, boost its stats and merge its existing abilities with
                // any provided by the equipment.
                boostCombatantStatsFromEquipment(combatantModel, equipmentItemModels);
                combatantModel.AbilityItemModels = mergeAbilities(equippedAbilities, equipmentItemModels);
            }
            else
            {
                // Otherwise simply assign the combatant's abilities to the ones that are specified.
                combatantModel.AbilityItemModels = equippedAbilities;
            }

            return(combatantModel);
        }
예제 #8
0
        public void FromObjectArray(object[] properties)
        {
            int i = 0;

            ID             = properties[i++] as string;
            Name           = properties[i++] as string;
            NpcRole        = (NpcRole)properties[i++];
            NpcRace        = (NpcRace)properties[i++];
            NpcSize        = (NpcSize)properties[i++];
            RarityType     = (RarityType)properties[i++];
            CombatantModel = new CombatantModel();
            CombatantModel.FromObjectArray(properties[i++] as object[]);

            object[] alwaysDroppedItemIdObjects = properties[i++] as object[];
            AlwaysDroppedItemIDs = new string[alwaysDroppedItemIdObjects.Length];
            for (int j = 0; j < AlwaysDroppedItemIDs.Length; j++)
            {
                AlwaysDroppedItemIDs[j] = alwaysDroppedItemIdObjects[j] as string;
            }
        }
예제 #9
0
        private ServerNpcModel buildRandomNPC(int npcLevel, int npcTeamID, RarityType minRarityType, RarityType maxRarityType)
        {
            RarityType npcRarity = RarityConstants.GetRandomRarityRange(minRarityType, maxRarityType);
            NpcRole    npcRole   = (NpcRole)RandomGen.GetIntRange(0, NumNpcRoles - 1);
            NpcRace    npcRace   = (NpcRace)RandomGen.GetIntRange(0, NumNpcRaces - 1);
            NpcSize    npcSize   = (NpcSize)RandomGen.GetIntRange(0, NumNpcSizes - 1);

            // TODO: determine better naming scheme. For now just join Size+Race+Role;
            string npcName = npcSize.ToString() + " " + npcRace.ToString() + " " + npcRole.ToString();

            // Build combatant model
            AbilityItemModel[] randomAbilities = getRandomNPCAbilities((int)npcRarity + 1, npcLevel);
            CombatantModel     combatantModel  = BuildCombatantSCMD.Execute(npcLevel, npcTeamID, randomAbilities, npcRarity);

            // TODO: determine behaviour based on role. For now use default
            CombatBehaviourBase combatBehaviour = new AbilityCycleBehaviour();

            ServerNpcModel serverNpcModel = new ServerNpcModel(combatBehaviour, "", npcName, npcRole, npcRace, npcSize, npcRarity, combatantModel);

            DetermineNPCDropTableSCMD.Execute(serverNpcModel);
            return(serverNpcModel);
        }
예제 #10
0
        public static void Execute(List <ServerPlayerModel> eventReceivers, ZoneModel zoneModel, int turnNumber)
        {
            CombatantModel[] allCombatantModels = new CombatantModel[eventReceivers.Count + zoneModel.EnemyNpcModels.Length];
            for (int e = 0; e < eventReceivers.Count; e++)
            {
                allCombatantModels[e] = eventReceivers[e].CombatantModel;
            }
            for (int n = 0; n < zoneModel.EnemyNpcModels.Length; n++)
            {
                allCombatantModels[eventReceivers.Count + n] = zoneModel.EnemyNpcModels[n].CombatantModel;
            }

            ZoneStartedEvent zoneStartedEvent = new ZoneStartedEvent(zoneModel.ID, turnNumber, allCombatantModels);

            for (int i = 0; i < eventReceivers.Count; i++)
            {
                if (eventReceivers[i].ClientConnection.Connected)
                {
                    eventReceivers[i].ClientConnection.SendEvent(zoneStartedEvent.EventData, zoneStartedEvent.SendParameters);
                }
            }
        }
        public void AddCombatantWithBehaviour(CombatantModel combatantModel, CombatBehaviourBase combatBehaviour)
        {
            combatBehaviour.Init(combatantModel);
            // Update existing combatants to consider the newly added one.
            // And update new one with existing combatant
            for (int i = 0; i < allCombatants.Count; i++)
            {
                combatantModelToBehaviour[allCombatants[i]].AddOtherCombatant(combatantModel);
                combatBehaviour.AddOtherCombatant(allCombatants[i]);
            }

            List <CombatantModel> teamCombatantModels = null;

            if (!teamIDToCombatantModel.TryGetValue(combatantModel.TeamID, out teamCombatantModels))
            {
                teamCombatantModels = new List <CombatantModel>();
                teamIDToCombatantModel.Add(combatantModel.TeamID, teamCombatantModels);
            }
            teamCombatantModels.Add(combatantModel);
            allCombatants.Add(combatantModel);
            combatActionsCollection.Add(combatantModel.ID, new List <CombatActionModel>());
            combatantModelToBehaviour.Add(combatantModel, combatBehaviour);
        }
        private int getAbilityAmountWithStatMods(CombatantModel combatantModel, int abilityAmount, bool isAbilitySpellBased, out bool isCrit)
        {
            StatModifiersDeltas statModifiersDeltas = combatantModel.StatModifiersDeltas;
            int moddedAmount = abilityAmount;

            isCrit = false;
            if (isAbilitySpellBased)
            {
                moddedAmount += statModifiersDeltas.SpellDamageStatModifiersDelta;
                isCrit        = RandomGen.NextNormalizedFloat() < (combatantModel.SpellCritChanceNormalized + statModifiersDeltas.SpellCritStatModifiersDelta);
            }
            else
            {
                moddedAmount += statModifiersDeltas.MeleeDamageStatModifiersDelta;
                isCrit        = RandomGen.NextNormalizedFloat() < (combatantModel.MeleeCritChanceNormalized + statModifiersDeltas.MeleeDamageStatModifiersDelta);
            }

            if (isCrit)
            {
                moddedAmount = (int)((float)moddedAmount * CRITICAL_STRIKE_MULTIPLIER);
            }

            return(moddedAmount);
        }
 public bool ContainsCombatant(CombatantModel combatantModel)
 {
     return(combatantModelToBehaviour.ContainsKey(combatantModel));
 }
        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));
                }
            }
        }
        private CombatActionModel applyDamageAbilityEffectToCombatant(AbilityEffectType abilityEffectType, int abilityID,
                                                                      int abilityCombatantOwnerID, int abilityAmount, CombatantModel combatantModel, int turnsRemaining, bool isCrit)
        {
            StatModifiersDeltas statModifiersDeltas = combatantModel.StatModifiersDeltas;
            CombatActionType    combatActionType    = CombatActionType.None;
            int damageDeltaWithStatModifiers        = 0;

            switch (abilityEffectType)
            {
            case AbilityEffectType.MeleeDamage:
                damageDeltaWithStatModifiers = getDamageDeltaWithStatMod(statModifiersDeltas.ArmorStatModifiersDelta, abilityAmount);
                combatActionType             = CombatActionType.ReceiveMeleeDamage;
                break;

            case AbilityEffectType.SpellDamage:
                damageDeltaWithStatModifiers = getDamageDeltaWithStatMod(statModifiersDeltas.SpellResistStatModifiersDelta, abilityAmount);
                combatActionType             = CombatActionType.ReceiveSpellDamage;
                break;

            default:
                throw new Exception("Invalid AbilityEffectType");
            }
            combatantModel.SetCurrentHealth(combatantModel.CurrentHealth + damageDeltaWithStatModifiers);
            Logging.Log.Info("Combatant ID : " + combatantModel.ID + " on team " + combatantModel.TeamID +
                             " receives damage: " + damageDeltaWithStatModifiers + ".  New health = " + combatantModel.CurrentHealth);
            return(new CombatActionModel(
                       abilityCombatantOwnerID, combatActionType, abilityID, combatantModel.ID, damageDeltaWithStatModifiers,
                       turnsRemaining, isCrit));
        }
        private CombatActionModel applyRegenAbilityEffectToCombatant(AbilityEffectType abilityEffectType, int abilityID,
                                                                     int abilityCombatantOwnerID, int abilityAmount, CombatantModel combatantModel, int turnsRemaining, bool isCrit)
        {
            // Don't consider stat modifiers for regen abilities (if an enemy casts increased spell damage on you,
            // we don't want it to boost the healing you receive)
            CombatActionType combatActionType = CombatActionType.None;

            switch (abilityEffectType)
            {
            case AbilityEffectType.HealthRegen:
                combatantModel.SetCurrentHealth(combatantModel.CurrentHealth + abilityAmount);
                combatActionType = CombatActionType.RegenHealth;
                break;

            case AbilityEffectType.ManaRegen:
                combatantModel.SetCurrentMana(combatantModel.CurrentMana + abilityAmount);
                combatActionType = CombatActionType.RegenMana;
                break;

            default:
                throw new Exception("Invalid AbilityEffectType");
            }
            return(new CombatActionModel(abilityCombatantOwnerID, combatActionType, abilityID,
                                         combatantModel.ID, abilityAmount, turnsRemaining, isCrit));
        }
        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);
            }
        }
예제 #18
0
 public ServerNpcModel(CombatBehaviourBase combatantBehaviour, string id, string name, NpcRole npcRole, NpcRace npcRace,
                       NpcSize npcSize, RarityType rarityType, CombatantModel combatantModel, string[] alwaysDroppedItemIDs = null) : base(id,
                                                                                                                                           name, npcRole, npcRace, npcSize, rarityType, combatantModel, alwaysDroppedItemIDs)
 {
     this.CombatBehaviour = combatantBehaviour;
 }
예제 #19
0
 /* ... */
 public CombatantGameObject()
 {
     Model = new CombatantModel(this);
 }
예제 #20
0
 public void Init(CombatantModel ownerCombatantModel)
 {
     this.ownerCombatantModel = ownerCombatantModel;
     allies.Add(ownerCombatantModel);
     availableAbilities = new AbilityItemModel[ownerCombatantModel.AbilityItemModels.Length];
 }