第一批重构,主要是物理迁移脚本和部分命名空间的调整

- 结构上迁移文件,将脚本分成 Base/Runtime/Presentation/Procedure/Editor 五大文件夹
- 调整 DataTable 和 Definition 下脚本的命名空间
- 依据 UI-5层架构设计规范 拆分原先的 UI 到 Runtime 和 Presentation 下
This commit is contained in:
SepComet
2026-06-02 19:12:34 +08:00
parent 56f74eee9a
commit 34c0784190
655 changed files with 1272 additions and 516 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 00bdd73e7a7b66b479fcea9dafb6f312
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
namespace UI
{
public interface IUIFormController
{
int? OpenUI(object userData = null);
void CloseUI();
void BindUseCase(IUIUseCase useCase);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 08145adf06b2b2c4b9d61d3ef6d39cfc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UI
{
public interface IUIUseCase
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8b527e4ad6d6207418137211caa179d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,245 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using StarForce;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
{
public abstract class UGuiForm : UIFormLogic
{
public const int DepthFactor = 100;
private const float FadeTime = 0.3f;
private static Font _mainFont = null;
private static TMP_FontAsset _mainTMPFont = null;
private Canvas _cachedCanvas = null;
private CanvasGroup _canvasGroup = null;
private List<Canvas> _cachedCanvasContainer = new List<Canvas>();
public int OriginalDepth { get; private set; }
public int Depth => _cachedCanvas.sortingOrder;
public void Close(bool ignoreFade = false)
{
StopAllCoroutines();
if (ignoreFade)
{
GameEntry.UI.CloseUIForm(this);
}
else
{
StartCoroutine(CloseCo(FadeTime));
}
}
public void PlayUISound(int uiSoundId)
{
GameEntry.Sound.PlayUISound(uiSoundId);
}
public static void SetMainFont(Font mainFont)
{
if (mainFont == null)
{
Log.Error("Main font is invalid.");
return;
}
_mainFont = mainFont;
}
public static void SetMainTMPFont(TMP_FontAsset mainTMPFont)
{
if (mainTMPFont == null)
{
Log.Error("Main font is invalid.");
return;
}
_mainTMPFont = mainTMPFont;
}
#if UNITY_2017_3_OR_NEWER
protected override void OnInit(object userData)
#else
protected internal override void OnInit(object userData)
#endif
{
base.OnInit(userData);
_cachedCanvas = gameObject.GetOrAddComponent<Canvas>();
_cachedCanvas.overrideSorting = true;
OriginalDepth = _cachedCanvas.sortingOrder;
_canvasGroup = gameObject.GetOrAddComponent<CanvasGroup>();
RectTransform rect = GetComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.anchoredPosition = Vector2.zero;
rect.sizeDelta = Vector2.zero;
gameObject.GetOrAddComponent<GraphicRaycaster>();
if (_mainTMPFont == null)
{
Log.Warning("Main TMP font isn't set.");
}
else
{
var tmp_texts = GetComponentsInChildren<TMP_Text>(true);
foreach (var text in tmp_texts)
{
text.font = _mainTMPFont;
// if (!string.IsNullOrEmpty(text.text))
// {
// text.text = GameEntry.Localization.GetString(text.text);
// }
}
}
if (_mainFont == null)
{
Log.Warning("Main font isn't set.");
}
else
{
var texts = GetComponentsInChildren<Text>(true);
foreach (var text in texts)
{
text.font = _mainFont;
// if (!string.IsNullOrEmpty(text.text))
// {
// text.text = GameEntry.Localization.GetString(text.text);
// }
}
}
}
#if UNITY_2017_3_OR_NEWER
protected override void OnRecycle()
#else
protected internal override void OnRecycle()
#endif
{
base.OnRecycle();
}
#if UNITY_2017_3_OR_NEWER
protected override void OnOpen(object userData)
#else
protected internal override void OnOpen(object userData)
#endif
{
base.OnOpen(userData);
_canvasGroup.alpha = 0f;
StopAllCoroutines();
StartCoroutine(_canvasGroup.FadeToAlpha(1f, FadeTime));
}
#if UNITY_2017_3_OR_NEWER
protected override void OnClose(bool isShutdown, object userData)
#else
protected internal override void OnClose(bool isShutdown, object userData)
#endif
{
base.OnClose(isShutdown, userData);
}
#if UNITY_2017_3_OR_NEWER
protected override void OnPause()
#else
protected internal override void OnPause()
#endif
{
base.OnPause();
}
#if UNITY_2017_3_OR_NEWER
protected override void OnResume()
#else
protected internal override void OnResume()
#endif
{
base.OnResume();
_canvasGroup.alpha = 0f;
StopAllCoroutines();
StartCoroutine(_canvasGroup.FadeToAlpha(1f, FadeTime));
}
#if UNITY_2017_3_OR_NEWER
protected override void OnCover()
#else
protected internal override void OnCover()
#endif
{
base.OnCover();
}
#if UNITY_2017_3_OR_NEWER
protected override void OnReveal()
#else
protected internal override void OnReveal()
#endif
{
base.OnReveal();
}
#if UNITY_2017_3_OR_NEWER
protected override void OnRefocus(object userData)
#else
protected internal override void OnRefocus(object userData)
#endif
{
base.OnRefocus(userData);
}
#if UNITY_2017_3_OR_NEWER
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
#else
protected internal override void OnUpdate(float elapseSeconds, float realElapseSeconds)
#endif
{
base.OnUpdate(elapseSeconds, realElapseSeconds);
}
#if UNITY_2017_3_OR_NEWER
protected override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
#else
protected internal override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
#endif
{
int oldDepth = Depth;
base.OnDepthChanged(uiGroupDepth, depthInUIGroup);
int deltaDepth = UGuiGroupHelper.DepthFactor * uiGroupDepth + DepthFactor * depthInUIGroup - oldDepth +
OriginalDepth;
GetComponentsInChildren(true, _cachedCanvasContainer);
for (int i = 0; i < _cachedCanvasContainer.Count; i++)
{
_cachedCanvasContainer[i].sortingOrder += deltaDepth;
}
_cachedCanvasContainer.Clear();
}
private IEnumerator CloseCo(float duration)
{
yield return _canvasGroup.FadeToAlpha(0f, duration);
GameEntry.UI.CloseUIForm(this);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0b92f84dc56dc764a9c261fe47df5520
timeCreated: 1528026161
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,53 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
{
/// <summary>
/// uGUI 界面组辅助器。
/// </summary>
public class UGuiGroupHelper : UIGroupHelperBase
{
public const int DepthFactor = 10000;
private int m_Depth = 0;
private Canvas m_CachedCanvas = null;
/// <summary>
/// 设置界面组深度。
/// </summary>
/// <param name="depth">界面组深度。</param>
public override void SetDepth(int depth)
{
m_Depth = depth;
m_CachedCanvas.overrideSorting = true;
m_CachedCanvas.sortingOrder = DepthFactor * depth;
}
private void Awake()
{
m_CachedCanvas = gameObject.GetOrAddComponent<Canvas>();
gameObject.GetOrAddComponent<GraphicRaycaster>();
}
private void Start()
{
m_CachedCanvas.overrideSorting = true;
m_CachedCanvas.sortingOrder = DepthFactor * m_Depth;
RectTransform rect = GetComponent<RectTransform>();
rect.anchorMin = Vector2.zero;
rect.anchorMax = Vector2.one;
rect.anchoredPosition = Vector2.zero;
rect.sizeDelta = Vector2.zero;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 05a35a4a1f7dd5646a70cb1a73348780
timeCreated: 1528026161
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UI
{
public class UIContext
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ac4a8b30b5b7684ca58f70386314a4b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,160 @@
using GameFramework.DataTable;
using GameFramework.UI;
using System.Collections;
using SepCore.DataTable;
using SepCore.Definition;
using CustomUtility;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
{
public static class UIExtension
{
public static IEnumerator FadeToAlpha(this CanvasGroup canvasGroup, float alpha, float duration)
{
float time = 0f;
float originalAlpha = canvasGroup.alpha;
while (time < duration)
{
time += Time.deltaTime;
canvasGroup.alpha = Mathf.Lerp(originalAlpha, alpha, time / duration);
yield return new WaitForEndOfFrame();
}
canvasGroup.alpha = alpha;
}
public static IEnumerator SmoothValue(this Slider slider, float value, float duration)
{
float time = 0f;
float originalValue = slider.value;
while (time < duration)
{
time += Time.deltaTime;
slider.value = Mathf.Lerp(originalValue, value, time / duration);
yield return new WaitForEndOfFrame();
}
slider.value = value;
}
public static bool HasUIForm(this UIComponent uiComponent, UIFormType uiFormType, string uiGroupName = null)
{
return uiComponent.HasUIForm((int)uiFormType, uiGroupName);
}
public static bool HasUIForm(this UIComponent uiComponent, int uiFormId, string uiGroupName = null)
{
IDataTable<DRUIForm> dtUIForm = GameEntry.DataTable.GetDataTable<DRUIForm>();
DRUIForm drUIForm = dtUIForm.GetDataRow(uiFormId);
if (drUIForm == null)
{
return false;
}
string assetName = AssetUtility.GetUIFormAsset(drUIForm.AssetName);
if (string.IsNullOrEmpty(uiGroupName))
{
return uiComponent.HasUIForm(assetName);
}
IUIGroup uiGroup = uiComponent.GetUIGroup(uiGroupName);
if (uiGroup == null)
{
return false;
}
return uiGroup.HasUIForm(assetName);
}
public static UGuiForm GetUIForm(this UIComponent uiComponent, UIFormType uiFormType, string uiGroupName = null)
{
return uiComponent.GetUIForm((int)uiFormType, uiGroupName);
}
public static UGuiForm GetUIForm(this UIComponent uiComponent, int uiFormId, string uiGroupName = null)
{
IDataTable<DRUIForm> dtUIForm = GameEntry.DataTable.GetDataTable<DRUIForm>();
DRUIForm drUIForm = dtUIForm.GetDataRow(uiFormId);
if (drUIForm == null)
{
return null;
}
string assetName = AssetUtility.GetUIFormAsset(drUIForm.AssetName);
UIForm uiForm = null;
if (string.IsNullOrEmpty(uiGroupName))
{
uiForm = uiComponent.GetUIForm(assetName);
if (uiForm == null)
{
return null;
}
return (UGuiForm)uiForm.Logic;
}
IUIGroup uiGroup = uiComponent.GetUIGroup(uiGroupName);
if (uiGroup == null)
{
return null;
}
uiForm = (UIForm)uiGroup.GetUIForm(assetName);
if (uiForm == null)
{
return null;
}
return (UGuiForm)uiForm.Logic;
}
public static void CloseUIForm(this UIComponent uiComponent, UGuiForm uiForm)
{
uiComponent.CloseUIForm(uiForm.UIForm);
}
public static int? OpenUIForm(this UIComponent uiComponent, UIFormType uiFormType, object userData = null)
{
return uiComponent.OpenUIForm((int)uiFormType, userData);
}
public static int? OpenUIForm(this UIComponent uiComponent, int uiFormId, object userData = null)
{
IDataTable<DRUIForm> dtUIForm = GameEntry.DataTable.GetDataTable<DRUIForm>();
DRUIForm drUIForm = dtUIForm.GetDataRow(uiFormId);
if (drUIForm == null)
{
Log.Warning("Can not load UI form '{0}' from data table.", uiFormId.ToString());
return null;
}
string assetName = AssetUtility.GetUIFormAsset(drUIForm.AssetName);
if (!drUIForm.AllowMultiInstance)
{
if (uiComponent.IsLoadingUIForm(assetName))
{
return null;
}
if (uiComponent.HasUIForm(assetName))
{
return null;
}
}
return uiComponent.OpenUIForm(assetName, drUIForm.UIGroupName, Constant.AssetPriority.UIFormAsset, drUIForm.PauseCoveredUIForm, userData);
}
private static void OpenNativeDialog(DialogFormRawData rawData)
{
// TODO:这里应该弹出原生对话框,先简化实现为直接按确认按钮
if (rawData != null && rawData.OnClickConfirm != null)
{
rawData.OnClickConfirm(rawData.UserData);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9cfc2c881ce240349901812c61f4476b
timeCreated: 1528026162
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
namespace UI
{
public abstract class UIFormControllerBase<TContext> : IUIFormController where TContext : UIContext
{
protected abstract int? OpenUIInternal(TContext context);
public abstract int? OpenUI(object userData = null);
public abstract void CloseUI();
public abstract void BindUseCase(IUIUseCase useCase);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 692b282b1ecbf5a44839d5bf4a03a937
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,183 @@
using SepCore.Definition;
using GameFramework.Event;
using UnityGameFramework.Runtime;
namespace UI
{
public abstract class UIFormControllerCommonBase<TContext, TForm> : UIFormControllerBase<TContext>
where TContext : UIContext
where TForm : UGuiForm
{
private TContext _context;
private TForm _form;
private int? _formSerialId;
private bool _pendingRefresh;
private bool _isBindEvent;
protected TContext Context => _context;
protected TForm Form => _form;
protected int? FormSerialId => _formSerialId;
protected abstract UIFormType UIFormTypeId { get; }
protected abstract void RefreshUI(TForm form, TContext context);
protected virtual void SubscribeCustomEvents()
{
}
protected virtual void UnsubscribeCustomEvents()
{
}
protected virtual void CloseLoadedFormDirect(TForm form)
{
form.Close();
}
protected void SetContext(TContext context)
{
_context = context;
}
protected void RefreshCurrentUI()
{
if (_context == null)
{
return;
}
if (_form == null)
{
_pendingRefresh = true;
return;
}
RefreshUI(_form, _context);
_pendingRefresh = false;
}
protected override int? OpenUIInternal(TContext context)
{
if (context == null)
{
Log.Warning("{0}.OpenUI() context is null.", GetType().Name);
return null;
}
_context = context;
if (_form != null && _formSerialId.HasValue && GameEntry.UI.HasUIForm(_formSerialId.Value))
{
RefreshUI(_form, _context);
return _formSerialId;
}
CloseUI();
_pendingRefresh = true;
SubscribeEvents();
_formSerialId = GameEntry.UI.OpenUIForm(UIFormTypeId, _context);
return _formSerialId;
}
public override void CloseUI()
{
_pendingRefresh = false;
UnsubscribeEvents();
if (_formSerialId.HasValue)
{
if (GameEntry.UI.HasUIForm(_formSerialId.Value))
{
GameEntry.UI.CloseUIForm(_formSerialId.Value);
}
_form = null;
_formSerialId = null;
return;
}
if (_form != null)
{
CloseLoadedFormDirect(_form);
_form = null;
}
}
private void SubscribeEvents()
{
if (_isBindEvent)
{
return;
}
GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
GameEntry.Event.Subscribe(CloseUIFormCompleteEventArgs.EventId, CloseUIFormComplete);
SubscribeCustomEvents();
_isBindEvent = true;
}
private void UnsubscribeEvents()
{
if (!_isBindEvent)
{
return;
}
GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
GameEntry.Event.Unsubscribe(CloseUIFormCompleteEventArgs.EventId, CloseUIFormComplete);
UnsubscribeCustomEvents();
_isBindEvent = false;
}
private void OpenUIFormSuccess(object sender, GameEventArgs e)
{
if (!(e is OpenUIFormSuccessEventArgs args))
{
return;
}
if (!_formSerialId.HasValue)
{
return;
}
if (args.UIForm == null || args.UIForm.SerialId != _formSerialId.Value || args.UserData != _context)
{
return;
}
_form = args.UIForm.Logic as TForm;
if (_form == null)
{
Log.Warning("{0} open success but form logic is invalid.", GetType().Name);
return;
}
if (_pendingRefresh)
{
RefreshCurrentUI();
}
}
private void CloseUIFormComplete(object sender, GameEventArgs e)
{
if (!(e is CloseUIFormCompleteEventArgs args))
{
return;
}
if (args.SerialId != _formSerialId)
{
return;
}
_form = null;
_formSerialId = null;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 696c0314286f89c4082c2aa2eddaec2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,44 @@
using SepCore.Definition;
using UnityGameFramework.Runtime;
namespace UI
{
public class TUIFormController : UIFormControllerCommonBase<UIContext, TUIForm>
{
private IUIUseCase _useCase;
protected override UIFormType UIFormTypeId => UIFormType.TUIForm;
protected override void RefreshUI(TUIForm form, UIContext context)
{
form.RefreshUI(context);
}
public override int? OpenUI(object userData = null)
{
if (userData is UIContext context)
{
return OpenUIInternal(context);
}
if (userData != null)
{
Log.Warning("TUIFormController.OpenUI() userData type is invalid.");
return null;
}
return OpenUIInternal(Context);
}
public override void BindUseCase(IUIUseCase useCase)
{
if (!(useCase is IUIUseCase uiFormUseCase))
{
Log.Error("LevelUpForm.BindUseCase() useCase is invalid.");
return;
}
_useCase = uiFormUseCase;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e46538e3d51b6b4ca463fa6080ad335
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,27 @@
using UnityEngine;
using UnityGameFramework.Runtime;
namespace UI
{
public class TUIForm : UGuiForm
{
public void RefreshUI(UIContext context)
{
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (!(userData is UIContext context))
{
Log.Error("UIContext is invalid.");
return;
}
RefreshUI(context);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8bc5e59a2be3094798c8c46d1a4999f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5b80dd4adb0a8e148abc7c52a2e23b42
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,88 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace UI
{
public class CommonButton : MonoBehaviour, IPointerEnterHandler, IPointerDownHandler, IPointerExitHandler,
IPointerUpHandler
{
private const float FadeTime = 0.3f;
private const float OnHoverAlpha = 0.7f;
private const float OnClickAlpha = 0.6f;
[SerializeField] private UnityEvent _onPointerEnterAction = new();
[SerializeField] private UnityEvent _onClickAction = new();
[SerializeField] private UnityEvent _onPointerExitAction = new();
[SerializeField] private bool _enableFade = true;
private CanvasGroup _canvasGroup = null;
private void Awake()
{
_canvasGroup = gameObject.GetOrAddComponent<CanvasGroup>();
}
private void OnDisable()
{
_canvasGroup.alpha = 1f;
}
public void OnPointerEnter(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
{
return;
}
StopAllCoroutines();
if (_enableFade)
StartCoroutine(_canvasGroup.FadeToAlpha(OnHoverAlpha, FadeTime));
_onPointerEnterAction.Invoke();
}
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
{
return;
}
_canvasGroup.alpha = OnClickAlpha;
_onClickAction.Invoke();
}
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
{
return;
}
_canvasGroup.alpha = OnHoverAlpha;
}
public void OnPointerExit(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
{
return;
}
StopAllCoroutines();
if (_enableFade)
StartCoroutine(_canvasGroup.FadeToAlpha(1.0f, FadeTime));
_onPointerExitAction.Invoke();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a5079836f95c2a44b96fa331487ebb70
timeCreated: 1528026160
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 72f6a6b2649f7294daf538a63839678e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,109 @@
using GameFramework;
namespace UI
{
/// <summary>
/// 对话框显示数据。
/// </summary>
public class DialogFormRawData
{
/// <summary>
/// 模式,即按钮数量。取值 1、2、3。
/// </summary>
public int Mode
{
get;
set;
}
/// <summary>
/// 标题。
/// </summary>
public string Title
{
get;
set;
}
/// <summary>
/// 消息内容。
/// </summary>
public string Message
{
get;
set;
}
/// <summary>
/// 弹出窗口时是否暂停游戏。
/// </summary>
public bool PauseGame
{
get;
set;
}
/// <summary>
/// 确认按钮文本。
/// </summary>
public string ConfirmText
{
get;
set;
}
/// <summary>
/// 确定按钮回调。
/// </summary>
public GameFrameworkAction<object> OnClickConfirm
{
get;
set;
}
/// <summary>
/// 取消按钮文本。
/// </summary>
public string CancelText
{
get;
set;
}
/// <summary>
/// 取消按钮回调。
/// </summary>
public GameFrameworkAction<object> OnClickCancel
{
get;
set;
}
/// <summary>
/// 中立按钮文本。
/// </summary>
public string OtherText
{
get;
set;
}
/// <summary>
/// 其它按钮回调。
/// </summary>
public GameFrameworkAction<object> OnClickOther
{
get;
set;
}
/// <summary>
/// 用户自定义数据。
/// </summary>
public object UserData
{
get;
set;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ad9ca3c36c52b0a4e8b25c8b451966da
timeCreated: 1528026160
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c41ec32ecc913a3479f29daf48e3da04
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e71c46052b43081479b67b14e2e449d3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using SepCore.Definition;
using UnityEngine;
namespace UI
{
public class DisplayItemInfoFormRawData
{
public int Index;
public string IconAssetName;
public string Title;
public string TypeText;
public ItemRarity Rarity;
public string Description;
public int Price;
public bool IsWeapon;
public Vector3 TargetPos;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 012ded06be40bcf48b3e79ce89df4e2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,75 @@
using SepCore.Definition;
using Entity;
using CustomUtility;
using Entity.Weapon;
using Procedure;
namespace UI
{
public class DisplayItemInfoFormUseCase : IUIUseCase
{
private readonly ProcedureGame _procedureGame;
private Player Player => _procedureGame != null ? _procedureGame.Player : null;
public DisplayItemInfoFormUseCase(ProcedureGame procedureGame)
{
_procedureGame = procedureGame;
}
public DisplayItemInfoFormRawData CreateModel(int index, bool isWeapon)
{
if (index < 0 || Player == null)
{
return null;
}
if (isWeapon)
{
var weapons = Player.Weapons;
if (weapons == null || index >= weapons.Count)
{
return null;
}
WeaponBase weapon = weapons[index];
if (weapon == null || weapon.WeaponData == null)
{
return null;
}
return new DisplayItemInfoFormRawData
{
IconAssetName = weapon.WeaponData.IconAssetName,
Title = weapon.WeaponData.Title,
TypeText = "Weapon",
Description = ItemDescUtility.CreateWeaponDescription(weapon),
Price = 0,
IsWeapon = true
};
}
var props = Player.Props;
if (props == null || index >= props.Count)
{
return null;
}
PropItem prop = props[index];
if (prop == null)
{
return null;
}
return new DisplayItemInfoFormRawData
{
IconAssetName = prop.IconAssetName,
Title = prop.Title,
TypeText = "Prop",
Description = ItemDescUtility.CreatePropDescription(prop),
Price = 0,
IsWeapon = false
};
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 48c1f32fe95e20c43b8015ac1438d54e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a3d54de71bcad264da3c1ca92ff54e4f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 30e2cee5e6a424c42a01db1b7e582a8a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using SepCore.DataTable;
namespace UI
{
public class LevelUpFormRawData
{
public List<DRLevelUpReward> Rewards;
public int RefreshPrice;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a3ece8e2fb75f424cb4885d4344434d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,194 @@
using System.Collections.Generic;
using System.Linq;
using SepCore.DataTable;
using SepCore.Definition;
using Entity;
using Procedure;
using UnityEngine;
using UnityGameFramework.Runtime;
using CustomUtility;
using GameFramework.DataTable;
namespace UI
{
internal class LevelUpFormUseCase : IUIUseCase
{
private const int BaseRefreshPrice = 2;
private readonly GameStateLevelUp _gameStateLevelUp;
private readonly DRLevelUpReward[] _allRewards;
private readonly IDataTable<DRLevelRarity> _levelRarityTable;
private readonly Dictionary<ItemRarity, List<DRLevelUpReward>> _rewardsByRarity = new();
private readonly List<DRLevelUpReward> _validRewards = new();
private int _refreshCount;
private LevelUpFormRawData _currentModel;
private readonly Player _player;
public LevelUpFormUseCase(Player player, GameStateLevelUp gameStateLevelUp)
{
_player = player;
_gameStateLevelUp = gameStateLevelUp;
_allRewards = GameEntry.DataTable.GetDataTable<DRLevelUpReward>().ToArray();
_levelRarityTable = GameEntry.DataTable.GetDataTable<DRLevelRarity>();
BuildRewardRarityPools();
}
public LevelUpFormRawData CreateInitialModel(int count = 4)
{
_refreshCount = 0;
if (_gameStateLevelUp == null || _player.PendingLevelPoints <= 0)
{
_currentModel = null;
return null;
}
_currentModel = BuildModel(BaseRefreshPrice, count);
return _currentModel;
}
public LevelUpFormRawData TryRefresh(int refreshCost, int count = 4)
{
if (_currentModel == null)
{
return null;
}
if (_player == null || _player.Coin < refreshCost)
{
return null;
}
_player.Coin -= refreshCost;
_refreshCount++;
_currentModel = BuildModel((_refreshCount + 1) * BaseRefreshPrice, count);
return _currentModel;
}
public LevelUpFormRawData SelectReward(int selectedIndex, int count = 4)
{
if (_currentModel?.Rewards == null)
{
return null;
}
if (selectedIndex < 0 || selectedIndex >= _currentModel.Rewards.Count)
{
Log.Warning("LevelUpFormUseCase::SelectReward: Invalid index");
return null;
}
ApplyReward(_currentModel.Rewards[selectedIndex]);
if (--_player.PendingLevelPoints > 0)
{
_refreshCount = 0;
_currentModel = BuildModel(BaseRefreshPrice, count);
return _currentModel;
}
_gameStateLevelUp.IsCompleted = true;
_currentModel = null;
return null;
}
private LevelUpFormRawData BuildModel(int refreshPrice, int count)
{
if (_allRewards == null || _allRewards.Length == 0)
{
Log.Error("LevelUpFormUseCase::BuildModel(): _allRewards is empty");
return null;
}
int finalCount = count > 0 ? System.Math.Min(count, _allRewards.Length) : _allRewards.Length;
List<DRLevelUpReward> selections = new List<DRLevelUpReward>(finalCount);
int currentLevel = _player != null ? _player.CurrentLevel : 1;
for (int i = 0; i < finalCount; i++)
{
ItemRarity rarity = RarityUtility.SelectRarityForLevel(_levelRarityTable, currentLevel);
DRLevelUpReward reward = PickRewardByRarity(rarity);
if (reward == null)
{
Log.Warning("LevelUpFormUseCase::BuildModel(): No available reward for selection.");
break;
}
selections.Add(reward);
}
return new LevelUpFormRawData
{
Rewards = selections,
RefreshPrice = refreshPrice
};
}
private void ApplyReward(DRLevelUpReward reward)
{
if (reward == null)
{
return;
}
if (_player == null)
{
Log.Warning("LevelUpFormUseCase::ApplyReward: Player is null");
return;
}
if (reward.Modifiers == null || reward.Modifiers.Length == 0)
{
Log.Warning("LevelUpFormUseCase::ApplyReward: Reward modifiers are empty");
return;
}
_player.AddProp(new PropItem(reward.Modifiers, reward.Rarity, reward.Title, reward.IconAssetName));
}
private void BuildRewardRarityPools()
{
_rewardsByRarity.Clear();
_validRewards.Clear();
if (_allRewards == null) return;
foreach (DRLevelUpReward reward in _allRewards)
{
if (reward == null)
{
continue;
}
ItemRarity rarity = reward.Rarity;
_validRewards.Add(reward);
if (!_rewardsByRarity.TryGetValue(rarity, out List<DRLevelUpReward> list))
{
list = new List<DRLevelUpReward>();
_rewardsByRarity.Add(rarity, list);
}
list.Add(reward);
}
}
private DRLevelUpReward PickRewardByRarity(ItemRarity rarity)
{
if (_rewardsByRarity.TryGetValue(rarity, out List<DRLevelUpReward> list) && list.Count > 0)
{
return list[Random.Range(0, list.Count)];
}
if (_validRewards.Count > 0)
{
return _validRewards[Random.Range(0, _validRewards.Count)];
}
return null;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 19d2fa806b03510498d072c5b8710bcb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c3ed3acef12ff8d40935205a69fb63ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using SepCore.Definition;
using Entity.Weapon;
namespace UI
{
public class ShopFormRawData
{
public int CurrentLevel;
public int RefreshPrice;
public int PlayerCoin;
public List<GoodsItemContext> GoodsItems;
public IReadOnlyList<PropItem> PropItems;
public int PropMaxCount = -1;
public IReadOnlyList<WeaponBase> WeaponItems;
public int WeaponMaxCount = -1;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 533bff5f9d3bc7847af44dcd1cdffba3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,445 @@
using System.Collections.Generic;
using System.Linq;
using SepCore.DataTable;
using SepCore.Definition;
using Entity;
using Entity.EntityData;
using CustomUtility;
using GameFramework.DataTable;
using Procedure;
using UnityEngine;
using UnityGameFramework.Runtime;
using Random = UnityEngine.Random;
namespace UI
{
internal sealed class ShopRefreshResult
{
public List<GoodsItemContext> GoodsItems;
public int RefreshPrice;
}
internal sealed class ShopPurchaseResult
{
public int GoodsIndex;
public DisplayItemContext DisplayItem;
}
internal class ShopFormUseCase : IUIUseCase
{
private readonly ProcedureGame _procedureGame;
private readonly GameStateShop _gameStateShop;
private readonly DRGoods[] _allGoods;
private readonly IDataTable<DRProp> _propDataTable;
private readonly IDataTable<DRWeapon> _weaponDataTable;
private readonly IDataTable<DRLevelRarity> _levelRarityTable;
private readonly List<DRGoods> _validGoods = new();
private readonly Dictionary<ItemRarity, List<DRGoods>> _goodsByRarity = new();
private readonly List<ShopGoodsSelection> _selections = new();
private int _refreshTime;
private Player Player => _procedureGame.Player;
private sealed class ShopGoodsSelection
{
public GoodsType GoodsType;
public int GoodsTypeId;
public int Price;
}
public ShopFormUseCase(ProcedureGame procedureGame, GameStateShop gameStateShop)
{
_procedureGame = procedureGame;
_gameStateShop = gameStateShop;
_allGoods = GameEntry.DataTable.GetDataTable<DRGoods>().ToArray();
_propDataTable = GameEntry.DataTable.GetDataTable<DRProp>();
_weaponDataTable = GameEntry.DataTable.GetDataTable<DRWeapon>();
_levelRarityTable = GameEntry.DataTable.GetDataTable<DRLevelRarity>();
BuildGoodsRarityPools();
}
public ShopFormRawData CreateInitialModel()
{
_refreshTime = 0;
Player player = Player;
if (_procedureGame == null || player == null)
{
return null;
}
int currentLevel = _procedureGame.CurrentLevel;
return new ShopFormRawData
{
CurrentLevel = currentLevel,
RefreshPrice = currentLevel,
PlayerCoin = player.Coin,
GoodsItems = BuildRandomGoodsItems(4),
PropItems = player.Props,
PropMaxCount = -1,
WeaponItems = player.Weapons,
WeaponMaxCount = player.WeaponCapacity
};
}
public ShopRefreshResult TryRefresh(int cost)
{
Player player = Player;
if (player == null || _procedureGame == null || player.Coin < cost)
{
return null;
}
player.Coin -= cost;
int refreshPrice = (_refreshTime + 1) * _procedureGame.CurrentLevel;
_refreshTime++;
return new ShopRefreshResult
{
GoodsItems = BuildRandomGoodsItems(4),
RefreshPrice = refreshPrice
};
}
public ShopPurchaseResult TryPurchase(int goodsIndex)
{
if (goodsIndex < 0 || goodsIndex >= _selections.Count)
{
Log.Warning("ShopFormUseCase::TryPurchase: Invalid index");
return null;
}
ShopGoodsSelection selection = _selections[goodsIndex];
if (selection == null)
{
Log.Warning("ShopFormUseCase::TryPurchase: Item already purchased.");
return null;
}
Player player = Player;
if (player == null || player.Coin < selection.Price)
{
return null;
}
DisplayItemContext displayItem = ApplyGoodsPurchase(selection);
if (displayItem == null)
{
return null;
}
player.Coin -= selection.Price;
_selections[goodsIndex] = null;
return new ShopPurchaseResult
{
GoodsIndex = goodsIndex,
DisplayItem = displayItem
};
}
public void Continue()
{
_gameStateShop.ShopFinish = true;
}
private List<GoodsItemContext> BuildRandomGoodsItems(int count)
{
if (_allGoods == null || _allGoods.Length == 0)
{
Log.Error("ShopFormUseCase::BuildRandomGoodsItems(): _allGoods is empty");
return null;
}
int finalCount = Mathf.Min(count, _allGoods.Length);
List<GoodsItemContext> goodsItems = new List<GoodsItemContext>(finalCount);
_selections.Clear();
int currentLevel = _procedureGame != null ? _procedureGame.CurrentLevel : 1;
for (int i = 0; i < finalCount; i++)
{
ItemRarity rarity = RarityUtility.SelectRarityForLevel(_levelRarityTable, currentLevel);
DRGoods drGoods = PickGoodsByRarity(rarity);
if (drGoods == null)
{
Log.Warning("ShopFormUseCase::BuildRandomGoodsItems: No available goods for selection.");
break;
}
GoodsItemContext goodsItem = new GoodsItemContext();
int price;
if (drGoods.GoodsType == GoodsType.Prop)
{
DRProp drProp = _propDataTable.GetDataRow(drGoods.GoodsTypeId);
if (drProp == null)
{
Log.Warning($"ShopFormUseCase::BuildRandomGoodsItems: Missing DRProp, id = {drGoods.GoodsTypeId}");
continue;
}
price = CalculateRandomizedPrice(drProp.Price, drProp.PriceRandomPercent);
goodsItem.Title = drProp.Title;
goodsItem.Type = "Prop";
goodsItem.Rarity = drProp.Rarity;
GameEntry.SpriteCache.GetSprite(drProp.IconAssetName, sprite => goodsItem.Icon = sprite);
goodsItem.Description = ItemDescUtility.CreatePropDescription(drProp.Modifiers);
}
else if (drGoods.GoodsType == GoodsType.Weapon)
{
DRWeapon drWeapon = _weaponDataTable.GetDataRow(drGoods.GoodsTypeId);
if (drWeapon == null)
{
Log.Warning($"ShopFormUseCase::BuildRandomGoodsItems: Missing DRWeapon, id = {drGoods.GoodsTypeId}");
continue;
}
price = CalculateRandomizedPrice(drWeapon.Price, drWeapon.PriceRandomPercent);
goodsItem.Title = drWeapon.Title;
goodsItem.Type = "Weapon";
goodsItem.Rarity = drWeapon.Rarity;
GameEntry.SpriteCache.GetSprite(drWeapon.IconAssetName, sprite => goodsItem.Icon = sprite);
goodsItem.Description = ItemDescUtility.CreateWeaponDescription(drWeapon);
}
else
{
Log.Warning($"ShopFormUseCase::BuildRandomGoodsItems: Unsupported goods type = {drGoods.GoodsType}");
continue;
}
goodsItem.Price = price;
_selections.Add(new ShopGoodsSelection
{
GoodsType = drGoods.GoodsType,
GoodsTypeId = drGoods.GoodsTypeId,
Price = price
});
goodsItems.Add(goodsItem);
}
return goodsItems;
}
private void BuildGoodsRarityPools()
{
_goodsByRarity.Clear();
_validGoods.Clear();
if (_allGoods == null) return;
foreach (DRGoods goods in _allGoods)
{
if (goods == null) continue;
if (!TryGetGoodsRarity(goods, out ItemRarity rarity))
{
continue;
}
_validGoods.Add(goods);
if (!_goodsByRarity.TryGetValue(rarity, out List<DRGoods> list))
{
list = new List<DRGoods>();
_goodsByRarity.Add(rarity, list);
}
list.Add(goods);
}
}
private DRGoods PickGoodsByRarity(ItemRarity rarity)
{
if (_goodsByRarity.TryGetValue(rarity, out List<DRGoods> list) && list.Count > 0)
{
return list[Random.Range(0, list.Count)];
}
if (_validGoods.Count > 0)
{
return _validGoods[Random.Range(0, _validGoods.Count)];
}
return null;
}
private bool TryGetGoodsRarity(DRGoods goods, out ItemRarity rarity)
{
rarity = ItemRarity.None;
if (goods == null)
{
return false;
}
if (goods.GoodsType == GoodsType.Prop)
{
DRProp drProp = _propDataTable != null ? _propDataTable.GetDataRow(goods.GoodsTypeId) : null;
if (drProp == null)
{
Log.Warning($"ShopFormUseCase::TryGetGoodsRarity: Missing DRProp, id = {goods.GoodsTypeId}");
return false;
}
rarity = drProp.Rarity;
return true;
}
if (goods.GoodsType == GoodsType.Weapon)
{
DRWeapon drWeapon = _weaponDataTable != null ? _weaponDataTable.GetDataRow(goods.GoodsTypeId) : null;
if (drWeapon == null)
{
Log.Warning($"ShopFormUseCase::TryGetGoodsRarity: Missing DRWeapon, id = {goods.GoodsTypeId}");
return false;
}
rarity = drWeapon.Rarity;
return true;
}
Log.Warning($"ShopFormUseCase::TryGetGoodsRarity: Unsupported goods type = {goods.GoodsType}");
return false;
}
private static int CalculateRandomizedPrice(int basePrice, float priceRandomPercent)
{
float normalizedPercent = priceRandomPercent > 1f ? priceRandomPercent / 100f : priceRandomPercent;
normalizedPercent = Mathf.Max(0f, normalizedPercent);
float offsetPercent = Random.Range(-normalizedPercent, normalizedPercent);
int finalPrice = Mathf.RoundToInt(basePrice * (1f + offsetPercent));
return Mathf.Max(1, finalPrice);
}
private DisplayItemContext ApplyGoodsPurchase(ShopGoodsSelection goods)
{
if (goods == null || Player == null)
{
return null;
}
if (goods.GoodsType == GoodsType.Prop)
{
DRProp drProp = _propDataTable != null ? _propDataTable.GetDataRow(goods.GoodsTypeId) : null;
if (drProp == null || drProp.Modifiers == null || drProp.Modifiers.Length == 0)
{
Log.Warning("ShopFormUseCase::ApplyGoodsPurchase: Prop modifiers are empty");
return null;
}
Player.AddProp(new PropItem(drProp.Modifiers, drProp.Rarity, drProp.Title, drProp.IconAssetName));
return new DisplayItemContext
{
IconAssetName = drProp.IconAssetName,
Rarity = drProp.Rarity,
IsWeapon = false
};
}
if (goods.GoodsType == GoodsType.Weapon)
{
if (Player.Weapons != null && Player.Weapons.Count >= Player.WeaponCapacity)
{
Log.Warning("ShopFormUseCase::ApplyGoodsPurchase: Weapon capacity is full.");
return null;
}
DRWeapon drWeapon = _weaponDataTable != null ? _weaponDataTable.GetDataRow(goods.GoodsTypeId) : null;
if (drWeapon == null)
{
Log.Warning($"ShopFormUseCase::ApplyGoodsPurchase: Missing DRWeapon, id = {goods.GoodsTypeId}");
return null;
}
var weaponData = CreateWeaponData(goods.GoodsTypeId);
if (weaponData == null)
{
Log.Warning(
$"ShopFormUseCase::ApplyGoodsPurchase: Unsupported weapon type id = {goods.GoodsTypeId}");
return null;
}
GameEntry.Entity.ShowWeapon(weaponData);
return new DisplayItemContext
{
IconAssetName = drWeapon.IconAssetName,
Rarity = drWeapon.Rarity,
IsWeapon = true
};
}
return null;
}
private WeaponData CreateWeaponData(int weaponTypeId)
{
int entityId = GameEntry.Entity.GenerateSerialId();
int ownerId = Player.Id;
CampType ownerCamp = CampType.Player;
WeaponType weaponType = (WeaponType)weaponTypeId;
switch (weaponType)
{
case WeaponType.WeaponKnife:
return new WeaponKnifeData(entityId, ownerId, ownerCamp);
case WeaponType.WeaponHandgun:
return new WeaponHandgunData(entityId, ownerId, ownerCamp);
case WeaponType.WeaponSlash:
return new WeaponSlashData(entityId, ownerId, ownerCamp);
case WeaponType.WeaponLightning:
return new WeaponLightningData(entityId, ownerId, ownerCamp);
case WeaponType.WeaponLance:
return new WeaponLanceData(entityId, ownerId, ownerCamp);
default:
return null;
}
}
public bool TryRecycleWeapon(int argsIndex, int argsPrice)
{
Player player = Player;
if (player == null)
{
return false;
}
var weapons = player.Weapons;
if (weapons == null || weapons.Count <= 1)
{
Log.Warning("ShopFormUseCase::TryRecycleWeapon: Can not recycle the last weapon.");
return false;
}
if (argsIndex < 0 || argsIndex >= weapons.Count)
{
Log.Warning($"ShopFormUseCase::TryRecycleWeapon: Invalid weapon index = {argsIndex}");
return false;
}
var weapon = weapons[argsIndex];
if (weapon == null)
{
Log.Warning("ShopFormUseCase::TryRecycleWeapon: Weapon is null.");
return false;
}
int recyclePrice = Mathf.Max(0, argsPrice);
if (!player.RemoveWeapon(weapon))
{
Log.Warning("ShopFormUseCase::TryRecycleWeapon: Remove weapon failed.");
return false;
}
player.Coin += recyclePrice;
return true;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e973748d1bd846349d42e219a80f07c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f228612923ff51343a4dab06ce4c1f92
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eb6dcefdb25c4eb4e98cb364ac73a7c9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
namespace UI
{
public class SelectRoleFormRawData
{
public int[] RoleIds;
public string[] RoleIconNames;
public int SelectedRoleId;
public string SelectedRoleName;
public string SelectedRoleInitialPropertyText;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5c23c1db541a47b09b8c475018758f9e
timeCreated: 1771144321
@@ -0,0 +1,99 @@
using System.Text;
using SepCore.DataTable;
using GameFramework.DataTable;
using Procedure;
using UnityEngine;
namespace UI
{
public class SelectRoleFormUseCase : IUIUseCase
{
private readonly IDataTable<DRRole> _roleDataTable;
private readonly ProcedureStartMenu _procedureStartMenu;
public int SelectedRoleId { get; private set; }
public SelectRoleFormUseCase(ProcedureStartMenu procedureStartMenu)
{
_procedureStartMenu = procedureStartMenu;
_roleDataTable = GameEntry.DataTable.GetDataTable<DRRole>();
}
public SelectRoleFormRawData CreateModel()
{
return BuildModel(0);
}
public SelectRoleFormRawData SelectRole(int roleId)
{
SelectedRoleId = roleId;
return BuildModel(roleId);
}
public bool ConfirmSelectedRole()
{
DRRole[] roles = _roleDataTable != null ? _roleDataTable.GetAllDataRows() : null;
if (roles == null || roles.Length == 0)
{
return false;
}
if (SelectedRoleId < 0 || _roleDataTable.GetDataRow(SelectedRoleId) == null)
{
int randomIndex = Random.Range(0, roles.Length);
SelectedRoleId = roles[randomIndex].Id;
}
bool result = SelectedRoleId >= 0;
if (result)
{
_procedureStartMenu.StartGame(SelectedRoleId);
}
return result;
}
private SelectRoleFormRawData BuildModel(int selectedRoleId)
{
DRRole[] roles = _roleDataTable.GetAllDataRows();
int count = _roleDataTable.Count;
int[] roleIds = new int[count];
string[] iconNames = new string[count];
for (int i = 0; i < count; i++)
{
roleIds[i] = roles[i].Id;
iconNames[i] = roles[i].IconName;
}
DRRole selectedRole = selectedRoleId > 0 ? _roleDataTable.GetDataRow(selectedRoleId) : null;
return new SelectRoleFormRawData
{
RoleIds = roleIds,
RoleIconNames = iconNames,
SelectedRoleId = selectedRole?.Id ?? -1,
SelectedRoleName = selectedRole?.RoleName,
SelectedRoleInitialPropertyText = selectedRole != null
? BuildRoleInitialPropertyText(selectedRole)
: null
};
}
private static string BuildRoleInitialPropertyText(DRRole role)
{
if (role == null || role.InitialProperties == null || role.InitialProperties.Length == 0)
{
return string.Empty;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < role.InitialProperties.Length; i++)
{
sb.Append(role.InitialProperties[i]);
sb.Append('\n');
}
return sb.ToString();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aec2db2225cb4bb890eb347e73fc5890
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 35c8961f073eae8479506bdec8b745f8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8e4010de30b33144fa20400058edfeba
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
namespace UI
{
public class StartMenuFormRawData
{
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7f5cdd950661442fa1760bc2b2db6f2d
timeCreated: 1771144299