Compare commits

...

2 Commits

Author SHA1 Message Date
SepComet 41ff2c6df8 迁移 Player/ProcedureGame/ShopUseCase 里的实体方法调用风格
- Player/ShopUseCase:调整了 Weapon 实体的打开方式
- ProcedureGame:调整初始化时的 Hud 和 Player 的初始化写法,流程更清楚
2026-06-06 14:12:05 +08:00
SepComet f896a4a9c8 Update EntityAsyncExtension.cs
为 EntityAsyncExtension 添加了便利的打开各类实体的方法
2026-06-06 13:40:59 +08:00
9 changed files with 356 additions and 128 deletions

View File

@ -448,6 +448,11 @@ namespace SepCore.UI
}
private void ShopPurchase(object sender, GameEventArgs e)
{
ShopPurchaseAsync(sender, e).Forget();
}
private async UniTaskVoid ShopPurchaseAsync(object sender, GameEventArgs e)
{
if (sender is not ShopForm)
{
@ -459,7 +464,7 @@ namespace SepCore.UI
return;
}
ShopPurchaseResult result = _useCase.TryPurchase(args.GoodsIndex);
ShopPurchaseResult result = await _useCase.TryPurchaseAsync(args.GoodsIndex);
if (result == null)
{
return;

View File

@ -10,12 +10,11 @@ namespace SepCore.Procedure
{
public abstract GameStateType GameStateType { get; }
public abstract void OnInit(ProcedureGame master);
public abstract void OnEnter(IFsm<IProcedureManager> procedureOwner);
public abstract void OnEnter();
public abstract void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
float realElapseSeconds);
public abstract void OnUpdate(float elapseSeconds, float realElapseSeconds);
public abstract void OnLeave(IFsm<IProcedureManager> procedureOwner);
public abstract void OnDestroy(IFsm<IProcedureManager> procedureOwner);
public abstract void OnLeave();
public abstract void OnDestroy();
}
}
}

View File

@ -38,7 +38,7 @@ namespace SepCore.Procedure
_procedureGame = master;
}
public override void OnEnter(IFsm<IProcedureManager> procedureOwner)
public override void OnEnter()
{
_currentLevel = _procedureGame.CurrentLevel;
@ -55,8 +55,7 @@ namespace SepCore.Procedure
if (Player != null) Player.Enable = true;
}
public override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
float realElapseSeconds)
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (_levelTimeLeft < 0)
{
@ -77,7 +76,7 @@ namespace SepCore.Procedure
GameEntry.Event.Fire(this, LevelProcessEventArgs.Create((int)_levelTimeLeft));
}
public override void OnLeave(IFsm<IProcedureManager> procedureOwner)
public override void OnLeave()
{
// 隐藏所有敌人实体
_enemyManager.OnReset();
@ -97,7 +96,7 @@ namespace SepCore.Procedure
HideEntityGroup("EnemyProjectile");
}
public override void OnDestroy(IFsm<IProcedureManager> procedureOwner)
public override void OnDestroy()
{
_enemyManager = null;
_procedureGame = null;

View File

@ -12,7 +12,7 @@ namespace SepCore.Procedure
public override GameStateType GameStateType => GameStateType.LevelUp;
private ProcedureGame _procedureGame;
public bool IsCompleted { get; set; }
#region FSM
@ -22,22 +22,21 @@ namespace SepCore.Procedure
Log.Debug("GameStateLevelUp::OnInit");
_procedureGame = master;
var useCase = new LevelUpUseCase(_procedureGame.Player, () => IsCompleted = true);
GameEntry.UIRouter.BindUIUseCase(UIFormType.LevelUpForm, useCase);
}
public override void OnEnter(IFsm<IProcedureManager> procedureOwner)
public override void OnEnter()
{
Log.Debug("GameStateLevelUp::OnEnter");
IsCompleted = false;
GameEntry.UIRouter.OpenUIAsync(UIFormType.LevelUpForm).Forget();
}
public override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
float realElapseSeconds)
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (IsCompleted)
{
@ -45,14 +44,14 @@ namespace SepCore.Procedure
}
}
public override void OnLeave(IFsm<IProcedureManager> procedureOwner)
public override void OnLeave()
{
Log.Debug("GameStateLevelUp::OnLeave");
GameEntry.UIRouter.CloseUIAsync(UIFormType.LevelUpForm).Forget();
}
public override void OnDestroy(IFsm<IProcedureManager> procedureOwner)
public override void OnDestroy()
{
_procedureGame = null;
@ -60,6 +59,5 @@ namespace SepCore.Procedure
}
#endregion
}
}

View File

@ -21,12 +21,13 @@ namespace SepCore.Procedure
{
Log.Debug("GameStateShop::OnInit");
_procedureGame = master;
var shopFormUseCase = new ShopUseCase(_procedureGame.Player, _procedureGame.CurrentLevel, () => ShopFinish = true);
var shopFormUseCase =
new ShopUseCase(_procedureGame.Player, _procedureGame.CurrentLevel, () => ShopFinish = true);
GameEntry.UIRouter.BindUIUseCase(UIFormType.ShopForm, shopFormUseCase);
}
public override void OnEnter(IFsm<IProcedureManager> procedureOwner)
public override void OnEnter()
{
Log.Debug("GameStateShop::OnEnter");
@ -35,8 +36,7 @@ namespace SepCore.Procedure
GameEntry.UIRouter.OpenUIAsync(UIFormType.ShopForm).Forget();
}
public override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
float realElapseSeconds)
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (ShopFinish)
{
@ -44,14 +44,14 @@ namespace SepCore.Procedure
}
}
public override void OnLeave(IFsm<IProcedureManager> procedureOwner)
public override void OnLeave()
{
Log.Debug("GameStateShop::OnLeave");
GameEntry.UIRouter.CloseUIAsync(UIFormType.ShopForm).Forget();
}
public override void OnDestroy(IFsm<IProcedureManager> procedureOwner)
public override void OnDestroy()
{
_procedureGame = null;
@ -60,4 +60,4 @@ namespace SepCore.Procedure
#endregion
}
}
}

View File

@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using SepCore.DataTable;
using SepCore.Definition;
using SepCore.Entity;
using GameFramework.Event;
using GameFramework.Fsm;
using GameFramework.Procedure;
using UnityGameFramework.Runtime;
using SepCore.UI;
using SepCore.AsyncTask;
namespace SepCore.Procedure
{
@ -23,10 +23,6 @@ namespace SepCore.Procedure
{
public override bool UseNativeDialog => false;
private HudForm _hudForm;
private bool _hudInitialized;
private IFsm<IProcedureManager> _procedureOwner;
private PlayerData _currentPlayerData;
public int CurrentLevel = 1;
@ -50,7 +46,7 @@ namespace SepCore.Procedure
_gameStates[GameStateType.Shop].OnInit(this);
_currentGameState = GameStateType.Battle;
_gameStates[_currentGameState].OnEnter(_procedureOwner);
_gameStates[_currentGameState].OnEnter();
}
public void BattleToShopOrLevelUp()
@ -58,27 +54,27 @@ namespace SepCore.Procedure
CurrentLevel++;
if (_currentGameState == GameStateType.Shop || _currentGameState == GameStateType.LevelUp) return;
_gameStates[_currentGameState].OnLeave(_procedureOwner);
_gameStates[_currentGameState].OnLeave();
_currentGameState = Player.PendingLevelPoints > 0 ? GameStateType.LevelUp : GameStateType.Shop;
_gameStates[_currentGameState].OnEnter(_procedureOwner);
_gameStates[_currentGameState].OnEnter();
}
public void ShopToBattle()
{
if (_currentGameState == GameStateType.Battle) return;
_gameStates[_currentGameState].OnLeave(_procedureOwner);
_gameStates[_currentGameState].OnLeave();
_currentGameState = GameStateType.Battle;
_gameStates[_currentGameState].OnEnter(_procedureOwner);
_gameStates[_currentGameState].OnEnter();
}
public void LevelUpToShop()
{
if (_currentGameState == GameStateType.Shop) return;
_gameStates[_currentGameState].OnLeave(_procedureOwner);
_gameStates[_currentGameState].OnLeave();
_currentGameState = GameStateType.Shop;
_gameStates[_currentGameState].OnEnter(_procedureOwner);
_gameStates[_currentGameState].OnEnter();
}
#region FSM
@ -87,87 +83,65 @@ namespace SepCore.Procedure
{
base.OnEnter(procedureOwner);
_procedureOwner = procedureOwner;
GameEntry.SimulationWorld?.ClearSimulationState();
GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess);
CurrentLevel = 1;
_currentPlayerData = new PlayerData(-1, 1001);
GameEntry.Entity.ShowPlayer(_currentPlayerData);
GameEntry.UIRouter.OpenUIAsync(UIFormType.HudForm).Forget();
EnterAsync(procedureOwner).Forget();
}
protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds,
float realElapseSeconds)
{
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
_procedureOwner = procedureOwner;
if (!_hudInitialized && _hudForm != null && Player != null)
{
int selectedRoleId = _procedureOwner.GetData<VarInt32>("SelectedRoleId").Value;
var role = GameEntry.DataTable.GetDataTableRow<DRRole>(selectedRoleId);
Player.InitRole(role);
_hudInitialized = true;
InitGameState();
}
if (_hudInitialized)
_gameStates[_currentGameState].OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
_gameStates?[_currentGameState].OnUpdate(elapseSeconds, realElapseSeconds);
}
protected override void OnLeave(IFsm<IProcedureManager> procedureOwner, bool isShutdown)
{
foreach (var state in _gameStates.Values)
if (_gameStates != null)
{
state.OnDestroy(procedureOwner);
}
foreach (var state in _gameStates.Values)
{
state.OnDestroy();
}
_gameStates.Clear();
_gameStates.Clear();
}
GameEntry.UIRouter.CloseUIAsync(UIFormType.HudForm).Forget();
_hudForm = null;
Player = null;
_procedureOwner = null;
GameEntry.SimulationWorld?.ClearSimulationState();
GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess);
GameEntry.Event.Unsubscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess);
base.OnLeave(procedureOwner, isShutdown);
}
#endregion
#region Event Handler
private void OpenUIFormSuccess(object sender, GameEventArgs e)
private async UniTaskVoid EnterAsync(IFsm<IProcedureManager> procedureOwner)
{
if (!(e is OpenUIFormSuccessEventArgs args)) return;
if (args.UIForm.Logic is HudForm hudForm)
try
{
_hudForm = hudForm;
Player = await GameEntry.Entity.ShowPlayerAsync(_currentPlayerData);
await GameEntry.UIRouter.OpenUIAsync(UIFormType.HudForm);
int selectedRoleId = procedureOwner.GetData<VarInt32>("SelectedRoleId").Value;
var role = GameEntry.DataTable.GetDataTableRow<DRRole>(selectedRoleId);
if (role == null)
{
Log.Error("ProcedureGame.EnterAsync() can not load role '{0}'.", selectedRoleId.ToString());
return;
}
Player.InitRole(role);
InitGameState();
}
catch (Exception exception)
{
Log.Error("ProcedureGame.EnterAsync() failed with exception '{0}'.", exception);
}
}
private void ShowEntitySuccess(object sender, GameEventArgs e)
{
if (!(e is ShowEntitySuccessEventArgs args)) return;
if (args.Entity.Logic is Player player)
{
Player = player;
}
}
#endregion
}
}

View File

@ -1,5 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using SepCore.CustomUtility;
using SepCore.DataTable;
using SepCore.Definition;
using SepCore.Entity;
using SepCore.Entity.Weapon;
using UnityGameFramework.Runtime;
using HideEntityCompleteEventArgs = UnityGameFramework.Runtime.HideEntityCompleteEventArgs;
using ShowEntityFailureEventArgs = UnityGameFramework.Runtime.ShowEntityFailureEventArgs;
@ -12,6 +19,11 @@ namespace SepCore.AsyncTask
/// </summary>
public static class EntityAsyncExtension
{
private const string EntityNamespace = "SepCore.Entity.";
private static readonly Dictionary<string, Type> _typeDict = new();
private static readonly Dictionary<int, string> _assetNameDict = new();
/// <summary>
/// 异步显示实体
/// </summary>
@ -22,6 +34,7 @@ namespace SepCore.AsyncTask
/// <param name="entityGroupName">实体组名称</param>
/// <param name="userData">用户自定义数据</param>
/// <param name="timeout">超时时间0表示不超时</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>显示的实体</returns>
public static UniTask<UnityGameFramework.Runtime.Entity> ShowEntityAsync(this EntityComponent entityComponent,
int entityId,
@ -29,17 +42,46 @@ namespace SepCore.AsyncTask
string entityAssetName,
string entityGroupName,
object userData = null,
float timeout = 30f)
float timeout = 30f,
CancellationToken cancellationToken = default)
{
return ShowEntityAsync(entityComponent, entityId, entityLogicType, entityAssetName, entityGroupName, 0,
userData, timeout, cancellationToken);
}
/// <summary>
/// 异步显示实体
/// </summary>
/// <param name="entityComponent">实体组件</param>
/// <param name="entityId">实体编号</param>
/// <param name="entityLogicType">实体逻辑类型</param>
/// <param name="entityAssetName">实体资源名称</param>
/// <param name="entityGroupName">实体组名称</param>
/// <param name="priority">加载优先级</param>
/// <param name="userData">用户自定义数据</param>
/// <param name="timeout">超时时间0表示不超时</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>显示的实体</returns>
public static UniTask<UnityGameFramework.Runtime.Entity> ShowEntityAsync(this EntityComponent entityComponent,
int entityId,
Type entityLogicType,
string entityAssetName,
string entityGroupName,
int priority,
object userData = null,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
UniTask<UnityGameFramework.Runtime.Entity> waitTask = AsyncTaskHelper.WaitSuccessOrFailureAsync<ShowEntitySuccessEventArgs, ShowEntityFailureEventArgs>(
ShowEntitySuccessEventArgs.EventId,
ShowEntityFailureEventArgs.EventId,
successArgs => successArgs.Entity.Id == entityId && ReferenceEquals(successArgs.UserData, userData),
failureArgs => failureArgs.EntityId == entityId && ReferenceEquals(failureArgs.UserData, userData),
timeout
timeout,
cancellationToken
).ContinueWith(successArgs => successArgs.Entity);
entityComponent.ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, userData);
entityComponent.ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, priority, userData);
return waitTask;
}
@ -53,26 +95,157 @@ namespace SepCore.AsyncTask
/// <param name="entityGroupName">实体组名称</param>
/// <param name="userData">用户自定义数据</param>
/// <param name="timeout">超时时间0表示不超时</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>显示的实体</returns>
public static UniTask<T> ShowEntityAsync<T>(this EntityComponent entityComponent,
int entityId,
string entityAssetName,
string entityGroupName,
object userData = null,
float timeout = 30f) where T : EntityLogic
float timeout = 30f,
CancellationToken cancellationToken = default) where T : EntityLogic
{
return ShowEntityAsync<T>(entityComponent, entityId, entityAssetName, entityGroupName, 0, userData, timeout,
cancellationToken);
}
/// <summary>
/// 异步显示实体(泛型版本)
/// </summary>
/// <typeparam name="T">实体逻辑类型</typeparam>
/// <param name="entityComponent">实体组件</param>
/// <param name="entityId">实体编号</param>
/// <param name="entityAssetName">实体资源名称</param>
/// <param name="entityGroupName">实体组名称</param>
/// <param name="priority">加载优先级</param>
/// <param name="userData">用户自定义数据</param>
/// <param name="timeout">超时时间0表示不超时</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>显示的实体</returns>
public static UniTask<T> ShowEntityAsync<T>(this EntityComponent entityComponent,
int entityId,
string entityAssetName,
string entityGroupName,
int priority,
object userData = null,
float timeout = 30f,
CancellationToken cancellationToken = default) where T : EntityLogic
{
UniTask<T> waitTask = AsyncTaskHelper.WaitSuccessOrFailureAsync<ShowEntitySuccessEventArgs, ShowEntityFailureEventArgs>(
ShowEntitySuccessEventArgs.EventId,
ShowEntityFailureEventArgs.EventId,
successArgs => successArgs.Entity.Id == entityId && ReferenceEquals(successArgs.UserData, userData),
failureArgs => failureArgs.EntityId == entityId && ReferenceEquals(failureArgs.UserData, userData),
timeout
timeout,
cancellationToken
).ContinueWith(successArgs => (T)successArgs.Entity.Logic);
entityComponent.ShowEntity<T>(entityId, entityAssetName, entityGroupName, userData);
entityComponent.ShowEntity<T>(entityId, entityAssetName, entityGroupName, priority, userData);
return waitTask;
}
/// <summary>
/// 异步显示玩家实体。
/// </summary>
public static UniTask<Player> ShowPlayerAsync(this EntityComponent entityComponent,
PlayerData data,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
return ShowEntityByDataAsync<Player>(entityComponent, typeof(Player), "Player",
Constant.AssetPriority.PlayerAsset, data, timeout, cancellationToken);
}
/// <summary>
/// 异步显示敌人实体。
/// </summary>
public static UniTask<EnemyBase> ShowEnemyAsync(this EntityComponent entityComponent,
EnemyData data,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
if (data == null)
{
Log.Warning("Enemy data is invalid.");
return UniTask.FromResult<EnemyBase>(null);
}
Type enemyType = TryGetType(data.EnemyType.ToString());
string assetName = TryGetAssetName(data.EntityTypeId);
if (enemyType == null || string.IsNullOrEmpty(assetName))
{
return UniTask.FromResult<EnemyBase>(null);
}
return entityComponent
.ShowEntityAsync(data.Id, enemyType, AssetUtility.GetEntityAsset(assetName), "Enemy",
Constant.AssetPriority.BulletAsset, data, timeout, cancellationToken)
.ContinueWith(entity => entity?.Logic as EnemyBase);
}
/// <summary>
/// 异步显示武器实体。
/// </summary>
public static UniTask<WeaponBase> ShowWeaponAsync(this EntityComponent entityComponent,
WeaponData data,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
if (data == null)
{
Log.Warning("Weapon data is invalid.");
return UniTask.FromResult<WeaponBase>(null);
}
Type weaponType = TryGetType("Weapon." + data.WeaponType);
string assetName = TryGetAssetName(data.EntityTypeId);
if (weaponType == null || string.IsNullOrEmpty(assetName))
{
return UniTask.FromResult<WeaponBase>(null);
}
return entityComponent
.ShowEntityAsync(data.Id, weaponType, AssetUtility.GetEntityAsset(assetName), "Weapon",
Constant.AssetPriority.BulletAsset, data, timeout, cancellationToken)
.ContinueWith(entity => entity?.Logic as WeaponBase);
}
/// <summary>
/// 异步显示特效实体。
/// </summary>
public static UniTask<Effect> ShowEffectAsync(this EntityComponent entityComponent,
EffectData data,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
return ShowEntityByDataAsync<Effect>(entityComponent, typeof(Effect), "Effect",
Constant.AssetPriority.EffectAsset, data, timeout, cancellationToken);
}
/// <summary>
/// 异步显示金币掉落实体。
/// </summary>
public static UniTask<CoinEntity> ShowCoinAsync(this EntityComponent entityComponent,
CoinData data,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
return ShowEntityByDataAsync<CoinEntity>(entityComponent, typeof(CoinEntity), "Drop",
Constant.AssetPriority.EffectAsset, data, timeout, cancellationToken);
}
/// <summary>
/// 异步显示经验掉落实体。
/// </summary>
public static UniTask<ExpEntity> ShowExpAsync(this EntityComponent entityComponent,
ExpData data,
float timeout = 30f,
CancellationToken cancellationToken = default)
{
return ShowEntityByDataAsync<ExpEntity>(entityComponent, typeof(ExpEntity), "Drop",
Constant.AssetPriority.EffectAsset, data, timeout, cancellationToken);
}
/// <summary>
/// 异步隐藏实体
/// </summary>
@ -80,16 +253,19 @@ namespace SepCore.AsyncTask
/// <param name="entityId">实体编号</param>
/// <param name="userData">用户自定义数据</param>
/// <param name="timeout">超时时间0表示不超时</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>隐藏完成事件</returns>
public static UniTask<HideEntityCompleteEventArgs> HideEntityAsync(this EntityComponent entityComponent,
int entityId,
object userData = null,
float timeout = 30f)
float timeout = 30f,
CancellationToken cancellationToken = default)
{
UniTask<HideEntityCompleteEventArgs> waitTask = AsyncTaskHelper.WaitEventAsync<HideEntityCompleteEventArgs>(
HideEntityCompleteEventArgs.EventId,
args => args.EntityId == entityId,
timeout
timeout,
cancellationToken
);
entityComponent.HideEntity(entityId, userData);
@ -103,13 +279,76 @@ namespace SepCore.AsyncTask
/// <param name="entity">要隐藏的实体</param>
/// <param name="userData">用户自定义数据</param>
/// <param name="timeout">超时时间0表示不超时</param>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>隐藏完成事件</returns>
public static UniTask<HideEntityCompleteEventArgs> HideEntityAsync(this EntityComponent entityComponent,
UnityGameFramework.Runtime.Entity entity,
object userData = null,
float timeout = 30f)
float timeout = 30f,
CancellationToken cancellationToken = default)
{
return HideEntityAsync(entityComponent, entity.Id, userData, timeout);
return HideEntityAsync(entityComponent, entity.Id, userData, timeout, cancellationToken);
}
private static UniTask<T> ShowEntityByDataAsync<T>(EntityComponent entityComponent,
Type logicType,
string entityGroupName,
int priority,
EntityDataBase data,
float timeout,
CancellationToken cancellationToken) where T : EntityLogic
{
if (data == null)
{
Log.Warning("Data is invalid.");
return UniTask.FromResult<T>(null);
}
DREntity drEntity = GameEntry.DataTable.GetDataTableRow<DREntity>(data.TypeId);
if (drEntity == null)
{
Log.Warning("Can not load entity id '{0}' from data table.", data.TypeId.ToString());
return UniTask.FromResult<T>(null);
}
return entityComponent.ShowEntityAsync<T>(data.Id, AssetUtility.GetEntityAsset(drEntity.AssetName),
entityGroupName, priority, data, timeout, cancellationToken);
}
private static Type TryGetType(string rawTypeName)
{
string typeName = EntityNamespace + rawTypeName;
if (!_typeDict.TryGetValue(typeName, out Type type))
{
type = Type.GetType(typeName);
if (type == null)
{
Log.Warning("Can not load entity type '{0}'.", typeName);
return null;
}
_typeDict.Add(typeName, type);
}
return type;
}
private static string TryGetAssetName(int entityId)
{
if (!_assetNameDict.TryGetValue(entityId, out string assetName))
{
DREntity drEntity = GameEntry.DataTable.GetDataTableRow<DREntity>(entityId);
if (drEntity == null)
{
Log.Warning("Can not load entity id '{0}' from data table.", entityId.ToString());
return null;
}
assetName = drEntity.AssetName;
_assetNameDict.Add(entityId, assetName);
}
return assetName;
}
}
}

View File

@ -1,13 +1,13 @@
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using SepCore.Components;
using SepCore.Event;
using SepCore.DataTable;
using SepCore.Definition;
using SepCore.Entity;
using GameFramework.Event;
using UnityGameFramework.Runtime;
using SepCore.Entity.Weapon;
using SepCore.CustomUtility;
using SepCore.AsyncTask;
namespace SepCore.Entity
{
@ -92,6 +92,28 @@ namespace SepCore.Entity
return _backpackComponent.AttachProp(prop);
}
public async UniTask<WeaponBase> AddWeaponAsync(WeaponData weaponData, float timeout = 30f)
{
if (weaponData == null || _backpackComponent == null)
{
return null;
}
WeaponBase weapon = await GameEntry.Entity.ShowWeaponAsync(weaponData, timeout);
if (weapon == null)
{
return null;
}
if (!_backpackComponent.AttachWeapon(weapon))
{
GameEntry.Entity.HideEntity(weapon);
return null;
}
return weapon;
}
public bool RemoveWeapon(WeaponBase weapon)
{
if (weapon == null || _backpackComponent == null)
@ -141,8 +163,8 @@ namespace SepCore.Entity
// BackpackComponent
Coin = role.Coin;
_backpackComponent.OnInit(this, role.WeaponCapacity);
GameEntry.Entity.ShowWeapon(EntityDataFactory.Create(GameEntry.Entity.NextId(),
WeaponType.WeaponKnife, Id, _playerData.Camp));
AddWeaponAsync(EntityDataFactory.Create(GameEntry.Entity.NextId(),
WeaponType.WeaponKnife, Id, _playerData.Camp)).Forget();
// StatComponent
foreach (var modifier in role.InitialProperties)
@ -158,8 +180,7 @@ namespace SepCore.Entity
GameEntry.Event.Fire(this, PlayerExpChangeEventArgs.Create(0, 100));
GameEntry.Event.Fire(this,
PlayerCoinChangeEventArgs.Create(Coin, Coin));
GameEntry.Event.Fire(this, PlayerCoinChangeEventArgs.Create(Coin, Coin));
}
#region FSM
@ -190,8 +211,6 @@ namespace SepCore.Entity
{
base.OnShow(userData);
GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess);
_statComponent.OnInit();
if (userData is PlayerData playerData)
@ -230,18 +249,5 @@ namespace SepCore.Entity
}
#endregion
#region Event Handlers
private void ShowEntitySuccess(object sender, GameEventArgs e)
{
if (!(e is ShowEntitySuccessEventArgs args)) return;
if (args.Entity.Logic is WeaponBase weapon)
{
_backpackComponent.AttachWeapon(weapon);
}
}
#endregion
}
}

View File

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cysharp.Threading.Tasks;
using SepCore.DataTable;
using SepCore.Definition;
using SepCore.Entity;
using SepCore.CustomUtility;
using SepCore.Entity.Weapon;
using GameFramework.DataTable;
using UnityEngine;
using UnityGameFramework.Runtime;
@ -107,7 +109,7 @@ namespace SepCore.UI
};
}
public ShopPurchaseResult TryPurchase(int goodsIndex)
public async UniTask<ShopPurchaseResult> TryPurchaseAsync(int goodsIndex)
{
if (goodsIndex < 0 || goodsIndex >= _selections.Count)
{
@ -128,7 +130,7 @@ namespace SepCore.UI
return null;
}
DisplayItemRawData displayItem = ApplyGoodsPurchase(selection);
DisplayItemRawData displayItem = await ApplyGoodsPurchaseAsync(selection);
if (displayItem == null)
{
return null;
@ -318,7 +320,7 @@ namespace SepCore.UI
return Mathf.Max(1, finalPrice);
}
private DisplayItemRawData ApplyGoodsPurchase(ShopGoodsSelection goods)
private async UniTask<DisplayItemRawData> ApplyGoodsPurchaseAsync(ShopGoodsSelection goods)
{
if (goods == null || Player == null)
{
@ -362,7 +364,13 @@ namespace SepCore.UI
return null;
}
GameEntry.Entity.ShowWeapon(weaponData);
WeaponBase weapon = await Player.AddWeaponAsync(weaponData);
if (weapon == null)
{
Log.Warning(
$"ShopFormUseCase::ApplyGoodsPurchase: Show weapon failed, weapon type id = {goods.GoodsTypeId}");
return null;
}
return new DisplayItemRawData
{