重构:修复 Shop 与 ItemTooltip 跨模块事件边界问题
- 将 _tooltipLocked 状态从 ItemTooltipController 移到 ShopController 维护 - DisplayItem 只发 Shop 模块 UI 事件(Hover/Lock/Hide) - ItemTooltipForm 取消按钮发 ItemTooltip 模块事件自关闭 - ShopController 通过 UIRouter 跨模块控制 ItemTooltipForm - 移除 DisplayItemHideEventArgs 的 Force 字段,分离两种关闭场景
This commit is contained in:
parent
2590f31250
commit
c30b256d7a
|
|
@ -9,24 +9,19 @@ namespace SepCore.Event
|
||||||
|
|
||||||
public override int Id => EventId;
|
public override int Id => EventId;
|
||||||
|
|
||||||
public bool Force = false;
|
|
||||||
|
|
||||||
public ItemTooltipHideEventArgs()
|
public ItemTooltipHideEventArgs()
|
||||||
{
|
{
|
||||||
Force = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemTooltipHideEventArgs Create(bool force = false)
|
public static ItemTooltipHideEventArgs Create(bool force = false)
|
||||||
{
|
{
|
||||||
var args = ReferencePool.Acquire<ItemTooltipHideEventArgs>();
|
var args = ReferencePool.Acquire<ItemTooltipHideEventArgs>();
|
||||||
args.Force = force;
|
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Clear()
|
public override void Clear()
|
||||||
{
|
{
|
||||||
Force = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 17754f00ac924fc29b3604cfed7a5efe
|
|
||||||
timeCreated: 1771488601
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 51bff2c6818f44398b4b8f7d1448b310
|
|
||||||
timeCreated: 1771071724
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
using GameFramework;
|
||||||
|
using GameFramework.Event;
|
||||||
|
|
||||||
|
namespace SepCore.Event
|
||||||
|
{
|
||||||
|
public class DisplayItemHideEventArgs : GameEventArgs
|
||||||
|
{
|
||||||
|
public static readonly int EventId = typeof(DisplayItemHideEventArgs).GetHashCode();
|
||||||
|
|
||||||
|
public override int Id => EventId;
|
||||||
|
|
||||||
|
public DisplayItemHideEventArgs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayItemHideEventArgs Create()
|
||||||
|
{
|
||||||
|
var args = ReferencePool.Acquire<DisplayItemHideEventArgs>();
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Clear()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eb8173a4a0fb12245bc81b5bd66b5948
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -4,30 +4,30 @@ using UnityEngine;
|
||||||
|
|
||||||
namespace SepCore.Event
|
namespace SepCore.Event
|
||||||
{
|
{
|
||||||
public class ItemTooltipShowEventArgs : GameEventArgs
|
public class DisplayItemHoverEventArgs : GameEventArgs
|
||||||
{
|
{
|
||||||
public static readonly int EventId = typeof(ItemTooltipShowEventArgs).GetHashCode();
|
public static readonly int EventId = typeof(DisplayItemHoverEventArgs).GetHashCode();
|
||||||
|
|
||||||
public override int Id => EventId;
|
public override int Id => EventId;
|
||||||
|
|
||||||
public int Index { get; private set; }
|
public int Index;
|
||||||
|
public bool IsWeapon;
|
||||||
|
public Vector3 TargetPos;
|
||||||
|
|
||||||
public bool IsWeapon { get; private set; }
|
public DisplayItemHoverEventArgs()
|
||||||
|
|
||||||
public Vector3 TargetPos { get; private set; }
|
|
||||||
|
|
||||||
public ItemTooltipShowEventArgs()
|
|
||||||
{
|
{
|
||||||
Index = -1;
|
Index = -1;
|
||||||
IsWeapon = false;
|
IsWeapon = false;
|
||||||
|
TargetPos = Vector3.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemTooltipShowEventArgs Create(int index, bool isWeapon, Vector3 targetPos)
|
public static DisplayItemHoverEventArgs Create(int index, bool isWeapon, Vector3 targetPos)
|
||||||
{
|
{
|
||||||
var args = ReferencePool.Acquire<ItemTooltipShowEventArgs>();
|
var args = ReferencePool.Acquire<DisplayItemHoverEventArgs>();
|
||||||
args.Index = index;
|
args.Index = index;
|
||||||
args.IsWeapon = isWeapon;
|
args.IsWeapon = isWeapon;
|
||||||
args.TargetPos = targetPos;
|
args.TargetPos = targetPos;
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f43032aabf2403746bf0977988e91bbb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -3,19 +3,19 @@ using GameFramework.Event;
|
||||||
|
|
||||||
namespace SepCore.Event
|
namespace SepCore.Event
|
||||||
{
|
{
|
||||||
public class ItemTooltipLockEventArgs : GameEventArgs
|
public class DisplayItemLockEventArgs : GameEventArgs
|
||||||
{
|
{
|
||||||
public static readonly int EventId = typeof(ItemTooltipLockEventArgs).GetHashCode();
|
public static readonly int EventId = typeof(DisplayItemLockEventArgs).GetHashCode();
|
||||||
|
|
||||||
public override int Id => EventId;
|
public override int Id => EventId;
|
||||||
|
|
||||||
public ItemTooltipLockEventArgs()
|
public DisplayItemLockEventArgs()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemTooltipLockEventArgs Create()
|
public static DisplayItemLockEventArgs Create()
|
||||||
{
|
{
|
||||||
var args = ReferencePool.Acquire<ItemTooltipLockEventArgs>();
|
var args = ReferencePool.Acquire<DisplayItemLockEventArgs>();
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5ad9bcc1ac9ad4141b810d224a31a201
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: b09ad1baac8a41338c0e42baf398beb8
|
guid: e5e26cd3da0c8bc46ac72f106b73357d
|
||||||
timeCreated: 1770986449
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,5 @@ namespace SepCore.Event
|
||||||
{
|
{
|
||||||
GoodsIndex = -1;
|
GoodsIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 11c82e4a45804087b1aaf337e38a8836
|
guid: a39ac97844dfeea4dacfdd80316ddb1e
|
||||||
timeCreated: 1770986490
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using GameFramework;
|
||||||
|
using GameFramework.Event;
|
||||||
|
|
||||||
|
namespace SepCore.Event
|
||||||
|
{
|
||||||
|
public class ShopRefreshEventArgs : GameEventArgs
|
||||||
|
{
|
||||||
|
public static readonly int EventId = typeof(ShopRefreshEventArgs).GetHashCode();
|
||||||
|
|
||||||
|
public override int Id => EventId;
|
||||||
|
|
||||||
|
public int Cost { get; private set; }
|
||||||
|
|
||||||
|
public ShopRefreshEventArgs()
|
||||||
|
{
|
||||||
|
Cost = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShopRefreshEventArgs Create(int cost)
|
||||||
|
{
|
||||||
|
var args = ReferencePool.Acquire<ShopRefreshEventArgs>();
|
||||||
|
|
||||||
|
args.Cost = cost;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Clear()
|
||||||
|
{
|
||||||
|
Cost = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8ebfa286438bc924f8c0fb8ebdfc5ce1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -25,37 +25,32 @@ namespace SepCore.UI
|
||||||
ItemType = ItemType.None;
|
ItemType = ItemType.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async UniTask<GoodsItemContext> CreateAsync(GoodsItemRawData rawData)
|
public GoodsItemContext(GoodsItemRawData rawData)
|
||||||
{
|
{
|
||||||
var context = new GoodsItemContext
|
|
||||||
{
|
|
||||||
Price = rawData.Price,
|
|
||||||
Rarity = rawData.Rarity,
|
|
||||||
ItemType = rawData.ItemType
|
|
||||||
};
|
|
||||||
|
|
||||||
if (context.ItemType == ItemType.None)
|
Price = rawData.Price;
|
||||||
|
Rarity = rawData.Rarity;
|
||||||
|
ItemType = rawData.ItemType;
|
||||||
|
|
||||||
|
|
||||||
|
if (ItemType == ItemType.None)
|
||||||
{
|
{
|
||||||
context.Description = string.Empty;
|
Description = string.Empty;
|
||||||
context.Icon = null;
|
Icon = null;
|
||||||
context.Title = string.Empty;
|
Title = string.Empty;
|
||||||
}
|
}
|
||||||
else if (context.ItemType == ItemType.Weapon)
|
else if (ItemType == ItemType.Weapon)
|
||||||
{
|
{
|
||||||
var weapon = (DRWeapon)rawData.DataRow;
|
var weapon = (DRWeapon)rawData.DataRow;
|
||||||
context.Title = weapon.Title;
|
Title = weapon.Title;
|
||||||
context.Description = ItemDescUtility.CreateWeaponDescription(weapon);
|
Description = ItemDescUtility.CreateWeaponDescription(weapon);
|
||||||
context.Icon = await GameEntry.SpriteCache.GetSprite(weapon.IconAssetName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var prop = (DRProp)rawData.DataRow;
|
var prop = (DRProp)rawData.DataRow;
|
||||||
context.Title = prop.Title;
|
Title = prop.Title;
|
||||||
context.Description = ItemDescUtility.CreatePropDescription(prop.Modifiers);
|
Description = ItemDescUtility.CreatePropDescription(prop.Modifiers);
|
||||||
context.Icon = await GameEntry.SpriteCache.GetSprite(prop.IconAssetName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using Cysharp.Threading.Tasks;
|
||||||
using SepCore.Event;
|
using SepCore.Event;
|
||||||
using SepCore.Definition;
|
using SepCore.Definition;
|
||||||
using GameFramework.Event;
|
using GameFramework.Event;
|
||||||
using UnityEngine;
|
|
||||||
using UnityGameFramework.Runtime;
|
using UnityGameFramework.Runtime;
|
||||||
|
|
||||||
namespace SepCore.UI
|
namespace SepCore.UI
|
||||||
|
|
@ -12,21 +11,24 @@ namespace SepCore.UI
|
||||||
{
|
{
|
||||||
protected override UIFormType UIFormType => UIFormType.ItemTooltipForm;
|
protected override UIFormType UIFormType => UIFormType.ItemTooltipForm;
|
||||||
|
|
||||||
private bool _locked = false;
|
|
||||||
private Action<int, int> _onRecycle;
|
private Action<int, int> _onRecycle;
|
||||||
|
|
||||||
|
private bool _subscribed = false;
|
||||||
|
|
||||||
protected override void SubscribeCustomEvents()
|
protected override void SubscribeCustomEvents()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Subscribe(DisplayItemLockEventArgs.EventId, OnDisplayItemLock);
|
if (_subscribed) return;
|
||||||
GameEntry.Event.Subscribe(DisplayItemHideEventArgs.EventId, OnDisplayItemHide);
|
|
||||||
GameEntry.Event.Subscribe(ItemTooltipRecycleEventArgs.EventId, ItemTooltipRecycle);
|
GameEntry.Event.Subscribe(ItemTooltipRecycleEventArgs.EventId, ItemTooltipRecycle);
|
||||||
|
GameEntry.Event.Subscribe(ItemTooltipHideEventArgs.EventId, ItemTooltipHide);
|
||||||
|
_subscribed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UnsubscribeCustomEvents()
|
protected override void UnsubscribeCustomEvents()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Unsubscribe(DisplayItemLockEventArgs.EventId, OnDisplayItemLock);
|
if (!_subscribed) return;
|
||||||
GameEntry.Event.Unsubscribe(DisplayItemHideEventArgs.EventId, OnDisplayItemHide);
|
|
||||||
GameEntry.Event.Unsubscribe(ItemTooltipRecycleEventArgs.EventId, ItemTooltipRecycle);
|
GameEntry.Event.Unsubscribe(ItemTooltipRecycleEventArgs.EventId, ItemTooltipRecycle);
|
||||||
|
GameEntry.Event.Unsubscribe(ItemTooltipHideEventArgs.EventId, ItemTooltipHide);
|
||||||
|
_subscribed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RefreshUI(ItemTooltipForm form, ItemTooltipContext context)
|
protected override void RefreshUI(ItemTooltipForm form, ItemTooltipContext context)
|
||||||
|
|
@ -79,7 +81,6 @@ namespace SepCore.UI
|
||||||
|
|
||||||
public override async UniTask CloseUIAsync(object userData = null, float timeout = 30f)
|
public override async UniTask CloseUIAsync(object userData = null, float timeout = 30f)
|
||||||
{
|
{
|
||||||
_locked = false;
|
|
||||||
_onRecycle = null;
|
_onRecycle = null;
|
||||||
await base.CloseUIAsync(userData, timeout);
|
await base.CloseUIAsync(userData, timeout);
|
||||||
}
|
}
|
||||||
|
|
@ -92,45 +93,8 @@ namespace SepCore.UI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsCurrentFormSender(object sender)
|
|
||||||
{
|
|
||||||
if (sender is ItemTooltipForm ItemTooltipForm)
|
|
||||||
{
|
|
||||||
return ItemTooltipForm == Form;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender is Component component && Form != null)
|
|
||||||
{
|
|
||||||
return component.transform.IsChildOf(Form.transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Event Handlers
|
#region Event Handlers
|
||||||
|
|
||||||
private void OnDisplayItemLock(object sender, GameEventArgs e)
|
|
||||||
{
|
|
||||||
if (e is not DisplayItemLockEventArgs)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisplayItemHide(object sender, GameEventArgs e)
|
|
||||||
{
|
|
||||||
if (e is not DisplayItemHideEventArgs args)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_locked && !args.Force) return;
|
|
||||||
|
|
||||||
GameEntry.UIRouter.CloseUIAsync(UIFormType.ItemTooltipForm).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ItemTooltipRecycle(object sender, GameEventArgs e)
|
private void ItemTooltipRecycle(object sender, GameEventArgs e)
|
||||||
{
|
{
|
||||||
if (e is not ItemTooltipRecycleEventArgs args)
|
if (e is not ItemTooltipRecycleEventArgs args)
|
||||||
|
|
@ -138,12 +102,14 @@ namespace SepCore.UI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsCurrentFormSender(sender))
|
_onRecycle?.Invoke(args.Index, args.Price);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRecycle?.Invoke(args.Index, args.Price);
|
private void ItemTooltipHide(object sender, GameEventArgs e)
|
||||||
|
{
|
||||||
|
if (e is not ItemTooltipHideEventArgs args) return;
|
||||||
|
|
||||||
|
CloseUIAsync().Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ namespace SepCore.UI
|
||||||
|
|
||||||
public void OnCancelButtonClick()
|
public void OnCancelButtonClick()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create(true));
|
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create());
|
||||||
}
|
}
|
||||||
|
|
||||||
private string BuildTypeText(ItemType type)
|
private string BuildTypeText(ItemType type)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,12 @@ namespace SepCore.UI
|
||||||
public List<GoodsItemContext> GoodsItems;
|
public List<GoodsItemContext> GoodsItems;
|
||||||
public DisplayListAreaContext PropListContext;
|
public DisplayListAreaContext PropListContext;
|
||||||
public DisplayListAreaContext WeaponListContext;
|
public DisplayListAreaContext WeaponListContext;
|
||||||
public float WeaponRecycleRate = 0.3f;
|
|
||||||
|
// 控制字段
|
||||||
|
public bool NeedRefreshGoodsItems;
|
||||||
|
public bool NeedRefreshPlayerCoin;
|
||||||
|
public bool NeedRefreshWeaponList;
|
||||||
|
public bool NeedRefreshPropList;
|
||||||
|
public bool NeedRefreshPrice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ using System.Collections.Generic;
|
||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using SepCore.Event;
|
using SepCore.Event;
|
||||||
using SepCore.Definition;
|
using SepCore.Definition;
|
||||||
using SepCore.CustomUtility;
|
|
||||||
using SepCore.Entity.Weapon;
|
using SepCore.Entity.Weapon;
|
||||||
using GameFramework.Event;
|
using GameFramework.Event;
|
||||||
|
using SepCore.DataTable;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityGameFramework.Runtime;
|
using UnityGameFramework.Runtime;
|
||||||
|
|
||||||
|
|
@ -14,6 +14,7 @@ namespace SepCore.UI
|
||||||
{
|
{
|
||||||
private ShopUseCase _useCase;
|
private ShopUseCase _useCase;
|
||||||
private ShopRawData _rawData;
|
private ShopRawData _rawData;
|
||||||
|
private bool _tooltipLocked = false;
|
||||||
|
|
||||||
protected override UIFormType UIFormType => UIFormType.ShopForm;
|
protected override UIFormType UIFormType => UIFormType.ShopForm;
|
||||||
|
|
||||||
|
|
@ -24,18 +25,26 @@ namespace SepCore.UI
|
||||||
|
|
||||||
protected override void SubscribeCustomEvents()
|
protected override void SubscribeCustomEvents()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Subscribe(RefreshEventArgs.EventId, Refresh);
|
GameEntry.Event.Subscribe(ShopRefreshEventArgs.EventId, ShopRefresh);
|
||||||
GameEntry.Event.Subscribe(ShopPurchaseEventArgs.EventId, ShopPurchase);
|
GameEntry.Event.Subscribe(ShopPurchaseEventArgs.EventId, ShopPurchase);
|
||||||
GameEntry.Event.Subscribe(ShopContinueEventArgs.EventId, ShopContinue);
|
GameEntry.Event.Subscribe(ShopContinueEventArgs.EventId, ShopContinue);
|
||||||
GameEntry.Event.Subscribe(ItemTooltipShowEventArgs.EventId, DisplayItemShow);
|
GameEntry.Event.Subscribe(DisplayItemHoverEventArgs.EventId, DisplayItemHover);
|
||||||
|
GameEntry.Event.Subscribe(DisplayItemLockEventArgs.EventId, DisplayItemLock);
|
||||||
|
GameEntry.Event.Subscribe(DisplayItemHideEventArgs.EventId, DisplayItemHide);
|
||||||
|
GameEntry.Event.Subscribe(PlayerCoinChangeEventArgs.EventId, PlayerCoinChange);
|
||||||
|
GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UnsubscribeCustomEvents()
|
protected override void UnsubscribeCustomEvents()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Unsubscribe(RefreshEventArgs.EventId, Refresh);
|
GameEntry.Event.Unsubscribe(ShopRefreshEventArgs.EventId, ShopRefresh);
|
||||||
GameEntry.Event.Unsubscribe(ShopPurchaseEventArgs.EventId, ShopPurchase);
|
GameEntry.Event.Unsubscribe(ShopPurchaseEventArgs.EventId, ShopPurchase);
|
||||||
GameEntry.Event.Unsubscribe(ShopContinueEventArgs.EventId, ShopContinue);
|
GameEntry.Event.Unsubscribe(ShopContinueEventArgs.EventId, ShopContinue);
|
||||||
GameEntry.Event.Unsubscribe(ItemTooltipShowEventArgs.EventId, DisplayItemShow);
|
GameEntry.Event.Unsubscribe(DisplayItemHoverEventArgs.EventId, DisplayItemHover);
|
||||||
|
GameEntry.Event.Unsubscribe(DisplayItemLockEventArgs.EventId, DisplayItemLock);
|
||||||
|
GameEntry.Event.Unsubscribe(DisplayItemHideEventArgs.EventId, DisplayItemHide);
|
||||||
|
GameEntry.Event.Unsubscribe(PlayerCoinChangeEventArgs.EventId, PlayerCoinChange);
|
||||||
|
GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region BuildContext
|
#region BuildContext
|
||||||
|
|
@ -53,7 +62,8 @@ namespace SepCore.UI
|
||||||
List<GoodsItemContext> goodsItems = new List<GoodsItemContext>();
|
List<GoodsItemContext> goodsItems = new List<GoodsItemContext>();
|
||||||
foreach (var item in rawData.GoodsItems)
|
foreach (var item in rawData.GoodsItems)
|
||||||
{
|
{
|
||||||
goodsItems.Add(await GoodsItemContext.CreateAsync(item));
|
var context = await CreateGoodsItemContextAsync(item);
|
||||||
|
goodsItems.Add(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ShopContext
|
return new ShopContext
|
||||||
|
|
@ -65,7 +75,12 @@ namespace SepCore.UI
|
||||||
PropListContext =
|
PropListContext =
|
||||||
BuildDisplayListAreaContext(DisplayListAreaType.Prop, rawData.PropItems, rawData.PropMaxCount),
|
BuildDisplayListAreaContext(DisplayListAreaType.Prop, rawData.PropItems, rawData.PropMaxCount),
|
||||||
WeaponListContext = BuildDisplayListAreaContext(DisplayListAreaType.Weapon, rawData.WeaponItems,
|
WeaponListContext = BuildDisplayListAreaContext(DisplayListAreaType.Weapon, rawData.WeaponItems,
|
||||||
rawData.WeaponMaxCount)
|
rawData.WeaponMaxCount),
|
||||||
|
NeedRefreshGoodsItems = true,
|
||||||
|
NeedRefreshPlayerCoin = true,
|
||||||
|
NeedRefreshPropList = true,
|
||||||
|
NeedRefreshWeaponList = true,
|
||||||
|
NeedRefreshPrice = true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,14 +214,28 @@ namespace SepCore.UI
|
||||||
listContext.CurrentCount = oldCount + 1;
|
listContext.CurrentCount = oldCount + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async UniTask<GoodsItemContext> CreateGoodsItemContextAsync(GoodsItemRawData rawData,
|
||||||
|
float timeout = 30f)
|
||||||
|
{
|
||||||
|
var context = new GoodsItemContext(rawData);
|
||||||
|
context.Icon = context.ItemType switch
|
||||||
|
{
|
||||||
|
ItemType.Weapon => await GameEntry.SpriteCache.GetSprite(((DRWeapon)rawData.DataRow).IconAssetName),
|
||||||
|
ItemType.Prop => await GameEntry.SpriteCache.GetSprite(((DRProp)rawData.DataRow).IconAssetName),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region UI Methods
|
#region UI Methods
|
||||||
|
|
||||||
public override async UniTask CloseUIAsync(object userData = null, float timeout = 30f)
|
public override async UniTask CloseUIAsync(object userData = null, float timeout = 30f)
|
||||||
{
|
{
|
||||||
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create(true));
|
GameEntry.UIRouter.CloseUIAsync(UIFormType.ItemTooltipForm).Forget();
|
||||||
_rawData = null;
|
_rawData = null;
|
||||||
|
_tooltipLocked = false;
|
||||||
await base.CloseUIAsync(userData, timeout);
|
await base.CloseUIAsync(userData, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,8 +300,10 @@ namespace SepCore.UI
|
||||||
for (int i = 0; i < result.GoodsItems.Count; i++)
|
for (int i = 0; i < result.GoodsItems.Count; i++)
|
||||||
{
|
{
|
||||||
if (i < Context.GoodsItems.Count)
|
if (i < Context.GoodsItems.Count)
|
||||||
Context.GoodsItems[i] = await GoodsItemContext.CreateAsync(result.GoodsItems[i]);
|
{
|
||||||
else Context.GoodsItems.Add(await GoodsItemContext.CreateAsync(result.GoodsItems[i]));
|
Context.GoodsItems[i] = await CreateGoodsItemContextAsync(result.GoodsItems[i]);
|
||||||
|
}
|
||||||
|
else Context.GoodsItems.Add(await CreateGoodsItemContextAsync(result.GoodsItems[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Context.GoodsItems.Count != result.GoodsItems.Count)
|
if (Context.GoodsItems.Count != result.GoodsItems.Count)
|
||||||
|
|
@ -282,15 +313,10 @@ namespace SepCore.UI
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.RefreshPrice = result.RefreshPrice;
|
Context.RefreshPrice = result.RefreshPrice;
|
||||||
|
Context.NeedRefreshGoodsItems = true;
|
||||||
|
Context.NeedRefreshPrice = true;
|
||||||
|
|
||||||
if (Form == null)
|
RefreshUI(Form, Context);
|
||||||
{
|
|
||||||
Log.Error("ShopFormController.RefreshGoodsItems() Form is null.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Form.RefreshGoodsItems(Context.GoodsItems);
|
|
||||||
Form.RefreshRefreshPrice(Context.RefreshPrice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyGoodsPurchased(ShopPurchaseResult result)
|
private void ApplyGoodsPurchased(ShopPurchaseResult result)
|
||||||
|
|
@ -319,29 +345,17 @@ namespace SepCore.UI
|
||||||
if (result.DisplayItem.IsWeapon)
|
if (result.DisplayItem.IsWeapon)
|
||||||
{
|
{
|
||||||
AppendDisplayItemContext(Context.WeaponListContext, context);
|
AppendDisplayItemContext(Context.WeaponListContext, context);
|
||||||
|
Context.NeedRefreshWeaponList = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AppendDisplayItemContext(Context.PropListContext, context);
|
AppendDisplayItemContext(Context.PropListContext, context);
|
||||||
|
Context.NeedRefreshPropList = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Form?.ApplyGoodsPurchased(result.GoodsIndex, context);
|
Context.NeedRefreshGoodsItems = true;
|
||||||
}
|
RefreshUI(Form, Context);
|
||||||
|
|
||||||
private bool IsCurrentFormEventSender(object sender)
|
|
||||||
{
|
|
||||||
if (sender is ShopForm shopForm)
|
|
||||||
{
|
|
||||||
return shopForm == Form;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender is Component component && Form != null)
|
|
||||||
{
|
|
||||||
return component.transform.IsChildOf(Form.transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetWeaponInfoRawData(int index, Vector3 targetPos, out ItemTooltipRawData rawData)
|
private bool TryGetWeaponInfoRawData(int index, Vector3 targetPos, out ItemTooltipRawData rawData)
|
||||||
|
|
@ -380,8 +394,8 @@ namespace SepCore.UI
|
||||||
WeaponData = weapon.WeaponData,
|
WeaponData = weapon.WeaponData,
|
||||||
Rarity = weapon.WeaponData.Rarity,
|
Rarity = weapon.WeaponData.Rarity,
|
||||||
ItemType = ItemType.Weapon,
|
ItemType = ItemType.Weapon,
|
||||||
Price = Mathf.FloorToInt(weapon.WeaponData.Price * Context.WeaponRecycleRate),
|
Price = _useCase.CalculateRecyclePrice(weapon.WeaponData.Price),
|
||||||
OnRecycle = (recycleIndex, recyclePrice) => RecycleWeapon(recycleIndex, recyclePrice),
|
OnRecycle = RecycleWeapon,
|
||||||
};
|
};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -441,22 +455,18 @@ namespace SepCore.UI
|
||||||
Context.WeaponListContext.CurrentCount = currentCount;
|
Context.WeaponListContext.CurrentCount = currentCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Form?.RemoveWeaponDisplayItem(index);
|
Context.NeedRefreshWeaponList = true;
|
||||||
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create(true));
|
RefreshUI(Form, Context);
|
||||||
|
GameEntry.UIRouter.CloseUIAsync(UIFormType.ItemTooltipForm).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event Handlers
|
#region Event Handlers
|
||||||
|
|
||||||
private async void Refresh(object sender, GameEventArgs e)
|
private async void ShopRefresh(object sender, GameEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is not ShopForm)
|
if (e is not ShopRefreshEventArgs args)
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e is not RefreshEventArgs args)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -472,16 +482,11 @@ namespace SepCore.UI
|
||||||
|
|
||||||
private void ShopPurchase(object sender, GameEventArgs e)
|
private void ShopPurchase(object sender, GameEventArgs e)
|
||||||
{
|
{
|
||||||
ShopPurchaseAsync(sender, e).Forget();
|
OnPurchaseRequestAsync(sender, e).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async UniTaskVoid ShopPurchaseAsync(object sender, GameEventArgs e)
|
private async UniTaskVoid OnPurchaseRequestAsync(object sender, GameEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is not ShopForm)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e is not ShopPurchaseEventArgs args)
|
if (e is not ShopPurchaseEventArgs args)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -498,11 +503,6 @@ namespace SepCore.UI
|
||||||
|
|
||||||
private void ShopContinue(object sender, GameEventArgs e)
|
private void ShopContinue(object sender, GameEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is not ShopForm)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e is not ShopContinueEventArgs)
|
if (e is not ShopContinueEventArgs)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -511,21 +511,16 @@ namespace SepCore.UI
|
||||||
_useCase?.Continue();
|
_useCase?.Continue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisplayItemShow(object sender, GameEventArgs e)
|
private void DisplayItemHover(object sender, GameEventArgs e)
|
||||||
{
|
{
|
||||||
if (e is not ItemTooltipShowEventArgs args)
|
if (e is not DisplayItemHoverEventArgs args)
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsCurrentFormEventSender(sender))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_rawData == null)
|
if (_rawData == null)
|
||||||
{
|
{
|
||||||
Log.Error("ShopFormController.DisplayItemShow() _rawData is null.");
|
Log.Error("ShopFormController.OnDisplayItemHover() _rawData is null.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -539,9 +534,55 @@ namespace SepCore.UI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_tooltipLocked = false;
|
||||||
GameEntry.UIRouter.OpenUIAsync(UIFormType.ItemTooltipForm, rawData).Forget();
|
GameEntry.UIRouter.OpenUIAsync(UIFormType.ItemTooltipForm, rawData).Forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DisplayItemLock(object sender, GameEventArgs e)
|
||||||
|
{
|
||||||
|
if (e is not DisplayItemLockEventArgs)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tooltipLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisplayItemHide(object sender, GameEventArgs e)
|
||||||
|
{
|
||||||
|
if (e is not DisplayItemHideEventArgs args)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_tooltipLocked)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameEntry.UIRouter.CloseUIAsync(UIFormType.ItemTooltipForm).Forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayerCoinChange(object sender, GameEventArgs e)
|
||||||
|
{
|
||||||
|
if (e is not PlayerCoinChangeEventArgs args) return;
|
||||||
|
if (Context == null) return;
|
||||||
|
|
||||||
|
Context.PlayerCoin = args.CoinCount;
|
||||||
|
Context.NeedRefreshPlayerCoin = true;
|
||||||
|
RefreshUI(Form, Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenUIFormComplete(object sender, GameEventArgs e)
|
||||||
|
{
|
||||||
|
if (e is not OpenUIFormSuccessEventArgs ne) return;
|
||||||
|
|
||||||
|
if (ne.UIForm.Logic is ItemTooltipForm)
|
||||||
|
{
|
||||||
|
_tooltipLocked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using SepCore.Event;
|
using SepCore.Event;
|
||||||
using GameFramework.Event;
|
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityGameFramework.Runtime;
|
using UnityGameFramework.Runtime;
|
||||||
|
|
@ -18,7 +17,6 @@ namespace SepCore.UI
|
||||||
[SerializeField] private TMP_Text _refreshPriceText;
|
[SerializeField] private TMP_Text _refreshPriceText;
|
||||||
|
|
||||||
[SerializeField] private TMP_Text _playerCoinText;
|
[SerializeField] private TMP_Text _playerCoinText;
|
||||||
private int _currentCoin;
|
|
||||||
|
|
||||||
[SerializeField] private ShopGoodsItem[] _goodsItems;
|
[SerializeField] private ShopGoodsItem[] _goodsItems;
|
||||||
|
|
||||||
|
|
@ -35,25 +33,41 @@ namespace SepCore.UI
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
||||||
|
// 首次打开或需要全量刷新时
|
||||||
|
if (context.NeedRefreshGoodsItems)
|
||||||
|
{
|
||||||
_titleText.text = $"商店 (Lv.{context.CurrentLevel})";
|
_titleText.text = $"商店 (Lv.{context.CurrentLevel})";
|
||||||
_continueButtonText.text = $"继续 (Lv.{context.CurrentLevel + 1})";
|
_continueButtonText.text = $"继续 (Lv.{context.CurrentLevel + 1})";
|
||||||
RefreshRefreshPrice(context.RefreshPrice);
|
|
||||||
_playerCoinText.text = $"<sprite name=\"coin\" index=0> {context.PlayerCoin}";
|
|
||||||
|
|
||||||
RefreshGoodsItems(context.GoodsItems);
|
RefreshGoodsItems(context.GoodsItems);
|
||||||
|
context.NeedRefreshGoodsItems = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_propListArea != null && context.PropListContext != null)
|
if (context.NeedRefreshPrice)
|
||||||
|
{
|
||||||
|
RefreshRefreshPrice(context.RefreshPrice);
|
||||||
|
context.NeedRefreshPrice = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.NeedRefreshPlayerCoin)
|
||||||
|
{
|
||||||
|
_playerCoinText.text = $"<sprite name=\"coin\"> {context.PlayerCoin}";
|
||||||
|
context.NeedRefreshPlayerCoin = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.NeedRefreshPropList && _propListArea != null && context.PropListContext != null)
|
||||||
{
|
{
|
||||||
_propListArea.OnInit(context.PropListContext);
|
_propListArea.OnInit(context.PropListContext);
|
||||||
|
context.NeedRefreshPropList = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_weaponListArea != null && context.WeaponListContext != null)
|
if (context.NeedRefreshWeaponList && _weaponListArea != null && context.WeaponListContext != null)
|
||||||
{
|
{
|
||||||
_weaponListArea.OnInit(context.WeaponListContext);
|
_weaponListArea.OnInit(context.WeaponListContext);
|
||||||
|
context.NeedRefreshWeaponList = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RefreshGoodsItems(List<GoodsItemContext> goodsItems)
|
private void RefreshGoodsItems(List<GoodsItemContext> goodsItems)
|
||||||
{
|
{
|
||||||
foreach (var item in _goodsItems)
|
foreach (var item in _goodsItems)
|
||||||
{
|
{
|
||||||
|
|
@ -68,17 +82,19 @@ namespace SepCore.UI
|
||||||
int count = Mathf.Min(_goodsItems.Length, goodsItems.Count);
|
int count = Mathf.Min(_goodsItems.Length, goodsItems.Count);
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
if (goodsItems[i] == null) continue;
|
||||||
|
|
||||||
_goodsItems[i].Init(goodsItems[i]);
|
_goodsItems[i].Init(goodsItems[i]);
|
||||||
_goodsItems[i].gameObject.SetActive(true);
|
_goodsItems[i].gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RefreshRefreshPrice(int refreshPrice)
|
private void RefreshRefreshPrice(int refreshPrice)
|
||||||
{
|
{
|
||||||
_refreshPriceText.text = $"刷新 -{refreshPrice} <sprite name=\"coin\" index=0>";
|
_refreshPriceText.text = $"刷新 -{refreshPrice} <sprite name=\"coin\">";
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ApplyGoodsPurchased(int goodsIndex, DisplayItemContext displayItem)
|
private void ApplyGoodsPurchased(int goodsIndex, DisplayItemContext displayItem)
|
||||||
{
|
{
|
||||||
SetGoodsItemVisible(goodsIndex, false);
|
SetGoodsItemVisible(goodsIndex, false);
|
||||||
|
|
||||||
|
|
@ -140,7 +156,7 @@ namespace SepCore.UI
|
||||||
|
|
||||||
public void OnRefreshButtonClick()
|
public void OnRefreshButtonClick()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Fire(this, RefreshEventArgs.Create(_context.RefreshPrice));
|
GameEntry.Event.Fire(this, ShopRefreshEventArgs.Create(_context.RefreshPrice));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -151,8 +167,6 @@ namespace SepCore.UI
|
||||||
{
|
{
|
||||||
base.OnOpen(userData);
|
base.OnOpen(userData);
|
||||||
|
|
||||||
GameEntry.Event.Subscribe(PlayerCoinChangeEventArgs.EventId, OnPlayerCoinChange);
|
|
||||||
|
|
||||||
if (userData is ShopContext context)
|
if (userData is ShopContext context)
|
||||||
{
|
{
|
||||||
RefreshUI(context);
|
RefreshUI(context);
|
||||||
|
|
@ -166,8 +180,6 @@ namespace SepCore.UI
|
||||||
{
|
{
|
||||||
_context = null;
|
_context = null;
|
||||||
|
|
||||||
GameEntry.Event.Unsubscribe(PlayerCoinChangeEventArgs.EventId, OnPlayerCoinChange);
|
|
||||||
|
|
||||||
_propListArea?.OnReset();
|
_propListArea?.OnReset();
|
||||||
_weaponListArea?.OnReset();
|
_weaponListArea?.OnReset();
|
||||||
|
|
||||||
|
|
@ -175,18 +187,5 @@ namespace SepCore.UI
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event Handlers
|
|
||||||
|
|
||||||
private void OnPlayerCoinChange(object sender, GameEventArgs e)
|
|
||||||
{
|
|
||||||
if (!(e is PlayerCoinChangeEventArgs args)) return;
|
|
||||||
if (args.CoinCount == _currentCoin) return;
|
|
||||||
|
|
||||||
_currentCoin = args.CoinCount;
|
|
||||||
_playerCoinText.text = $"<sprite name=\"coin\" index=0> {_currentCoin}";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,17 +56,17 @@ namespace SepCore.UI
|
||||||
rect.yMax,
|
rect.yMax,
|
||||||
0f)
|
0f)
|
||||||
);
|
);
|
||||||
GameEntry.Event.Fire(this, ItemTooltipShowEventArgs.Create(_index, _context.IsWeapon, targetPos));
|
GameEntry.Event.Fire(this, DisplayItemHoverEventArgs.Create(_index, _context.IsWeapon, targetPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnItemInfoLock()
|
public void OnItemInfoLock()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Fire(this, ItemTooltipLockEventArgs.Create());
|
GameEntry.Event.Fire(this, DisplayItemLockEventArgs.Create());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnItemInfoHide()
|
public void OnItemInfoHide()
|
||||||
{
|
{
|
||||||
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create());
|
GameEntry.Event.Fire(this, DisplayItemHideEventArgs.Create());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,6 +28,8 @@ namespace SepCore.UI
|
||||||
|
|
||||||
public class ShopUseCase : IUIUseCase
|
public class ShopUseCase : IUIUseCase
|
||||||
{
|
{
|
||||||
|
private const float WeaponRecycleRate = 0.3f;
|
||||||
|
|
||||||
private readonly Player _player;
|
private readonly Player _player;
|
||||||
private readonly int _currentLevel;
|
private readonly int _currentLevel;
|
||||||
private readonly Action _onShopFinish;
|
private readonly Action _onShopFinish;
|
||||||
|
|
@ -404,5 +406,10 @@ namespace SepCore.UI
|
||||||
Player.Coin += recyclePrice;
|
Player.Coin += recyclePrice;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int CalculateRecyclePrice(int basePrice)
|
||||||
|
{
|
||||||
|
return Mathf.FloorToInt(basePrice * WeaponRecycleRate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ View
|
||||||
- 在 `Controller` 中堆叠大段领域业务规则
|
- 在 `Controller` 中堆叠大段领域业务规则
|
||||||
- 绕过 `Context` 直接把业务对象塞给 `View`
|
- 绕过 `Context` 直接把业务对象塞给 `View`
|
||||||
- 直接修改其他 UI 的内部 `View`
|
- 直接修改其他 UI 的内部 `View`
|
||||||
|
- **直接调用 View 的公开方法进行局部刷新**;应通过更新 `Context` 并设置刷新粒度控制字段,再调用 `RefreshUI` 让 View 自行决定刷新内容
|
||||||
|
|
||||||
### 3.4 Context 层
|
### 3.4 Context 层
|
||||||
|
|
||||||
|
|
@ -152,12 +153,16 @@ View
|
||||||
- **不允许携带回调委托或行为**,交互行为由 Controller 注册,View 通过 UI 专用事件通知 Controller
|
- **不允许携带回调委托或行为**,交互行为由 Controller 注册,View 通过 UI 专用事件通知 Controller
|
||||||
- 允许组合子 `Context`
|
- 允许组合子 `Context`
|
||||||
- 不进入 `UseCase`
|
- 不进入 `UseCase`
|
||||||
|
- **允许提供构造函数**,但只能由对应的 `Controller` 调用,用于封装从 `RawData` 到展示数据的转换逻辑
|
||||||
|
- **允许提供刷新粒度控制字段**(如 `NeedRefreshXxx` 布尔字段),用于支持局部刷新;View 根据这些字段决定刷新哪些部分,Controller 在更新数据后设置对应字段并调用 `RefreshUI`
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
- `Context` 可以包含展示层需要的最终数据
|
- `Context` 可以包含展示层需要的最终数据
|
||||||
- `Context` 可以是“已格式化”的显示数据
|
- `Context` 可以是“已格式化”的显示数据
|
||||||
- 但这些数据必须由 `Controller` 负责准备,而不是 `UseCase`
|
- 但这些数据必须由 `Controller` 负责准备,而不是 `UseCase`
|
||||||
|
- `Context` 的构造函数可以包含轻量的展示逻辑转换(如格式化文本、选择图标),但不应包含复杂业务规则
|
||||||
|
- 刷新粒度控制字段的典型用法:Controller 更新 Context 数据后,设置 `NeedRefreshXxx = true`,然后调用 `RefreshUI`;View 在 `RefreshUI` 中检查这些字段,只刷新需要更新的部分,最后将字段重置为 `false`
|
||||||
|
|
||||||
### 3.5 View 层
|
### 3.5 View 层
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue