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); }
/// <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); }
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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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); }
public DebuffData(DebuffData old) { debuff = old.debuff; fTimeRemaining = old.fTimeRemaining; debuffIcon = old.debuffIcon; }
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); }