修了很多bug和增加功能,优化不少问题

This commit is contained in:
2026-02-28 06:59:22 +08:00
parent 508a40bba0
commit e11cc1da7a
345 changed files with 173803 additions and 69332 deletions
+49 -10
View File
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using UnityEngine;
@@ -8,6 +8,9 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
{
public EnemyData_SO sourceData;
private int _currentDifficultyID;
private GameObject _lastAttacker;
// runtime stats
public int maxHP = 100;
public int currentHP = 100;
@@ -35,21 +38,24 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
}
// Documentation text normalized.
public void InitializeFromSO(EnemyData_SO so)
public void InitializeFromSO(EnemyData_SO so, int difficultyID)
{
// This enemy GameObject can be reused for multiple enemy entries in sequence.
// Clear any runtime buffs so they don't leak across enemy transitions.
activeBuffs.Clear();
_attackBaseInitialized = false;
_attackBaseUnbuffed = 0;
_lastAttacker = null;
_currentDifficultyID = difficultyID;
sourceData = so;
if (so != null)
{
maxHP = Mathf.Max(1, so.enemy_maxHP);
damageResistance = so.enemy_damageResistance;
SetAttack(so.enemy_baseAttack);
maxMana = Mathf.Max(0, so.GetEffectiveMaxMana());
var stats = so.GetStatsByDifficultyID(difficultyID);
maxHP = Mathf.Max(1, stats.enemy_maxHP);
damageResistance = stats.enemy_damageResistance;
SetAttack(stats.enemy_baseAttack);
maxMana = Mathf.Max(0, stats.enemy_maxMana);
}
else
{
@@ -131,6 +137,13 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
{
if (isDead) return;
// Check if any allies are active before receiving damage
if (teamUIController.Instance != null && !teamUIController.Instance.IsAnyAllyActive())
{
return;
}
_lastAttacker = source;
float effective = amount * (1f - damageResistance);
int delta = Mathf.CeilToInt(effective);
currentHP = Mathf.Clamp(currentHP - delta, 0, maxHP);
@@ -278,9 +291,27 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
{
if (isDead) return;
// Finally mark dead so further damage/heal is ignored.
// We set this EARLY because listeners (OnEnemyDied) might re-initialize this instance
// for the next enemy in sequence, which would set isDead = false.
// award score to last attacker
if (sourceData != null)
{
var stats = sourceData.GetStatsByDifficultyID(_currentDifficultyID);
int award = stats.scoreOnBeingDefeated;
if (award > 0)
{
var ally = _lastAttacker != null ? _lastAttacker.GetComponent<AllyCombatant>() : null;
if (ally != null)
{
ally.AddScoreDirect(award);
}
else
{
// If no specific attacker, try to find current primary track or just add to global
ScoreManager.Instance?.AddIdolScoreForTrack(0, award);
}
}
}
// Finally mark dead
isDead = true;
// 播放 KO 特效
@@ -318,11 +349,19 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
// notify listeners (UI/manager) that enemy died AFTER triggering skills so they operate on the current instance
OnEnemyDied?.Invoke(this);
// Check whether all enemies are now defeated. Use currentHP/IsDead to determine status.
// Check whether all enemies are now defeated.
// If teamUIController exists, it owns enemy-sequence completion and will fire this event exactly once.
// Fallback to legacy scene scan only when teamUIController is not present.
if (Application.isPlaying)
{
try
{
var ui = UnityEngine.Object.FindAnyObjectByType<teamUIController>();
if (ui != null)
{
return;
}
var all = UnityEngine.Object.FindObjectsByType<EnemyCombatant>(FindObjectsInactive.Include, FindObjectsSortMode.None);
bool anyAlive = false;
foreach (var e in all)