Beispiel #1
0
    public PFX_DebuffIcon ApplyDebuff(DebuffData dataToApply, float fDuration)
    {
        if (template.bImmuneToDebuffs)
        {
            return(null);
        }

        foreach (DebuffData old in timedDebuffs)
        {
            if (old.debuff == dataToApply.debuff)
            {
                old.fTimeRemaining = fDuration;
                return(null);
            }
        }

        DebuffData data = new DebuffData();

        data.debuff         = dataToApply.debuff;
        data.fTimeRemaining = fDuration;
        if (dataToApply.debuffIcon != null)
        {
            data.debuffIcon = Instantiate <PFX_DebuffIcon>(dataToApply.debuffIcon);
        }
        timedDebuffs.Add(data);
        return(data.debuffIcon);
    }
Beispiel #2
0
    /// <summary>
    /// 【定身】鎖定目標所有動作
    /// </summary>
    public void Bind(Character target, float duration)
    {
        DebuffData debuffData = new DebuffData
        {
            icon        = bindIcon,
            name        = bindDebuffName,
            duration    = duration,
            applyAffect = delegate
            {
                target.move.Lock(LockType.Bind);
                target.attack.Lock(LockType.Bind);
                target.evade.Lock(LockType.Bind);
                target.jump.Lock(LockType.Bind);
                target.useSkill.Lock(LockType.Bind);
            },
            endAffect = delegate
            {
                target.move.UnLock(LockType.Bind);
                target.attack.UnLock(LockType.Bind);
                target.evade.UnLock(LockType.Bind);
                target.jump.UnLock(LockType.Bind);
                target.useSkill.UnLock(LockType.Bind);
            },
        };

        ApplyDebuff(target, debuffData);
    }
Beispiel #3
0
    public bool Damage(Damage damage, float fMultiplier, float fAdditionalDamage)
    {
        fCurrentHealth -= (damage.fAmount + fAdditionalDamage) * fMultiplier;

        if (damage.debuff != DebuffData.Debuff.NO_DEBUFF)
        {
            DebuffData data = new DebuffData();
            data.debuff     = damage.debuff;
            data.debuffIcon = damage.debuffIcon;
            PFX_DebuffIcon debuffIcon = ApplyDebuff(data, damage.fDebuffDuration);
            if (debuffIcon != null)
            {
                debuffIcon.transform.SetParent(transform);
                debuffIcon.transform.localPosition = Vector3.zero;
            }
        }

        if ((fCurrentHealth <= 0.0f) || (damage.fInstadeathThreshold > 0.0f && fCurrentHealth / fMaxHealthPostBuffs < damage.fInstadeathThreshold))
        {
            Destroy(gameObject);
            return(true);
        }

        return(false);
    }
Beispiel #4
0
    /// <summary>
    /// 【跛腳】目標無法使用跳躍,持續X秒。
    /// </summary>
    public void Lame(Character target, float duration)
    {
        DebuffData debuffData = new DebuffData
        {
            icon        = lameIcon,
            name        = lameDebuffName,
            duration    = duration,
            applyAffect = delegate { target.jump.Lock(LockType.Lame); },
            endAffect   = delegate { target.jump.UnLock(LockType.Lame); },
        };

        ApplyDebuff(target, debuffData);
    }
Beispiel #5
0
    /// <summary>
    /// 【緩速】減緩目標N%移動速度,持續X秒。
    /// </summary>
    /// <param name="percentage">N => [Range 1 ~ 100]%, retrun if out of range</param>
    /// <param name="duration">X => Debuff duration</param>
    public void SlowMoveSpeed(Character target, float percentage, float duration)
    {
        if (percentage > 100f || percentage <= 0f)
        {
            return;
        }

        var        speedstat  = target.data.moveSpeed;
        var        mod        = new StatModifier(-percentage, StatModType.PercentageTime, slowDebuffName);
        DebuffData debuffData = new DebuffData
        {
            icon        = slowIcon,
            name        = slowDebuffName,
            duration    = duration,
            applyAffect = delegate { speedstat.AddModifier(mod); },
            endAffect   = delegate { speedstat.RemoveModifier(mod); },
        };

        ApplyDebuff(target, debuffData);
    }
Beispiel #6
0
    /// <summary>
    /// 【燃燒】點燃目標,並造成基於攻擊力與最大生命的傷害,持續X秒。
    /// </summary>
    /// <param name="source">造成異常的來源施法者</param>
    public void Ignite(Character source, Character target, float duration)
    {
        var currentFireResis = target.GetResistance(ElementType.Fire);

        // 火抗小於等於50不會被燃燒。
        if (currentFireResis.Value <= 50)
        {
            return;
        }

        DebuffData debuffData = new DebuffData
        {
            icon        = igniteIcon,
            name        = igniteDebuffName,
            duration    = duration,
            applyAffect = delegate { IgniteEffect(source, target, duration); },
            endAffect   = delegate { RemoveIgniteEffect(target); },
        };

        ApplyDebuff(target, debuffData);
    }
Beispiel #7
0
    /// <summary>
    /// 破甲Lv1: 對命中的目標造成-20%基礎防禦,持續N秒。
    /// 破甲Lv2: -30%
    /// 破甲Lv3: -45%
    /// 破甲Lv4: -60%
    /// 破甲Lv5: -80%
    /// </summary>
    public void ArmorBreakWithLevel(Character target, int level, float duration)
    {
        var   armorStat = target.data.defense;
        float value     = 0;

        switch (level)
        {
        case 1:
            value = -20f;
            break;

        case 2:
            value = -30f;
            break;

        case 3:
            value = -45f;
            break;

        case 4:
            value = -60f;
            break;

        case 5:
            value = -80f;
            break;
        }

        var        mod        = new StatModifier(value, StatModType.PercentageAdd, armorBreakDebuffName);
        DebuffData debuffData = new DebuffData
        {
            icon        = armorBreakIcon,
            name        = armorBreakDebuffName,
            duration    = duration,
            applyAffect = delegate { armorStat.AddModifier(mod); },
            endAffect   = delegate { armorStat.RemoveModifier(mod); },
        };

        ApplyDebuff(target, debuffData);
    }
Beispiel #8
0
    private void ApplyDebuff(Character target, DebuffData data)
    {
        if (target.iconController == null)
        {
            return;
        }

        UnityEvent affectEvent = new UnityEvent();
        UnityEvent endEvent    = new UnityEvent();

        affectEvent.AddListener(data.applyAffect);
        endEvent.AddListener(data.endAffect);

        // Pop Text Hint
        affectEvent.AddListener(delegate { target.PopTextMessage(data.name, Color.white, 0.8f); });
        endEvent.AddListener(delegate { target.PopTextMessage("-" + data.name, Color.white, 0.4f); });
        // Add icon remove event when debuff end.
        endEvent.AddListener(delegate { target.iconController.RemoveIcon(data.name); });

        target.buffController.AddBuff(data.name, affectEvent, endEvent, data.duration);
        target.iconController.SetIcon(data.name, data.icon);
    }
Beispiel #9
0
 public DebuffData(DebuffData old)
 {
     debuff         = old.debuff;
     fTimeRemaining = old.fTimeRemaining;
     debuffIcon     = old.debuffIcon;
 }
Beispiel #10
0
    public override bool Damage(Damage damage, float fMultiplier, float fStunTime, float fAdditionalCritChance, float fAdditionalCritMultiplier, float fVampirism, float fAdditionalDamage)
    {
        if (IsDead())
        {
            return(true);
        }

        if (fStunTime > 0.0f)
        {
            DebuffData data = new DebuffData();
            data.debuff         = DebuffData.Debuff.STUNNED;
            data.fTimeRemaining = fStunTime;
            data.debuffIcon     = Core.GetMinionTemplateManager().stunPFXPrefab;
            PFX_DebuffIcon debuffIcon = minion.ApplyDebuff(data, fStunTime);
            if (debuffIcon != null)
            {
                debuffIcon.transform.SetParent(transform);
                debuffIcon.transform.localPosition = Vector3.zero;
            }
        }

        if (damage.fPushAmount > 0.0f)
        {
            fPushAmount = damage.fPushAmount;
        }

        float fCritChance = damage.fCritChance + fAdditionalCritChance;
        bool  bCrit       = Random.Range(0.0f, 1.0f) < fCritChance;

        if (IsSpotted())
        {
            bCrit = true;
        }

        float fCritMultiplier = bCrit ? damage.fCritMultiplier + fAdditionalCritMultiplier : 1.0f;

        if (damage.GetSlotType() == MinionSlotType.MELEE)
        {
            fMultiplier *= GetMeleeDamageModifierFromDebuffs();
        }
        if (damage.GetSlotType() == MinionSlotType.RANGED)
        {
            OnRangedHit();
        }

        fMultiplier *= GetDamageModifierFromDebuffs();

        // Give vampiric health to players
        Core.GetCurrentRoster().HealGroup(damage.GetSlotType(), (damage.fAmount + fAdditionalDamage) * fMultiplier * fCritMultiplier * fVampirism);

        if (damage.onHitEffect != null)
        {
            damage.onHitEffect.OnTriggered(null, null);
        }

        int iDamage = Mathf.FloorToInt((damage.fAmount + fAdditionalDamage) * fMultiplier * fCritMultiplier);

        if (bCrit)
        {
            Core.IncrementStat("CRITICAL_HITS", 1);
        }
        Core.IncrementStat("DAMAGE_DEALT", iDamage);
        if (iDamage >= 500)
        {
            Core.TriggerAchievement(damage.GetSlotType() == MinionSlotType.MELEE ? "BRUTAL" : "SNIPER");
        }

        MakeDamageNumbers(iDamage, bCrit ? Core.GetMinionTemplateManager().criticalDamage : Core.GetMinionTemplateManager().enemyDamage);

        bool bDead = minion.Damage(damage, fMultiplier * fCritMultiplier, fAdditionalDamage);

        if (bDead)
        {
            minion.template.OnDeath(this);
            Core.GetLevel().EnemyDied(this);
            render.PlayDeathAnimation();
            render.transform.SetParent(null);
            Destroy(gameObject);
        }

        return(bDead);
    }