public BaseCharacterMono GetTarget()
        {
            if (TimeDelta < 2.0f)
            {
                TimeDelta += Time.deltaTime;
            }

            if (TimeDelta > 2.0F)
            {
                var targets = Tracker.Where(t => t.Key != null).ToList();

                if (targets.Any())
                {
                    targets = targets.Where(p => p.Key.Character.Alive).ToList();
                    if (!targets.Any())
                    {
                        return(null);
                    }
                    Target    = targets.Aggregate((i1, i2) => i1.Value > i2.Value ? i1 : i2).Key;
                    TimeDelta = 0;
                    return(Target);
                }
            }
            else
            {
                return(Target);
            }

            return(null);
        }
Exemple #2
0
        public static RPGAction WarpToPosition(BaseCharacterMono combatantObject)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Combatant", combatantObject }
            };

            return(new RPGAction(RPGActionType.WarpToPosition, parameters));
        }
Exemple #3
0
        public static RPGAction AddTimedPassiveEffect(BaseCharacterMono target, TimedPassiveEffect timedPassiveEffect)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "TimedPassiveEffect", timedPassiveEffect }
            };

            return(new RPGAction(RPGActionType.AddEffect, parameters));
        }
Exemple #4
0
        public static RPGAction AddRestorationEffect(BaseCharacterMono target, Restoration restoration)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "Restoration", restoration }
            };

            return(new RPGAction(RPGActionType.AddEffect, parameters));
        }
Exemple #5
0
        public static RPGAction RemoveStatusEffect(BaseCharacterMono target, string removeStatusEffectID)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "StatusEffectToRemove", removeStatusEffectID }
            };

            return(new RPGAction(RPGActionType.RemoveStatusEffect, parameters));
        }
Exemple #6
0
        public static RPGAction DealBonusTaunt(BaseCharacterMono target, int bonusTaunt)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "BonusTaunt", bonusTaunt }
            };

            return(new RPGAction(RPGActionType.DealBonusTaunt, parameters));
        }
Exemple #7
0
        public static RPGAction AddAuraEffect(BaseCharacterMono target, AuraSkill auraSkill)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "AuraSkill", auraSkill }
            };

            return(new RPGAction(RPGActionType.AddEffect, parameters));
        }
Exemple #8
0
        public static RPGAction AddDoT(BaseCharacterMono target, DamageOverTime damageOverTime)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "DamageOverTime", damageOverTime }
            };

            return(new RPGAction(RPGActionType.AddDamageOverTime, parameters));
        }
Exemple #9
0
        public static RPGAction DamageTargetMelee(BaseCharacterMono target, Damage damageToDeal, Vector3 targetPos)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "TargetPos", targetPos },
                { "DamageToDeal", damageToDeal }
            };

            return(new RPGAction(RPGActionType.DamageTargetMelee, parameters));
        }
Exemple #10
0
        public static RPGAction KnockBack(BaseCharacterMono target, Direction dir, float distance)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "Direction", dir },
                { "Distance", distance }
            };

            return(new RPGAction(RPGActionType.KnockBack, parameters));
        }
Exemple #11
0
        public static RPGAction PullTowards(BaseCharacterMono target, BaseCharacterMono characterMono, float distance)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "Combatant", characterMono },
                { "Distance", distance }
            };

            return(new RPGAction(RPGActionType.PullTowards, parameters));
        }
Exemple #12
0
        public static RPGAction PullTowards(BaseCharacterMono target, Vector3 targetPosition, float distance)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "TargetPosition", targetPosition },
                { "Distance", distance }
            };

            return(new RPGAction(RPGActionType.PullTowards, parameters));
        }
 public RPGAction FacingPosition(BaseCharacterMono combatant)
 {
     if (!Params.ContainsKey("Combatant"))
     {
         Params.Add("Combatant", combatant);
     }
     else
     {
         Debug.LogWarning("Action already contains combatant!");
     }
     return(this);
 }
Exemple #14
0
        public static RPGAction JumpToPosition(BaseCharacterMono combatantObject, float peakHeight, float speed = -1f)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Combatant", combatantObject },
                { "Height", peakHeight }
            };

            if (speed != -1f)
            {
                parameters.Add("MoveSpeed", speed);
            }
            return(new RPGAction(RPGActionType.JumpToPosition, parameters));
        }
Exemple #15
0
        public static RPGAction MoveToPosition(BaseCharacterMono combatant, float stopRange = -1, float speed = -1f)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Combatant", combatant },
                { "StopRange", stopRange }
            };

            if (speed != -1f)
            {
                parameters.Add("MoveSpeed", speed);
            }

            return(new RPGAction(RPGActionType.MoveToPosition, parameters));
        }
Exemple #16
0
        public static RPGAction AddStatusEffect(BaseCharacterMono target, StatusEffect statusEffect, bool?withDuration = null, float duration = 0)
        {
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "StatusEffect", statusEffect },
                { "Duration", duration }
            };

            if (withDuration != null)
            {
                parameters.Add("WithDuration", withDuration.Value);
            }

            return(new RPGAction(RPGActionType.AddEffect, parameters));
        }
Exemple #17
0
        public void Init(ProjectileSkill projSkill, BaseCharacterMono target, Vector3 targetPos = default(Vector3))
        {
            _projSkill         = GeneralMethods.CopySkill(projSkill);
            _skill             = _projSkill;
            _charTarget        = target;
            _direction         = targetPos;
            _baseHeight        = transform.localScale.y / 2;
            transform.position = transform.position + new Vector3(0, _baseHeight, 0);

            if (projSkill.CasterMono != null)
            {
                var spawnPosition = projSkill.CasterMono.GetComponentInChildren <ProjectileSpawnPosition>();
                if (spawnPosition != null)
                {
                    transform.position = spawnPosition.transform.position;
                }
            }



            if (targetPos != Vector3.zero)
            {
                transform.LookAt(new Vector3(targetPos.x, transform.position.y, targetPos.z));
            }
            else if (target != null)
            {
                transform.LookAt(target.transform.position);
            }
            else
            {
                Destroy(gameObject);
                return;
            }

            if (_projSkill.TravelSound.Audio != null)
            {
                var sound = AudioPlayer.Instance.Play(_projSkill.TravelSound.Audio, AudioType.SoundFX, transform.position, transform);
                sound.GetComponent <AudioSource>().loop = true;
                sound.AddComponent <DestroyHelper>().Init(DestroyCondition.GameObjectIsNull, gameObject);
            }

            //todo: projectile radius: transform.localScale = new Vector3(_projSkill.Diameter, _projSkill.Diameter, _projSkill.Diameter);

            Destroy(gameObject, projSkill.TimeTillDestroy);
            _initialised = true;
            //Debug.Log("Initialised skill");
        }
        public void Init(BaseCharacterMono caster, Damage damage, Vector3 targetPos, BaseCharacterMono target = null)
        {
            Caster        = caster.Character;
            CasterMono    = caster;
            _damage       = damage;
            Target        = target;
            HaveTransform = Target != null;

            transform.LookAt(new Vector3(targetPos.x, targetPos.y, targetPos.z));

            //resize for attack range and radius
            var boxCollider    = GetComponent <BoxCollider>();
            var casterNavAgent = caster.GetComponent <NavMeshAgent>();
            var attackRange    = caster.Character.AttackRange;

            boxCollider.size    = new Vector3(casterNavAgent.radius + 0.25f, casterNavAgent.height, attackRange);
            transform.position += transform.forward * (attackRange / 2);
            transform.position += new Vector3(0, casterNavAgent.height / 2, 0);

            if (caster.Character.CharacterType == CharacterType.Player)
            {
                var player   = (PlayerCharacter)caster.Character;
                var classDef = Rm_RPGHandler.Instance.Player.CharacterDefinitions.First(c => c.ID == player.PlayerCharacterID);
                ImpactPrefabPath = classDef.AutoAttackImpactPrefabPath;
                ImpactSound      = classDef.AutoAttackImpactSound;

                var weapon = player.Equipment.EquippedWeapon as Weapon;
                weapon = weapon ?? player.Equipment.EquippedOffHand as Weapon;
                if (weapon != null)
                {
                    var wepDef = Rm_RPGHandler.Instance.Items.WeaponTypes.First(w => w.ID == weapon.WeaponTypeID);
                    ImpactPrefabPath = wepDef.AutoAttackImpactPrefabPath;
                    ImpactSound      = wepDef.AutoAttackImpactSound;
                }
            }
            else
            {
                var cc = (CombatCharacter)caster.Character;
                ImpactPrefabPath = cc.AutoAttackImpactPrefabPath;
                ImpactSound      = cc.AutoAttackImpactSound;
            }

            Destroy(gameObject, 0.25f);
            _initialised = true;
        }
Exemple #19
0
        public void Init(Skill spawnSkill, BaseCharacterMono target)
        {
            if (spawnSkill.LimitSpawnInstances)
            {
                if (SpawnedObjectInstanceTracker.ContainsKey(spawnSkill.ID))
                {
                    var currentInstances = SpawnedObjectInstanceTracker[spawnSkill.ID];
                    if (currentInstances < spawnSkill.MaxInstances)
                    {
                        SpawnedObjectInstanceTracker[spawnSkill.ID] += 1;
                    }
                    else
                    {
                        Debug.Log("Max instances of this spawn reached.");
                        Destroy(gameObject);
                        return;
                    }
                }
                else
                {
                    SpawnedObjectInstanceTracker.Add(spawnSkill.ID, 1);
                }
            }

            _spawnSkill        = GeneralMethods.CopySkill(spawnSkill);
            _charTarget        = target;
            transform.position = transform.position + new Vector3(0, transform.localScale.y / 2, 0);


            if (spawnSkill.HasDuration)
            {
                Destroy(gameObject, spawnSkill.SpawnForTime);
            }



            //LoadAllData();

            _initialised = true;
            Debug.Log("Initialised skill");
        }
Exemple #20
0
        public static RPGAction AddStatusEffect(BaseCharacterMono target, string statusEffectID, bool?withDuration = null, float duration = 0)
        {
            var effect     = GeneralMethods.CopyObject(Rm_RPGHandler.Instance.Repositories.StatusEffects.AllStatusEffects.FirstOrDefault(s => s.ID == statusEffectID));
            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "StatusEffect", effect },
                { "Duration", duration }
            };

            if (withDuration != null)
            {
                parameters.Add("WithDuration", withDuration.Value);
            }

            if (parameters["StatusEffect"] == null)
            {
                Debug.Log("Trying to add status effect which is null inside action.");
            }
            return(new RPGAction(RPGActionType.AddEffect, parameters));
        }
Exemple #21
0
        public static RPGAction DamageTarget(BaseCharacterMono target, Damage damageToDeal,
                                             List <RPGAction> onHitActions = null, List <RPGAction> onCritHitActions = null, Skill skillRef = null)
        {
            if (onHitActions == null)
            {
                onHitActions = new List <RPGAction>();
            }
            if (onCritHitActions == null)
            {
                onCritHitActions = new List <RPGAction>();
            }

            var parameters = new Dictionary <string, object>()
            {
                { "Target", target },
                { "DamageToDeal", damageToDeal },
                { "HitActions", onHitActions },
                { "CritHitActions", onCritHitActions },
                { "SkillRef", skillRef }
            };

            return(new RPGAction(RPGActionType.DamageTarget, parameters));
        }
        public bool AddFriendlyAura(BaseCharacterMono source, AuraEffect auraEffect)
        {
            var aura = GeneralMethods.CopyObject(auraEffect);
            var foundFriendlyAura = FriendlyAuras.FirstOrDefault(a => a.AuraEffect.SkillId == aura.SkillId);
            var foundSelfAura     = AuraEffects.FirstOrDefault(a => a.SkillId == aura.SkillId);
            var canAddAura        = foundFriendlyAura == null && foundSelfAura == null;

            bool active;

            if (canAddAura)
            {
                var friendlyAura = new FriendlyAura
                {
                    SourceCharacter = source,
                    AuraEffect      = aura
                };
                FriendlyAuras.Add(friendlyAura);
                CustomVariableHandler.HandleCvarSetters(aura.PassiveEffect.CustomVariableSetters);
                active = true;

                DestroyHelper destroyCondition;
                AddEffectPrefabs(aura.PassiveEffect, out destroyCondition, false);
                if (destroyCondition != null)
                {
                    destroyCondition.Init(DestroyCondition.FriendlyAuraNotAvailable, CharacterMono.Controller, aura.SkillId);
                }
                FullUpdateStats();
            }
            else
            {
                active = true;
            }


            return(active);
        }
Exemple #23
0
        public void SpawnLoot(BaseCharacterMono character)
        {
            var positionToSpawn = character.transform.position + (character.transform.up);

            var itemsToLoot = new List <Item>();
            var goldToLoot  = 0;

            //todo: nicer code this, maybe move to function
            var mm = GetObject.PlayerSave.QuestLog.ActiveObjectives;
            //note: we are double checking isDone here as we don't want to spawn loot for already completed itemConditions
            var active             = mm.SelectMany(y => y.ActiveConditions).Where(i => !i.IsDone).ToList();
            var conditions         = active.Select(a => a as ItemCondition);
            var interactConditions = conditions.Where(c => c != null);
            var foundCondition     = interactConditions.FirstOrDefault(i => i.CombatantIDThatDropsItem == (character.Character as CombatCharacter).ID);

            if (foundCondition != null)
            {
                var qItem = Rm_RPGHandler.Instance.Repositories.QuestItems.Get(foundCondition.ItemToCollectID);
                if (qItem != null)
                {
                    itemsToLoot.Add(qItem);
                }
            }

            var enemyInfo = character.Character as CombatCharacter;

            foreach (var loot in enemyInfo.GuaranteedLoot)
            {
                var item = Rm_RPGHandler.Instance.Repositories.Items.Get(loot.ItemID);
                if (item == null)
                {
                    Debug.LogError("Did not find item in guaranteed loot of : " + enemyInfo.Name);
                    continue;
                }

                if (loot.Amount != 0)
                {
                    var stackable = item as IStackable;

                    if (stackable != null)
                    {
                        stackable.CurrentStacks = loot.Amount;
                    }
                }

                itemsToLoot.Add(item);
            }

            var randomGold = Random.Range(0, 100 + 1);

            if (enemyInfo.DropsGold)
            {
                var drops = randomGold <= (enemyInfo.GoldDropChance * 100);
                if (drops)
                {
                    goldToLoot += Random.Range(enemyInfo.MinGoldDrop, enemyInfo.MaxGoldDrop + 1);
                }
            }

            if (enemyInfo.LootTables.Count > 0)
            {
                var random = Random.Range(0, 100 + 1);
                //Debug.Log("LootOption Random: " + random);
                var         currentProbability = random;
                var         prevChance         = 0;
                var         currentIndex       = 0;
                LootOptions lootOptionsToUse   = null;

                while (prevChance < 100)
                {
                    var currentTableChance = enemyInfo.LootTables[currentIndex].Chance + prevChance;
                    prevChance = (int)currentTableChance;


                    //Debug.Log("currentTableChance:" + currentTableChance);
                    if (currentProbability <= currentTableChance)
                    {
                        lootOptionsToUse = enemyInfo.LootTables[currentIndex];
                        break;
                    }
                    else
                    {
                        currentIndex++;
                    }
                }

                if (lootOptionsToUse != null)
                {
                    var lootTableToUse = Rm_RPGHandler.Instance.Repositories.LootTables.AllTables.FirstOrDefault(l => l.ID == enemyInfo.LootTables[currentIndex].LootTableID);
                    for (int x = 0; x < enemyInfo.MaxItemsFromLootTable; x++)
                    {
                        var chanceToGet = lootOptionsToUse.AlwaysGetItem ? 100 : lootTableToUse.ChanceForItem;
                        var randomRoll  = Random.Range(0, 100 + 1);
                        //Debug.Log("LootTableItem Random: " + random);
                        if (randomRoll <= chanceToGet)
                        {
                            randomRoll = Random.Range(0, 100 + 1);
                            var currentProb      = randomRoll;
                            var currentItemIndex = 0;
                            var prevLootChance   = 0;
                            Rm_LootTableItem lootTableItemToLoot = null;
                            while (prevLootChance < 100)
                            {
                                var currentItemChance = lootTableToUse.LootTableItems[currentItemIndex].Chance + prevLootChance;
                                prevLootChance = (int)currentItemChance;

                                //Debug.Log("currentItemChance:" + currentItemChance);
                                if (currentProb <= currentItemChance)
                                {
                                    lootTableItemToLoot = lootTableToUse.LootTableItems[currentItemIndex];
                                    break;
                                }
                                else
                                {
                                    currentItemIndex++;
                                }
                            }
                            if (lootTableItemToLoot != null)
                            {
                                if (!lootTableItemToLoot.IsGold && !lootTableItemToLoot.IsEmpty)
                                {
                                    Item item = null;

                                    if (lootTableItemToLoot.IsNormalItem)
                                    {
                                        item = Rm_RPGHandler.Instance.Repositories.Items.Get(lootTableItemToLoot.ItemID);
                                    }
                                    else if (lootTableItemToLoot.IsQuestItem)
                                    {
                                        item = Rm_RPGHandler.Instance.Repositories.QuestItems.Get(lootTableItemToLoot.ItemID);
                                    }
                                    else if (lootTableItemToLoot.IsCraftableItem)
                                    {
                                        item = Rm_RPGHandler.Instance.Repositories.CraftableItems.Get(lootTableItemToLoot.ItemID);
                                    }


                                    //item = Rm_RPGHandler.Instance.Repositories.Items.AllItems.FirstOrDefault(i => i.ID == lootTableItemToLoot.ItemID);
                                    if (item == null)
                                    {
                                        Debug.LogError("Did not find item in guaranteed loot of : " + enemyInfo.Name);
                                        continue;
                                    }

                                    var itemCopy = GeneralMethods.CopyObject(item);

                                    if (lootTableItemToLoot.MaxQuantity != 1)
                                    {
                                        var stackable = itemCopy as IStackable;
                                        stackable.CurrentStacks = Random.Range(lootTableItemToLoot.MinQuantity, lootTableItemToLoot.MaxQuantity + 1);
                                    }

                                    itemsToLoot.Add(itemCopy);
                                }
                                else if (lootTableItemToLoot.IsGold)
                                {
                                    goldToLoot += Random.Range(lootTableItemToLoot.MinQuantity, lootTableItemToLoot.MaxQuantity + 1);
                                }
                            }
                        }
                    }
                }
            }

            StartCoroutine(SpawnListOfItems(itemsToLoot, positionToSpawn, goldToLoot));
        }
        public void Init(BaseCharacterMono caster, Damage damage, BaseCharacterMono target, Vector3 targetPos = default(Vector3))
        {
            Caster             = caster.Character;
            CasterMono         = caster;
            _damage            = damage;
            Target             = target;
            Direction          = targetPos;
            _baseHeight        = transform.localScale.y + 0.2f;
            transform.position = transform.position + new Vector3(0, _baseHeight, 0);

            var spawnPosition = caster.GetComponentInChildren <ProjectileSpawnPosition>();

            if (spawnPosition != null)
            {
                transform.position = spawnPosition.transform.position;
            }

            if (Direction != Vector3.zero)
            {
                transform.LookAt(Direction);
            }
            else if (target != null)
            {
                transform.LookAt(target.transform.position);
            }
            else
            {
                Destroy(gameObject);
                return;
            }

            //todo: hi

            if (caster.Character.CharacterType == CharacterType.Player)
            {
                var player   = (PlayerCharacter)caster.Character;
                var classDef = Rm_RPGHandler.Instance.Player.CharacterDefinitions.First(c => c.ID == player.PlayerCharacterID);
                ProjectileSpeed  = classDef.ProjectileSpeed;
                ImpactPrefabPath = classDef.AutoAttackImpactPrefabPath;
                ImpactSound      = classDef.AutoAttackImpactSound;
                TravelSound      = classDef.ProjectileTravelSound;

                var weapon = player.Equipment.EquippedWeapon as Weapon;
                weapon = weapon ?? player.Equipment.EquippedOffHand as Weapon;
                if (weapon != null)
                {
                    var wepDef = Rm_RPGHandler.Instance.Items.WeaponTypes.First(w => w.ID == weapon.WeaponTypeID);
                    ProjectileSpeed  = wepDef.ProjectileSpeed;
                    ImpactPrefabPath = wepDef.AutoAttackImpactPrefabPath;
                    ImpactSound      = wepDef.AutoAttackImpactSound;
                    TravelSound      = wepDef.ProjectileTravelSound;
                }
            }
            else
            {
                var cc = (CombatCharacter)caster.Character;
                ProjectileSpeed  = cc.ProjectileSpeed;
                ImpactPrefabPath = cc.AutoAttackImpactPrefabPath;
                ImpactSound      = cc.AutoAttackImpactSound;
                TravelSound      = cc.ProjectileTravelSound;
            }

            if (TravelSound.Audio != null)
            {
                SoundGameObject = AudioPlayer.Instance.Play(TravelSound.Audio, AudioType.SoundFX, transform.position, transform);
                SoundGameObject.GetComponent <AudioSource>().loop = true;
                SoundGameObject.AddComponent <DestroyHelper>().Init(DestroyCondition.GameObjectIsNull, gameObject);
            }

            Destroy(gameObject, 5.0f);
            _initialised = true;
        }
Exemple #25
0
        private void HandleHitOnTarget(Damage damage, BaseCharacterMono target)
        {
            if (Caster != null)
            {
                DamageOutcome outcome      = new DamageOutcome(new Damage(), AttackOutcome.Success);
                var           damageToDeal = damage;
                if (damageToDeal.MaxTotal > 0)
                {
                    if (CasterMono != null)
                    {
                        outcome = CasterMono.Controller.RPGCombat.DamageTarget(target, damageToDeal);
                    }
                    else
                    {
                        outcome = target.Character.VitalHandler.TakeDamage(Caster, damageToDeal);
                    }
                }



                var onCritProcs = new List <Rm_ProcEffect>();
                var onHitProcs  = new List <Rm_ProcEffect>();

                var procs = Caster.ProcEffects;

                foreach (var procEffect in procs)
                {
                    switch (procEffect.ProcCondition)
                    {
                    case Rm_ProcCondition.Every_N_Hits:
                    case Rm_ProcCondition.Chance_On_Hit:
                    case Rm_ProcCondition.On_Hit:
                        onHitProcs.Add(procEffect);
                        break;

                    case Rm_ProcCondition.Chance_On_Critical_Hit:
                        onCritProcs.Add(procEffect);
                        break;
                    }
                }

                if (damageToDeal.MaxTotal == 0 || outcome != null && (outcome.AttackOutcome == AttackOutcome.Success || outcome.AttackOutcome == AttackOutcome.Critical))
                {
                    foreach (var proc in onHitProcs)
                    {
                        HandleProc(proc, target);
                    }
                    var impact = GeneralMethods.SpawnPrefab(ImpactPrefabPath, target.transform.position, Quaternion.identity, target.transform);
                    if (impact != null)
                    {
                        impact.GetComponent <DestroyHelper>().Init(DestroyCondition.Time, 0.3f);
                    }
                    AudioPlayer.Instance.Play(ImpactSound.Audio, AudioType.SoundFX, target.transform.position, target.transform);
                }

                if (outcome != null && outcome.AttackOutcome == AttackOutcome.Critical)
                {
                    foreach (var proc in onCritProcs)
                    {
                        HandleProc(proc, target);
                    }
                }
            }
        }
        private void HandleSkillOnTarget(Skill originalSkill, BaseCharacterMono target)
        {
            var skillToUse = GeneralMethods.CopySkill(originalSkill);

            //Debug.Log("Handled skill hit for " + target.Character.Name);
            if (skillToUse.Caster != null)
            {
                DamageOutcome outcome      = new DamageOutcome(new Damage(), AttackOutcome.Success);
                var           damageToDeal = skillToUse.Damage;
                if (damageToDeal.MaxTotal > 0)
                {
                    var projSkillHandler = this as ProjectileSkillHandler;
                    if (projSkillHandler != null)
                    {
                        var projSkill = (ProjectileSkill)_skill;
                        if (projSkill.IsPiercing)
                        {
                            damageToDeal.ApplyMultiplier(projSkill.PiercingScaling[projSkillHandler.PierceCounter]);
                        }
                    }

                    if (skillToUse.CasterMono != null)
                    {
                        outcome = skillToUse.CasterMono.Controller.RPGCombat.DamageTarget(target, damageToDeal);
                        var cc = target.Character as CombatCharacter;
                        if (cc != null)
                        {
                            var targetTaunt = cc.TauntHandler;
                            if (!targetTaunt.Tracker.ContainsKey(skillToUse.CasterMono))
                            {
                                targetTaunt.Tracker.Add(skillToUse.CasterMono, 1);
                            }

                            targetTaunt.Tracker[skillToUse.CasterMono] += skillToUse.BonusTaunt;
                        }
                    }
                    else
                    {
                        outcome = target.Character.VitalHandler.TakeDamage(skillToUse.Caster, damageToDeal);
                    }
                }



                var onCritProcs = new List <Rm_ProcEffect>();
                var onHitProcs  = new List <Rm_ProcEffect>();

                var procs = skillToUse.Caster.ProcEffects;

                if (skillToUse.HasProcEffect)
                {
                    switch (skillToUse.ProcEffect.ProcCondition)
                    {
                    case Rm_ProcCondition.Every_N_Hits:
                    case Rm_ProcCondition.Chance_On_Hit:
                    case Rm_ProcCondition.On_Hit:
                        onHitProcs.Add(skillToUse.ProcEffect);
                        break;

                    case Rm_ProcCondition.Chance_On_Critical_Hit:
                        onCritProcs.Add(skillToUse.ProcEffect);
                        break;
                    }
                }

                foreach (var procEffect in procs)
                {
                    switch (procEffect.ProcCondition)
                    {
                    case Rm_ProcCondition.Every_N_Hits:
                    case Rm_ProcCondition.Chance_On_Hit:
                    case Rm_ProcCondition.On_Hit:
                        onHitProcs.Add(procEffect);
                        break;

                    case Rm_ProcCondition.Chance_On_Critical_Hit:
                        onCritProcs.Add(procEffect);
                        break;
                    }
                }

                if (damageToDeal.MaxTotal == 0 || outcome != null && (outcome.AttackOutcome == AttackOutcome.Success || outcome.AttackOutcome == AttackOutcome.Critical))
                {
                    foreach (var proc in onHitProcs)
                    {
                        IncrementSkillCounters(skillToUse);
                        HandleProc(proc, target);
                    }

                    if (skillToUse.ApplyDOTOnHit)
                    {
                        var canApply = Random.Range(0, 100 + 1) <= (int)(skillToUse.ChanceToApplyDOT * 100);
                        if (canApply)
                        {
                            skillToUse.DamageOverTime.SkillMetaID = skillToUse.SkillMetaID;
                            skillToUse.DamageOverTime.Attacker    = skillToUse.Caster;
                            target.Character.AddDoT(skillToUse.DamageOverTime);
                        }
                    }

                    if (skillToUse.RunEventOnHit)
                    {
                        if (!string.IsNullOrEmpty(skillToUse.EventOnHitID))
                        {
                            Debug.Log("Not implemented: do event:" + skillToUse.EventOnHitID);
                        }
                    }

                    if (skillToUse.SkillType == SkillType.Aura)
                    {
                        var auraSkill = (AuraSkill)skillToUse;
                        target.Character.ToggleAura(auraSkill, true);
                    }
                    else if (skillToUse.SkillType == SkillType.Restoration)
                    {
                        var restoSkill = (RestorationSkill)skillToUse;
                        target.Character.AddRestoration(restoSkill.Restoration);
                    }

                    if (skillToUse.AppliesBuffDebuff)
                    {
                        target.Character.AddTimedPassiveEffect(skillToUse.Effect);
                    }

                    if (skillToUse.ApplyStatusEffect)
                    {
                        var apply = Random.Range(0, 100 + 1) <= (int)(skillToUse.ChanceToApplyStatusEffect * 100);
                        if (apply)
                        {
                            var statusEffect = Rm_RPGHandler.Instance.Repositories.StatusEffects.Get(skillToUse.StatusEffectID);
                            if (statusEffect != null)
                            {
                                statusEffect.Effect.HasDuration = skillToUse.ApplyStatusEffectWithDuration;
                                if (statusEffect.Effect.HasDuration)
                                {
                                    statusEffect.Effect.Duration = skillToUse.ApplyStatusEffectDuration;
                                }
                                target.Character.AddStatusEffect(statusEffect);
                            }
                        }
                    }

                    if (skillToUse.RemoveStatusEffect)
                    {
                        var apply = Random.Range(0, 100 + 1) <= (int)(skillToUse.ChanceToRemoveStatusEffect * 100);
                        if (apply)
                        {
                            target.Character.RemoveStatusEffect(skillToUse.RemoveStatusEffectID);
                        }
                    }

                    var impact = GeneralMethods.SpawnPrefab(skillToUse.ImpactPrefabPath, target.transform.position, Quaternion.identity, target.transform);
                    if (impact != null)
                    {
                        impact.GetComponent <DestroyHelper>().Init(DestroyCondition.Time, 0.3f);
                    }
                    AudioPlayer.Instance.Play(skillToUse.ImpactSound.Audio, AudioType.SoundFX, target.transform.position, target.transform);
                }

                if (outcome != null && outcome.AttackOutcome == AttackOutcome.Critical)
                {
                    foreach (var proc in onCritProcs)
                    {
                        IncrementSkillCounters(skillToUse);
                        HandleProc(proc, target);
                    }
                }
            }
        }
        protected void HandleProc(Rm_ProcEffect procEffect, BaseCharacterMono target)
        {
            var canProc = false;

            if (procEffect.ProcCondition == Rm_ProcCondition.On_Hit)
            {
                canProc = true;
            }
            else if (procEffect.ProcCondition == Rm_ProcCondition.Chance_On_Critical_Hit ||
                     procEffect.ProcCondition == Rm_ProcCondition.Chance_On_Hit)
            {
                canProc = Random.Range(0, 100 + 1) <= (int)(procEffect.Parameter * 100);
            }
            else if (procEffect.ProcCondition == Rm_ProcCondition.Every_N_Hits)
            {
                var n = (int)procEffect.Parameter;
                canProc = procEffect.ParameterCounter % n == 0;
                Debug.Log("Proc:" + procEffect.ParameterCounter % n + " / " + n + "  " + canProc);
            }

            if (canProc)
            {
                //add actions
                if (procEffect.ProcEffectType == Rm_ProcEffectType.StatusEffect ||
                    procEffect.ProcEffectType == Rm_ProcEffectType.StatusEffectOnSelf)
                {
                    if (procEffect.ProcEffectType == Rm_ProcEffectType.StatusEffect)
                    {
                        target.Character.AddStatusEffect(procEffect.EffectParameterString);
                    }
                    else
                    {
                        if (_skill.CasterMono != null)
                        {
                            _skill.CasterMono.Character.AddStatusEffect(procEffect.EffectParameterString);
                        }
                    }
                }
                else if (procEffect.ProcEffectType == Rm_ProcEffectType.CastSkill ||
                         procEffect.ProcEffectType == Rm_ProcEffectType.CastSkillOnSelf)
                {
                    var allSkills = Rm_RPGHandler.Instance.Repositories.Skills.AllSkills;
                    var skill     = Rm_RPGHandler.Instance.Repositories.Skills.Get(procEffect.EffectParameterString);
                    if (skill != null)
                    {
                        skill.CasterMono = _skill.CasterMono;
                        skill.Caster     = _skill.Caster;

                        if (procEffect.ProcEffectType == Rm_ProcEffectType.CastSkill)
                        {
                            CastSkill(skill, target, null);
                        }
                        else
                        {
                            if (_skill.CasterMono != null)
                            {
                                CastSkill(skill, _skill.CasterMono, null);
                            }
                        }
                    }
                }
                else if (procEffect.ProcEffectType == Rm_ProcEffectType.KnockBack)
                {
                    target.Controller.AddImpact(Direction.Back, procEffect.EffectParameter);
                }
                else if (procEffect.ProcEffectType == Rm_ProcEffectType.KnockUp)
                {
                    target.Controller.AddImpact(Direction.Up, procEffect.EffectParameter);
                }
                else if (procEffect.ProcEffectType == Rm_ProcEffectType.PullTowards)
                {
                    var pullposition = transform.position;
                    pullposition.y = target.transform.position.y;
                    target.Controller.PullTo(pullposition, procEffect.PullAllTheWay ? -1 : procEffect.EffectParameter);
                }
            }
        }
        protected void CastSkill(Skill originalSkill, BaseCharacterMono target, Vector3?nullableTargetPos)
        {
            if (originalSkill.SkillType == SkillType.Area_Of_Effect || originalSkill.SkillType == SkillType.Spawn)
            {
                if (nullableTargetPos == null)
                {
                    if (target != null)
                    {
                        nullableTargetPos = target.transform.position;
                        target            = null;
                    }
                }
            }

            if (target == null && !nullableTargetPos.HasValue)
            {
                return;
            }
            if (target != null && !target.Character.Alive)
            {
                return;
            }

            var hasCharacterTarget = target != null;
            var targetPos          = nullableTargetPos.GetValueOrDefault();

            if (hasCharacterTarget)
            {
                HandleSkillOnTarget(originalSkill, target);
            }
            else
            {
                var skillToUse = GeneralMethods.CopySkill(originalSkill);

                var newTargetPos = targetPos;
                if (skillToUse.SkillType == SkillType.Area_Of_Effect)
                {
                    var aoeSkill = (AreaOfEffectSkill)skillToUse;
                    newTargetPos = targetPos + new Vector3(0, aoeSkill.Height / 2, 0);
                    var skillPrefab = GeneralMethods.SpawnPrefab(aoeSkill.PrefabPath, newTargetPos, Quaternion.identity, null);
                    skillPrefab.GetComponent <AreaOfEffectSkillHandler>().Init(aoeSkill);
                }
                else if (skillToUse.SkillType == SkillType.Projectile)
                {
                    var projSkill = (ProjectileSkill)skillToUse;

                    var projectilePosition = targetPos;

                    var casterTransform = transform;
                    newTargetPos = casterTransform.position + (casterTransform.up * 1.3f);

                    var skillPrefab = GeneralMethods.SpawnPrefab(skillToUse.PrefabPath, newTargetPos, Quaternion.identity, null);
                    skillPrefab.GetComponent <ProjectileSkillHandler>().Init(projSkill, null, projectilePosition);
                }
                else if (skillToUse.SkillType == SkillType.Spawn)
                {
                    var spawnSkill = skillToUse;
                    newTargetPos = targetPos + new Vector3(0, 1, 0);
                    var skillPrefab = GeneralMethods.SpawnPrefab(skillToUse.PrefabPath, newTargetPos, Quaternion.identity, null);
                    skillPrefab.GetComponent <SpawnSkillHandler>().Init(spawnSkill, target);
                }
            }
        }
 public TauntHandler()
 {
     Tracker   = new Dictionary <BaseCharacterMono, int>();
     TimeDelta = 100;
     Target    = null;
 }
 public FriendlyAura()
 {
     SourceCharacter = null;
     AuraEffect      = null;
 }