public static object[] ToObjectArray(CombatActionModel cam)
        {
            object[] objArray = new object[] {
                cam.CasterCombatantID,
                (int)cam.CombatActionType,
                cam.AbilityID,
                cam.TargetCombatantID,
                cam.Amount,
                cam.TurnsRemaining,
                cam.IsCrit
            };

            return(objArray);
        }
        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));
                }
            }
        }