成就系统 巨大修改 新的ui 黑白效果 等一堆
This commit is contained in:
@@ -4,13 +4,13 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// EffectSystem 提供技能效果的统一分发接口。
|
||||
/// - 选择器范围(Selector)决定目标集合(自己、全体友军、除自己外友军、相邻友军、场上敌人、所有人)
|
||||
/// - 效果类型(EffectType)定义了即时/持续的伤害/治疗/增益/减益等。
|
||||
/// EffectSystem �ṩ����Ч����ͳһ�ַ��ӿڡ�
|
||||
/// - ѡ������Χ��Selector������Ŀ�꼯�ϣ��Լ���ȫ���Ѿ������Լ����Ѿ��������Ѿ������ϵ��ˡ������ˣ�
|
||||
/// - Ч�����ͣ�EffectType�������˼�ʱ/�������˺�/����/����/����ȡ�
|
||||
///
|
||||
/// 目标实体应实现 ICombatant 接口以便 EffectSystem 能调用统一方法来处理伤害/治疗/增益等;如果没有实现,会在日志中提醒。
|
||||
/// Ŀ��ʵ��Ӧʵ�� ICombatant �ӿ��Ա� EffectSystem �ܵ���ͳһ�����������˺�/����/����ȣ����û��ʵ�֣�������־�����ѡ�
|
||||
///
|
||||
/// 该脚本为框架:不包含具体技能配置,只提供 ApplyEffect(...) 等方法供其他脚本调用。
|
||||
/// �ýű�Ϊ��ܣ����������弼�����ã�ֻ�ṩ ApplyEffect(...) �ȷ����������ű����á�
|
||||
/// </summary>
|
||||
public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
@@ -23,22 +23,32 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ApplyEffect: 对指定选择器范围内目标应用效果。
|
||||
/// - selector: 目标选择器
|
||||
/// - effectType: 效果类型(即时/持续等)
|
||||
/// - amount: 数值(伤害或治疗总量或效果强度)
|
||||
/// - duration: 持续时间(对持续效果或 Buff/Debuff 有效),即时效果可为 0
|
||||
/// - source: 发起者(用于 Self/AlliesExceptSelf 判断或记录)
|
||||
/// - specificTarget: 当 selector 为 CurrentEnemies 且只想指定单体时可传入具体目标
|
||||
/// - tickInterval: 持续效果的 tick 间隔(秒),默认 1 秒
|
||||
/// ApplyEffect: ��ָ��ѡ������Χ��Ŀ��Ӧ��Ч����
|
||||
/// - selector: Ŀ��ѡ����
|
||||
/// - effectType: Ч�����ͣ���ʱ/�����ȣ�
|
||||
/// - amount: ��ֵ���˺�������������Ч��ǿ�ȣ�
|
||||
/// - duration: ����ʱ�䣨�Գ���Ч���� Buff/Debuff ��Ч������ʱЧ����Ϊ 0
|
||||
/// - source: �����ߣ����� Self/AlliesExceptSelf �жϻ��¼��
|
||||
/// - specificTarget: �� selector Ϊ CurrentEnemies ��ֻ��ָ������ʱ�ɴ������Ŀ��
|
||||
/// - tickInterval: ����Ч���� tick ������룩��Ĭ�� 1 ��
|
||||
/// </summary>
|
||||
public void ApplyEffect(Selector selector, EffectType effectType, float amount, float duration = 0f, GameObject source = null, GameObject specificTarget = null, float tickInterval = 1f)
|
||||
{
|
||||
List<GameObject> targets = ResolveTargets(selector, source, specificTarget);
|
||||
// If caller provided a specificTarget, prefer it as the single target regardless of selector.
|
||||
// Many callers pass specificTarget when they intend to hit a single unit (ally or enemy).
|
||||
List<GameObject> targets;
|
||||
if (specificTarget != null)
|
||||
{
|
||||
targets = new List<GameObject> { specificTarget };
|
||||
}
|
||||
else
|
||||
{
|
||||
targets = ResolveTargets(selector, source, specificTarget);
|
||||
}
|
||||
|
||||
if (targets == null || targets.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"[EffectSystem] No targets resolved for selector={selector}");
|
||||
Debug.LogWarning($"[EffectSystem] No targets resolved for selector={selector} specificTarget={(specificTarget ? specificTarget.name : "null")}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,9 +77,16 @@ public class EffectSystem : MonoBehaviour
|
||||
break;
|
||||
|
||||
case EffectType.DamageSingleAlly:
|
||||
// damage a single ally (first target)
|
||||
if (targets.Count > 0)
|
||||
// damage a single ally (first target) - if selector resolved multiple allies, apply to all to support "AllAllies + DamageSingleAlly" designer usage
|
||||
if (targets.Count == 1)
|
||||
{
|
||||
ApplyInstantDamage(targets[0], amount, source);
|
||||
}
|
||||
else if (targets.Count > 1)
|
||||
{
|
||||
foreach (var t in targets)
|
||||
ApplyInstantDamage(t, amount, source);
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.DamageOverTimeAlly:
|
||||
@@ -155,6 +172,235 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
break;
|
||||
|
||||
// New handling for max HP / max Mana modifications via EffectSystem (mirrors direct path in SkillBuilder)
|
||||
case EffectType.IncreaseMaxHP:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxHP(ally.maxHP + Mathf.CeilToInt(amount), false);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy))
|
||||
{
|
||||
enemy.SetMaxHP(enemy.maxHP + Mathf.CeilToInt(amount), false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.DecreaseMaxHP:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxHP(Mathf.Max(1, ally.maxHP - Mathf.CeilToInt(amount)), false);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy2))
|
||||
{
|
||||
enemy2.SetMaxHP(Mathf.Max(1, enemy2.maxHP - Mathf.CeilToInt(amount)), false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.IncreaseMaxMana:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxMana(ally.maxMana + Mathf.CeilToInt(amount), false);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy3))
|
||||
{
|
||||
enemy3.SetMaxMana(enemy3.maxMana + Mathf.CeilToInt(amount), false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.DecreaseMaxMana:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
ally.SetMaxMana(Mathf.Max(1, ally.maxMana - Mathf.CeilToInt(amount)), false);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy4))
|
||||
{
|
||||
enemy4.SetMaxMana(Mathf.Max(1, enemy4.maxMana - Mathf.CeilToInt(amount)), false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// New: Increase/Decrease ScoreEfficiency handled by EffectSystem (mirrors SkillBuilder direct path)
|
||||
case EffectType.IncreaseScoreEfficiency:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.scoreEfficiency += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
// temporary additive change, revert after duration
|
||||
StartCoroutine(ApplyTemporaryScoreEfficiencyChangeCoroutine(ally, amount, duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.DecreaseScoreEfficiency:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.scoreEfficiency = Mathf.Max(0f, ally.scoreEfficiency - amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ApplyTemporaryScoreEfficiencyChangeCoroutine(ally, -amount, duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// New: Increase/Decrease Attack handled by EffectSystem (mirrors SkillBuilder direct path)
|
||||
case EffectType.IncreaseAttack:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.attack += delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ApplyTemporaryAttackChangeCoroutine(ally, delta, duration));
|
||||
}
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy5))
|
||||
{
|
||||
int deltaE = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy5.attack += deltaE;
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryAttackChangeCoroutine(enemy5, deltaE, duration));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.DecreaseAttack:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.attack = Mathf.Max(0, ally.attack - delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
// apply decrease now, revert after duration
|
||||
StartCoroutine(ApplyTemporaryAttackChangeCoroutine(ally, -delta, duration));
|
||||
}
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy6))
|
||||
{
|
||||
int deltaE = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
enemy6.attack = Mathf.Max(0, enemy6.attack - deltaE);
|
||||
else
|
||||
StartCoroutine(ApplyTemporaryAttackChangeCoroutine(enemy6, -deltaE, duration));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.IncreaseDamageResistance:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
// amount interpreted as additive delta (0..1). Clamp result 0..0.9 to avoid invulnerability
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.damageResistance = Mathf.Clamp01(ally.damageResistance + amount);
|
||||
Debug.Log($"[EffectSystem] IncreaseDamageResistance applied to {t.name}: new resistance={ally.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ApplyTemporaryDamageResistanceChangeCoroutine(ally.gameObject, amount, duration));
|
||||
}
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemyR))
|
||||
{
|
||||
if (duration <= 0f)
|
||||
{
|
||||
enemyR.damageResistance = Mathf.Clamp01(enemyR.damageResistance + amount);
|
||||
Debug.Log($"[EffectSystem] IncreaseDamageResistance applied to enemy {t.name}: new resistance={enemyR.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ApplyTemporaryDamageResistanceChangeCoroutine(enemyR.gameObject, amount, duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.DecreaseDamageResistance:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.damageResistance = Mathf.Clamp01(ally.damageResistance - amount);
|
||||
Debug.Log($"[EffectSystem] DecreaseDamageResistance applied to {t.name}: new resistance={ally.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// apply negative delta
|
||||
StartCoroutine(ApplyTemporaryDamageResistanceChangeCoroutine(ally.gameObject, -amount, duration));
|
||||
}
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemyR2))
|
||||
{
|
||||
if (duration <= 0f)
|
||||
{
|
||||
enemyR2.damageResistance = Mathf.Clamp01(enemyR2.damageResistance - amount);
|
||||
Debug.Log($"[EffectSystem] DecreaseDamageResistance applied to enemy {t.name}: new resistance={enemyR2.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ApplyTemporaryDamageResistanceChangeCoroutine(enemyR2.gameObject, -amount, duration));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.LogWarning($"[EffectSystem] Unhandled EffectType {effectType}");
|
||||
break;
|
||||
@@ -171,6 +417,9 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
List<GameObject> list = new List<GameObject>();
|
||||
|
||||
// prefer teamUIController when available for authoritative ally/enemy objects
|
||||
var ui = teamUIController.Instance ?? FindObjectOfType<teamUIController>();
|
||||
|
||||
switch (selector)
|
||||
{
|
||||
case Selector.Self:
|
||||
@@ -178,13 +427,39 @@ public class EffectSystem : MonoBehaviour
|
||||
break;
|
||||
|
||||
case Selector.AllAllies:
|
||||
list.AddRange(FindAllAllies());
|
||||
if (ui != null)
|
||||
{
|
||||
int count = ui.allySlotIds != null ? ui.allySlotIds.Count : 5;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var go = ui.GetAllyObjectBySlot(i);
|
||||
if (go != null && !list.Contains(go)) list.Add(go);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.AddRange(FindAllAllies());
|
||||
}
|
||||
break;
|
||||
|
||||
case Selector.AllAlliesExceptSelf:
|
||||
list.AddRange(FindAllAllies());
|
||||
if (source != null)
|
||||
list.RemoveAll(g => g == null || g == source || g.gameObject == source.gameObject);
|
||||
if (ui != null)
|
||||
{
|
||||
int count = ui.allySlotIds != null ? ui.allySlotIds.Count : 5;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var go = ui.GetAllyObjectBySlot(i);
|
||||
if (go != null && !list.Contains(go)) list.Add(go);
|
||||
}
|
||||
if (source != null)
|
||||
list.RemoveAll(g => g == null || g == source || g.gameObject == source.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.AddRange(FindAllAllies());
|
||||
if (source != null)
|
||||
list.RemoveAll(g => g == null || g == source || g.gameObject == source.gameObject);
|
||||
}
|
||||
break;
|
||||
|
||||
case Selector.AdjacentAllies:
|
||||
@@ -214,7 +489,6 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
if (slotIndex >= 0)
|
||||
{
|
||||
var ui = teamUIController.Instance;
|
||||
if (ui != null)
|
||||
{
|
||||
try
|
||||
@@ -283,18 +557,41 @@ public class EffectSystem : MonoBehaviour
|
||||
var uniq = new List<GameObject>();
|
||||
foreach (var g in list)
|
||||
if (!uniq.Contains(g)) uniq.Add(g);
|
||||
|
||||
// Debug: log resolved targets for diagnosis
|
||||
if (uniq.Count == 0)
|
||||
Debug.LogWarning($"[EffectSystem] ResolveTargets -> selector={selector} returned 0 targets (source={(source ? source.name : "null")}, specificTarget={(specificTarget ? specificTarget.name : "null")})");
|
||||
else
|
||||
Debug.Log($"[EffectSystem] ResolveTargets -> selector={selector} resolved {uniq.Count} targets: {string.Join(",", uniq.ConvertAll(x => x != null ? x.name : "null"))}");
|
||||
|
||||
return uniq;
|
||||
}
|
||||
|
||||
private IEnumerable<GameObject> FindAllAllies()
|
||||
{
|
||||
List<GameObject> allies = new List<GameObject>();
|
||||
// try names ally_01..ally_05
|
||||
// prefer teamUIController if available to get authoritative ally objects
|
||||
var ui = teamUIController.Instance;
|
||||
if (ui != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
int count = ui.allySlotIds != null ? ui.allySlotIds.Count : 5;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var go = ui.GetAllyObjectBySlot(i);
|
||||
if (go != null && !allies.Contains(go)) allies.Add(go);
|
||||
}
|
||||
}
|
||||
catch { /* ignore and fallback */ }
|
||||
}
|
||||
|
||||
// fallback: try names ally_01..ally_05 (keeps compatibility with legacy scene setups)
|
||||
for (int i = 1; i <= 5; i++)
|
||||
{
|
||||
string name = $"ally_0{i}"; // ally_01..ally_05
|
||||
var go = GameObject.Find(name);
|
||||
if (go != null) allies.Add(go);
|
||||
if (go != null && !allies.Contains(go)) allies.Add(go);
|
||||
}
|
||||
|
||||
// also include objects tagged "Ally"
|
||||
@@ -341,13 +638,53 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
|
||||
#region Instant / OverTime Helpers
|
||||
private bool AreAllEnemiesDead()
|
||||
{
|
||||
var enemies = GameObject.FindObjectsOfType<EnemyCombatant>(true);
|
||||
if (enemies.Length == 0) return true;
|
||||
|
||||
foreach (var e in enemies)
|
||||
{
|
||||
if (e != null && !e.IsDead && e.currentHP > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ApplyInstantDamage(GameObject target, float amount, GameObject source)
|
||||
{
|
||||
if (target == null) return;
|
||||
|
||||
// If target is an enemy, check if all enemies are already dead
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
{
|
||||
Debug.Log($"[EffectSystem] Skip ApplyInstantDamage to {target.name} because all enemies are dead.");
|
||||
return;
|
||||
}
|
||||
|
||||
var comp = target.GetComponent<ICombatant>();
|
||||
if (comp != null)
|
||||
{
|
||||
comp.ReceiveDamage(amount, source);
|
||||
|
||||
// Record stats if source is an ally
|
||||
if (source != null && target.GetComponent<EnemyCombatant>() != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null)
|
||||
{
|
||||
teamUIController.Instance.RecordDamage(ally.slotIndex, amount);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -362,6 +699,16 @@ public class EffectSystem : MonoBehaviour
|
||||
if (comp != null)
|
||||
{
|
||||
comp.ReceiveHeal(amount, source);
|
||||
|
||||
// Record stats if source is an ally
|
||||
if (source != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null)
|
||||
{
|
||||
teamUIController.Instance.RecordHeal(ally.slotIndex, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -381,7 +728,23 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
if (duration <= 0f)
|
||||
{
|
||||
// check death state for immediate damage
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
{
|
||||
Debug.Log($"[EffectSystem] Skip DOT (immediate) to {target.name} because all enemies are dead.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
comp.ReceiveDamage(totalAmount, source);
|
||||
// Record stats
|
||||
if (source != null && target.GetComponent<EnemyCombatant>() != 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;
|
||||
}
|
||||
|
||||
@@ -390,7 +753,25 @@ public class EffectSystem : MonoBehaviour
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
if (target == null) yield break;
|
||||
|
||||
// check death state inside loop
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
{
|
||||
Debug.Log($"[EffectSystem] Stopping DOT to {target.name} because all enemies are dead.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
comp.ReceiveDamage(perTick, source);
|
||||
// Record stats
|
||||
if (source != null && target.GetComponent<EnemyCombatant>() != 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;
|
||||
}
|
||||
@@ -409,6 +790,12 @@ public class EffectSystem : MonoBehaviour
|
||||
if (duration <= 0f)
|
||||
{
|
||||
comp.ReceiveHeal(totalAmount, source);
|
||||
// Record stats
|
||||
if (source != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordHeal(ally.slotIndex, totalAmount);
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -417,7 +804,14 @@ public class EffectSystem : MonoBehaviour
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
if (target == null) yield break;
|
||||
comp.ReceiveHeal(perTick, source);
|
||||
// Record stats
|
||||
if (source != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordHeal(ally.slotIndex, perTick);
|
||||
}
|
||||
yield return new WaitForSeconds(tickInterval);
|
||||
elapsed += tickInterval;
|
||||
}
|
||||
@@ -438,7 +832,16 @@ public class EffectSystem : MonoBehaviour
|
||||
if (duration <= 0f)
|
||||
{
|
||||
// immediate add totalAmount to mana if ally present
|
||||
if (ally != null) ally.ModifyMana(Mathf.CeilToInt(totalAmount), true);
|
||||
if (ally != null)
|
||||
{
|
||||
ally.ModifyMana(Mathf.CeilToInt(totalAmount), true, true);
|
||||
// Record stats
|
||||
if (source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordMana(sourceAlly.slotIndex, totalAmount);
|
||||
}
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -447,7 +850,17 @@ public class EffectSystem : MonoBehaviour
|
||||
float elapsed = 0f;
|
||||
while (elapsed < duration)
|
||||
{
|
||||
if (ally != null) ally.ModifyMana(Mathf.CeilToInt(perTick), true);
|
||||
if (target == null) yield break;
|
||||
if (ally != null)
|
||||
{
|
||||
ally.ModifyMana(Mathf.CeilToInt(perTick), true, true);
|
||||
// Record stats
|
||||
if (source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordMana(sourceAlly.slotIndex, perTick);
|
||||
}
|
||||
}
|
||||
yield return new WaitForSeconds(tickInterval);
|
||||
elapsed += tickInterval;
|
||||
}
|
||||
@@ -483,5 +896,59 @@ public class EffectSystem : MonoBehaviour
|
||||
yield return new WaitForSeconds(debuff.duration);
|
||||
comp.RemoveBuff(debuff.buffId);
|
||||
}
|
||||
|
||||
// Coroutine to apply temporary scoreEfficiency change and revert after duration
|
||||
private IEnumerator ApplyTemporaryScoreEfficiencyChangeCoroutine(AllyCombatant ally, float delta, float duration)
|
||||
{
|
||||
if (ally == null) yield break;
|
||||
ally.scoreEfficiency = Mathf.Max(0f, ally.scoreEfficiency + delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
ally.scoreEfficiency = Mathf.Max(0f, ally.scoreEfficiency - delta);
|
||||
}
|
||||
|
||||
// Coroutine to apply temporary damageResistance change and revert after duration
|
||||
private IEnumerator ApplyTemporaryDamageResistanceChangeCoroutine(GameObject target, float delta, float duration)
|
||||
{
|
||||
if (target == null) yield break;
|
||||
// support both ally and enemy
|
||||
var ally = target.GetComponent<AllyCombatant>();
|
||||
if (ally != null)
|
||||
{
|
||||
float before = ally.damageResistance;
|
||||
ally.damageResistance = Mathf.Clamp01(ally.damageResistance + delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
// revert by subtracting delta, clamp
|
||||
ally.damageResistance = Mathf.Clamp01(ally.damageResistance - delta);
|
||||
yield break;
|
||||
}
|
||||
|
||||
var enemy = target.GetComponent<EnemyCombatant>();
|
||||
if (enemy != null)
|
||||
{
|
||||
float beforeE = enemy.damageResistance;
|
||||
enemy.damageResistance = Mathf.Clamp01(enemy.damageResistance + delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
enemy.damageResistance = Mathf.Clamp01(enemy.damageResistance - delta);
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
// Coroutine to apply temporary attack change for AllyCombatant
|
||||
private IEnumerator ApplyTemporaryAttackChangeCoroutine(AllyCombatant ally, int delta, float duration)
|
||||
{
|
||||
if (ally == null) yield break;
|
||||
ally.attack = Mathf.Max(0, ally.attack + delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
ally.attack = Mathf.Max(0, ally.attack - delta);
|
||||
}
|
||||
|
||||
// Coroutine to apply temporary attack change for EnemyCombatant
|
||||
private IEnumerator ApplyTemporaryAttackChangeCoroutine(EnemyCombatant enemy, int delta, float duration)
|
||||
{
|
||||
if (enemy == null) yield break;
|
||||
enemy.attack = Mathf.Max(0, enemy.attack + delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
enemy.attack = Mathf.Max(0, enemy.attack - delta);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user