protected override void Update()
    {
        base.Update();

        maxLife = playerData.GetMaxLife();

        if (playerData.name.StartsWith("#") && Input.GetKeyDown(KeyCode.L))
        {
            playerData.GrantExperience(playerData.ExperienceToNextLevel - playerData.Experience);
        }

        if (Input.GetKeyDown(KeyCode.Tab))
        {
            if (!TryAndSwitchTarget())
            {
                enemyTabCache = (from e in GameObject.FindGameObjectsWithTag("Enemy")
                                 where reasonableTargetFunc(e) && e.GetComponent <EntityLiving>()
                                 orderby Vector3.Distance(e.transform.position, transform.position) ascending
                                 select e.GetComponent <EntityLiving>()).ToList();

                TryAndSwitchTarget();
            }
        }

        SpellBase[] keys = cooldowns.Keys.ToArray();

        for (int i = 0; i < keys.Length; i++)
        {
            SpellBase key = keys[i];

            if (cooldowns[key] > .0F)
            {
                cooldowns[key] -= Time.deltaTime;
            }
        }

        if (casting != null)
        {
            if (progress >= casting.castTime)
            {
                if (casting.VerifyCanCastSpell(this))
                {
                    anim.Pause(false);

                    if (!string.IsNullOrEmpty(casting.animation) && !casting.animateBeforeCast && anim.IsPlaying())
                    {
                        return;
                    }

                    cooldowns[casting] = casting.cooldown;
                    casting.Cast(this);
                }

                anim.Stop();

                if (castingParticle)
                {
                    castEffect = null;

                    foreach (Transform t in castingParticle)
                    {
                        Destroy(t.gameObject);
                    }
                }

                casting = null;
            }
            else
            {
                progress += Time.deltaTime;
            }
            return;
        }

        for (int i = 0; i < spells.Count && i < spellKeys.Length; i++)
        {
            if (Input.GetKeyDown(spellKeys[i]))
            {
                if (cooldowns.ContainsKey(spells[i]) && cooldowns[spells[i]] > 0)
                {
                    UIHelper.Alert("alerts.player.spell.cooldown", "InGameError");
                    continue;
                }
                if (!spells[i].VerifyCanCastSpell(this))
                {
                    continue;
                }
                progress = 0;
                casting  = spells[i];

                if (!string.IsNullOrEmpty(casting.animation))
                {
                    anim.Play(Resources.Load <TextAsset>("Poses/" + casting.animation));
                    if (!casting.animateBeforeCast)
                    {
                        anim.Pause(true);
                    }
                }

                if (castingParticle && !string.IsNullOrEmpty(casting.particle))
                {
                    castEffect = Instantiate(Resources.Load <GameObject>("Particles/" + casting.particle), castingParticle);
                }

                return;
            }
        }
    }