展前冒死重构

This commit is contained in:
FloatGaming
2026-07-24 04:43:13 +08:00
parent d09597472b
commit 4eb70b0ac9
61 changed files with 74951 additions and 328 deletions
+1
View File
@@ -2053,6 +2053,7 @@ public class AllyCombatant : MonoBehaviour, ICombatant
else
{
SkillBuilder.Instance?.TriggerOnAdjacentAllySkillCast(slotIndex);
GameplayLevelRuleEventBus.NotifyAllySkillCast(slotIndex, GameplayClock.NowSongTime);
}
return anyTriggered;
}
+55 -15
View File
@@ -90,19 +90,46 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
SkillBuilder.Instance.TriggerOnEnemyRevive(this);
}
// Trigger primary skill on revive if defined and trigger condition matches
TryTriggerPrimarySkill(SkillDefinition.SkillTrigger.OnEnemyRevive);
// Trigger configured enemy skills on revive if defined and trigger condition matches.
TryTriggerConfiguredSkills(SkillDefinition.SkillTrigger.OnEnemyRevive);
}
// Documentation text normalized.
private void TryTriggerPrimarySkill(SkillDefinition.SkillTrigger when)
private void TryTriggerConfiguredSkills(SkillDefinition.SkillTrigger when)
{
if (sourceData == null) return;
var def = sourceData.GetPrimarySkill();
if (def == null) return;
HashSet<SkillDefinition> executed = new HashSet<SkillDefinition>();
SkillDefinition primary = sourceData.GetPrimarySkill();
ExecuteEnemySkillIfMatched(primary, when, executed);
int[] groupIds = sourceData.GetEffectiveEquippedSkillGroupIDs();
if (groupIds == null || groupIds.Length == 0)
return;
for (int i = 0; i < groupIds.Length; i++)
{
int groupId = groupIds[i];
if (groupId == 0) continue;
SkillGroup group = sourceData.GetSkillGroupByID(groupId);
if (group == null || group.skills == null)
continue;
for (int j = 0; j < group.skills.Length; j++)
{
ExecuteEnemySkillIfMatched(group.skills[j], when, executed);
}
}
}
private void ExecuteEnemySkillIfMatched(SkillDefinition def, SkillDefinition.SkillTrigger when, HashSet<SkillDefinition> executed)
{
if (def == null || executed == null) return;
if (executed.Contains(def)) return;
if (def.triggerCondition != when) return;
// Evaluate formula into amount using enemy fields as variables
executed.Add(def);
float perTick = 0f;
var vars = new Dictionary<string, float>();
vars["maxHP"] = maxHP;
@@ -135,7 +162,6 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
totalAmount = perTick * ticks;
}
// Use SkillBuilder to execute effect, using this Enemy GameObject as caster
if (SkillBuilder.Instance != null)
{
SkillBuilder.Instance.ExecuteSkill(def.displayName ?? def.skillId, def.effectType, totalAmount, def.defaultSelector, this.gameObject, null, def.defaultDuration, def.defaultTickInterval);
@@ -190,6 +216,11 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
}
}
if (actual > 0)
{
GameplayLevelRuleEventBus.NotifyEnemyDamaged(this, actual, source);
}
// grant mana based on sourceData setting
if (sourceData != null && sourceData.manaGainOnDamagePercent > 0f && maxMana > 0)
{
@@ -352,7 +383,16 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
var type = actual > 0 ? iNumberPrefabController.InstantNumberType.Heal : iNumberPrefabController.InstantNumberType.Damage;
iNumberPrefabController.SpawnForEnemyStatic(type, actual);
}
if (currentHP <= 0) Die();
if (currentHP <= 0)
{
if (GameplayLevelRuleEventBus.ShouldPreventEnemyDeath(this))
{
currentHP = 1;
return;
}
Die();
}
}
public void ModifyMana(int delta, bool animate = true)
@@ -371,18 +411,18 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
}
}
// If mana reached full, trigger primary skill and reset mana
// If mana reached full, trigger configured skills and reset mana
if (currentMana >= maxMana && maxMana > 0 && Application.isPlaying)
{
Debug.Log($"[EnemyCombatant] Mana full for {gameObject.name} (slot) - triggering OnManaFull");
try
{
// Trigger primary skill configured for OnManaFull
TryTriggerPrimarySkill(SkillDefinition.SkillTrigger.OnManaFull);
TryTriggerConfiguredSkills(SkillDefinition.SkillTrigger.OnManaFull);
GameplayLevelRuleEventBus.NotifyEnemyManaFull(this);
}
catch (Exception ex)
{
Debug.LogError($"[EnemyCombatant] TryTriggerPrimarySkill threw: {ex}");
Debug.LogError($"[EnemyCombatant] OnManaFull handling threw: {ex}");
}
// reset mana after casting
@@ -457,8 +497,8 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
}
}
// Trigger primary skill on death if configured (enemy's own skill)
TryTriggerPrimarySkill(SkillDefinition.SkillTrigger.OnEnemyDead);
// Trigger configured enemy skills on death if configured.
TryTriggerConfiguredSkills(SkillDefinition.SkillTrigger.OnEnemyDead);
// notify listeners (UI/manager) that enemy died AFTER triggering skills so they operate on the current instance
OnEnemyDied?.Invoke(this);
+23 -2
View File
@@ -1369,6 +1369,10 @@ ResolvedGroup:
}
catch { /* never break gameplay because of optional UI */ }
// Spawn the track skill popup as soon as the skill is confirmed for this frame.
// This avoids later target-resolution branches swallowing the popup on early returns.
SpawnTrackSkillPopup(slotIndex, smallSkillName, smallSkillIcon);
GameObject caster = GetAllyObjectBySlot(slotIndex);
if (caster == null)
{
@@ -1926,7 +1930,10 @@ ResolvedGroup:
}
// For listed skills: do not stack when retriggered, only refresh duration.
if (appliedRefreshOnly) return;
if (appliedRefreshOnly)
{
return;
}
}
// For non-direct path, EffectSystem expects 'amount' to be total amount for sustained effects
@@ -1986,7 +1993,6 @@ ResolvedGroup:
GameplaySkillLogger.RecordSkillRelease(casterDisplayName, skillDisplayName, def.effectType.ToString(), effectSummary, targetSummary);
}
catch { }
return true;
}
@@ -2111,6 +2117,21 @@ ResolvedGroup:
}
}
private static readonly string[] s_trackSkillPopupColors = { "red", "green", "yellow", "purple", "blue" };
private void SpawnTrackSkillPopup(int slotIndex, string skillName, Sprite skillIcon)
{
if (slotIndex < 0 || slotIndex >= s_trackSkillPopupColors.Length)
return;
var fx = Animation_GenerateJudgementSituationPrefab.Instance
?? SceneObjectLookupCache.FindAny<Animation_GenerateJudgementSituationPrefab>();
if (fx == null)
return;
fx.SpawnTrackSkillPrefab(s_trackSkillPopupColors[slotIndex], skillIcon, skillName ?? string.Empty);
}
private bool HandleEquipSkillGhoulSchool(int slotIndex)
{
_equipGhoulSchoolActiveSlots.Add(slotIndex);