修了很多bug和增加功能,优化不少问题
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -163,7 +163,7 @@ public class SkillBuilder : MonoBehaviour
|
||||
var allyGO = GetAllyObjectBySlot(trackIndex);
|
||||
if (allyGO == null) return;
|
||||
var ally = allyGO.GetComponent<AllyCombatant>();
|
||||
if (ally != null && ally.IsDead) return; // dead allies should not gain mana / take miss damage / deal note-hit damage
|
||||
if (ally != null && (ally.IsDead || ally.maxHP == 0)) return; // dead or empty allies should not gain mana / take miss damage / deal note-hit damage
|
||||
var so = GetAllyHeroSOBySlot(trackIndex);
|
||||
// try to obtain per-level params from SO if present
|
||||
AllyHero_SO.AllyLevelInfo levelInfo = so != null ? (so.GetEffectiveLevelForCurrentEXP()) : null;
|
||||
@@ -214,7 +214,35 @@ public class SkillBuilder : MonoBehaviour
|
||||
else if (ally != null) mName = ally.name; // fallback to GameObject name
|
||||
SkillTriggerFeedUI.PushMiss(mName);
|
||||
|
||||
float missBase = (levelInfo != null) ? levelInfo.missHpLossBase : missHpLossBase;
|
||||
// --- New Miss Damage Formula ---
|
||||
// Formula: EnemyAttack * DifficultyLevel * 0.03 * AllyMissHpLossBase * (1 - Resistance)
|
||||
// Note: AllyCombatant.ReceiveDamage already applies (1 - Resistance), so we calculate the base here.
|
||||
|
||||
float enemyAtk = 0f;
|
||||
var enemyGO = GameObject.Find("thisEnemy");
|
||||
if (enemyGO != null)
|
||||
{
|
||||
var ec = enemyGO.GetComponent<EnemyCombatant>();
|
||||
if (ec != null) enemyAtk = ec.attack;
|
||||
}
|
||||
|
||||
float diffLevel = 1f;
|
||||
if (BeatmapManager.Instance != null && BeatmapManager.Instance.assignedSongData != null)
|
||||
{
|
||||
int curDiff = BeatmapManager.Instance.assignedDifficulty;
|
||||
if (BeatmapManager.Instance.assignedSongData.chartFiles != null)
|
||||
{
|
||||
var chart = BeatmapManager.Instance.assignedSongData.chartFiles.Find(c => c.difficulty == curDiff);
|
||||
if (chart != null) diffLevel = chart.difficultyLEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
float fixedMult = 0.03f;
|
||||
float allyMissBase = (levelInfo != null) ? levelInfo.missHpLossBase : missHpLossBase;
|
||||
|
||||
float missBase = enemyAtk * diffLevel * fixedMult * allyMissBase;
|
||||
|
||||
LogVerbose($"[SkillBuilder] Miss Damage Calc: Atk({enemyAtk}) * DiffLvl({diffLevel}) * Mult({fixedMult}) * AllyBase({allyMissBase}) = {missBase}");
|
||||
|
||||
// 播放敌人攻击特效,并将伤害逻辑延迟到特效到达时执行
|
||||
bool effectStarted = false;
|
||||
@@ -779,6 +807,64 @@ public class SkillBuilder : MonoBehaviour
|
||||
case EffectType.DecreaseAttack:
|
||||
case EffectType.RedirectNextDamageToSelf:
|
||||
case EffectType.RedirectSelfDamageToAdjacent:
|
||||
case EffectType.RewriteNonMissToPerfect:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Buff redirection (交给我!/都给你!) should affect any "buff-like" effect that is represented
|
||||
// by budeff icons or timed status changes, not only Buff objects.
|
||||
private static bool IsRedirectableBudeffEvent(EffectType effectType)
|
||||
{
|
||||
switch (effectType)
|
||||
{
|
||||
case EffectType.DamageOverTimeEnemy:
|
||||
case EffectType.DamageOverTimeAlly:
|
||||
case EffectType.ReduceEnemyHealOverTime:
|
||||
case EffectType.BuffDuration:
|
||||
case EffectType.DebuffDuration:
|
||||
case EffectType.IncreaseManaOverTime:
|
||||
case EffectType.IncreaseMaxHP:
|
||||
case EffectType.DecreaseMaxHP:
|
||||
case EffectType.IncreaseMaxMana:
|
||||
case EffectType.DecreaseMaxMana:
|
||||
case EffectType.IncreaseScoreEfficiency:
|
||||
case EffectType.DecreaseScoreEfficiency:
|
||||
case EffectType.IncreaseDamageResistance:
|
||||
case EffectType.DecreaseDamageResistance:
|
||||
case EffectType.IncreaseAttack:
|
||||
case EffectType.DecreaseAttack:
|
||||
case EffectType.RedirectNextDamageToSelf:
|
||||
case EffectType.RedirectSelfDamageToAdjacent:
|
||||
case EffectType.RewriteNonMissToPerfect:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Subset for def.operateDirectly branch where effects are applied inside SkillBuilder switch.
|
||||
// Do not include types that fall through to default ExecuteSkill, otherwise redirect would be consumed too early.
|
||||
private static bool IsRedirectableDirectBranchEffect(EffectType effectType)
|
||||
{
|
||||
switch (effectType)
|
||||
{
|
||||
case EffectType.DamageOverTimeEnemy:
|
||||
case EffectType.IncreaseManaOverTime:
|
||||
case EffectType.ReduceEnemyHealOverTime:
|
||||
case EffectType.BuffDuration:
|
||||
case EffectType.DebuffDuration:
|
||||
case EffectType.IncreaseMaxHP:
|
||||
case EffectType.DecreaseMaxHP:
|
||||
case EffectType.IncreaseMaxMana:
|
||||
case EffectType.DecreaseMaxMana:
|
||||
case EffectType.IncreaseScoreEfficiency:
|
||||
case EffectType.DecreaseScoreEfficiency:
|
||||
case EffectType.IncreaseAttack:
|
||||
case EffectType.DecreaseAttack:
|
||||
case EffectType.RedirectNextDamageToSelf:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -1372,14 +1458,23 @@ ResolvedGroup:
|
||||
{
|
||||
if (t == null) continue;
|
||||
|
||||
GameObject target = t;
|
||||
var ally = target.GetComponent<AllyCombatant>();
|
||||
if (ally != null && IsRedirectableDirectBranchEffect(def.effectType))
|
||||
{
|
||||
if (ally.TryRedirectIncomingGenericBuff(out var redirectedAlly) && redirectedAlly != null)
|
||||
{
|
||||
target = redirectedAlly.gameObject;
|
||||
ally = redirectedAlly;
|
||||
}
|
||||
}
|
||||
var ic = target.GetComponent<ICombatant>();
|
||||
|
||||
if (GameConfig.skillDebugMode)
|
||||
{
|
||||
Debug.Log($"<color=#00FFFF>[SkillDebug]</color> <color=#FFD700>ID: {def.skillId}</color> | <color=#00FF00>Trigger: {def.triggerCondition}</color> | <color=#FFA500>Target: {t.name}</color> | <color=#EE82EE>Effect: {def.effectType}</color> | <color=#FF4500>Value: {amountTotal:F2}</color>");
|
||||
Debug.Log($"<color=#00FFFF>[SkillDebug]</color> <color=#FFD700>ID: {def.skillId}</color> | <color=#00FF00>Trigger: {def.triggerCondition}</color> | <color=#FFA500>Target: {target.name}</color> | <color=#EE82EE>Effect: {def.effectType}</color> | <color=#FF4500>Value: {amountTotal:F2}</color>");
|
||||
}
|
||||
|
||||
var ally = t.GetComponent<AllyCombatant>();
|
||||
var ic = t.GetComponent<ICombatant>();
|
||||
|
||||
if (ally != null && ShouldSpawnApprForEffect(def.effectType))
|
||||
{
|
||||
var apprSprite = iBudeffPrefabController.Instance != null ? iBudeffPrefabController.Instance.GetSpriteForEffect(def.effectType) : null;
|
||||
@@ -1405,7 +1500,7 @@ ResolvedGroup:
|
||||
string iconId = null;
|
||||
int allySlotIndex = -1;
|
||||
int enemyInstanceId = 0;
|
||||
var enemyDot = t.GetComponent<EnemyCombatant>() ?? t.GetComponentInChildren<EnemyCombatant>(true);
|
||||
var enemyDot = target.GetComponent<EnemyCombatant>() ?? target.GetComponentInChildren<EnemyCombatant>(true);
|
||||
if (enemyDot != null)
|
||||
{
|
||||
int ticks = Mathf.Max(1, Mathf.CeilToInt(def.defaultDuration / def.GetEffectiveTickInterval()));
|
||||
@@ -1420,7 +1515,7 @@ ResolvedGroup:
|
||||
iconId = iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_bleeding, perTick, def.defaultDuration);
|
||||
allySlotIndex = ally.slotIndex;
|
||||
}
|
||||
StartCoroutine(ApplyDamageOverTimeDirect(t, amountTotal, def.defaultDuration, def.GetEffectiveTickInterval(), caster, iconId, allySlotIndex, enemyInstanceId));
|
||||
StartCoroutine(ApplyDamageOverTimeDirect(target, amountTotal, def.defaultDuration, def.GetEffectiveTickInterval(), caster, iconId, allySlotIndex, enemyInstanceId));
|
||||
}
|
||||
break;
|
||||
case EffectType.HealSingleSelf:
|
||||
@@ -1437,7 +1532,7 @@ ResolvedGroup:
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(ApplyHealOverTimeDirect(t, amountTotal, def.defaultDuration, def.GetEffectiveTickInterval(), caster));
|
||||
StartCoroutine(ApplyHealOverTimeDirect(target, amountTotal, def.defaultDuration, def.GetEffectiveTickInterval(), caster));
|
||||
}
|
||||
break;
|
||||
case EffectType.IncreaseManaOverTime:
|
||||
@@ -1467,7 +1562,7 @@ ResolvedGroup:
|
||||
healReceivedMultiplier = 1f - reduction
|
||||
};
|
||||
ic.ApplyBuff(deb, caster);
|
||||
StartCoroutine(RemoveBuffAfterDuration(t, deb.buffId, deb.duration));
|
||||
StartCoroutine(RemoveBuffAfterDuration(target, deb.buffId, deb.duration));
|
||||
}
|
||||
break;
|
||||
case EffectType.BuffDuration:
|
||||
@@ -1484,7 +1579,7 @@ ResolvedGroup:
|
||||
scoreMultiplier = mult
|
||||
};
|
||||
ic.ApplyBuff(b, caster);
|
||||
StartCoroutine(RemoveBuffAfterDuration(t, b.buffId, b.duration));
|
||||
StartCoroutine(RemoveBuffAfterDuration(target, b.buffId, b.duration));
|
||||
}
|
||||
break;
|
||||
// Documentation text normalized.
|
||||
@@ -1496,7 +1591,7 @@ ResolvedGroup:
|
||||
if (d > 0) ally.SetCurrentHP(ally.currentHP + d, false);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_maxHP_up, d, 0f);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy))
|
||||
else if (target.TryGetComponent<EnemyCombatant>(out var enemy))
|
||||
{
|
||||
int d = Mathf.CeilToInt(amountTotal);
|
||||
enemy.SetMaxHP(enemy.maxHP + d, false);
|
||||
@@ -1511,7 +1606,7 @@ ResolvedGroup:
|
||||
ally.SetMaxHP(Mathf.Max(1, ally.maxHP - d), false);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_maxHP_down, -d, 0f);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy2))
|
||||
else if (target.TryGetComponent<EnemyCombatant>(out var enemy2))
|
||||
{
|
||||
int d = Mathf.CeilToInt(amountTotal);
|
||||
enemy2.SetMaxHP(Mathf.Max(1, enemy2.maxHP - d), false);
|
||||
@@ -1525,7 +1620,7 @@ ResolvedGroup:
|
||||
ally.SetMaxMana(ally.maxMana + d, false);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_maxMana_up, d, 0f);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy3))
|
||||
else if (target.TryGetComponent<EnemyCombatant>(out var enemy3))
|
||||
{
|
||||
int d = Mathf.CeilToInt(amountTotal);
|
||||
enemy3.SetMaxMana(enemy3.maxMana + d, false);
|
||||
@@ -1539,7 +1634,7 @@ ResolvedGroup:
|
||||
ally.SetMaxMana(Mathf.Max(1, ally.maxMana - d), false);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_maxMana_down, -d, 0f);
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy4))
|
||||
else if (target.TryGetComponent<EnemyCombatant>(out var enemy4))
|
||||
{
|
||||
int d = Mathf.CeilToInt(amountTotal);
|
||||
enemy4.SetMaxMana(Mathf.Max(1, enemy4.maxMana - d), false);
|
||||
@@ -1554,7 +1649,7 @@ ResolvedGroup:
|
||||
ally.scoreEfficiency += amountTotal;
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_scoreEfficiency_up, amountTotal, 0f);
|
||||
}
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration))
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration))
|
||||
{
|
||||
var iconId = iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_scoreEfficiency_up, amountTotal, def.defaultDuration);
|
||||
StartCoroutine(ApplyTemporaryScoreEfficiencyChangeDirect(ally, amountTotal, def.defaultDuration, iconId));
|
||||
@@ -1569,7 +1664,7 @@ ResolvedGroup:
|
||||
ally.scoreEfficiency = Mathf.Max(0f, ally.scoreEfficiency - amountTotal);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_scoreEfficiency_down, -amountTotal, 0f);
|
||||
}
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration))
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration))
|
||||
{
|
||||
var iconId = iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_scoreEfficiency_down, -amountTotal, def.defaultDuration);
|
||||
StartCoroutine(ApplyTemporaryScoreEfficiencyChangeDirect(ally, -amountTotal, def.defaultDuration, iconId));
|
||||
@@ -1586,20 +1681,20 @@ ResolvedGroup:
|
||||
ally.ModifyAttack(delta);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_atk_up, delta, 0f);
|
||||
}
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration))
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration))
|
||||
{
|
||||
var iconId = iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_atk_up, delta, def.defaultDuration);
|
||||
StartCoroutine(ApplyTemporaryAttackChangeDirect(ally, delta, def.defaultDuration, iconId));
|
||||
}
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy5))
|
||||
else if (target.TryGetComponent<EnemyCombatant>(out var enemy5))
|
||||
{
|
||||
if (def.defaultDuration <= 0f)
|
||||
{
|
||||
enemy5.ModifyAttack(delta);
|
||||
iBudeffPrefabController.Instance?.RegisterEnemyTimedEffect(enemy5, PlayerBudeffIconType.ot_atk_up, delta, 0f);
|
||||
}
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration))
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration))
|
||||
{
|
||||
var iconId = iBudeffPrefabController.Instance?.RegisterEnemyTimedEffect(enemy5, PlayerBudeffIconType.ot_atk_up, delta, def.defaultDuration);
|
||||
StartCoroutine(ApplyTemporaryAttackChangeDirect(enemy5, delta, def.defaultDuration, iconId, enemy5.GetInstanceID()));
|
||||
@@ -1617,20 +1712,20 @@ ResolvedGroup:
|
||||
ally.ModifyAttack(-delta);
|
||||
iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_atk_down, -delta, 0f);
|
||||
}
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration))
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration))
|
||||
{
|
||||
var iconId = iBudeffPrefabController.Instance?.RegisterTimedEffect(ally, PlayerBudeffIconType.ot_atk_down, -delta, def.defaultDuration);
|
||||
StartCoroutine(ApplyTemporaryAttackChangeDirect(ally, -delta, def.defaultDuration, iconId));
|
||||
}
|
||||
}
|
||||
else if (t.TryGetComponent<EnemyCombatant>(out var enemy6))
|
||||
else if (target.TryGetComponent<EnemyCombatant>(out var enemy6))
|
||||
{
|
||||
if (def.defaultDuration <= 0f)
|
||||
{
|
||||
enemy6.ModifyAttack(-delta);
|
||||
iBudeffPrefabController.Instance?.RegisterEnemyTimedEffect(enemy6, PlayerBudeffIconType.ot_atk_down, -delta, 0f);
|
||||
}
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration))
|
||||
else if (!TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration))
|
||||
{
|
||||
var iconId = iBudeffPrefabController.Instance?.RegisterEnemyTimedEffect(enemy6, PlayerBudeffIconType.ot_atk_down, -delta, def.defaultDuration);
|
||||
StartCoroutine(ApplyTemporaryAttackChangeDirect(enemy6, -delta, def.defaultDuration, iconId, enemy6.GetInstanceID()));
|
||||
@@ -1677,13 +1772,27 @@ ResolvedGroup:
|
||||
{
|
||||
var resolvedTargets = ResolveTargetsLocal(def.defaultSelector, caster, specificTarget);
|
||||
bool appliedRefreshOnly = false;
|
||||
bool mayHandleLocally = IsRefreshOnlyTimedSkill(def) || IsRefreshOnlyOverTimeSkill(def);
|
||||
if (resolvedTargets != null)
|
||||
{
|
||||
foreach (var t in resolvedTargets)
|
||||
{
|
||||
if (t == null) continue;
|
||||
bool handled = TryApplyRefreshOnlyTimedEffect(def, t, amountTotal, def.defaultDuration);
|
||||
if (!handled) handled = TryApplyRefreshOnlyOverTimeEffect(def, t, amountTotal, caster);
|
||||
var target = t;
|
||||
if (mayHandleLocally)
|
||||
{
|
||||
var ally = target.GetComponent<AllyCombatant>() ?? target.GetComponentInChildren<AllyCombatant>(true);
|
||||
if (ally != null && IsRedirectableBudeffEvent(def.effectType))
|
||||
{
|
||||
if (ally.TryRedirectIncomingGenericBuff(out var redirectedAlly) && redirectedAlly != null)
|
||||
{
|
||||
target = redirectedAlly.gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool handled = TryApplyRefreshOnlyTimedEffect(def, target, amountTotal, def.defaultDuration);
|
||||
if (!handled) handled = TryApplyRefreshOnlyOverTimeEffect(def, target, amountTotal, caster);
|
||||
if (handled) appliedRefreshOnly = true;
|
||||
}
|
||||
}
|
||||
@@ -1992,6 +2101,89 @@ ResolvedGroup:
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger ally skills when an adjacent ally releases a skill (mana-full cast path).
|
||||
public void TriggerOnAdjacentAllySkillCast(int casterSlotIndex)
|
||||
{
|
||||
if (!Application.isPlaying) return;
|
||||
if (casterSlotIndex < 0) return;
|
||||
|
||||
int slots = 5;
|
||||
if (teamUIController.Instance != null && teamUIController.Instance.allySlotIds != null)
|
||||
slots = teamUIController.Instance.allySlotIds.Count;
|
||||
|
||||
for (int i = 0; i < slots; i++)
|
||||
{
|
||||
if (i == casterSlotIndex) continue;
|
||||
|
||||
bool isAdjacent = false;
|
||||
if (teamUIController.Instance != null)
|
||||
{
|
||||
int[] adj = teamUIController.Instance.GetAdjacentAllyIndices(i);
|
||||
if (adj != null)
|
||||
{
|
||||
for (int j = 0; j < adj.Length; j++)
|
||||
{
|
||||
if (adj[j] == casterSlotIndex) { isAdjacent = true; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isAdjacent = Mathf.Abs(i - casterSlotIndex) == 1;
|
||||
}
|
||||
|
||||
if (!isAdjacent) continue;
|
||||
|
||||
var allyObj = GetAllyObjectBySlot(i);
|
||||
var allyComp = allyObj != null ? allyObj.GetComponent<AllyCombatant>() : null;
|
||||
if (allyComp != null && allyComp.IsDead) continue;
|
||||
|
||||
var so = GetAllyHeroSOBySlot(i);
|
||||
if (so == null) continue;
|
||||
|
||||
if (so.equippedSkillGroupIDs != null && so.equippedSkillGroupIDs.Length > 0 && so.skillGroups != null)
|
||||
{
|
||||
foreach (int gid in so.equippedSkillGroupIDs)
|
||||
{
|
||||
if (gid == 0) continue;
|
||||
SkillGroup group = null;
|
||||
for (int k = 0; k < so.skillGroups.Length; k++)
|
||||
{
|
||||
var g = so.skillGroups[k];
|
||||
if (g != null && g.skillGroupID == gid) { group = g; break; }
|
||||
}
|
||||
if (group == null || group.skills == null) continue;
|
||||
|
||||
foreach (var def in group.skills)
|
||||
{
|
||||
if (def == null) continue;
|
||||
if (def.triggerCondition != SkillDefinition.SkillTrigger.OnAdjacentAllySkillCast) continue;
|
||||
UseSkillDefinition(def, i, -1f, null);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var fallbackGroup = so.GetPrimarySkillGroup();
|
||||
if (fallbackGroup != null && fallbackGroup.skills != null)
|
||||
{
|
||||
foreach (var def in fallbackGroup.skills)
|
||||
{
|
||||
if (def == null) continue;
|
||||
if (def.triggerCondition != SkillDefinition.SkillTrigger.OnAdjacentAllySkillCast) continue;
|
||||
UseSkillDefinition(def, i, -1f, null);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var primary = so.GetPrimarySkill();
|
||||
if (primary != null && primary.triggerCondition == SkillDefinition.SkillTrigger.OnAdjacentAllySkillCast)
|
||||
{
|
||||
UsePrimarySkillForSlot(i, -1f, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, float> _lastOnNoteHitTriggerTime = new Dictionary<string, float>();
|
||||
|
||||
// track processed unique note IDs (e.g. long-hold note id) so shared effects (mana/hp) are applied only once
|
||||
@@ -2306,6 +2498,23 @@ ResolvedGroup:
|
||||
|
||||
if (duration <= 0f || tickInterval <= 0f)
|
||||
{
|
||||
if (target.GetComponent<EnemyCombatant>() != null && teamUIController.Instance != null)
|
||||
{
|
||||
if (!teamUIController.Instance.IsAnyAllyActive())
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && !teamUIController.Instance.IsAllySlotActive(sourceAlly.slotIndex))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ally != null) ally.ModifyHP(-Mathf.CeilToInt(totalAmount), true);
|
||||
else ic?.ReceiveDamage(totalAmount, source);
|
||||
yield break;
|
||||
@@ -2317,6 +2526,24 @@ ResolvedGroup:
|
||||
while (elapsed < duration)
|
||||
{
|
||||
if (target == null) yield break;
|
||||
|
||||
if (target.GetComponent<EnemyCombatant>() != null && teamUIController.Instance != null)
|
||||
{
|
||||
if (!teamUIController.Instance.IsAnyAllyActive())
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && !teamUIController.Instance.IsAllySlotActive(sourceAlly.slotIndex))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ally != null) ally.ModifyHP(-Mathf.CeilToInt(perTick), true);
|
||||
else ic?.ReceiveDamage(perTick, source);
|
||||
yield return new WaitForSeconds(tickInterval);
|
||||
|
||||
Reference in New Issue
Block a user