超大量的更新 修复很多问题,gameplay特效初步
This commit is contained in:
@@ -4,13 +4,13 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// EffectSystem �ṩ����Ч����ͳһ�ַ��ӿڡ�
|
||||
/// - ѡ������Χ��Selector������Ŀ�꼯�ϣ��Լ���ȫ���Ѿ������Լ����Ѿ��������Ѿ������ϵ��ˡ������ˣ�
|
||||
/// - Ч�����ͣ�EffectType�������˼�ʱ/�������˺�/����/����/����ȡ�?
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
///
|
||||
/// Ŀ��ʵ��Ӧʵ�� ICombatant �ӿ��Ա� EffectSystem �ܵ���ͳһ�����������˺�/����/����ȣ����û��ʵ�֣�������־�����ѡ�
|
||||
/// Documentation text normalized.
|
||||
///
|
||||
/// �ýű�Ϊ��ܣ����������弼�����ã�ֻ��?ApplyEffect(...) �ȷ����������ű����á�
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
@@ -34,14 +34,14 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ApplyEffect: ��ָ��ѡ������Χ��Ŀ��Ӧ��Ч����
|
||||
/// - selector: Ŀ��ѡ����
|
||||
/// - effectType: Ч�����ͣ���ʱ/�����ȣ�
|
||||
/// - amount: ��ֵ���˺�������������Ч��ǿ�ȣ�
|
||||
/// - duration: ����ʱ�䣨�Գ���Ч���� Buff/Debuff ��Ч������ʱЧ����Ϊ 0
|
||||
/// - source: �����ߣ����� Self/AlliesExceptSelf �жϻ��¼��?
|
||||
/// - specificTarget: �� selector Ϊ CurrentEnemies ��ֻ��ָ������ʱ�ɴ������Ŀ��?
|
||||
/// - tickInterval: ����Ч���� tick ������룩��Ĭ��?1 ��
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// Documentation text normalized.
|
||||
/// </summary>
|
||||
public void ApplyEffect(Selector selector, EffectType effectType, float amount, float duration = 0f, GameObject source = null, GameObject specificTarget = null, float tickInterval = 1f)
|
||||
{
|
||||
@@ -59,10 +59,42 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
if (targets == null || targets.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"[EffectSystem] No targets resolved for selector={selector} specificTarget={(specificTarget ? specificTarget.name : "null")}");
|
||||
LogVerbose($"[EffectSystem] ApplyEffect: no targets (selector={selector}, source={(source ? source.name : "null")}, specificTarget={(specificTarget ? specificTarget.name : "null")})");
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Projectile Logic ---
|
||||
// Trigger projectile if source exists and is targeting the opposite side
|
||||
if (GfxController.Instance != null && source != null)
|
||||
{
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t != null && t != source)
|
||||
{
|
||||
// Identify if this is an offensive targeting (Ally -> Enemy or Enemy -> Ally)
|
||||
bool sourceIsAlly = source.name.StartsWith("ally_0");
|
||||
bool sourceIsEnemy = source.name == "thisEnemy";
|
||||
bool targetIsAlly = t.name.StartsWith("ally_0");
|
||||
bool targetIsEnemy = t.name == "thisEnemy";
|
||||
|
||||
if ((sourceIsAlly && targetIsEnemy) || (sourceIsEnemy && targetIsAlly))
|
||||
{
|
||||
// Captured target for callback
|
||||
GameObject targetToHit = t;
|
||||
bool isEnemyTarget = targetIsEnemy;
|
||||
|
||||
GfxController.Instance.PlayProjectile(source, t, (finalPos) => {
|
||||
// Only play hit FX when projectile arrives
|
||||
if (targetToHit != null && GfxController.Instance != null)
|
||||
{
|
||||
GfxController.Instance.PlayHitFX(targetToHit, null, isEnemyTarget, finalPos);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (effectType)
|
||||
{
|
||||
case EffectType.DamageSingleEnemy:
|
||||
@@ -126,14 +158,25 @@ public class EffectSystem : MonoBehaviour
|
||||
break;
|
||||
|
||||
case EffectType.BuffDuration:
|
||||
// create a simple buff with id+duration; additional fields can be filled by caller when using Buff instances directly
|
||||
Buff buff = new Buff { buffId = Guid.NewGuid().ToString(), duration = duration };
|
||||
// Generic timed buff: treat amount as a score multiplier (1.5 = +50%, 0.5 = -50%).
|
||||
Buff buff = new Buff
|
||||
{
|
||||
buffId = Guid.NewGuid().ToString(),
|
||||
duration = duration,
|
||||
scoreMultiplier = amount > 0f ? amount : 1f
|
||||
};
|
||||
foreach (var t in targets)
|
||||
StartCoroutine(ApplyTimedBuffCoroutine(t, buff, source));
|
||||
break;
|
||||
|
||||
case EffectType.DebuffDuration:
|
||||
Buff debuff = new Buff { buffId = Guid.NewGuid().ToString(), duration = duration };
|
||||
// Generic timed debuff: treat amount as a score multiplier (usually < 1).
|
||||
Buff debuff = new Buff
|
||||
{
|
||||
buffId = Guid.NewGuid().ToString(),
|
||||
duration = duration,
|
||||
scoreMultiplier = amount > 0f ? amount : 1f
|
||||
};
|
||||
foreach (var t in targets)
|
||||
StartCoroutine(ApplyTimedDebuffCoroutine(t, debuff, source));
|
||||
break;
|
||||
@@ -144,8 +187,16 @@ public class EffectSystem : MonoBehaviour
|
||||
break;
|
||||
|
||||
case EffectType.ReduceEnemyHealOverTime:
|
||||
// create a debuff that marks heal reduction in its description; enforcement depends on ICombatant.ReceiveHeal implementation
|
||||
Buff healReductionDebuff = new Buff { buffId = Guid.NewGuid().ToString(), duration = duration, description = "ReduceHeal" };
|
||||
// Debuff: reduce heals received (healReceivedMultiplier < 1).
|
||||
// amount is interpreted as a reduction ratio in [0..1], so 0.2 means -20% heals, 1 means -100% heals.
|
||||
float reduction = Mathf.Clamp01(amount);
|
||||
Buff healReductionDebuff = new Buff
|
||||
{
|
||||
buffId = Guid.NewGuid().ToString(),
|
||||
duration = duration,
|
||||
description = "ReduceHeal",
|
||||
healReceivedMultiplier = 1f - reduction
|
||||
};
|
||||
foreach (var t in targets)
|
||||
StartCoroutine(ApplyTimedDebuffCoroutine(t, healReductionDebuff, source));
|
||||
break;
|
||||
@@ -191,11 +242,19 @@ public class EffectSystem : MonoBehaviour
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxHP(ally.maxHP + Mathf.CeilToInt(amount), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
ally.SetMaxHP(ally.maxHP + delta, false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxHPDeltaCoroutine(ally, delta, duration));
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy))
|
||||
{
|
||||
enemy.SetMaxHP(enemy.maxHP + Mathf.CeilToInt(amount), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy.SetMaxHP(enemy.maxHP + delta, false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxHPDeltaCoroutine(enemy, delta, duration));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -207,11 +266,19 @@ public class EffectSystem : MonoBehaviour
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxHP(Mathf.Max(1, ally.maxHP - Mathf.CeilToInt(amount)), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
ally.SetMaxHP(Mathf.Max(1, ally.maxHP - delta), false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxHPDeltaCoroutine(ally, -delta, duration));
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy2))
|
||||
{
|
||||
enemy2.SetMaxHP(Mathf.Max(1, enemy2.maxHP - Mathf.CeilToInt(amount)), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy2.SetMaxHP(Mathf.Max(1, enemy2.maxHP - delta), false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxHPDeltaCoroutine(enemy2, -delta, duration));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -223,11 +290,19 @@ public class EffectSystem : MonoBehaviour
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxMana(ally.maxMana + Mathf.CeilToInt(amount), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
ally.SetMaxMana(ally.maxMana + delta, false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxManaDeltaCoroutine(ally, delta, duration));
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy3))
|
||||
{
|
||||
enemy3.SetMaxMana(enemy3.maxMana + Mathf.CeilToInt(amount), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy3.SetMaxMana(enemy3.maxMana + delta, false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxManaDeltaCoroutine(enemy3, delta, duration));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -239,11 +314,19 @@ public class EffectSystem : MonoBehaviour
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxMana(Mathf.Max(1, ally.maxMana - Mathf.CeilToInt(amount)), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
ally.SetMaxMana(Mathf.Max(1, ally.maxMana - delta), false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxManaDeltaCoroutine(ally, -delta, duration));
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy4))
|
||||
{
|
||||
enemy4.SetMaxMana(Mathf.Max(1, enemy4.maxMana - Mathf.CeilToInt(amount)), false);
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy4.SetMaxMana(Mathf.Max(1, enemy4.maxMana - delta), false);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryMaxManaDeltaCoroutine(enemy4, -delta, duration));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -310,7 +393,7 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
int deltaE = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy5.attack += deltaE;
|
||||
enemy5.ModifyAttack(deltaE);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryAttackChangeCoroutine(enemy5, deltaE, duration));
|
||||
}
|
||||
@@ -339,7 +422,7 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
int deltaE = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy6.attack = Mathf.Max(0, enemy6.attack - deltaE);
|
||||
enemy6.ModifyAttack(-deltaE);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryAttackChangeCoroutine(enemy6, -deltaE, duration));
|
||||
}
|
||||
@@ -430,6 +513,56 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.GrantExtraPerfect:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally == null) continue;
|
||||
if (ally.IsDead) continue;
|
||||
|
||||
int slot = ally.slotIndex;
|
||||
|
||||
// Update judgement counts (for settlement UI).
|
||||
var sm = ScoreManager.Instance;
|
||||
if (sm != null)
|
||||
{
|
||||
sm.countPerfect += 1;
|
||||
if (slot >= 0 && slot < sm.trackPerfectCounts.Length) sm.trackPerfectCounts[slot] += 1;
|
||||
}
|
||||
|
||||
// Grant score as if a Perfect happened on this track.
|
||||
try
|
||||
{
|
||||
int pmDelta = ally.AddScoreForJudge("Perfect");
|
||||
float eff = ally.scoreEfficiency;
|
||||
sm?.AddPmScoreForTrack(slot, pmDelta, eff);
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Trigger note-hit hooks as a virtual Perfect event (mana gain, damage, and Perfect-triggered skills).
|
||||
try
|
||||
{
|
||||
if (SkillBuilder.Instance != null)
|
||||
{
|
||||
string uid = $"virtualPerfect:{slot}:{Time.frameCount}:{Guid.NewGuid()}";
|
||||
SkillBuilder.Instance.NotifyNoteHit(slot, "Perfect", SkillDefinition.NoteTypeTrigger.Tap, uid);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.RedirectSelfDamageToAdjacent:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally == null) continue;
|
||||
ally.ActivateSelfDamageRedirectToAdjacent(duration);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.LogWarning($"[EffectSystem] Unhandled EffectType {effectType}");
|
||||
break;
|
||||
@@ -587,9 +720,21 @@ public class EffectSystem : MonoBehaviour
|
||||
foreach (var g in list)
|
||||
if (!uniq.Contains(g)) uniq.Add(g);
|
||||
|
||||
// Debug: log resolved targets for diagnosis
|
||||
// Filter out dead combatants so they won't receive further effects (damage/score/etc.).
|
||||
// This prevents "dead units still get hit / still gain score" edge cases.
|
||||
uniq.RemoveAll(go =>
|
||||
{
|
||||
if (go == null) return true;
|
||||
var ally = go.GetComponent<AllyCombatant>();
|
||||
if (ally != null) return ally.IsDead;
|
||||
var enemy = go.GetComponent<EnemyCombatant>();
|
||||
if (enemy != null) return enemy.IsDead || enemy.currentHP <= 0;
|
||||
return false;
|
||||
});
|
||||
|
||||
// Debug: log resolved targets for diagnosis (guarded to avoid log spam in normal gameplay).
|
||||
if (uniq.Count == 0)
|
||||
Debug.LogWarning($"[EffectSystem] ResolveTargets -> selector={selector} returned 0 targets (source={(source ? source.name : "null")}, specificTarget={(specificTarget ? specificTarget.name : "null")})");
|
||||
LogVerbose($"[EffectSystem] ResolveTargets -> selector={selector} returned 0 targets (source={(source ? source.name : "null")}, specificTarget={(specificTarget ? specificTarget.name : "null")})");
|
||||
else
|
||||
LogVerbose($"[EffectSystem] ResolveTargets -> selector={selector} resolved {uniq.Count} targets: {string.Join(",", uniq.ConvertAll(x => x != null ? x.name : "null"))}");
|
||||
|
||||
@@ -656,8 +801,14 @@ public class EffectSystem : MonoBehaviour
|
||||
catch { }
|
||||
|
||||
// Also include a single named instance if present
|
||||
var single = GameObject.Find("thisEnemy");
|
||||
if (single != null && !_cachedEnemies.Contains(single)) _cachedEnemies.Add(single);
|
||||
// Note: GameObject.Find only works on active objects.
|
||||
// We already use FindObjectsByType with Include Inactive above, which is safer.
|
||||
// If we really need to find "thisEnemy" by name even if inactive, we should do it differently.
|
||||
try
|
||||
{
|
||||
var single = GameObject.Find("thisEnemy");
|
||||
if (single != null && !_cachedEnemies.Contains(single)) _cachedEnemies.Add(single);
|
||||
} catch { }
|
||||
|
||||
// Finally include any objects tagged "Enemy" (if tag exists)
|
||||
try
|
||||
@@ -672,7 +823,7 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
|
||||
#region Instant / OverTime Helpers
|
||||
private bool AreAllEnemiesDead()
|
||||
public bool AreAllEnemiesDead()
|
||||
{
|
||||
var enemies = FindAllEnemies();
|
||||
foreach (var go in enemies)
|
||||
@@ -691,8 +842,14 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
if (target == null) return;
|
||||
|
||||
// Skip dead targets (prevents edge cases where something bypasses ResolveTargets filtering).
|
||||
var targetAlly = target.GetComponent<AllyCombatant>();
|
||||
if (targetAlly != null && targetAlly.IsDead) return;
|
||||
var targetEnemy = target.GetComponent<EnemyCombatant>();
|
||||
if (targetEnemy != null && (targetEnemy.IsDead || targetEnemy.currentHP <= 0)) return;
|
||||
|
||||
// If target is an enemy, check if all enemies are already dead
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
if (targetEnemy != null && AreAllEnemiesDead())
|
||||
{
|
||||
LogVerbose($"[EffectSystem] Skip ApplyInstantDamage to {target.name} because all enemies are dead.");
|
||||
return;
|
||||
@@ -714,7 +871,6 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
|
||||
// Record damage taken if target is an ally
|
||||
var targetAlly = target.GetComponent<AllyCombatant>();
|
||||
if (targetAlly != null && teamUIController.Instance != null)
|
||||
{
|
||||
teamUIController.Instance.RecordDamageTaken(targetAlly.slotIndex, amount);
|
||||
@@ -760,10 +916,16 @@ public class EffectSystem : MonoBehaviour
|
||||
yield break;
|
||||
}
|
||||
|
||||
var targetAlly = target.GetComponent<AllyCombatant>();
|
||||
var targetEnemy = target.GetComponent<EnemyCombatant>();
|
||||
// Stop immediately if the target is already dead.
|
||||
if (targetAlly != null && targetAlly.IsDead) yield break;
|
||||
if (targetEnemy != null && (targetEnemy.IsDead || targetEnemy.currentHP <= 0)) yield break;
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
// check death state for immediate damage
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
if (targetEnemy != null && AreAllEnemiesDead())
|
||||
{
|
||||
LogVerbose($"[EffectSystem] Skip DOT (immediate) to {target.name} because all enemies are dead.");
|
||||
yield break;
|
||||
@@ -771,13 +933,12 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
comp.ReceiveDamage(totalAmount, source);
|
||||
// Record stats
|
||||
if (source != null && target.GetComponent<EnemyCombatant>() != null)
|
||||
if (source != null && targetEnemy != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamage(ally.slotIndex, totalAmount);
|
||||
}
|
||||
// Record damage taken
|
||||
var targetAlly = target.GetComponent<AllyCombatant>();
|
||||
if (targetAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamageTaken(targetAlly.slotIndex, totalAmount);
|
||||
yield break;
|
||||
}
|
||||
@@ -790,7 +951,9 @@ public class EffectSystem : MonoBehaviour
|
||||
if (target == null) yield break;
|
||||
|
||||
// check death state inside loop
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
if (targetAlly != null && targetAlly.IsDead) yield break;
|
||||
if (targetEnemy != null && (targetEnemy.IsDead || targetEnemy.currentHP <= 0)) yield break;
|
||||
if (targetEnemy != null && AreAllEnemiesDead())
|
||||
{
|
||||
LogVerbose($"[EffectSystem] Stopping DOT to {target.name} because all enemies are dead.");
|
||||
yield break;
|
||||
@@ -798,13 +961,12 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
comp.ReceiveDamage(perTick, source);
|
||||
// Record stats
|
||||
if (source != null && target.GetComponent<EnemyCombatant>() != null)
|
||||
if (source != null && targetEnemy != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamage(ally.slotIndex, perTick);
|
||||
}
|
||||
// Record damage taken
|
||||
var targetAlly = target.GetComponent<AllyCombatant>();
|
||||
if (targetAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamageTaken(targetAlly.slotIndex, perTick);
|
||||
yield return new WaitForSeconds(tickInterval);
|
||||
elapsed += tickInterval;
|
||||
@@ -870,7 +1032,7 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
ally.ModifyMana(Mathf.CeilToInt(totalAmount), true, true);
|
||||
// Record stats
|
||||
if (source != null)
|
||||
if (totalAmount > 0f && source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordMana(sourceAlly.slotIndex, totalAmount);
|
||||
@@ -889,7 +1051,7 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
ally.ModifyMana(Mathf.CeilToInt(perTick), true, true);
|
||||
// Record stats
|
||||
if (source != null)
|
||||
if (perTick > 0f && source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordMana(sourceAlly.slotIndex, perTick);
|
||||
@@ -980,9 +1142,45 @@ public class EffectSystem : MonoBehaviour
|
||||
private IEnumerator ApplyTemporaryAttackChangeCoroutine(EnemyCombatant enemy, int delta, float duration)
|
||||
{
|
||||
if (enemy == null) yield break;
|
||||
enemy.attack = Mathf.Max(0, enemy.attack + delta);
|
||||
enemy.ModifyAttack(delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
enemy.attack = Mathf.Max(0, enemy.attack - delta);
|
||||
enemy.ModifyAttack(-delta);
|
||||
}
|
||||
|
||||
private IEnumerator ApplyTemporaryMaxHPDeltaCoroutine(AllyCombatant ally, int delta, float duration)
|
||||
{
|
||||
if (ally == null) yield break;
|
||||
ally.SetMaxHP(Mathf.Max(1, ally.maxHP + delta), false);
|
||||
yield return new WaitForSeconds(duration);
|
||||
if (ally == null) yield break;
|
||||
ally.SetMaxHP(Mathf.Max(1, ally.maxHP - delta), false);
|
||||
}
|
||||
|
||||
private IEnumerator ApplyTemporaryMaxHPDeltaCoroutine(EnemyCombatant enemy, int delta, float duration)
|
||||
{
|
||||
if (enemy == null) yield break;
|
||||
enemy.SetMaxHP(Mathf.Max(1, enemy.maxHP + delta), false);
|
||||
yield return new WaitForSeconds(duration);
|
||||
if (enemy == null) yield break;
|
||||
enemy.SetMaxHP(Mathf.Max(1, enemy.maxHP - delta), false);
|
||||
}
|
||||
|
||||
private IEnumerator ApplyTemporaryMaxManaDeltaCoroutine(AllyCombatant ally, int delta, float duration)
|
||||
{
|
||||
if (ally == null) yield break;
|
||||
ally.SetMaxMana(Mathf.Max(1, ally.maxMana + delta), false);
|
||||
yield return new WaitForSeconds(duration);
|
||||
if (ally == null) yield break;
|
||||
ally.SetMaxMana(Mathf.Max(1, ally.maxMana - delta), false);
|
||||
}
|
||||
|
||||
private IEnumerator ApplyTemporaryMaxManaDeltaCoroutine(EnemyCombatant enemy, int delta, float duration)
|
||||
{
|
||||
if (enemy == null) yield break;
|
||||
enemy.SetMaxMana(Mathf.Max(1, enemy.maxMana + delta), false);
|
||||
yield return new WaitForSeconds(duration);
|
||||
if (enemy == null) yield break;
|
||||
enemy.SetMaxMana(Mathf.Max(1, enemy.maxMana - delta), false);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user