ui基本完毕,修了一大把的bug
This commit is contained in:
@@ -1266,6 +1266,18 @@ public class AllyCombatant : MonoBehaviour, ICombatant
|
||||
|
||||
// Trigger HP changed events
|
||||
int delta = currentHP - old;
|
||||
if (delta != 0 && teamUIController.Instance != null)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
teamUIController.Instance.RecordHeal(slotIndex, delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
teamUIController.Instance.RecordDamageTaken(slotIndex, -delta);
|
||||
}
|
||||
}
|
||||
|
||||
if (delta != 0 && !skipPopup)
|
||||
{
|
||||
if (iNumberPrefabController.Instance != null)
|
||||
@@ -1387,6 +1399,11 @@ public class AllyCombatant : MonoBehaviour, ICombatant
|
||||
|
||||
// Trigger mana changed events
|
||||
int delta = currentMana - old;
|
||||
if (delta > 0 && teamUIController.Instance != null)
|
||||
{
|
||||
teamUIController.Instance.RecordMana(slotIndex, delta);
|
||||
}
|
||||
|
||||
if (delta != 0)
|
||||
{
|
||||
if (iNumberPrefabController.Instance != null)
|
||||
|
||||
@@ -1078,22 +1078,6 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
// Use deferPopup: true for synchronization with hit fx
|
||||
comp.ReceiveDamage(amount, source, true);
|
||||
|
||||
// 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
|
||||
if (targetAlly != null && teamUIController.Instance != null)
|
||||
{
|
||||
teamUIController.Instance.RecordDamageTaken(targetAlly.slotIndex, amount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1109,16 +1093,6 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
// Use deferPopup: false for heals (usually immediate)
|
||||
comp.ReceiveHeal(amount, source, false);
|
||||
|
||||
// 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
|
||||
{
|
||||
@@ -1175,13 +1149,6 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
comp.ReceiveDamage(totalAmount, source, false);
|
||||
// No need to call TriggerQueuedPopups manually as deferPopup is false
|
||||
|
||||
if (source != null && targetEnemy != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamage(ally.slotIndex, totalAmount);
|
||||
}
|
||||
if (targetAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamageTaken(targetAlly.slotIndex, totalAmount);
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -1224,13 +1191,6 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
comp.ReceiveDamage(perTick, source, false);
|
||||
// No need to call TriggerQueuedPopups manually as deferPopup is false
|
||||
|
||||
if (source != null && targetEnemy != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamage(ally.slotIndex, perTick);
|
||||
}
|
||||
if (targetAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordDamageTaken(targetAlly.slotIndex, perTick);
|
||||
yield return new WaitForSeconds(tickInterval);
|
||||
elapsed += tickInterval;
|
||||
}
|
||||
@@ -1265,13 +1225,6 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
comp.ReceiveHeal(totalAmount, source, false);
|
||||
// No need to call TriggerQueuedPopups manually as deferPopup is false
|
||||
|
||||
// Record stats
|
||||
if (source != null)
|
||||
{
|
||||
var ally = source.GetComponent<AllyCombatant>();
|
||||
if (ally != null && teamUIController.Instance != null) teamUIController.Instance.RecordHeal(ally.slotIndex, totalAmount);
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -1286,13 +1239,6 @@ public class EffectSystem : MonoBehaviour
|
||||
|
||||
comp.ReceiveHeal(perTick, source, false);
|
||||
// No need to call TriggerQueuedPopups manually as deferPopup is false
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -1345,12 +1291,6 @@ public class EffectSystem : MonoBehaviour
|
||||
if (ally != null)
|
||||
{
|
||||
ally.ModifyMana(Mathf.CeilToInt(totalAmount), true, true);
|
||||
// Record stats
|
||||
if (totalAmount > 0f && source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null) teamUIController.Instance.RecordMana(sourceAlly.slotIndex, totalAmount);
|
||||
}
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
@@ -1364,12 +1304,6 @@ public class EffectSystem : MonoBehaviour
|
||||
if (ally != null)
|
||||
{
|
||||
ally.ModifyMana(Mathf.CeilToInt(perTick), true, true);
|
||||
// Record stats
|
||||
if (perTick > 0f && 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;
|
||||
|
||||
@@ -159,6 +159,15 @@ public class EnemyCombatant : MonoBehaviour, ICombatant
|
||||
ModifyHP(-delta, true);
|
||||
|
||||
int actual = before - currentHP;
|
||||
if (actual > 0 && source != null && teamUIController.Instance != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null)
|
||||
{
|
||||
teamUIController.Instance.RecordDamage(sourceAlly.slotIndex, actual);
|
||||
}
|
||||
}
|
||||
|
||||
GameplaySkillLogger.RecordEnemyHpEvent(
|
||||
gameObject.name,
|
||||
"Damage",
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
public static class GameplaySkillLogger
|
||||
@@ -18,6 +20,24 @@ public static class GameplaySkillLogger
|
||||
|
||||
private const float RapidDuplicateSkillThresholdSeconds = 0.05f;
|
||||
|
||||
// Off-thread writer: judge/skill events push formatted lines into this queue and a
|
||||
// single background thread writes them to disk in FIFO order. This keeps the
|
||||
// synchronous file I/O off the gameplay hot path (first-note hitch) while producing
|
||||
// byte-identical output: the queue preserves enqueue order (enqueues happen under
|
||||
// s_fileLock), and the writer thread is the sole owner of the file so a session
|
||||
// truncate (header) can never interleave with an append.
|
||||
private struct LogMessage
|
||||
{
|
||||
public bool Truncate; // true => WriteAllText (new session header); false => AppendAllText
|
||||
public string Text;
|
||||
}
|
||||
|
||||
private static readonly ConcurrentQueue<LogMessage> s_pendingLines = new ConcurrentQueue<LogMessage>();
|
||||
private static readonly AutoResetEvent s_writeSignal = new AutoResetEvent(false);
|
||||
private static Thread s_writerThread;
|
||||
private static volatile bool s_writerRunning;
|
||||
private static readonly object s_writerStartLock = new object();
|
||||
|
||||
public static string LogFilePath
|
||||
{
|
||||
get { return EnsureLogFilePath(); }
|
||||
@@ -256,14 +276,9 @@ public static class GameplaySkillLogger
|
||||
"# Format: [elapsedSec] [CATEGORY] key=value | key=value" + Environment.NewLine +
|
||||
Environment.NewLine;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(path, header, s_utf8NoBom);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning("[GameplaySkillLogger] Failed to create session log: " + ex.Message);
|
||||
}
|
||||
EnsureWriterThread();
|
||||
s_pendingLines.Enqueue(new LogMessage { Truncate = true, Text = header });
|
||||
s_writeSignal.Set();
|
||||
}
|
||||
|
||||
private static float AppendEventLineLocked(string category, string payload)
|
||||
@@ -286,18 +301,70 @@ public static class GameplaySkillLogger
|
||||
.Append("] ")
|
||||
.AppendLine(payload);
|
||||
|
||||
try
|
||||
{
|
||||
File.AppendAllText(EnsureLogFilePath(), builder.ToString(), s_utf8NoBom);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning("[GameplaySkillLogger] Failed to append log: " + ex.Message);
|
||||
}
|
||||
EnsureWriterThread();
|
||||
s_pendingLines.Enqueue(new LogMessage { Truncate = false, Text = builder.ToString() });
|
||||
s_writeSignal.Set();
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
private static void EnsureWriterThread()
|
||||
{
|
||||
if (s_writerRunning)
|
||||
return;
|
||||
|
||||
lock (s_writerStartLock)
|
||||
{
|
||||
if (s_writerRunning)
|
||||
return;
|
||||
|
||||
s_writerRunning = true;
|
||||
s_writerThread = new Thread(WriterLoop)
|
||||
{
|
||||
Name = "GameplaySkillLoggerWriter",
|
||||
IsBackground = true
|
||||
};
|
||||
s_writerThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriterLoop()
|
||||
{
|
||||
while (s_writerRunning)
|
||||
{
|
||||
s_writeSignal.WaitOne(200);
|
||||
DrainPendingLines();
|
||||
}
|
||||
|
||||
// Final drain so nothing queued right before shutdown is lost.
|
||||
DrainPendingLines();
|
||||
}
|
||||
|
||||
private static void DrainPendingLines()
|
||||
{
|
||||
while (s_pendingLines.TryDequeue(out LogMessage message))
|
||||
{
|
||||
// Read the cached path directly: it is always resolved on the main thread
|
||||
// (BeginSessionInternal -> EnsureLogFilePath) before the writer thread starts,
|
||||
// so we must never call Application.dataPath from this background thread.
|
||||
string path = s_logFilePath;
|
||||
if (string.IsNullOrEmpty(path))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
if (message.Truncate)
|
||||
File.WriteAllText(path, message.Text, s_utf8NoBom);
|
||||
else
|
||||
File.AppendAllText(path, message.Text, s_utf8NoBom);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning("[GameplaySkillLogger] Failed to write log: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureSessionLocked()
|
||||
{
|
||||
if (!s_sessionActive)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
|
||||
public class ScoreManager : MonoBehaviour
|
||||
{
|
||||
@@ -56,6 +57,12 @@ public class ScoreManager : MonoBehaviour
|
||||
private bool perfectBonusHooked = false;
|
||||
private int perfectClearBonusPm = 0;
|
||||
private bool perfectClearBonusApplied = false;
|
||||
private int comboRecentPlusAmount = 0;
|
||||
private int displayedRecentPlusAmount = 0;
|
||||
private int lastKnownCombo = 0;
|
||||
private float lastRecentPlusScoreTime = float.NegativeInfinity;
|
||||
private Tween recentPlusAmountValueTween;
|
||||
private const float RecentPlusResetDelaySeconds = 5f;
|
||||
|
||||
[Header("Judgement Statistics")]
|
||||
public int countPerfect = 0;
|
||||
@@ -126,6 +133,10 @@ public class ScoreManager : MonoBehaviour
|
||||
}
|
||||
|
||||
ResetStatistics();
|
||||
comboRecentPlusAmount = 0;
|
||||
displayedRecentPlusAmount = 0;
|
||||
lastKnownCombo = 0;
|
||||
lastRecentPlusScoreTime = float.NegativeInfinity;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
@@ -140,6 +151,7 @@ public class ScoreManager : MonoBehaviour
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
KillRecentPlusAmountValueTween();
|
||||
UnhookPerfectBonusEvent();
|
||||
}
|
||||
|
||||
@@ -148,11 +160,13 @@ public class ScoreManager : MonoBehaviour
|
||||
// Ensure the progress keys start at 0.
|
||||
UpdateIdolscoreKeyScales();
|
||||
TryHookPerfectBonusEvent();
|
||||
RefreshAllScoreUi();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
EnsureIdolscoreKeys();
|
||||
UpdateRecentPlusAmountTimeout();
|
||||
|
||||
float dt = Time.unscaledDeltaTime;
|
||||
if (dt <= 0f) return;
|
||||
@@ -428,6 +442,8 @@ public class ScoreManager : MonoBehaviour
|
||||
if (JudgeManager.IsDebugEnabled)
|
||||
Debug.Log($"[ScoreManager] Added {pmDelta} to track {trackIndex} pm sum, idol delta {idolDelta}. New pm sums: R{red_pmScore_sum} G{green_pmScore_sum} Y{yellow_pmScore_sum} P{purple_pmScore_sum} B{blue_pmScore_sum} -> allSumPm={allSum_pmScore}. Idol sums: R{red_idolScore_sum} G{green_idolScore_sum} Y{yellow_idolScore_sum} P{purple_idolScore_sum} B{blue_idolScore_sum} -> allSumIdol={allSum_idolScore}");
|
||||
|
||||
UpdateRecentPlusAmountUi(pmActualDelta + idolActualDelta);
|
||||
|
||||
// Update UI in teamUIController if available (per-track pm sums + aggregate)
|
||||
var ui = teamUIController.Instance;
|
||||
if (ui != null)
|
||||
@@ -514,6 +530,8 @@ public class ScoreManager : MonoBehaviour
|
||||
iNumberPrefabController.SpawnForAllyStatic(trackIndex, type, actual);
|
||||
}
|
||||
|
||||
UpdateRecentPlusAmountUi(actual);
|
||||
|
||||
red_idolScore_sum = idolScoreSums[0];
|
||||
green_idolScore_sum = idolScoreSums[1];
|
||||
yellow_idolScore_sum = idolScoreSums[2];
|
||||
@@ -694,10 +712,172 @@ public class ScoreManager : MonoBehaviour
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.LogWarning("[ScoreManager] teamUIController.currentTotalScore is null; cannot display total score.");
|
||||
}
|
||||
|
||||
if (ui.currentScoreRankImage != null && ui.currentScoreRankConfig != null)
|
||||
{
|
||||
ui.currentScoreRankImage.sprite = ui.currentScoreRankConfig.GetRankSprite(totalScore);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.LogWarning("[ScoreManager] teamUIController.Instance is null; cannot update UI.");
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyExternalTotalScoreDelta(int delta)
|
||||
{
|
||||
if (delta == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long next = (long)totalScore + delta;
|
||||
if (next < 0) next = 0;
|
||||
if (next > int.MaxValue - 1L) next = int.MaxValue - 1L;
|
||||
totalScore = (int)next;
|
||||
|
||||
UpdateRecentPlusAmountUi(delta);
|
||||
RefreshAllScoreUi();
|
||||
}
|
||||
|
||||
private void UpdateRecentPlusAmountUi(int scoreDelta)
|
||||
{
|
||||
var ui = teamUIController.Instance;
|
||||
if (ui == null || ui.recentPlusAmountText == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int comboNow = ui.CurrentCombo;
|
||||
bool comboBroken = comboNow <= 0;
|
||||
bool comboRestarted = comboNow > 0 && lastKnownCombo <= 0;
|
||||
|
||||
if (comboBroken)
|
||||
{
|
||||
ResetRecentPlusAmountState(ui, true);
|
||||
lastKnownCombo = comboNow;
|
||||
return;
|
||||
}
|
||||
|
||||
if (comboRestarted)
|
||||
{
|
||||
ResetRecentPlusAmountState(ui, false);
|
||||
}
|
||||
|
||||
if (scoreDelta != 0)
|
||||
{
|
||||
comboRecentPlusAmount += scoreDelta;
|
||||
lastRecentPlusScoreTime = Time.unscaledTime;
|
||||
}
|
||||
|
||||
ui.ResetRecentPlusAmountVisual();
|
||||
AnimateRecentPlusAmountText(ui, comboRecentPlusAmount);
|
||||
lastKnownCombo = comboNow;
|
||||
}
|
||||
|
||||
public void RefreshAllScoreUi()
|
||||
{
|
||||
var ui = teamUIController.Instance;
|
||||
if (ui == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui.currentTotalScore != null)
|
||||
{
|
||||
ui.currentTotalScore.text = totalScore.ToString();
|
||||
}
|
||||
|
||||
if (ui.currentScoreRankImage != null && ui.currentScoreRankConfig != null)
|
||||
{
|
||||
ui.currentScoreRankImage.sprite = ui.currentScoreRankConfig.GetRankSprite(totalScore);
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimateRecentPlusAmountText(teamUIController ui, int targetValue)
|
||||
{
|
||||
if (ui == null || ui.recentPlusAmountText == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KillRecentPlusAmountValueTween();
|
||||
|
||||
int startValue = displayedRecentPlusAmount;
|
||||
if (startValue == targetValue)
|
||||
{
|
||||
ui.recentPlusAmountText.text = FormatSignedScoreDelta(targetValue);
|
||||
return;
|
||||
}
|
||||
|
||||
recentPlusAmountValueTween = DOTween
|
||||
.To(() => startValue, value =>
|
||||
{
|
||||
startValue = value;
|
||||
displayedRecentPlusAmount = value;
|
||||
ui.recentPlusAmountText.text = FormatSignedScoreDelta(value);
|
||||
}, targetValue, 0.2f)
|
||||
.SetEase(Ease.OutQuad)
|
||||
.SetUpdate(true)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
displayedRecentPlusAmount = targetValue;
|
||||
if (ui.recentPlusAmountText != null)
|
||||
{
|
||||
ui.recentPlusAmountText.text = FormatSignedScoreDelta(targetValue);
|
||||
}
|
||||
recentPlusAmountValueTween = null;
|
||||
});
|
||||
}
|
||||
|
||||
private void KillRecentPlusAmountValueTween()
|
||||
{
|
||||
if (recentPlusAmountValueTween == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
recentPlusAmountValueTween.Kill();
|
||||
recentPlusAmountValueTween = null;
|
||||
}
|
||||
|
||||
private void UpdateRecentPlusAmountTimeout()
|
||||
{
|
||||
if (comboRecentPlusAmount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Time.unscaledTime - lastRecentPlusScoreTime < RecentPlusResetDelaySeconds)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ResetRecentPlusAmountState(teamUIController.Instance, false);
|
||||
}
|
||||
|
||||
private void ResetRecentPlusAmountState(teamUIController ui, bool killTweenOnly)
|
||||
{
|
||||
comboRecentPlusAmount = 0;
|
||||
displayedRecentPlusAmount = 0;
|
||||
lastRecentPlusScoreTime = float.NegativeInfinity;
|
||||
KillRecentPlusAmountValueTween();
|
||||
|
||||
if (ui == null || ui.recentPlusAmountText == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ui.recentPlusAmountText.text = FormatSignedScoreDelta(0);
|
||||
|
||||
if (killTweenOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatSignedScoreDelta(int value)
|
||||
{
|
||||
return value >= 0 ? $"+{value}" : value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,14 +535,7 @@ public class SkillBuilder : MonoBehaviour
|
||||
public void ModifyTotalScore(int delta)
|
||||
{
|
||||
if (ScoreManager.Instance == null) { Debug.LogWarning("ModifyTotalScore: ScoreManager.Instance is null"); return; }
|
||||
// adjust total and attempt to update UI
|
||||
ScoreManager.Instance.totalScore += delta;
|
||||
// try to force UI update via ScoreManager.RecalculateTotal() is not appropriate because it recalculates from allies
|
||||
// so instead update displayed total directly if teamUIController present
|
||||
if (teamUIController.Instance != null && teamUIController.Instance.currentTotalScore != null)
|
||||
{
|
||||
teamUIController.Instance.currentTotalScore.text = ScoreManager.Instance.totalScore.ToString();
|
||||
}
|
||||
ScoreManager.Instance.ApplyExternalTotalScoreDelta(delta);
|
||||
}
|
||||
|
||||
// Documentation text normalized.
|
||||
@@ -1238,24 +1231,12 @@ public class SkillBuilder : MonoBehaviour
|
||||
var comp = target.GetComponent<ICombatant>();
|
||||
if (comp == null) return false;
|
||||
comp.ReceiveHeal(amount, source);
|
||||
if (source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null)
|
||||
teamUIController.Instance.RecordHeal(sourceAlly.slotIndex, amount);
|
||||
}
|
||||
return true;
|
||||
|
||||
case EffectType.IncreaseManaOverTime:
|
||||
var ally = target.GetComponent<AllyCombatant>();
|
||||
if (ally == null) return false;
|
||||
ally.ModifyMana(Mathf.CeilToInt(amount), true, true);
|
||||
if (amount > 0f && source != null)
|
||||
{
|
||||
var sourceAlly = source.GetComponent<AllyCombatant>();
|
||||
if (sourceAlly != null && teamUIController.Instance != null)
|
||||
teamUIController.Instance.RecordMana(sourceAlly.slotIndex, amount);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user