[Fix] Code visual

This commit is contained in:
2026-02-28 19:25:26 +07:00
parent bee20fd1f8
commit e24b30743b
39 changed files with 2611 additions and 2687 deletions
+70 -71
View File
@@ -5,94 +5,93 @@ using YachtDice.Scoring;
namespace YachtDice.Inventory
{
public sealed class InventoryController : MonoBehaviour
{
[SerializeField] private InventoryView inventoryView;
[SerializeField] private ScoringSystem scoringSystem;
[SerializeField] private CurrencyBank currencyBank;
private InventoryModel model;
public InventoryModel Model => model;
public void Initialize(InventoryModel inventoryModel)
public class InventoryController : MonoBehaviour
{
model = inventoryModel;
[SerializeField] private InventoryView inventoryView;
[SerializeField] private ScoringSystem scoringSystem;
[SerializeField] private CurrencyBank currencyBank;
inventoryView.OnActivateClicked += HandleActivate;
inventoryView.OnDeactivateClicked += HandleDeactivate;
inventoryView.OnSellClicked += HandleSell;
private InventoryModel model;
model.OnActiveModifiersChanged += HandleActiveModifiersChanged;
model.OnInventoryChanged += HandleInventoryChanged;
public InventoryModel Model => model;
if (scoringSystem != null)
scoringSystem.OnCategoryConfirmed += HandleCategoryConfirmed;
RefreshView();
}
private void OnDestroy()
{
if (inventoryView != null)
public void Initialize(InventoryModel inventoryModel)
{
inventoryView.OnActivateClicked -= HandleActivate;
inventoryView.OnDeactivateClicked -= HandleDeactivate;
inventoryView.OnSellClicked -= HandleSell;
model = inventoryModel;
inventoryView.OnActivateClicked += HandleActivate;
inventoryView.OnDeactivateClicked += HandleDeactivate;
inventoryView.OnSellClicked += HandleSell;
model.OnActiveModifiersChanged += HandleActiveModifiersChanged;
model.OnInventoryChanged += HandleInventoryChanged;
if (scoringSystem != null)
scoringSystem.OnCategoryConfirmed += HandleCategoryConfirmed;
RefreshView();
}
if (model != null)
private void OnDestroy()
{
model.OnActiveModifiersChanged -= HandleActiveModifiersChanged;
model.OnInventoryChanged -= HandleInventoryChanged;
if (inventoryView != null)
{
inventoryView.OnActivateClicked -= HandleActivate;
inventoryView.OnDeactivateClicked -= HandleDeactivate;
inventoryView.OnSellClicked -= HandleSell;
}
if (model != null)
{
model.OnActiveModifiersChanged -= HandleActiveModifiersChanged;
model.OnInventoryChanged -= HandleInventoryChanged;
}
if (scoringSystem != null)
scoringSystem.OnCategoryConfirmed -= HandleCategoryConfirmed;
}
if (scoringSystem != null)
scoringSystem.OnCategoryConfirmed -= HandleCategoryConfirmed;
}
private void HandleActivate(ModifierRuntime runtime)
{
model.TryActivate(runtime);
}
private void HandleActivate(ModifierRuntime runtime)
{
model.TryActivate(runtime);
}
private void HandleDeactivate(ModifierRuntime runtime)
{
model.Deactivate(runtime);
}
private void HandleDeactivate(ModifierRuntime runtime)
{
model.Deactivate(runtime);
}
private void HandleSell(ModifierRuntime runtime)
{
if (runtime.Data == null) return;
private void HandleSell(ModifierRuntime runtime)
{
if (runtime.Data == null) return;
int sellPrice = runtime.Data.SellPrice;
model.RemoveModifier(runtime);
int sellPrice = runtime.Data.SellPrice;
model.RemoveModifier(runtime);
if (currencyBank != null)
currencyBank.Add(sellPrice);
}
if (currencyBank != null)
currencyBank.Add(sellPrice);
}
private void HandleActiveModifiersChanged(System.Collections.Generic.List<ModifierData> activeModifiers)
{
if (scoringSystem != null)
scoringSystem.SetActiveModifiers(activeModifiers);
}
private void HandleActiveModifiersChanged(System.Collections.Generic.List<ModifierData> activeModifiers)
{
if (scoringSystem != null)
scoringSystem.SetActiveModifiers(activeModifiers);
}
private void HandleInventoryChanged()
{
RefreshView();
}
private void HandleInventoryChanged()
{
RefreshView();
}
private void HandleCategoryConfirmed(YachtCategory category, ScoreResult result)
{
model.ConsumeUseOnActive();
}
private void HandleCategoryConfirmed(YachtCategory category, ScoreResult result)
{
model.ConsumeUseOnActive();
}
private void RefreshView()
{
if (inventoryView != null && model != null)
inventoryView.Refresh(model.OwnedModifiers, model.MaxActiveSlots);
private void RefreshView()
{
if (inventoryView != null && model != null)
inventoryView.Refresh(model.OwnedModifiers, model.MaxActiveSlots);
}
}
}
}
+106 -107
View File
@@ -4,129 +4,128 @@ using YachtDice.Modifiers;
namespace YachtDice.Inventory
{
public sealed class InventoryModel
{
private readonly List<ModifierRuntime> ownedModifiers = new();
private int maxActiveSlots;
public IReadOnlyList<ModifierRuntime> OwnedModifiers => ownedModifiers;
public int MaxActiveSlots => maxActiveSlots;
public event Action OnInventoryChanged;
public event Action<List<ModifierData>> OnActiveModifiersChanged;
public InventoryModel(int maxActiveSlots = 5)
public class InventoryModel
{
this.maxActiveSlots = maxActiveSlots;
}
private readonly List<ModifierRuntime> ownedModifiers = new();
private int maxActiveSlots;
public int ActiveCount
{
get
public IReadOnlyList<ModifierRuntime> OwnedModifiers => ownedModifiers;
public int MaxActiveSlots => maxActiveSlots;
public event Action OnInventoryChanged;
public event Action<List<ModifierData>> OnActiveModifiersChanged;
public InventoryModel(int maxActiveSlots = 5)
{
int count = 0;
for (int i = 0; i < ownedModifiers.Count; i++)
if (ownedModifiers[i].IsActive) count++;
return count;
}
}
public void SetMaxActiveSlots(int slots)
{
maxActiveSlots = slots;
}
public void AddModifier(ModifierData data)
{
var runtime = ModifierRuntime.Create(data);
ownedModifiers.Add(runtime);
OnInventoryChanged?.Invoke();
}
public void RemoveModifier(ModifierRuntime modifier)
{
if (!ownedModifiers.Contains(modifier)) return;
if (modifier.IsActive)
{
modifier.IsActive = false;
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
this.maxActiveSlots = maxActiveSlots;
}
ownedModifiers.Remove(modifier);
OnInventoryChanged?.Invoke();
}
public bool TryActivate(ModifierRuntime modifier)
{
if (modifier.IsActive) return false;
if (!ownedModifiers.Contains(modifier)) return false;
if (ActiveCount >= maxActiveSlots) return false;
modifier.IsActive = true;
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
return true;
}
public void Deactivate(ModifierRuntime modifier)
{
if (!modifier.IsActive) return;
modifier.IsActive = false;
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
}
public void ConsumeUseOnActive()
{
bool changed = false;
for (int i = ownedModifiers.Count - 1; i >= 0; i--)
public int ActiveCount
{
var mod = ownedModifiers[i];
if (!mod.IsActive) continue;
if (mod.Data == null) continue;
if (mod.Data.Durability != ModifierDurability.LimitedUses) continue;
mod.ConsumeUse();
if (mod.IsExpired)
get
{
ownedModifiers.RemoveAt(i);
changed = true;
int count = 0;
for (int i = 0; i < ownedModifiers.Count; i++)
if (ownedModifiers[i].IsActive) count++;
return count;
}
}
if (changed)
public void SetMaxActiveSlots(int slots)
{
maxActiveSlots = slots;
}
public void AddModifier(ModifierData data)
{
var runtime = ModifierRuntime.Create(data);
ownedModifiers.Add(runtime);
OnInventoryChanged?.Invoke();
}
public void RemoveModifier(ModifierRuntime modifier)
{
if (!ownedModifiers.Contains(modifier)) return;
if (modifier.IsActive)
{
modifier.IsActive = false;
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
}
ownedModifiers.Remove(modifier);
OnInventoryChanged?.Invoke();
}
public bool TryActivate(ModifierRuntime modifier)
{
if (modifier.IsActive) return false;
if (!ownedModifiers.Contains(modifier)) return false;
if (ActiveCount >= maxActiveSlots) return false;
modifier.IsActive = true;
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
return true;
}
public void Deactivate(ModifierRuntime modifier)
{
if (!modifier.IsActive) return;
modifier.IsActive = false;
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
}
}
public List<ModifierData> GetActiveModifierData()
{
var result = new List<ModifierData>();
for (int i = 0; i < ownedModifiers.Count; i++)
public void ConsumeUseOnActive()
{
if (ownedModifiers[i].IsActive && ownedModifiers[i].Data != null)
result.Add(ownedModifiers[i].Data);
bool changed = false;
for (int i = ownedModifiers.Count - 1; i >= 0; i--)
{
var mod = ownedModifiers[i];
if (!mod.IsActive) continue;
if (mod.Data == null) continue;
if (mod.Data.Durability != ModifierDurability.LimitedUses) continue;
mod.ConsumeUse();
if (mod.IsExpired)
{
ownedModifiers.RemoveAt(i);
changed = true;
}
}
if (changed)
{
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
}
}
return result;
public List<ModifierData> GetActiveModifierData()
{
var result = new List<ModifierData>();
for (int i = 0; i < ownedModifiers.Count; i++)
{
if (ownedModifiers[i].IsActive && ownedModifiers[i].Data != null)
result.Add(ownedModifiers[i].Data);
}
return result;
}
public void LoadState(List<ModifierRuntime> loaded)
{
ownedModifiers.Clear();
if (loaded != null)
ownedModifiers.AddRange(loaded);
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
}
public List<ModifierRuntime> GetAllForSave() => new(ownedModifiers);
}
public void LoadState(List<ModifierRuntime> loaded)
{
ownedModifiers.Clear();
if (loaded != null)
ownedModifiers.AddRange(loaded);
OnActiveModifiersChanged?.Invoke(GetActiveModifierData());
OnInventoryChanged?.Invoke();
}
public List<ModifierRuntime> GetAllForSave() => new(ownedModifiers);
}
}
+62 -63
View File
@@ -6,78 +6,77 @@ using YachtDice.Modifiers;
namespace YachtDice.Inventory
{
public sealed class InventorySlotView : MonoBehaviour
{
[SerializeField] private Image iconImage;
[SerializeField] private TMP_Text nameText;
[SerializeField] private TMP_Text descriptionText;
[SerializeField] private TMP_Text usesText;
[SerializeField] private Button activateButton;
[SerializeField] private Button deactivateButton;
[SerializeField] private Button sellButton;
[SerializeField] private TMP_Text sellPriceText;
[SerializeField] private Image background;
[Header("Colors")]
[SerializeField] private Color activeColor = new(0.7f, 1f, 0.7f);
[SerializeField] private Color inactiveColor = Color.white;
private ModifierRuntime runtime;
public event Action<ModifierRuntime> OnActivateClicked;
public event Action<ModifierRuntime> OnDeactivateClicked;
public event Action<ModifierRuntime> OnSellClicked;
private void Awake()
public class InventorySlotView : MonoBehaviour
{
if (activateButton != null)
activateButton.onClick.AddListener(() => OnActivateClicked?.Invoke(runtime));
if (deactivateButton != null)
deactivateButton.onClick.AddListener(() => OnDeactivateClicked?.Invoke(runtime));
if (sellButton != null)
sellButton.onClick.AddListener(() => OnSellClicked?.Invoke(runtime));
}
[SerializeField] private Image iconImage;
[SerializeField] private TMP_Text nameText;
[SerializeField] private TMP_Text descriptionText;
[SerializeField] private TMP_Text usesText;
[SerializeField] private Button activateButton;
[SerializeField] private Button deactivateButton;
[SerializeField] private Button sellButton;
[SerializeField] private TMP_Text sellPriceText;
[SerializeField] private Image background;
public void Setup(ModifierRuntime modifierRuntime, bool canActivateMore)
{
runtime = modifierRuntime;
var data = runtime.Data;
[Header("Colors")]
[SerializeField] private Color activeColor = new(0.7f, 1f, 0.7f);
[SerializeField] private Color inactiveColor = Color.white;
if (data == null) return;
private ModifierRuntime runtime;
if (nameText != null) nameText.text = data.DisplayName;
if (descriptionText != null) descriptionText.text = data.Description;
if (iconImage != null && data.Icon != null) iconImage.sprite = data.Icon;
public event Action<ModifierRuntime> OnActivateClicked;
public event Action<ModifierRuntime> OnDeactivateClicked;
public event Action<ModifierRuntime> OnSellClicked;
if (usesText != null)
private void Awake()
{
if (data.Durability == ModifierDurability.LimitedUses)
{
usesText.gameObject.SetActive(true);
usesText.text = $"{runtime.RemainingUses}/{data.MaxUses}";
}
else
{
usesText.gameObject.SetActive(false);
}
if (activateButton != null)
activateButton.onClick.AddListener(() => OnActivateClicked?.Invoke(runtime));
if (deactivateButton != null)
deactivateButton.onClick.AddListener(() => OnDeactivateClicked?.Invoke(runtime));
if (sellButton != null)
sellButton.onClick.AddListener(() => OnSellClicked?.Invoke(runtime));
}
if (sellPriceText != null) sellPriceText.text = data.SellPrice.ToString();
bool isActive = runtime.IsActive;
if (activateButton != null)
public void Setup(ModifierRuntime modifierRuntime, bool canActivateMore)
{
activateButton.gameObject.SetActive(!isActive);
activateButton.interactable = canActivateMore;
runtime = modifierRuntime;
var data = runtime.Data;
if (data == null) return;
if (nameText != null) nameText.text = data.DisplayName;
if (descriptionText != null) descriptionText.text = data.Description;
if (iconImage != null && data.Icon != null) iconImage.sprite = data.Icon;
if (usesText != null)
{
if (data.Durability == ModifierDurability.LimitedUses)
{
usesText.gameObject.SetActive(true);
usesText.text = $"{runtime.RemainingUses}/{data.MaxUses}";
}
else
{
usesText.gameObject.SetActive(false);
}
}
if (sellPriceText != null) sellPriceText.text = data.SellPrice.ToString();
bool isActive = runtime.IsActive;
if (activateButton != null)
{
activateButton.gameObject.SetActive(!isActive);
activateButton.interactable = canActivateMore;
}
if (deactivateButton != null)
deactivateButton.gameObject.SetActive(isActive);
if (background != null)
background.color = isActive ? activeColor : inactiveColor;
}
if (deactivateButton != null)
deactivateButton.gameObject.SetActive(isActive);
if (background != null)
background.color = isActive ? activeColor : inactiveColor;
}
}
}
+58 -59
View File
@@ -7,73 +7,72 @@ using YachtDice.Modifiers;
namespace YachtDice.Inventory
{
public sealed class InventoryView : MonoBehaviour
{
[SerializeField] private Transform slotContainer;
[SerializeField] private InventorySlotView slotPrefab;
[SerializeField] private TMP_Text slotCountText;
[SerializeField] private Button closeButton;
private readonly List<InventorySlotView> spawnedSlots = new();
public event Action<ModifierRuntime> OnActivateClicked;
public event Action<ModifierRuntime> OnDeactivateClicked;
public event Action<ModifierRuntime> OnSellClicked;
private void Awake()
public class InventoryView : MonoBehaviour
{
if (closeButton != null)
closeButton.onClick.AddListener(Hide);
}
[SerializeField] private Transform slotContainer;
[SerializeField] private InventorySlotView slotPrefab;
[SerializeField] private TMP_Text slotCountText;
[SerializeField] private Button closeButton;
private void OnDestroy()
{
if (closeButton != null)
closeButton.onClick.RemoveListener(Hide);
}
private readonly List<InventorySlotView> spawnedSlots = new();
public void Show() => gameObject.SetActive(true);
public void Hide() => gameObject.SetActive(false);
public bool IsVisible => gameObject.activeSelf;
public event Action<ModifierRuntime> OnActivateClicked;
public event Action<ModifierRuntime> OnDeactivateClicked;
public event Action<ModifierRuntime> OnSellClicked;
public void Refresh(IReadOnlyList<ModifierRuntime> owned, int maxSlots)
{
ClearSlots();
int activeCount = 0;
for (int i = 0; i < owned.Count; i++)
private void Awake()
{
var runtime = owned[i];
if (runtime.IsActive) activeCount++;
var slot = Instantiate(slotPrefab, slotContainer);
slot.Setup(runtime, activeCount <= maxSlots);
slot.OnActivateClicked += HandleActivate;
slot.OnDeactivateClicked += HandleDeactivate;
slot.OnSellClicked += HandleSell;
spawnedSlots.Add(slot);
if (closeButton != null)
closeButton.onClick.AddListener(Hide);
}
if (slotCountText != null)
slotCountText.text = $"{activeCount}/{maxSlots}";
}
private void ClearSlots()
{
for (int i = 0; i < spawnedSlots.Count; i++)
private void OnDestroy()
{
spawnedSlots[i].OnActivateClicked -= HandleActivate;
spawnedSlots[i].OnDeactivateClicked -= HandleDeactivate;
spawnedSlots[i].OnSellClicked -= HandleSell;
Destroy(spawnedSlots[i].gameObject);
if (closeButton != null)
closeButton.onClick.RemoveListener(Hide);
}
spawnedSlots.Clear();
}
private void HandleActivate(ModifierRuntime runtime) => OnActivateClicked?.Invoke(runtime);
private void HandleDeactivate(ModifierRuntime runtime) => OnDeactivateClicked?.Invoke(runtime);
private void HandleSell(ModifierRuntime runtime) => OnSellClicked?.Invoke(runtime);
}
public void Show() => gameObject.SetActive(true);
public void Hide() => gameObject.SetActive(false);
public bool IsVisible => gameObject.activeSelf;
public void Refresh(IReadOnlyList<ModifierRuntime> owned, int maxSlots)
{
ClearSlots();
int activeCount = 0;
for (int i = 0; i < owned.Count; i++)
{
var runtime = owned[i];
if (runtime.IsActive) activeCount++;
var slot = Instantiate(slotPrefab, slotContainer);
slot.Setup(runtime, activeCount <= maxSlots);
slot.OnActivateClicked += HandleActivate;
slot.OnDeactivateClicked += HandleDeactivate;
slot.OnSellClicked += HandleSell;
spawnedSlots.Add(slot);
}
if (slotCountText != null)
slotCountText.text = $"{activeCount}/{maxSlots}";
}
private void ClearSlots()
{
for (int i = 0; i < spawnedSlots.Count; i++)
{
spawnedSlots[i].OnActivateClicked -= HandleActivate;
spawnedSlots[i].OnDeactivateClicked -= HandleDeactivate;
spawnedSlots[i].OnSellClicked -= HandleSell;
Destroy(spawnedSlots[i].gameObject);
}
spawnedSlots.Clear();
}
private void HandleActivate(ModifierRuntime runtime) => OnActivateClicked?.Invoke(runtime);
private void HandleDeactivate(ModifierRuntime runtime) => OnDeactivateClicked?.Invoke(runtime);
private void HandleSell(ModifierRuntime runtime) => OnSellClicked?.Invoke(runtime);
}
}