修了很多bug和增加功能,优化不少问题
This commit is contained in:
@@ -18,7 +18,8 @@ public enum PlayerBudeffIconType
|
||||
ot_defend_down,
|
||||
ot_vulnerability,
|
||||
dmg_redirect_toSelf,
|
||||
dmg_redirect_toAdjacent
|
||||
dmg_redirect_toAdjacent,
|
||||
ot_luckyChance
|
||||
}
|
||||
|
||||
public class PlayerBudeffPrefab : MonoBehaviour
|
||||
@@ -43,6 +44,7 @@ public class PlayerBudeffPrefab : MonoBehaviour
|
||||
public Sprite ot_vulnerability;
|
||||
public Sprite dmg_redirect_toSelf;
|
||||
public Sprite dmg_redirect_toAdjacent;
|
||||
public Sprite ot_luckyChance;
|
||||
|
||||
[Header("num colors")]
|
||||
public Color ot_maxHP_up_color;
|
||||
@@ -60,6 +62,7 @@ public class PlayerBudeffPrefab : MonoBehaviour
|
||||
public Color ot_vulnerability_color;
|
||||
public Color dmg_redirect_toSelf_color;
|
||||
public Color dmg_redirect_toAdjacent_color;
|
||||
public Color ot_luckyChance_color;
|
||||
|
||||
public void Apply(PlayerBudeffIconType type, string numText)
|
||||
{
|
||||
@@ -96,6 +99,7 @@ public class PlayerBudeffPrefab : MonoBehaviour
|
||||
case PlayerBudeffIconType.ot_vulnerability: return ot_vulnerability;
|
||||
case PlayerBudeffIconType.dmg_redirect_toSelf: return dmg_redirect_toSelf;
|
||||
case PlayerBudeffIconType.dmg_redirect_toAdjacent: return dmg_redirect_toAdjacent;
|
||||
case PlayerBudeffIconType.ot_luckyChance: return ot_luckyChance;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
@@ -119,6 +123,7 @@ public class PlayerBudeffPrefab : MonoBehaviour
|
||||
case PlayerBudeffIconType.ot_vulnerability: return ot_vulnerability_color;
|
||||
case PlayerBudeffIconType.dmg_redirect_toSelf: return dmg_redirect_toSelf_color;
|
||||
case PlayerBudeffIconType.dmg_redirect_toAdjacent: return dmg_redirect_toAdjacent_color;
|
||||
case PlayerBudeffIconType.ot_luckyChance: return ot_luckyChance_color;
|
||||
default: return Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +278,7 @@ MonoBehaviour:
|
||||
ot_vulnerability: {fileID: 21300000, guid: ba83152a6fcffb24899119ba44cae403, type: 3}
|
||||
dmg_redirect_toSelf: {fileID: 21300000, guid: d11b1c841cccade4c9f1c254d671ae15, type: 3}
|
||||
dmg_redirect_toAdjacent: {fileID: 21300000, guid: 54492507a5422564aa5db7c7ef96311e, type: 3}
|
||||
ot_luckyChance: {fileID: 2978455473066875312, guid: f2e1a192758189c49b8ef48c7a471107, type: 3}
|
||||
ot_maxHP_up_color: {r: 0.19215688, g: 0.8117648, b: 0.65882355, a: 0}
|
||||
ot_maxHP_down_color: {r: 0.10588236, g: 0.47058827, b: 0.3921569, a: 0}
|
||||
ot_maxMana_up_color: {r: 0.2784314, g: 0.75294125, b: 1, a: 0}
|
||||
@@ -293,3 +294,4 @@ MonoBehaviour:
|
||||
ot_vulnerability_color: {r: 0.18867922, g: 0.18867922, b: 0.18867922, a: 0}
|
||||
dmg_redirect_toSelf_color: {r: 0.82745105, g: 0.3647059, b: 0.23529413, a: 0}
|
||||
dmg_redirect_toAdjacent_color: {r: 0.8196079, g: 0.41960788, b: 0.19607845, a: 0}
|
||||
ot_luckyChance_color: {r: 0.8679245, g: 0.6304734, b: 0.8679245, a: 1}
|
||||
|
||||
+333
-21
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[DefaultExecutionOrder(-1000)]
|
||||
public class iBudeffPrefabController : MonoBehaviour
|
||||
@@ -17,6 +19,13 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
public float apprFloatDistance = 40f;
|
||||
public float apprFadeDuration = 0.6f;
|
||||
|
||||
[Header("buff icon flash animation")]
|
||||
public bool enableBuffIconFlashAnimation = true;
|
||||
[Range(1, 8)] public int buffIconEntryFlashCount = 3;
|
||||
[Range(0.02f, 0.6f)] public float buffIconEntryFlashDuration = 0.18f;
|
||||
[Range(1, 8)] public int buffIconExitFlashCount = 3;
|
||||
[Range(0.02f, 0.6f)] public float buffIconExitFlashDuration = 0.16f;
|
||||
|
||||
[Header("place to put")]
|
||||
public GameObject enemy_icon_put;
|
||||
public GameObject ally01_put;
|
||||
@@ -42,7 +51,8 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
DamageResistance,
|
||||
Attack,
|
||||
RedirectToSelf,
|
||||
RedirectToAdjacent
|
||||
RedirectToAdjacent,
|
||||
LuckyChance
|
||||
}
|
||||
|
||||
private class Entry
|
||||
@@ -51,6 +61,7 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
public Group group;
|
||||
public float value;
|
||||
public float startTime;
|
||||
public float duration;
|
||||
}
|
||||
|
||||
private class SlotState
|
||||
@@ -82,6 +93,8 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
|
||||
private readonly Dictionary<int, SlotState> _slots = new Dictionary<int, SlotState>(8);
|
||||
private readonly Dictionary<int, EnemyState> _enemies = new Dictionary<int, EnemyState>(8);
|
||||
private readonly Dictionary<int, Coroutine> _iconEntryCoroutines = new Dictionary<int, Coroutine>(32);
|
||||
private readonly Dictionary<int, Coroutine> _iconExitCoroutines = new Dictionary<int, Coroutine>(32);
|
||||
private bool _warnedMissingApprPrefab;
|
||||
private bool _warnedMissingApprParents;
|
||||
private PlayerBudeffPrefab _spriteSource;
|
||||
@@ -193,17 +206,159 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
|
||||
var group = GetGroupForIconType(type);
|
||||
string id = Guid.NewGuid().ToString();
|
||||
RegisterEntry(ally, group, id, value, Time.time);
|
||||
RegisterEntry(ally, group, id, value, Time.time, duration);
|
||||
return id;
|
||||
}
|
||||
|
||||
public void RefreshAllyNow(AllyCombatant ally)
|
||||
{
|
||||
if (ally == null) return;
|
||||
if (!Application.isPlaying) return;
|
||||
var s = GetOrCreateSlot(ally.slotIndex);
|
||||
s.ally = ally;
|
||||
if (!s.baselineReady) RegisterBaseline(ally);
|
||||
else RefreshSlot(ally.slotIndex);
|
||||
}
|
||||
|
||||
public void UnregisterTimedEffect(int slotIndex, string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
UnregisterEntry(slotIndex, id);
|
||||
if (!UnregisterEntry(slotIndex, id))
|
||||
{
|
||||
// Entry may have been transferred to another ally slot; fallback to global search.
|
||||
UnregisterEntryAnySlot(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterEntry(AllyCombatant ally, Group group, string id, float value, float startTime)
|
||||
public bool TryGetLatestAllyBuffTimestamp(AllyCombatant ally, out float latestStartTime)
|
||||
{
|
||||
latestStartTime = float.NegativeInfinity;
|
||||
if (ally == null) return false;
|
||||
if (!_slots.TryGetValue(ally.slotIndex, out var s) || s == null) return false;
|
||||
|
||||
bool found = false;
|
||||
foreach (var kv in s.entriesByGroup)
|
||||
{
|
||||
if (!IsTransferableGroupForRedirect(kv.Key)) continue;
|
||||
var list = kv.Value;
|
||||
if (list == null) continue;
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
var e = list[i];
|
||||
if (e == null) continue;
|
||||
if (!found || e.startTime > latestStartTime)
|
||||
{
|
||||
latestStartTime = e.startTime;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// Count currently-held transferable buff groups for target selection rules.
|
||||
// This mirrors what players perceive in budeff icon groups.
|
||||
public bool TryGetTransferableAllyBuffGroupCount(AllyCombatant ally, out int count)
|
||||
{
|
||||
count = 0;
|
||||
if (ally == null) return false;
|
||||
if (!_slots.TryGetValue(ally.slotIndex, out var s) || s == null) return false;
|
||||
|
||||
foreach (var kv in s.entriesByGroup)
|
||||
{
|
||||
if (!IsTransferableGroupForRedirect(kv.Key)) continue;
|
||||
var list = kv.Value;
|
||||
if (list != null && list.Count > 0) count++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryTransferLatestAllyBuff(AllyCombatant from, AllyCombatant to, out PlayerBudeffIconType iconType, out float value, out float startTime, out float duration)
|
||||
{
|
||||
iconType = PlayerBudeffIconType.ot_scoreEfficiency_up;
|
||||
value = 0f;
|
||||
startTime = 0f;
|
||||
duration = 0f;
|
||||
|
||||
if (from == null || to == null || from == to) return false;
|
||||
if (!_slots.TryGetValue(from.slotIndex, out var fromState) || fromState == null) return false;
|
||||
|
||||
Entry bestEntry = null;
|
||||
Group bestGroup = Group.ScoreEfficiency;
|
||||
|
||||
foreach (var kv in fromState.entriesByGroup)
|
||||
{
|
||||
if (!IsTransferableGroupForRedirect(kv.Key)) continue;
|
||||
var list = kv.Value;
|
||||
if (list == null) continue;
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
var e = list[i];
|
||||
if (e == null) continue;
|
||||
if (bestEntry == null || e.startTime > bestEntry.startTime)
|
||||
{
|
||||
bestEntry = e;
|
||||
bestGroup = kv.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestEntry == null) return false;
|
||||
|
||||
// Remove from source
|
||||
if (fromState.entriesByGroup.TryGetValue(bestGroup, out var srcList) && srcList != null)
|
||||
{
|
||||
srcList.Remove(bestEntry);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(bestEntry.id))
|
||||
{
|
||||
fromState.groupByEntryId.Remove(bestEntry.id);
|
||||
}
|
||||
|
||||
// Add to destination with same entry id so later unregistration still works.
|
||||
var toState = GetOrCreateSlot(to.slotIndex);
|
||||
toState.ally = to;
|
||||
if (!toState.baselineReady) RegisterBaseline(to);
|
||||
if (!toState.entriesByGroup.TryGetValue(bestGroup, out var dstList) || dstList == null)
|
||||
{
|
||||
dstList = new List<Entry>(4);
|
||||
toState.entriesByGroup[bestGroup] = dstList;
|
||||
}
|
||||
dstList.Add(bestEntry);
|
||||
if (!string.IsNullOrEmpty(bestEntry.id))
|
||||
{
|
||||
toState.groupByEntryId[bestEntry.id] = bestGroup;
|
||||
}
|
||||
|
||||
iconType = GetRepresentativeIconType(bestGroup, bestEntry.value);
|
||||
value = bestEntry.value;
|
||||
startTime = bestEntry.startTime;
|
||||
duration = bestEntry.duration;
|
||||
|
||||
RefreshSlot(from.slotIndex);
|
||||
RefreshSlot(to.slotIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsTransferableGroupForRedirect(Group group)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case Group.MaxHP:
|
||||
case Group.MaxMana:
|
||||
case Group.ScoreEfficiency:
|
||||
case Group.DamageResistance:
|
||||
case Group.Attack:
|
||||
case Group.RedirectToSelf:
|
||||
case Group.RedirectToAdjacent:
|
||||
return true;
|
||||
default:
|
||||
// Exclude unsupported/non-transfer payload groups only.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterEntry(AllyCombatant ally, Group group, string id, float value, float startTime, float duration = 0f)
|
||||
{
|
||||
var s = GetOrCreateSlot(ally.slotIndex);
|
||||
s.ally = ally;
|
||||
@@ -215,17 +370,17 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
s.entriesByGroup[group] = list;
|
||||
}
|
||||
|
||||
var e = new Entry { id = id, group = group, value = value, startTime = startTime };
|
||||
var e = new Entry { id = id, group = group, value = value, startTime = startTime, duration = duration };
|
||||
list.Add(e);
|
||||
s.groupByEntryId[id] = group;
|
||||
|
||||
RefreshSlot(ally.slotIndex);
|
||||
}
|
||||
|
||||
private void UnregisterEntry(int slotIndex, string id)
|
||||
private bool UnregisterEntry(int slotIndex, string id)
|
||||
{
|
||||
if (!_slots.TryGetValue(slotIndex, out var s)) return;
|
||||
if (!s.groupByEntryId.TryGetValue(id, out var group)) return;
|
||||
if (!_slots.TryGetValue(slotIndex, out var s)) return false;
|
||||
if (!s.groupByEntryId.TryGetValue(id, out var group)) return false;
|
||||
if (s.entriesByGroup.TryGetValue(group, out var list))
|
||||
{
|
||||
for (int i = list.Count - 1; i >= 0; i--)
|
||||
@@ -239,6 +394,17 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
}
|
||||
s.groupByEntryId.Remove(id);
|
||||
RefreshSlot(slotIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool UnregisterEntryAnySlot(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return false;
|
||||
foreach (var kv in _slots)
|
||||
{
|
||||
if (UnregisterEntry(kv.Key, id)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void RefreshSlot(int slotIndex)
|
||||
@@ -341,6 +507,12 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
display.Add((Group.RedirectToAdjacent, PlayerBudeffIconType.dmg_redirect_toAdjacent, "1", GetOrderKey(s, Group.RedirectToAdjacent)));
|
||||
}
|
||||
|
||||
bool hasLuckyChanceByState = s.ally != null && s.ally.HasNonMissToPerfectRewriteForUI();
|
||||
if (HasAny(s, Group.LuckyChance) || hasLuckyChanceByState)
|
||||
{
|
||||
display.Add((Group.LuckyChance, PlayerBudeffIconType.ot_luckyChance, " ", GetOrderKey(s, Group.LuckyChance)));
|
||||
}
|
||||
|
||||
display.Sort((a, b) => a.orderKey.CompareTo(b.orderKey));
|
||||
|
||||
var shouldShow = new HashSet<Group>();
|
||||
@@ -354,7 +526,7 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
{
|
||||
var go = s.iconByGroup[g];
|
||||
s.iconByGroup.Remove(g);
|
||||
if (go != null) Destroy(go);
|
||||
if (go != null) PlayBuffIconExitAndDestroy(go);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,6 +537,7 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
{
|
||||
go = Instantiate(budeff_prefab, parent.transform, false);
|
||||
s.iconByGroup[item.group] = go;
|
||||
PlayBuffIconEntry(go);
|
||||
}
|
||||
go.transform.SetSiblingIndex(i);
|
||||
var comp = go.GetComponent<PlayerBudeffPrefab>();
|
||||
@@ -472,6 +645,11 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
display.Add((Group.RedirectToAdjacent, PlayerBudeffIconType.dmg_redirect_toAdjacent, "1", GetOrderKeyEnemy(s, Group.RedirectToAdjacent)));
|
||||
}
|
||||
|
||||
if (HasAnyEnemy(s, Group.LuckyChance))
|
||||
{
|
||||
display.Add((Group.LuckyChance, PlayerBudeffIconType.ot_luckyChance, string.Empty, GetOrderKeyEnemy(s, Group.LuckyChance)));
|
||||
}
|
||||
|
||||
if (hasEntries)
|
||||
{
|
||||
if (display.Count == 0)
|
||||
@@ -497,7 +675,7 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
{
|
||||
var go = s.iconByGroup[g];
|
||||
s.iconByGroup.Remove(g);
|
||||
if (go != null) Destroy(go);
|
||||
if (go != null) PlayBuffIconExitAndDestroy(go);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,6 +686,7 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
{
|
||||
go = Instantiate(budeff_prefab, parent.transform, false);
|
||||
s.iconByGroup[item.group] = go;
|
||||
PlayBuffIconEntry(go);
|
||||
}
|
||||
go.transform.SetSiblingIndex(i);
|
||||
var comp = go.GetComponent<PlayerBudeffPrefab>();
|
||||
@@ -709,7 +888,7 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
{
|
||||
var g = existingGroups[i];
|
||||
var go = s.iconByGroup[g];
|
||||
if (go != null) Destroy(go);
|
||||
if (go != null) PlayBuffIconExitAndDestroy(go);
|
||||
}
|
||||
s.iconByGroup.Clear();
|
||||
s.entriesByGroup.Clear();
|
||||
@@ -740,12 +919,14 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
{
|
||||
if (s == null || enemy == null) return;
|
||||
var so = enemy.sourceData;
|
||||
if (so != null && !ShouldUseRuntimeBaseline(enemy, so))
|
||||
int diffID = BeatmapManager.Instance != null ? BeatmapManager.Instance.assignedDifficulty : 0;
|
||||
if (so != null && !ShouldUseRuntimeBaseline(enemy, so, diffID))
|
||||
{
|
||||
s.baseMaxHP = Mathf.Max(1, so.enemy_maxHP);
|
||||
s.baseMaxMana = Mathf.Max(0, so.GetEffectiveMaxMana());
|
||||
s.baseAttack = Mathf.Max(0, so.enemy_baseAttack);
|
||||
s.baseDamageResistance = ClampDamageResistance(so.enemy_damageResistance);
|
||||
var stats = so.GetStatsByDifficultyID(diffID);
|
||||
s.baseMaxHP = Mathf.Max(1, stats.enemy_maxHP);
|
||||
s.baseMaxMana = Mathf.Max(0, stats.enemy_maxMana);
|
||||
s.baseAttack = Mathf.Max(0, stats.enemy_baseAttack);
|
||||
s.baseDamageResistance = ClampDamageResistance(stats.enemy_damageResistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -756,13 +937,14 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ShouldUseRuntimeBaseline(EnemyCombatant enemy, EnemyData_SO so)
|
||||
private static bool ShouldUseRuntimeBaseline(EnemyCombatant enemy, EnemyData_SO so, int difficultyID)
|
||||
{
|
||||
if (enemy == null || so == null) return true;
|
||||
int soMaxHP = Mathf.Max(1, so.enemy_maxHP);
|
||||
int soMaxMana = Mathf.Max(0, so.GetEffectiveMaxMana());
|
||||
int soAttack = Mathf.Max(0, so.enemy_baseAttack);
|
||||
float soResist = ClampDamageResistance(so.enemy_damageResistance);
|
||||
var stats = so.GetStatsByDifficultyID(difficultyID);
|
||||
int soMaxHP = Mathf.Max(1, stats.enemy_maxHP);
|
||||
int soMaxMana = Mathf.Max(0, stats.enemy_maxMana);
|
||||
int soAttack = Mathf.Max(0, stats.enemy_baseAttack);
|
||||
float soResist = ClampDamageResistance(stats.enemy_damageResistance);
|
||||
if (enemy.maxHP != soMaxHP) return true;
|
||||
if (enemy.maxMana != soMaxMana) return true;
|
||||
if (enemy.attack != soAttack) return true;
|
||||
@@ -844,11 +1026,43 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
return Group.RedirectToSelf;
|
||||
case PlayerBudeffIconType.dmg_redirect_toAdjacent:
|
||||
return Group.RedirectToAdjacent;
|
||||
case PlayerBudeffIconType.ot_luckyChance:
|
||||
return Group.LuckyChance;
|
||||
default:
|
||||
return Group.ScoreEfficiency;
|
||||
}
|
||||
}
|
||||
|
||||
private static PlayerBudeffIconType GetRepresentativeIconType(Group group, float value)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case Group.MaxHP:
|
||||
return value >= 0f ? PlayerBudeffIconType.ot_maxHP_up : PlayerBudeffIconType.ot_maxHP_down;
|
||||
case Group.MaxMana:
|
||||
return value >= 0f ? PlayerBudeffIconType.ot_maxMana_up : PlayerBudeffIconType.ot_maxMana_down;
|
||||
case Group.Bleeding:
|
||||
return PlayerBudeffIconType.ot_bleeding;
|
||||
case Group.DeepHurt:
|
||||
return PlayerBudeffIconType.ot_deephurt;
|
||||
case Group.ScoreEfficiency:
|
||||
return value >= 0f ? PlayerBudeffIconType.ot_scoreEfficiency_up : PlayerBudeffIconType.ot_scoreEfficiency_down;
|
||||
case Group.DamageResistance:
|
||||
if (value < 0f) return PlayerBudeffIconType.ot_defend_down;
|
||||
return PlayerBudeffIconType.ot_defend_up;
|
||||
case Group.Attack:
|
||||
return value >= 0f ? PlayerBudeffIconType.ot_atk_up : PlayerBudeffIconType.ot_atk_down;
|
||||
case Group.RedirectToSelf:
|
||||
return PlayerBudeffIconType.dmg_redirect_toSelf;
|
||||
case Group.RedirectToAdjacent:
|
||||
return PlayerBudeffIconType.dmg_redirect_toAdjacent;
|
||||
case Group.LuckyChance:
|
||||
return PlayerBudeffIconType.ot_luckyChance;
|
||||
default:
|
||||
return PlayerBudeffIconType.ot_scoreEfficiency_up;
|
||||
}
|
||||
}
|
||||
|
||||
private void TryAutoBindPuts()
|
||||
{
|
||||
var ui = teamUIController.Instance != null ? teamUIController.Instance : FindAnyObjectByType<teamUIController>();
|
||||
@@ -967,6 +1181,8 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
return source.dmg_redirect_toSelf;
|
||||
case EffectType.RedirectSelfDamageToAdjacent:
|
||||
return source.dmg_redirect_toAdjacent;
|
||||
case EffectType.RewriteNonMissToPerfect:
|
||||
return source.ot_luckyChance;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -1006,4 +1222,100 @@ public class iBudeffPrefabController : MonoBehaviour
|
||||
_warnedMissingApprParents = true;
|
||||
Debug.LogWarning("[iBudeffPrefabController] appr_to_put objects are not assigned (no appr popup will be shown).");
|
||||
}
|
||||
|
||||
private static CanvasGroup EnsureCanvasGroup(GameObject go)
|
||||
{
|
||||
if (go == null) return null;
|
||||
var cg = go.GetComponent<CanvasGroup>();
|
||||
if (cg == null) cg = go.AddComponent<CanvasGroup>();
|
||||
return cg;
|
||||
}
|
||||
|
||||
private void PlayBuffIconEntry(GameObject go)
|
||||
{
|
||||
if (go == null) return;
|
||||
|
||||
int id = go.GetInstanceID();
|
||||
if (_iconExitCoroutines.TryGetValue(id, out var exitCo) && exitCo != null)
|
||||
{
|
||||
StopCoroutine(exitCo);
|
||||
_iconExitCoroutines.Remove(id);
|
||||
}
|
||||
|
||||
var cg = EnsureCanvasGroup(go);
|
||||
if (!enableBuffIconFlashAnimation || cg == null)
|
||||
{
|
||||
if (cg != null) cg.alpha = 1f;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_iconEntryCoroutines.TryGetValue(id, out var running) && running != null)
|
||||
StopCoroutine(running);
|
||||
|
||||
_iconEntryCoroutines[id] = StartCoroutine(BuffIconEntryFlashCoroutine(go, cg, id));
|
||||
}
|
||||
|
||||
private void PlayBuffIconExitAndDestroy(GameObject go)
|
||||
{
|
||||
if (go == null) return;
|
||||
|
||||
int id = go.GetInstanceID();
|
||||
if (_iconEntryCoroutines.TryGetValue(id, out var entryCo) && entryCo != null)
|
||||
{
|
||||
StopCoroutine(entryCo);
|
||||
_iconEntryCoroutines.Remove(id);
|
||||
}
|
||||
|
||||
var cg = EnsureCanvasGroup(go);
|
||||
if (!enableBuffIconFlashAnimation || cg == null)
|
||||
{
|
||||
Destroy(go);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_iconExitCoroutines.TryGetValue(id, out var running) && running != null)
|
||||
StopCoroutine(running);
|
||||
|
||||
_iconExitCoroutines[id] = StartCoroutine(BuffIconExitFlashCoroutine(go, cg, id));
|
||||
}
|
||||
|
||||
private IEnumerator BuffIconEntryFlashCoroutine(GameObject go, CanvasGroup cg, int id)
|
||||
{
|
||||
if (go == null || cg == null) yield break;
|
||||
|
||||
int toggles = Mathf.Max(2, buffIconEntryFlashCount * 2);
|
||||
float step = Mathf.Max(0.005f, buffIconEntryFlashDuration / toggles);
|
||||
|
||||
cg.alpha = 0f;
|
||||
for (int i = 0; i < toggles; i++)
|
||||
{
|
||||
if (go == null || cg == null) yield break;
|
||||
cg.alpha = (i % 2 == 0) ? 1f : 0.08f;
|
||||
yield return new WaitForSeconds(step);
|
||||
}
|
||||
|
||||
if (go != null && cg != null) cg.alpha = 1f;
|
||||
_iconEntryCoroutines.Remove(id);
|
||||
}
|
||||
|
||||
private IEnumerator BuffIconExitFlashCoroutine(GameObject go, CanvasGroup cg, int id)
|
||||
{
|
||||
if (go == null || cg == null) yield break;
|
||||
|
||||
int toggles = Mathf.Max(2, buffIconExitFlashCount * 2);
|
||||
float step = Mathf.Max(0.005f, buffIconExitFlashDuration / toggles);
|
||||
|
||||
cg.alpha = 1f;
|
||||
for (int i = 0; i < toggles; i++)
|
||||
{
|
||||
if (go == null || cg == null) yield break;
|
||||
cg.alpha = (i % 2 == 0) ? 0.08f : 1f;
|
||||
yield return new WaitForSeconds(step);
|
||||
}
|
||||
|
||||
if (go != null && cg != null) cg.alpha = 0f;
|
||||
_iconExitCoroutines.Remove(id);
|
||||
_iconEntryCoroutines.Remove(id);
|
||||
if (go != null) Destroy(go);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,156 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2e1a192758189c49b8ef48c7a471107
|
||||
TextureImporter:
|
||||
internalIDToNameTable:
|
||||
- first:
|
||||
213: 2978455473066875312
|
||||
second: "\u5E78\u8FD0\u5148\u673A_0"
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites:
|
||||
- serializedVersion: 2
|
||||
name: "\u5E78\u8FD0\u5148\u673A_0"
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 200
|
||||
height: 200
|
||||
alignment: 0
|
||||
pivot: {x: 0, y: 0}
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
customData:
|
||||
outline: []
|
||||
physicsShape: []
|
||||
tessellationDetail: -1
|
||||
bones: []
|
||||
spriteID: 0b91873e879955920800000000000000
|
||||
internalID: 2978455473066875312
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable:
|
||||
"\u5E78\u8FD0\u5148\u673A_0": 2978455473066875312
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+5
-2
@@ -144,9 +144,9 @@ public class iNumberPrefabController : MonoBehaviour
|
||||
WarnMissingPrefabOnce();
|
||||
return;
|
||||
}
|
||||
if (parent == null)
|
||||
if (parent == null || !parent.gameObject.activeInHierarchy)
|
||||
{
|
||||
WarnMissingParentsOnce();
|
||||
// If the parent is inactive (e.g., ally slot not active), skip spawning to avoid coroutine errors
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -158,6 +158,9 @@ public class iNumberPrefabController : MonoBehaviour
|
||||
if (prefab.activeSelf) prefab.SetActive(false);
|
||||
}
|
||||
|
||||
// Ensure the newly created object is active before playing animation
|
||||
if (!go.activeInHierarchy) go.SetActive(true);
|
||||
|
||||
var view = go.GetComponent<playerInstantNumbersPrefab>();
|
||||
if (view != null) view.Play(type, signedValue);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user