Merge branch 'develop' into feature/gfx-action
This commit is contained in:
@@ -2655,6 +2655,11 @@ MonoBehaviour:
|
||||
m_ReadOnly: 0
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
- m_GUID: 34322d27488583140acae7497762ccbc
|
||||
m_Address: minimaps/161
|
||||
m_ReadOnly: 0
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
- m_GUID: 343d97392dfbe4113b96ae477e3867eb
|
||||
m_Address: litmodels/a61/7/litmodel_1007.bmd
|
||||
m_ReadOnly: 0
|
||||
|
||||
Executable → Regular
Executable → Regular
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f809da92f7a74929fe4911b38ecddcf5bfe0fa9f667ad04f6c927511246975ae
|
||||
size 308267
|
||||
oid sha256:fdca6f6915cfc055b350581a53fbc4d2e19ab522da9eb954295d71d45d8aed58
|
||||
size 303299
|
||||
|
||||
@@ -7,6 +7,7 @@ using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.U2D;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
@@ -18,6 +19,7 @@ namespace BrewMonster.Scripts
|
||||
private Dictionary<string, AsyncOperationHandle<GameObject>> _loadedPrefabAssets = new();
|
||||
private Dictionary<string, AsyncOperationHandle<TextAsset>> _loadedTextAssets = new();
|
||||
private Dictionary<string, AsyncOperationHandle<AudioClip>> _loadedAudioAssets = new();
|
||||
private Dictionary<string, AsyncOperationHandle<SpriteAtlas>> _loadedSpriteAtlasAssets = new();
|
||||
|
||||
private Dictionary<string, int> _loadedAssetReferenceCount = new();
|
||||
|
||||
@@ -174,6 +176,56 @@ namespace BrewMonster.Scripts
|
||||
}
|
||||
|
||||
|
||||
AsyncOperationHandle<SpriteAtlas> _loadedSpriteAtlasHandle;
|
||||
/// <summary>Load a sprite atlas asynchronously.</summary>
|
||||
public async Task<SpriteAtlas> LoadSpriteAtlasAsync(string assetPath)
|
||||
{
|
||||
// increase the reference count of the asset.
|
||||
if (!_loadedAssetReferenceCount.ContainsKey(assetPath))
|
||||
{
|
||||
_loadedAssetReferenceCount[assetPath] = 0;
|
||||
}
|
||||
_loadedAssetReferenceCount[assetPath]++;
|
||||
|
||||
// remove the asset from the release timestamp dictionary. So it won't be released.
|
||||
RemoveFromReleaseAssetDictionary(assetPath);
|
||||
|
||||
if (_loadedSpriteAtlasAssets.TryGetValue(assetPath, out _loadedSpriteAtlasHandle))
|
||||
{
|
||||
if (_loadedTextAssetHandle.IsValid() && _loadedTextAssetHandle.Result != null)
|
||||
{
|
||||
BMLogger.Log($"AddressableManager: Loaded text asset from cache: {assetPath}");
|
||||
return _loadedSpriteAtlasHandle.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
BMLogger.Log($"AddressableManager: Text asset handle is invalid or result is null, need to load new one: {assetPath}");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var handle = Addressables.LoadAssetAsync<SpriteAtlas>(assetPath);
|
||||
await handle.Task;
|
||||
if (handle.OperationException != null)
|
||||
{
|
||||
BMLogger.Log($"AddressableManager: Failed to load Sprite Atlas '{assetPath}': {handle.OperationException.Message} {handle.OperationException.StackTrace}");
|
||||
#if UNITY_EDITOR
|
||||
_invalidAssetPaths.Add(assetPath);
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
_loadedSpriteAtlasAssets[assetPath] = handle;
|
||||
return handle.Result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BMLogger.LogError($"AddressableManager: Failed to load SpriteAtlas '{assetPath}': {e}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AsyncOperationHandle<GameObject> _loadedPrefabHandle;
|
||||
/// <summary>
|
||||
/// Load an asset asynchronously. The address should look like this: "models/npcs/npc/魅灵首领/魅灵首领/魅灵首领.prefab"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using BrewMonster.UI;
|
||||
using CSNetwork;
|
||||
|
||||
|
||||
//TODO: [DUCK] EC_Game shouldn't be in BrewMonster.Network namespace, it should be in BrewMonster.Scripts namespace.
|
||||
namespace BrewMonster.Network
|
||||
{
|
||||
public partial class EC_Game
|
||||
@@ -78,7 +78,7 @@ namespace BrewMonster.Network
|
||||
// return m_dwRealTickTime;
|
||||
// return Time.realtimeSinceStartup;
|
||||
// 0.018f is value to make mining process run fit with player animation. if have any issue => discussing with Mr. Drimdar
|
||||
return (Time.unscaledDeltaTime - 0.018f) * 1000f;//-0.001f
|
||||
return Mathf.Abs(Time.unscaledDeltaTime - 0.018f) * 1000f;//-0.001f
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Utils;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
using UnityEngine;
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
using WorkList = System.Collections.Generic.List<CECEPWork>;
|
||||
@@ -279,61 +279,56 @@ namespace BrewMonster.Scripts
|
||||
// class CECEPWorkSpell
|
||||
public class CECEPWorkSpell : CECEPWork
|
||||
{
|
||||
CECCounter m_SkillCnt;
|
||||
CECSkill m_pCurSkill;
|
||||
int m_idCurSkillTarget;
|
||||
|
||||
public CECEPWorkSpell(CECEPWorkMan pWorkMan, uint dwPeriod, CECSkill pSkill, int target) : base(CECEPWork.EP_work_ID.WORK_SPELL, pWorkMan)
|
||||
CECCounter m_SkillCnt;
|
||||
CECSkill m_pCurSkill;
|
||||
int m_idCurSkillTarget;
|
||||
public CECEPWorkSpell(CECEPWorkMan pWorkMan, uint dwPeriod, CECSkill pSkill, int target) : base(EP_work_ID.WORK_SPELL, pWorkMan)
|
||||
{
|
||||
m_pCurSkill = pSkill;
|
||||
m_idCurSkillTarget = target;
|
||||
if (m_SkillCnt == null){
|
||||
m_SkillCnt = new CECCounter();
|
||||
}
|
||||
m_SkillCnt.SetPeriod(dwPeriod);
|
||||
m_SkillCnt.Reset();
|
||||
}
|
||||
// public CECEWorkSpell(){
|
||||
// if (m_pCurSkill != null){
|
||||
// m_pCurSkill = null;
|
||||
// }
|
||||
// }
|
||||
public override void Start()
|
||||
{
|
||||
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
|
||||
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
|
||||
}
|
||||
public override void Tick(float dwDeltaTime)
|
||||
{
|
||||
//TO DO: fix later
|
||||
//GetPlayer().m_FightCnt.IncCounter(dwDeltaTime);
|
||||
//int iRealTime = g_pGame.GetRealTickTime();
|
||||
//if (m_SkillCnt.IncCounter(iRealTime))
|
||||
//{
|
||||
// Finish();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// if (m_idCurSkillTarget != 0)
|
||||
// {
|
||||
// GetPlayer().TurnFaceTo(m_idCurSkillTarget);
|
||||
// }
|
||||
// if (GetPlayer().IsPlayingMoveAction() && !GetPlayer().IsWorkMoveRunning())
|
||||
// { // ���ƶ�ʩ����ֹͣ�ƶ�����һֱ�ڳ��������ƶ��������˴���ͣ
|
||||
// GetPlayer().PlayAction(CECPlayer::ACT_FIGHTSTAND);
|
||||
// }
|
||||
// if (!GetPlayer().IsPlayingAction())
|
||||
// {
|
||||
// GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FIGHTSTAND); // ���ܶ���������ɺ���ս��վ������
|
||||
// }
|
||||
//}
|
||||
public override void Tick(float dwDeltaTime){
|
||||
GetPlayer().m_FightCnt.IncCounter(dwDeltaTime *1000);
|
||||
float iRealTime = EC_Game.GetRealTickTime();
|
||||
if (m_SkillCnt.IncCounter(Time.unscaledDeltaTime * 1000f, out float fCounter, out float fPeriod)){
|
||||
Finish();
|
||||
}else{
|
||||
if (m_idCurSkillTarget != 0){
|
||||
GetPlayer().TurnFaceTo(m_idCurSkillTarget);
|
||||
}
|
||||
if (GetPlayer().IsPlayingMoveAction() && !GetPlayer().IsWorkMoveRunning()){ // ´ÓÒÆ¶¯Ê©·¨µ½Í£Ö¹Òƶ¯¡¢»áÒ»Ö±ÔÚ³ÖÐø²¥·ÅÒÆ¶¯¶¯×÷£¬´Ë´¦ÔÝÍ£
|
||||
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND);
|
||||
}
|
||||
if (!GetPlayer().IsPlayingAction()){
|
||||
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND); // ¼¼Äܶ¯×÷²¥·ÅÍê³Éºó¡¢²¥·ÅÕ½¶·Õ¾Á¢¶¯×÷
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void Cancel()
|
||||
{
|
||||
//TO DO: fix later
|
||||
//if (m_pCurSkill != null)
|
||||
//{
|
||||
// m_pCurSkill = null;
|
||||
//}
|
||||
//m_idCurSkillTarget = 0;
|
||||
//GetPlayer().StopSkillAttackAction();
|
||||
//GetPlayer().TurnFaceTo(0);
|
||||
public override void Cancel(){
|
||||
if (m_pCurSkill != null){
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
m_idCurSkillTarget = 0;
|
||||
GetPlayer().StopSkillAttackAction();
|
||||
GetPlayer().TurnFaceTo(0);
|
||||
}
|
||||
public CECSkill GetSkill()
|
||||
{
|
||||
public CECSkill GetSkill(){
|
||||
return m_pCurSkill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CECEPWorkMan
|
||||
@@ -898,4 +893,43 @@ namespace BrewMonster.Scripts
|
||||
//GetPlayer().StopModelMove(GetPlayer().m_vStopDir, g_vAxisY, 150);
|
||||
}
|
||||
};
|
||||
public class CECEPWorkFlashMove : CECEPWork
|
||||
{
|
||||
private A3DVECTOR3 m_vServerPos;
|
||||
private float m_fMoveSpeed;
|
||||
public CECEPWorkFlashMove(CECEPWorkMan pWorkMan, A3DVECTOR3 vServerPos, float fMoveSpeed)
|
||||
: base(CECEPWork.EP_work_ID.WORK_FLASHMOVE, pWorkMan)
|
||||
{
|
||||
m_vServerPos = vServerPos;
|
||||
m_fMoveSpeed = fMoveSpeed;
|
||||
}
|
||||
public override void Start()
|
||||
{
|
||||
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_MOVE;
|
||||
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_START, true, 0);
|
||||
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 0, true);
|
||||
}
|
||||
public override void Tick(float dwDeltaTime)
|
||||
{
|
||||
base.Tick(dwDeltaTime);
|
||||
A3DVECTOR3 vCurPos = GetPlayer().GetPos();
|
||||
A3DVECTOR3 vDir = m_vServerPos - vCurPos;
|
||||
float fDist = vDir.Normalize();
|
||||
float fMoveDelta = m_fMoveSpeed * dwDeltaTime * 0.001f;
|
||||
if (fMoveDelta >= fDist)
|
||||
{
|
||||
GetPlayer().SetPos(m_vServerPos);
|
||||
Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
vCurPos = vCurPos + vDir * fMoveDelta;
|
||||
GetPlayer().SetPos(vCurPos);
|
||||
}
|
||||
}
|
||||
public override void Cancel()
|
||||
{
|
||||
GetPlayer().SetPos(m_vServerPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ namespace BrewMonster
|
||||
private bool m_bCooling;
|
||||
private int m_iChargeCnt;
|
||||
private int m_iChargeMax;
|
||||
public int ChargeMax => m_iChargeMax;
|
||||
private bool m_bCharging;
|
||||
|
||||
private static CECSkillStr l_SkillStr = new CECSkillStr();
|
||||
|
||||
@@ -40,6 +40,13 @@ public class CECCounter
|
||||
m_dwCounter += dwCounter;
|
||||
return (m_dwCounter >= m_dwPeriod) ? true : false;
|
||||
}
|
||||
public bool IncCounter(float dwCounter, out float fCounter, out float fPeriod)
|
||||
{
|
||||
m_dwCounter += dwCounter;
|
||||
fCounter = m_dwCounter;
|
||||
fPeriod = m_dwPeriod;
|
||||
return (m_dwCounter >= m_dwPeriod) ? true : false;
|
||||
}
|
||||
|
||||
// Decrease counter
|
||||
public void DecCounter(float dwCounter)
|
||||
|
||||
@@ -2491,7 +2491,6 @@ namespace BrewMonster
|
||||
else
|
||||
sprintf(szAct, "%s_¿ÕÖзɽ£_Ò÷³ª_%s", data.action_prefix, data.action_weapon_suffix[weapon_type].suffix);*/
|
||||
}
|
||||
|
||||
bool bHideFX = false; /*!CECOptimize::Instance().GetGFX().CanShowCast(GetCharacterID(), GetClassID());*/
|
||||
if (!PlaySkillCastActionWithName(idSkill, szAct, bHideFX))
|
||||
{
|
||||
@@ -2525,7 +2524,8 @@ namespace BrewMonster
|
||||
public bool IsHangerOn() { return m_bHangerOn; }
|
||||
public bool IsPlayingAction()
|
||||
{
|
||||
return true /*GetLowerBodyAction() != -1*/ ;
|
||||
var check = GetLowerBodyAction() != -1 ;
|
||||
return check;
|
||||
}
|
||||
public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX/* =false */)
|
||||
{
|
||||
@@ -4052,26 +4052,32 @@ namespace BrewMonster
|
||||
|
||||
public struct PlayActionEvent
|
||||
{
|
||||
public ChannelAct ChannelAct;
|
||||
public string AnimationName;
|
||||
public int ITransTime;
|
||||
public bool IsForceStopPrevious;
|
||||
public bool IsLoop;
|
||||
public CECAttackEvent AttackEvent;
|
||||
public PlayActionEvent(string shapeName, string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false)
|
||||
{
|
||||
this.AnimationName = shapeName + animationName;
|
||||
ITransTime = iTransTime;
|
||||
IsForceStopPrevious = isForceStopPrevious;
|
||||
AttackEvent = attackEvent;
|
||||
IsLoop = isLoop;
|
||||
}
|
||||
public int Rank;
|
||||
public PlayActionEvent(string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false)
|
||||
{
|
||||
this.ChannelAct = null;
|
||||
this.AnimationName = animationName;
|
||||
ITransTime = iTransTime;
|
||||
IsForceStopPrevious = isForceStopPrevious;
|
||||
AttackEvent = attackEvent;
|
||||
IsLoop = isLoop;
|
||||
Rank = 0;
|
||||
}
|
||||
public PlayActionEvent(ref ChannelAct channelAct, string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false, int rank = 0)
|
||||
{
|
||||
this.ChannelAct = channelAct;
|
||||
this.AnimationName = animationName;
|
||||
ITransTime = iTransTime;
|
||||
IsForceStopPrevious = isForceStopPrevious;
|
||||
AttackEvent = attackEvent;
|
||||
IsLoop = isLoop;
|
||||
Rank = rank;
|
||||
}
|
||||
}
|
||||
public struct PLAYER_ACTION
|
||||
@@ -4081,6 +4087,7 @@ namespace BrewMonster
|
||||
};
|
||||
public class QueueActionEvent
|
||||
{
|
||||
public ChannelAct ChannelAct;
|
||||
public string AnimationName;
|
||||
public int ITransTime;
|
||||
public Action<bool, CECAttackEvent> SetFlag;
|
||||
@@ -4088,9 +4095,11 @@ namespace BrewMonster
|
||||
public bool IsHitAnim;
|
||||
public bool IsForceStopPrevious;
|
||||
public bool IsLoop;
|
||||
public int Rank;
|
||||
public QueueActionEvent(string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
|
||||
CECAttackEvent attackEvent, int iTransTime, bool isForceStopPrevious = false, bool isLoop = false)
|
||||
{
|
||||
this.ChannelAct = null;
|
||||
this.AnimationName = animationName;
|
||||
SetFlag = setFlag;
|
||||
IsHitAnim = isHitAnim;
|
||||
@@ -4098,6 +4107,20 @@ namespace BrewMonster
|
||||
ITransTime = iTransTime;
|
||||
IsForceStopPrevious = isForceStopPrevious;
|
||||
IsLoop = isLoop;
|
||||
Rank = 0;
|
||||
}
|
||||
public QueueActionEvent(ref ChannelAct channelAct, string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
|
||||
CECAttackEvent attackEvent, int iTransTime, bool isForceStopPrevious = false, bool isLoop = false, int rank = 0)
|
||||
{
|
||||
this.ChannelAct = channelAct;
|
||||
this.AnimationName = animationName;
|
||||
SetFlag = setFlag;
|
||||
IsHitAnim = isHitAnim;
|
||||
AttackEvent = attackEvent;
|
||||
ITransTime = iTransTime;
|
||||
IsForceStopPrevious = isForceStopPrevious;
|
||||
IsLoop = isLoop;
|
||||
Rank = rank;
|
||||
}
|
||||
|
||||
public void SetData(string shapeName, string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
|
||||
|
||||
@@ -10,6 +10,7 @@ using CombinedActMap = System.Collections.Generic.Dictionary<string, object>;
|
||||
using CoGfxMap = System.Collections.Generic.Dictionary<string, object>;
|
||||
using ConvexHullDataArray = System.Collections.Generic.List<object>;
|
||||
using ECModelHookMap = System.Collections.Generic.Dictionary<string, object>;
|
||||
using ActQueue = System.Collections.Generic.List<A3DCombActDynData>;
|
||||
using BrewMonster;
|
||||
using BrewMonster.Scripts.ECModel;
|
||||
using Unity.VisualScripting.FullSerializer;
|
||||
@@ -45,7 +46,110 @@ public enum ECMScriptVar
|
||||
enumECMVarSelf,
|
||||
enumECMVarCount
|
||||
}
|
||||
public enum ActionChannel
|
||||
{
|
||||
ACTCHA_DEFAULT = 0,
|
||||
ACTCHA_WOUND = 1,
|
||||
ACTCHA_MAX = 16, // Keep this value same with A3DSkinModelActionCore::ACTCHA_MAX
|
||||
};
|
||||
public class A3DCombActDynData
|
||||
{
|
||||
public A3DCombinedAction combinedAction;
|
||||
public int nChannel;
|
||||
public int m_dwUserData;
|
||||
public bool IsAllActionFinished => m_EventNames.Count == 0;
|
||||
public List<string> m_EventNames = new List<string>();
|
||||
public void SetUserData(int dwUserData) { m_dwUserData = dwUserData; }
|
||||
public int GetUserData() { return m_dwUserData; }
|
||||
}
|
||||
public class ChannelActNode
|
||||
{
|
||||
public byte m_Rank;
|
||||
public A3DCombActDynData m_pActive;
|
||||
public bool m_pActFlag;
|
||||
public int m_dwFlagMode;
|
||||
public ActQueue m_ActQueue;
|
||||
public ChannelActNode()
|
||||
{
|
||||
m_Rank = 0;
|
||||
m_pActive = null;
|
||||
m_pActFlag = false;
|
||||
m_dwFlagMode = 0;
|
||||
if(m_ActQueue == null)
|
||||
{
|
||||
m_ActQueue = new ActQueue();
|
||||
}
|
||||
m_ActQueue.Clear();
|
||||
}
|
||||
public void RemoveQueuedActs()
|
||||
{
|
||||
m_ActQueue.Clear();
|
||||
}
|
||||
}
|
||||
public class ChannelAct
|
||||
{
|
||||
public List<ChannelActNode> m_RankNodes;
|
||||
|
||||
public ChannelAct()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
if(m_RankNodes == null)
|
||||
{
|
||||
m_RankNodes = new List<ChannelActNode>();
|
||||
}
|
||||
m_RankNodes.Clear();
|
||||
}
|
||||
|
||||
public ChannelActNode GetNodeByRank(byte rank)
|
||||
{
|
||||
if(m_RankNodes == null || m_RankNodes.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
foreach(var node in m_RankNodes)
|
||||
{
|
||||
if(node.m_Rank == rank)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChannelActNode GetHighestRankNode()
|
||||
{
|
||||
if(m_RankNodes == null || m_RankNodes.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
ChannelActNode highestNode = m_RankNodes[0];
|
||||
foreach(var node in m_RankNodes)
|
||||
{
|
||||
if(node.m_Rank > highestNode.m_Rank)
|
||||
{
|
||||
highestNode = node;
|
||||
}
|
||||
}
|
||||
return highestNode;
|
||||
}
|
||||
|
||||
public ChannelActNode RemoveNodeByRank(byte rank)
|
||||
{
|
||||
foreach(var node in m_RankNodes)
|
||||
{
|
||||
if(node.m_Rank == rank)
|
||||
{
|
||||
m_RankNodes.Remove(node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
public static class CECModelConstants
|
||||
{
|
||||
public const int ECM_SCRIPT_MAX_VAR_COUNT = 8;
|
||||
@@ -382,6 +486,15 @@ public class CECModel
|
||||
private Transform m_transform;
|
||||
public bool InheritParentId() => m_bInheritParentId;
|
||||
public void SetId(int nId) => m_nId = nId;
|
||||
//16 is
|
||||
ChannelAct[] m_ChannelActs = InitChannelActs();
|
||||
private static ChannelAct[] InitChannelActs()
|
||||
{
|
||||
var acts = new ChannelAct[(int)ActionChannel.ACTCHA_MAX];
|
||||
for (int i = 0; i < acts.Length; i++)
|
||||
acts[i] = new ChannelAct();
|
||||
return acts;
|
||||
}
|
||||
public void ClearComActFlag(bool bSignalCurrent) { ClearComActFlag(0, bSignalCurrent); }
|
||||
public void ClearComActFlag(int nChannel, bool bSignalCurrent)
|
||||
{
|
||||
@@ -672,11 +785,30 @@ public class CECModel
|
||||
}
|
||||
var actionInfos = combinedAction.m_ActLst;
|
||||
var isLoop = combinedAction.m_nLoops == 1;
|
||||
EventBus.PublishChannel(m_nId, new PlayActionEvent(actionInfos[0].m_strName, nTransTime, bForceStop, attackEvent, isLoop));
|
||||
var node = m_ChannelActs[nChannel].GetNodeByRank(0);
|
||||
if (node == null)
|
||||
{
|
||||
node = new ChannelActNode { m_Rank = 0 };
|
||||
m_ChannelActs[nChannel].m_RankNodes.Add(node);
|
||||
}
|
||||
var actData = new A3DCombActDynData
|
||||
{
|
||||
combinedAction = combinedAction,
|
||||
nChannel = nChannel,
|
||||
m_dwUserData = (int)dwUserData
|
||||
};
|
||||
EventBus.PublishChannel(m_nId, new PlayActionEvent(ref m_ChannelActs[nChannel], actionInfos[0].m_strName, nTransTime, bForceStop, attackEvent, isLoop, node.m_Rank));
|
||||
actData.m_EventNames.Add(actionInfos[0].m_strName);
|
||||
|
||||
for(int i = 1; i < actionInfos.Count; i++)
|
||||
{
|
||||
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop));
|
||||
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
|
||||
actData.m_EventNames.Add(actionInfos[i].m_strName);
|
||||
}
|
||||
|
||||
node.m_pActive = actData;
|
||||
|
||||
//Todo: should move those event logic to channel act because their control the animation life span.
|
||||
var eventInfoList = combinedAction.m_EventInfoLst;
|
||||
if(eventInfoList != null && eventInfoList.Count > 0)
|
||||
{
|
||||
@@ -716,25 +848,44 @@ public class CECModel
|
||||
return false;
|
||||
}
|
||||
A3DCombinedAction combinedAction = GetComActByName(szActName);
|
||||
if(combinedAction == null)
|
||||
if(combinedAction == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var actionInfos = combinedAction.m_ActLst;
|
||||
var isLoop = combinedAction.m_nLoops == 1;
|
||||
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(actionInfos[0].m_strName, null, false, attackEvent, nTransTime, bForceStopPrevAct, isLoop));
|
||||
var node = new ChannelActNode { m_Rank = (byte)m_ChannelActs[nChannel].m_RankNodes.Count};
|
||||
m_ChannelActs[nChannel].m_RankNodes.Add(node);
|
||||
var actData = new A3DCombActDynData
|
||||
{
|
||||
// combinedAction = combinedAction, // not needed now
|
||||
nChannel = nChannel,
|
||||
m_dwUserData = (int)dwUserData
|
||||
};
|
||||
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[0].m_strName, null, false, attackEvent, nTransTime, bForceStopPrevAct, isLoop, node.m_Rank));
|
||||
for(int i = 1; i < actionInfos.Count; i++)
|
||||
{
|
||||
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop));
|
||||
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
|
||||
actData.m_EventNames.Add(actionInfos[i].m_strName);
|
||||
}
|
||||
node.m_pActive = actData;
|
||||
//todo: should add sfx and gfx logic to channel act. currently we dont have logic for queue action. only available for play action.
|
||||
return true;
|
||||
}
|
||||
public bool ClearComActFlagAllRankNodes(bool bSignalCurrent){
|
||||
EventBus.PublishChannel(m_nId, new ClearComActFlagAllRankNodesEvent(bSignalCurrent));
|
||||
public bool ClearComActFlagAllRankNodes(bool bSignalCurrent)
|
||||
{
|
||||
foreach (var ca in m_ChannelActs)
|
||||
ca?.Release();
|
||||
//EventBus.PublishChannel(m_nId, new ClearComActFlagAllRankNodesEvent(bSignalCurrent));
|
||||
return false;
|
||||
}
|
||||
public uint GetCurActionUserData(){
|
||||
return 0;
|
||||
|
||||
public int GetCurActionUserData()
|
||||
{
|
||||
var returnValue = -1;
|
||||
if (m_ChannelActs[0].GetHighestRankNode() != null)
|
||||
returnValue = m_ChannelActs[0].GetHighestRankNode().m_pActive.GetUserData();
|
||||
return returnValue;
|
||||
}
|
||||
public bool QueueAction(CECNPC.INFO iNFO, string szActName, ref bool pNewActFlag, int nTransTime = 200, uint dwUserData = 0, bool bForceStopPrevAct = false, bool bCheckTailDup = false, bool bNoFx = false, bool bResetSpeed = false
|
||||
/*joslian*/, bool bResetActFlag = false, uint dwNewFlagMode = COMACT_FLAG_MODE_NONE)
|
||||
@@ -846,8 +997,3 @@ public class CECModel
|
||||
// m_CoGfxMap[strKey] = pInfo;
|
||||
}
|
||||
}
|
||||
// Action channel
|
||||
public enum ActionChannel
|
||||
{
|
||||
ACTCHA_WOUND = 1,
|
||||
};
|
||||
|
||||
@@ -450,13 +450,14 @@ namespace BrewMonster
|
||||
}
|
||||
public override bool IsPlayingMoveAction(){
|
||||
if (GetModel()!=null){
|
||||
return IsMoveAction((int)GetModel().GetCurActionUserData());
|
||||
var userData = GetModel().GetCurActionUserData();
|
||||
return IsMoveAction((int)userData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override int GetLowerBodyAction(){
|
||||
if (GetModel()!=null){
|
||||
return (int)GetModel().GetCurActionUserData();
|
||||
return GetModel().GetCurActionUserData();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -672,80 +672,70 @@ namespace BrewMonster
|
||||
// Get skill object (else players don't have skill lists, so we create a temporary skill reference)
|
||||
// For else players, we mainly need the skill ID for animation purposes
|
||||
int skillID = pCmd.skill;
|
||||
|
||||
if ((m_pCurSkill = new CECSkill(pCmd.skill, pCmd.level)) == null)
|
||||
{
|
||||
BMLogger.LogError($"OnMsgPlayerCastSkill: Failed to create CECSkill for skillID={pCmd.skill}, level={pCmd.level}");
|
||||
return;
|
||||
}
|
||||
// Store current skill target
|
||||
m_idCurSkillTarget = pCmd.target;
|
||||
|
||||
// Face the target
|
||||
TurnFaceTo(pCmd.target);
|
||||
uint dwPeriod = (uint)(pCmd.time + m_pCurSkill.GetExecuteTime()) * 10;
|
||||
m_pEPWorkMan.StartNormalWork(new CECEPWorkSpell(m_pEPWorkMan, dwPeriod, new CECSkill(pCmd.skill, pCmd.level), pCmd.target));
|
||||
PlaySkillCastAction(m_pCurSkill.GetSkillID());
|
||||
// // Face the target
|
||||
// TurnFaceTo(pCmd.target);
|
||||
|
||||
// Play skill cast animation
|
||||
PlaySkillCastAction(skillID);
|
||||
// // Play skill cast animation
|
||||
// PlaySkillCastAction(skillID);
|
||||
|
||||
// Create a temporary skill object for tracking (if needed)
|
||||
// Note: Else players don't maintain skill lists like host player does
|
||||
// We create a minimal skill object just for the current cast
|
||||
if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
|
||||
{
|
||||
// Create a temporary skill object with level 1 (we don't know the actual level)
|
||||
m_pCurSkill = new CECSkill(skillID, 1);
|
||||
}
|
||||
// // Create a temporary skill object for tracking (if needed)
|
||||
// // Note: Else players don't maintain skill lists like host player does
|
||||
// // We create a minimal skill object just for the current cast
|
||||
// if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
|
||||
// {
|
||||
// // Create a temporary skill object with level 1 (we don't know the actual level)
|
||||
// m_pCurSkill = new CECSkill(skillID, 1);
|
||||
// }
|
||||
|
||||
// Enter fight state
|
||||
EnterFightState();
|
||||
// // Enter fight state
|
||||
// EnterFightState();
|
||||
|
||||
break;
|
||||
}
|
||||
case CommandID.OBJECT_CAST_INSTANT_SKILL:
|
||||
{
|
||||
StopCurPosWork();
|
||||
ClearCastingSkill();
|
||||
m_pEPWorkMan.FinishWork(CECEPWork.EP_work_ID.WORK_SPELL);
|
||||
cmd_object_cast_instant_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_object_cast_instant_skill>((byte[])Msg.dwParam1);
|
||||
|
||||
int skillID = pCmd.skill;
|
||||
|
||||
m_idCurSkillTarget = pCmd.target;
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
PlaySkillCastAction(skillID);
|
||||
|
||||
if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
|
||||
{
|
||||
m_pCurSkill = new CECSkill(skillID, 1);
|
||||
}
|
||||
|
||||
EnterFightState();
|
||||
PlaySkillCastAction(pCmd.skill);
|
||||
break;
|
||||
}
|
||||
case CommandID.OBJECT_CAST_POS_SKILL:
|
||||
{
|
||||
StopCurPosWork();
|
||||
ClearCastingSkill();
|
||||
m_pEPWorkMan.FinishWork(CECEPWork.EP_work_ID.WORK_SPELL);
|
||||
|
||||
|
||||
cmd_object_cast_pos_skill pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_object_cast_pos_skill>((byte[])Msg.dwParam1);
|
||||
|
||||
int skillID = pCmd.skill;
|
||||
SetServerPos(pCmd.pos);
|
||||
|
||||
// For position-based skills, target is the position, not an object
|
||||
// We still play the cast animation
|
||||
PlaySkillCastAction(skillID);
|
||||
|
||||
if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
|
||||
float fDist = A3d_Magnitude(pCmd.pos - GetPos());
|
||||
if (fDist <= 0.0001f)
|
||||
{
|
||||
m_pCurSkill = new CECSkill(skillID, 1);
|
||||
}
|
||||
|
||||
EnterFightState();
|
||||
break;
|
||||
}
|
||||
case CommandID.SKILL_PERFORM:
|
||||
{
|
||||
// Skill perform - the skill has finished casting and is being executed
|
||||
// For else players, we keep m_pCurSkill until attack result is received
|
||||
// This allows PlayAttackEffect to use the skill information
|
||||
// Durative skills (channeling) will continue until interrupted
|
||||
if (m_pCurSkill != null && m_pCurSkill.IsDurative())
|
||||
{
|
||||
// For durative skills, we keep the skill active
|
||||
// It will be cleared when SKILL_INTERRUPTED is received
|
||||
SetPos(pCmd.pos);
|
||||
return;
|
||||
}
|
||||
int nExecuteTime = ElementSkill.GetExecuteTime((uint)pCmd.skill, pCmd.level);
|
||||
nExecuteTime = Mathf.Max(nExecuteTime, 50);
|
||||
|
||||
m_fMoveSpeed = 1.3f * fDist * 1000.0f / nExecuteTime;
|
||||
m_pEPWorkMan.StartNormalWork(new CECEPWorkFlashMove(m_pEPWorkMan, pCmd.pos, m_fMoveSpeed));
|
||||
break;
|
||||
}
|
||||
case CommandID.SKILL_INTERRUPTED:
|
||||
@@ -753,13 +743,10 @@ namespace BrewMonster
|
||||
// Skill was interrupted, clear current skill
|
||||
cmd_skill_interrupted pCmd =
|
||||
GPDataTypeHelper.FromBytes<cmd_skill_interrupted>((byte[])Msg.dwParam1);
|
||||
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
StopSkillCastAction();
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
m_idCurSkillTarget = 0;
|
||||
ClearComActFlagAllRankNodes(false);
|
||||
ClearCastingSkill();
|
||||
m_pEPWorkMan.FinishWork(CECEPWork.EP_work_ID.WORK_SPELL);
|
||||
StopSkillCastAction();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -768,7 +755,25 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearCastingSkill(){
|
||||
if (m_pCurSkill != null){
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
m_idCurSkillTarget = 0;
|
||||
}
|
||||
private void StopCurPosWork()
|
||||
{
|
||||
if (m_pEPWorkMan.IsWorkRunning(CECEPWork.EP_work_ID.WORK_MOVE)){
|
||||
m_pEPWorkMan.FinishRunningWork(CECEPWork.EP_work_ID.WORK_MOVE);
|
||||
}
|
||||
if (m_pEPWorkMan.IsWorkRunning(CECEPWork.EP_work_ID.WORK_PASSIVEMOVE)){
|
||||
m_pEPWorkMan.FinishRunningWork(CECEPWork.EP_work_ID.WORK_PASSIVEMOVE);
|
||||
}
|
||||
if (m_pEPWorkMan.IsWorkRunning(CECEPWork.EP_work_ID.WORK_FLASHMOVE)){
|
||||
m_pEPWorkMan.FinishRunningWork(CECEPWork.EP_work_ID.WORK_FLASHMOVE);
|
||||
}
|
||||
}
|
||||
|
||||
private async void LoadAppearGfx()
|
||||
{
|
||||
if (!m_pAppearGFX && m_iAppearFlag == (int)PlayerAppearFlag.APPEAR_ENTERWORLD)
|
||||
|
||||
@@ -39,10 +39,15 @@ namespace BrewMonster.Scripts
|
||||
_loadVersion++;
|
||||
int version = _loadVersion;
|
||||
|
||||
ClearModels();
|
||||
|
||||
if (roleInfos == null || roleInfos.Count == 0 || NPCManager.Instance == null)
|
||||
{
|
||||
ClearModels();
|
||||
return;
|
||||
}
|
||||
|
||||
List<GameObject> oldModels = new List<GameObject>(playerModels);
|
||||
playerModels.Clear();
|
||||
playerModelIds.Clear();
|
||||
|
||||
for (int i = 0; i < roleInfos.Count; i++)
|
||||
{
|
||||
@@ -68,6 +73,14 @@ namespace BrewMonster.Scripts
|
||||
|
||||
ApplyRequestedModelVisibility();
|
||||
}
|
||||
|
||||
for(int i=0; i < oldModels.Count; i++)
|
||||
{
|
||||
if (oldModels[i] != null)
|
||||
{
|
||||
Destroy(oldModels[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -108,13 +121,36 @@ namespace BrewMonster.Scripts
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearModels()
|
||||
public void HideAllPlayerModels()
|
||||
{
|
||||
_hasRequestedPlayerModelId = false;
|
||||
for (int i = 0; i < playerModels.Count; i++)
|
||||
{
|
||||
if (playerModels[i] != null)
|
||||
Destroy(playerModels[i]);
|
||||
{
|
||||
playerModels[i].SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearModels()
|
||||
{
|
||||
//for (int i = 0; i < playerModels.Count; i++)
|
||||
//{
|
||||
// if (playerModels[i] != null)
|
||||
// {
|
||||
// Destroy(playerModels[i]);
|
||||
// }
|
||||
//}
|
||||
|
||||
for (int i = 0; i < playerModels.Count; i++)
|
||||
{
|
||||
if (playerModels[i] != null)
|
||||
{
|
||||
Destroy(playerModels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
playerModels.Clear();
|
||||
playerModelIds.Clear();
|
||||
}
|
||||
@@ -123,14 +159,18 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
for (int i = 0; i < playerModels.Count; i++)
|
||||
{
|
||||
if (playerModels[i] != null)
|
||||
if (modelRoot != null)
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
Destroy(playerModels[i]);
|
||||
else
|
||||
DestroyImmediate(playerModels[i]);
|
||||
if(playerModels[i] != null)
|
||||
{
|
||||
if(Application.isPlaying)
|
||||
Destroy(playerModels[i]);
|
||||
else
|
||||
DestroyImmediate(playerModels[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playerModels.Clear();
|
||||
playerModelIds.Clear();
|
||||
}
|
||||
@@ -139,13 +179,17 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
BMLogger.Log($"LoadPlayerModel: {role.roleid}");
|
||||
var elemendataman = BrewMonster.ElementDataManProvider.GetElementDataMan();
|
||||
GameObject prefab = await NPCManager.Instance.GetModelPlayer(role.occupation, role.gender);
|
||||
if (prefab == null)
|
||||
{
|
||||
GameObject model = await NPCManager.Instance.GetModelPlayer(role.occupation, role.gender);
|
||||
if(model == null)
|
||||
return null;
|
||||
}
|
||||
|
||||
model.SetActive(false);
|
||||
BMLogger.Log($"LoadPlayerModel: {role.roleid} - prefab loaded");
|
||||
GameObject model = Instantiate(prefab);
|
||||
if (modelRoot != null)
|
||||
{
|
||||
model.transform.SetParent(modelRoot, false);
|
||||
}
|
||||
|
||||
var playerDefaultEquipments = model.GetComponentInChildren<PlayerDefaultEquipments>();
|
||||
if (playerDefaultEquipments == null)
|
||||
{
|
||||
|
||||
@@ -196,6 +196,15 @@ namespace BrewMonster.Scripts.Skills
|
||||
// ������ȴʱ�䣬��λ����
|
||||
public virtual int GetCoolingTime() { return 5000; }
|
||||
// ����ִ��ʱ�䣬��λ����
|
||||
public static int GetExecuteTime(uint id, int level)
|
||||
{
|
||||
Skill s = Skill.Create(id, level);
|
||||
if (s == null)
|
||||
return 0;
|
||||
|
||||
int ret = s.GetExecuteTime();
|
||||
return ret;
|
||||
}
|
||||
public virtual int GetExecuteTime() { return 1000; }
|
||||
// Ŀ����������, 0:����Ŀ�꣬1:��ҪĿ�꣬2:Ŀ��������?��, 3:Ŀ������?����, 4:Ŀ������?����
|
||||
public virtual int GetTargetType() { return 0; }
|
||||
|
||||
@@ -246,6 +246,11 @@ namespace BrewMonster.Scripts.UI.Inventory
|
||||
return;
|
||||
}
|
||||
|
||||
if (_previewInstance != null && _previewInstance != sourceRoot.gameObject)
|
||||
{
|
||||
DestroyPreviewInstance();
|
||||
}
|
||||
|
||||
if (!sourceRoot.gameObject.activeSelf)
|
||||
{
|
||||
sourceRoot.gameObject.SetActive(true);
|
||||
@@ -269,6 +274,15 @@ namespace BrewMonster.Scripts.UI.Inventory
|
||||
EnsureCameraBindings();
|
||||
}
|
||||
|
||||
private void DestroyPreviewInstance()
|
||||
{
|
||||
if (_previewInstance != null)
|
||||
{
|
||||
Destroy(_previewInstance);
|
||||
_previewInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Transform ResolveSourceModelRoot()
|
||||
{
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace BrewMonster.UI
|
||||
{
|
||||
Tech3CSDKWrapper.Instance.SetLoginCallback(OnLoginCallback);
|
||||
Tech3CSDKWrapper.Instance.SetLogoutCallback(OnLogoutCallback);
|
||||
|
||||
if(PlayerModelPreview.Instance != null)
|
||||
{
|
||||
PlayerModelPreview.Instance.HideAllPlayerModels();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
@@ -102,7 +107,7 @@ namespace BrewMonster.UI
|
||||
{
|
||||
if (_roleInfos != null)
|
||||
{
|
||||
_selectCharacterScreen.InitScreen(_roleInfos, OnClickSelectCharacter, OnCreateCharacterComplete);
|
||||
_selectCharacterScreen.InitScreen(_roleInfos, OnClickSelectCharacter, OnCreateCharacterComplete, OnExitCharacterSelect);
|
||||
_roleInfos = null;
|
||||
}
|
||||
|
||||
@@ -353,6 +358,13 @@ namespace BrewMonster.UI
|
||||
|
||||
private async void OnEnterWorldComplete()
|
||||
{
|
||||
// initialize the mini map
|
||||
CECGameUIMan pGameUI = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
if (pGameUI != null)
|
||||
{
|
||||
pGameUI.m_pDlgMiniMap.InitializeMiniMap();
|
||||
}
|
||||
|
||||
await Task.Delay(2000);
|
||||
// Request all known packages: 0=Inventory,1=Equipment,2=Task
|
||||
UnityGameSession.RequestAllInventoriesAsync(() => { /*BMLogger.Log("Sent Inventory Detail Requests (all packs)");*/ }, 0, 1, 2);
|
||||
@@ -422,6 +434,21 @@ namespace BrewMonster.UI
|
||||
{
|
||||
BMLogger.LogError($"Logout failed -- errorCode: {errorCode}: {errorMessage}");
|
||||
}
|
||||
|
||||
_loginInProgress = false;
|
||||
if (_loginButton != null)
|
||||
_loginButton.interactable = true;
|
||||
}
|
||||
|
||||
private void OnExitCharacterSelect()
|
||||
{
|
||||
BMLogger.Log("Exiting character select, returning to login screen.");
|
||||
if(_selectCharacterScreen != null)
|
||||
_selectCharacterScreen.gameObject.SetActive(false);
|
||||
|
||||
_loginInProgress = false;
|
||||
if(_loginButton != null)
|
||||
_loginButton.interactable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts;
|
||||
using BrewMonster.Scripts.Extensions;
|
||||
using BrewMonster.UI;
|
||||
@@ -55,13 +56,15 @@ namespace PerfectWorld.UI.MiniMap
|
||||
private bool isShowMiniMap = true;
|
||||
CECHostPlayer m_pHostPlayer;
|
||||
|
||||
private float coordinateFactor = 0.5f; // the factor to convert the world coordinates to the mini map coordinates.
|
||||
|
||||
Vector3Int _lastIntHostPos = Vector3Int.zero;
|
||||
|
||||
private int m_nMode; // TODO: currently, there is only get logic, not set logic
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
LoadAllMiniMapTextures();
|
||||
// LoadAllMiniMapTextures();
|
||||
|
||||
_worldMapButton.onClick.AddListener(OnMiniMapClicked);
|
||||
}
|
||||
@@ -80,7 +83,6 @@ namespace PerfectWorld.UI.MiniMap
|
||||
m_pHostPlayer = GetHostPlayer();
|
||||
if (m_pHostPlayer == null) return;
|
||||
|
||||
// TODO: This should be the position of the host player, not hardcoded.
|
||||
Transform hostTransform = m_pHostPlayer.transform;
|
||||
Vector3 vecPosHost = hostTransform.position;
|
||||
Vector3Int currentIntHostPos = new Vector3Int(Mathf.RoundToInt(vecPosHost.x) / 10 + 400, Mathf.RoundToInt(vecPosHost.y) / 10, Mathf.RoundToInt(vecPosHost.z) / 10 + 550);
|
||||
@@ -89,7 +91,7 @@ namespace PerfectWorld.UI.MiniMap
|
||||
txtHostPos.text = $"{currentIntHostPos.x}, {currentIntHostPos.z}, ↑{currentIntHostPos.y}";
|
||||
_lastIntHostPos = currentIntHostPos;
|
||||
}
|
||||
Vector2 hostPlayerPos = new Vector2(vecPosHost.x / 2, vecPosHost.z / 2);
|
||||
Vector2 hostPlayerPos = new Vector2(vecPosHost.x * coordinateFactor, vecPosHost.z * coordinateFactor);
|
||||
_transformMiniMapParent.anchoredPosition = -hostPlayerPos;
|
||||
_hostPlayerIcon.localRotation = Quaternion.Euler(0, 0, -hostTransform.localRotation.eulerAngles.y);
|
||||
}
|
||||
@@ -117,6 +119,40 @@ namespace PerfectWorld.UI.MiniMap
|
||||
// dlg?.OnInitDialog();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Call this function when user enter the game world (after select role or when use GOTO to jump to a new instance).
|
||||
/// This function will get the world instance data and setup the mini map.
|
||||
/// </summary>
|
||||
public async void InitializeMiniMap()
|
||||
{
|
||||
// get current world instance
|
||||
var idInstance = CECGameRun.Instance?.GetWorld()?.GetInstanceID() ?? 161;
|
||||
var worldInstance = EC_Game.GetGameRun()?.GetInstance(idInstance);
|
||||
|
||||
if (worldInstance == null)
|
||||
{
|
||||
BMLogger.LogError("InitializeMiniMap: worldInstance is null");
|
||||
return;
|
||||
}
|
||||
// set the number of rows and columns of the mini map
|
||||
nRow = (byte)worldInstance.GetRowNum();
|
||||
nCol = (byte)worldInstance.GetColNum();
|
||||
|
||||
|
||||
// use Addressable to load all the textures of the mini map
|
||||
_spriteAtlas = await AddressableManager.Instance.LoadSpriteAtlasAsync($"minimaps/{idInstance}");
|
||||
|
||||
if (_spriteAtlas == null)
|
||||
{
|
||||
BMLogger.LogError("InitializeMiniMap: sprite atlas is null");
|
||||
return;
|
||||
}
|
||||
|
||||
LoadAllMiniMapTextures();
|
||||
}
|
||||
|
||||
|
||||
// keep this so we can load all textures of other map also.
|
||||
[ContextMenu("LoadAllMiniMapTextures")]
|
||||
public void LoadAllMiniMapTextures()
|
||||
@@ -142,7 +178,7 @@ namespace PerfectWorld.UI.MiniMap
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// this is for debuging/testing while this feature was in development
|
||||
[ContextMenu("MoveHostPlayerIconToPos")]
|
||||
public void MoveHostPlayerIconToPos()
|
||||
@@ -151,5 +187,6 @@ namespace PerfectWorld.UI.MiniMap
|
||||
_transformMiniMapParent.anchoredPosition = -hostPlayerPos;
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b764c7c6d08a20e41a8ebfb3435954db
|
||||
guid: 34322d27488583140acae7497762ccbc
|
||||
SpriteAtlasImporter:
|
||||
externalObjects: {}
|
||||
textureSettings:
|
||||
@@ -989,8 +989,8 @@ MonoBehaviour:
|
||||
parentItems: {fileID: 2643174602035272289}
|
||||
createCharacterButton: {fileID: 2685968509838782728}
|
||||
_btnEnterGame: {fileID: 5173447691193350084}
|
||||
_btnExit: {fileID: 1166159884785039946}
|
||||
createCharacterScreen: {fileID: 0}
|
||||
playerModelPreview: {fileID: 0}
|
||||
--- !u!1 &7510180475820570348
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace BrewMonster
|
||||
public int ITransTime;
|
||||
public CECAttackEvent AttackEvent;
|
||||
public bool IsLoop;
|
||||
public ChannelAct ChannelAct;
|
||||
public int Rank;
|
||||
}
|
||||
public class PlayerVisual : MonoBehaviour
|
||||
{
|
||||
@@ -48,14 +50,16 @@ namespace BrewMonster
|
||||
{
|
||||
AnimationName = @event.AnimationName,
|
||||
IsForceStopPrevious = @event.IsForceStopPrevious,
|
||||
AttackEvent = @event.AttackEvent
|
||||
AttackEvent = @event.AttackEvent,
|
||||
ChannelAct = @event.ChannelAct,
|
||||
Rank = @event.Rank
|
||||
});
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
return;
|
||||
}
|
||||
previousAnimationName = @event.AnimationName;
|
||||
InternalPlayAnimation(@event.AnimationName, @event.ITransTime, FadeMode, @event.IsLoop);
|
||||
ApplyAttackSignalOnAnimationEnd(@event.AttackEvent);
|
||||
ApplyAnimationEndCallbacks(@event.AttackEvent, @event.ChannelAct, @event.Rank);
|
||||
}
|
||||
public void InitPlayerEventDoneHandler()
|
||||
{
|
||||
@@ -156,7 +160,9 @@ namespace BrewMonster
|
||||
IsForceStopPrevious = @event.IsForceStopPrevious,
|
||||
ITransTime = @event.ITransTime,
|
||||
AttackEvent = @event.AttackEvent,
|
||||
IsLoop = @event.IsLoop
|
||||
IsLoop = @event.IsLoop,
|
||||
ChannelAct = @event.ChannelAct,
|
||||
Rank = @event.Rank
|
||||
});
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
if (!isHit)
|
||||
@@ -222,18 +228,21 @@ namespace BrewMonster
|
||||
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
|
||||
previousAnimationName = animationQueue.AnimationName;
|
||||
InternalPlayAnimation(animationQueue.AnimationName, animationQueue.ITransTime, FadeMode, animationQueue.IsLoop);
|
||||
ApplyAttackSignalOnAnimationEnd(animationQueue.AttackEvent);
|
||||
ApplyAnimationEndCallbacks(animationQueue.AttackEvent, animationQueue.ChannelAct, animationQueue.Rank);
|
||||
}
|
||||
private void ApplyAttackSignalOnAnimationEnd(CECAttackEvent attackEvent)
|
||||
{
|
||||
if (attackEvent == null || _currentState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void ApplyAnimationEndCallbacks(CECAttackEvent attackEvent, ChannelAct channelAct, int rank)
|
||||
{
|
||||
if (_currentState == null) return;
|
||||
_currentState.Events.OnEnd = () =>
|
||||
{
|
||||
attackEvent.m_bSignaled = true;
|
||||
if (attackEvent != null)
|
||||
attackEvent.m_bSignaled = true;
|
||||
channelAct.GetNodeByRank((byte)rank).m_pActive.m_EventNames.Remove(_currentAnimationName);
|
||||
if(channelAct.GetNodeByRank((byte)rank).m_pActive.IsAllActionFinished)
|
||||
{
|
||||
//channelAct.RemoveNodeByRank((byte)rank);
|
||||
}
|
||||
};
|
||||
}
|
||||
void ApplyDamage()
|
||||
|
||||
@@ -18,11 +18,13 @@ namespace BrewMonster.UI
|
||||
[SerializeField] private RectTransform parentItems;
|
||||
[SerializeField] private Button createCharacterButton;
|
||||
[SerializeField] private Button _btnEnterGame;
|
||||
[SerializeField] private Button _btnExit;
|
||||
[SerializeField] private CreateCharacterScreen createCharacterScreen;
|
||||
|
||||
private CharacterItemUI _selectingCharacterItemUI;
|
||||
private Action<RoleInfo> _onClickItemChar;
|
||||
private Action<RoleInfo> _onCreateCharacterComplete;
|
||||
private Action _onExit;
|
||||
private List<RoleInfo> _roleInfos;
|
||||
|
||||
private Coroutine _showModelReadyCoroutine;
|
||||
@@ -33,6 +35,11 @@ namespace BrewMonster.UI
|
||||
_btnEnterGame.onClick.AddListener(OnClickedEnterGame);
|
||||
_btnEnterGame.gameObject.SetActive(false);
|
||||
|
||||
if(_btnExit != null)
|
||||
{
|
||||
_btnExit.onClick.AddListener(OnClickedExit);
|
||||
}
|
||||
|
||||
if (_roleInfos != null && _roleInfos.Count > 0)
|
||||
{
|
||||
PlayerModelPreview.Instance?.ShowAllPlayerModels(_roleInfos);
|
||||
@@ -57,10 +64,11 @@ namespace BrewMonster.UI
|
||||
}
|
||||
}
|
||||
|
||||
public void InitScreen(List<RoleInfo> roleInfos, Action<RoleInfo> OnClickItemChar, Action<RoleInfo> onCreateCharacterComplete = null)
|
||||
public void InitScreen(List<RoleInfo> roleInfos, Action<RoleInfo> OnClickItemChar, Action<RoleInfo> onCreateCharacterComplete = null, Action onExit = null)
|
||||
{
|
||||
_onClickItemChar = OnClickItemChar;
|
||||
_onCreateCharacterComplete = onCreateCharacterComplete;
|
||||
_onExit = onExit;
|
||||
|
||||
// Clear existing items
|
||||
if (parentItems != null)
|
||||
@@ -110,7 +118,7 @@ namespace BrewMonster.UI
|
||||
addButton.onClick.AddListener(OnCreateCharacterClicked);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -120,13 +128,13 @@ namespace BrewMonster.UI
|
||||
createCharacterButton.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load player preview 3D models
|
||||
PlayerModelPreview.Instance?.ShowAllPlayerModels(roleInfos);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PlayerModelPreview.Instance != null)
|
||||
if (PlayerModelPreview.Instance != null)
|
||||
PlayerModelPreview.Instance.ShowAllPlayerModels(null);
|
||||
// If roleInfos is null, show createCharacterButton
|
||||
if (createCharacterButton != null)
|
||||
@@ -143,7 +151,7 @@ namespace BrewMonster.UI
|
||||
return;
|
||||
|
||||
}
|
||||
if(_selectingCharacterItemUI!=null)
|
||||
if (_selectingCharacterItemUI != null)
|
||||
{
|
||||
_selectingCharacterItemUI.SetFocus(false);
|
||||
}
|
||||
@@ -230,5 +238,16 @@ namespace BrewMonster.UI
|
||||
BMLogger.LogError("No role selected");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClickedExit()
|
||||
{
|
||||
_onExit?.Invoke();
|
||||
gameObject.SetActive(false);
|
||||
|
||||
if(PlayerModelPreview.Instance != null)
|
||||
{
|
||||
PlayerModelPreview.Instance.HideAllPlayerModels();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user