diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs
index f267f0ed32..b76d1720b7 100644
--- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs
+++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using BrewMonster.Scripts.Chat;
using System.Collections.Generic;
using UnityEngine;
+using BrewMonster.Scripts.Skills;
public class CECNPC : CECObject
{
[SerializeField] protected INFO m_NPCInfo;
@@ -44,6 +45,14 @@ public class CECNPC : CECObject
protected CECNPCModelPolicy m_pNPCModelPolicy;
protected CECPolicyAction m_pPolicyAction;
public int m_iMMIndex;
+
+ // [中文] 上次从服务器收到的完整扩展状态位图(用于 SetNewExtendStates 中的 Array.Copy)
+ // [English] Last full extended-state bitmask received from server (copied in SetNewExtendStates)
+ protected uint[] m_aExtStates = new uint[(int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT];
+
+ // [中文] 当前已显示的扩展状态位图(与新数据做差分,控制 GFX 增删)
+ // [English] Currently displayed extended-state bitmask (diffed against new data to add/remove GFX)
+ protected uint[] m_aExtStatesShown = new uint[(int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT];
public int m_idAttackTarget;
/// Buff/debuff icon states from server (ICON_STATE_NOTIFY). Same role as CECPlayer.m_aIconStates.
public List m_aIconStates = new List();
@@ -137,7 +146,7 @@ public class CECNPC : CECObject
var ext = new uint[ojexitStateCount];
if ((info.state & PlayerNPCState.GP_STATE_EXTEND_PROPERTY) != 0)
r.ReadInto(ext);
- //SetNewExtendStates(0, ext, ojexitStateCount );
+ SetNewExtendStates(0, ext, (int)ojexitStateCount);
// PET
m_idMaster = 0;
@@ -234,6 +243,12 @@ public class CECNPC : CECObject
});
}
}
+ else if (Convert.ToInt32(Msg.dwParam2) == CommandID.UPDATE_EXT_STATE)
+ {
+ cmd_update_ext_state pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1);
+ if (pCmd.id == m_NPCInfo.nid)
+ SetNewExtendStates(0, pCmd.states, (int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT);
+ }
// UPDATE_EXT_STATE for NPC is handled separately from icon strip; extend if NPC state GFX is ported.
}
@@ -243,6 +258,91 @@ public class CECNPC : CECObject
//m_pNPCModelPolicy.PlayGfx(res_GFXFile(RES_GFX_LEVELUP), NULL);
}
+ // [中文] 处理服务器发来的扩展状态更新消息,驱动状态 GFX 的添加与移除
+ // [English] Handle server ext-state update message — drives state GFX add/remove
+
+
+ // [中文] 更新扩展状态并刷新 GFX 显示
+ // [English] Update the ext-state arrays and refresh GFX display
+ public void SetNewExtendStates(int start, uint[] pData, int count)
+ {
+ if (pData == null || start + count > (int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT)
+ return;
+
+ ShowExtendStates(start, pData, count);
+ Array.Copy(pData, 0, m_aExtStates, start, count);
+ }
+
+ // [中文] 清除所有已显示的状态效果 GFX(传入全零位图触发全量移除)
+ // [English] Clear all currently displayed state-effect GFX (pass all-zero bitmap to remove everything)
+ private void ClearShowExtendStates()
+ {
+ ShowExtendStates(0, new uint[(int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT],
+ (int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT, true);
+ }
+
+ // [中文] 对比旧位图与新位图,逐位差分,新增或移除对应状态效果 GFX
+ // [English] Diff old vs new bitmask bit-by-bit and add/remove state-effect GFX accordingly
+ private void ShowExtendStates(int start, uint[] pData, int count, bool bIgnoreOptimize = false)
+ {
+ if (pData == null || start + count > (int)OBJECT_EXT_STATE.OBJECT_EXT_STATE_COUNT)
+ return;
+
+ // [中文] 模型必须已加载才能挂载 GFX
+ // [English] Model must be loaded before GFX can be attached
+ if (!m_pNPCModelPolicy.IsModelLoaded())
+ return;
+
+ // [中文] 策划联入\状态效果\ —— 状态效果 GFX 的基础路径(与 C++ 保持一致)
+ // [English] Designer-linked state-effect GFX base path (matches C++)
+ const string szBasePath = "gfx/策划联入/状态效果/";
+
+ const int bitSize = sizeof(uint) * 8;
+ for (int index = 0; index < count; index++)
+ {
+ int idState = index + start;
+ for (int i = 0; i < bitSize; i++)
+ {
+ uint dwMask = 1u << i;
+ uint dwFlag1 = m_aExtStatesShown[idState] & dwMask; // currently shown
+ uint dwFlag2 = pData[index] & dwMask; // incoming
+
+ // [中文] 两者相同(都激活或都未激活),无需处理
+ // [English] Both unchanged — nothing to do
+ if ((dwFlag1 == 0 && dwFlag2 == 0) || (dwFlag1 != 0 && dwFlag2 != 0))
+ continue;
+
+ // [中文] 查询可见状态定义(NPC 固定使用 profession 127)
+ // [English] Query visible state definition (NPCs always use profession 127)
+ VisibleState pvs = GNET.QueryVisibleState(127, i + idState * bitSize);
+ if (pvs == null)
+ continue;
+
+ string strEffect = pvs.GetEffect();
+ if (string.IsNullOrEmpty(strEffect))
+ continue;
+
+ string strGFXFile = szBasePath + strEffect;
+
+ if (dwFlag1 != 0)
+ {
+ // [中文] 移除旧状态效果 GFX
+ // [English] Remove old state GFX
+ m_pNPCModelPolicy.RemoveGfx(strGFXFile, "HH_头顶" /*pvs.GetHH()*/);
+ }
+ else
+ {
+ // [中文] 添加新状态效果 GFX
+ // [English] Add new state GFX
+ BMLogger.Log($"[HoangDev NPC StateGFX] Playing: {strGFXFile}, hook: {pvs.GetHH()}");
+ m_pNPCModelPolicy.PlayGfx(strGFXFile,"HH_头顶" /*pvs.GetHH()*/);
+ }
+ }
+ }
+
+ Array.Copy(pData, 0, m_aExtStatesShown, start, count);
+ }
+
private void OnMsgNPCInvisible(ECMSG Msg)
{
cmd_object_invisible pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1);
@@ -683,6 +783,10 @@ public class CECNPC : CECObject
::memset(m_aExtStates, 0, sizeof(m_aExtStates));
m_aIconStates.clear();*/
m_aIconStates?.Clear();
+ // [中文] 模型释放前先移除所有状态效果 GFX,并重置位图
+ // [English] Remove all state-effect GFX and reset bitmasks before the model is released
+ ClearShowExtendStates();
+ Array.Clear(m_aExtStates, 0, m_aExtStates.Length);
m_pNPCModelPolicy = null;
PoolManager.Instance.Despawn(m_modelVisual);
@@ -1025,7 +1129,7 @@ public class CECNPC : CECObject
{
return;
}
-
+
try
{
szModelFile = AFile.NormalizePath(szModelFile.ToLower(), true);
diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPCModelDefaultPolicy.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPCModelDefaultPolicy.cs
index e46ab78a6c..0afdf771a1 100644
--- a/Assets/PerfectWorld/Scripts/NPC/CECNPCModelDefaultPolicy.cs
+++ b/Assets/PerfectWorld/Scripts/NPC/CECNPCModelDefaultPolicy.cs
@@ -1,6 +1,10 @@
using BrewMonster;
+using BrewMonster.Managers;
using CSNetwork.GPDataType;
using CSNetwork.Protocols;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using BrewMonster.Scripts;
using UnityEngine;
public class CECNPCModelDefaultPolicy
@@ -12,6 +16,14 @@ public class CECNPCModelDefaultPolicy
A3DAABB m_CHAABB; // AABB Updated with m_ppBrushes
// number of brush object used in collision
+ // [中文] 状态效果 GFX 对象缓存,键为 (路径 + 挂点名)
+ // [English] Active state-effect GFX objects, keyed by (path + hook name)
+ private Dictionary _stateGfxObjects = new Dictionary();
+
+ // [中文] 挂点 Transform 缓存,键为挂点名称
+ // [English] Hook transform cache, keyed by bone name
+ private Dictionary _hookCache = new Dictionary();
+
public CECNPCModelDefaultPolicy(CECNPC pNPC)
{
m_pNPCModel = new CECModel();
@@ -73,7 +85,7 @@ public class CECNPCModelDefaultPolicy
// m_CHAABB ¸ù¾Ý͹°üÉϵĶ¥µãλÖÃÀ´¼ÆËã°üΧºÐ£¬¸ü׼ȷ²¢Óë͹°ü¼ì²â±£³ÖÒ»ÖÂ
// ²»ÄÜʹÓà GetPos() À´µ÷Õû m_CHAABB ºó×÷Ϊ¼ÆËã½á¹û·µ»Ø
//aabb.Center = GetPos() + A3DVECTOR3(0.0f, m_CHAABB.Extents.y, 0.0f);
- //aabb.CompleteMinsMaxs();
+ //aabb.CompleteMinsMaxs();
bRet = true;
}
return bRet;
@@ -199,10 +211,107 @@ public class CECNPCModelDefaultPolicy
public override void SetNpcVisual(NPCVisual npcVisual)
{
_npcVisual = npcVisual;
+ // [中文] 模型重新加载时清除挂点缓存
+ // [English] Clear hook cache when the NPC model is reloaded
+ _hookCache.Clear();
}
public override void SetDefaultPickAABBExt(A3DVECTOR3 vExt)
{
-
+
+ }
+
+ // -----------------------------------------------------------------------
+ // IsModelLoaded / PlayGfx / RemoveGfx
+ // -----------------------------------------------------------------------
+
+ // [中文] 判断 NPC 模型是否已加载并激活(作为状态 GFX 的前置守卫)
+ // [English] Returns true when the NPC model is present and the game object is active
+ public override bool IsModelLoaded()
+ {
+ return m_pNPCModel != null && m_pNPC != null && m_pNPC.gameObject.activeInHierarchy;
+ }
+
+ // [中文] 异步加载并挂载状态效果 GFX 到指定挂点;以 (路径+挂点) 为键去重
+ // [English] Async-load and attach a state-effect GFX to the given hook; deduplicated by (path+hook)
+ public override async void PlayGfx(string szPath, string szHook)
+ {
+ if (string.IsNullOrEmpty(szPath)) return;
+
+ string key = szPath + szHook;
+ if (_stateGfxObjects.ContainsKey(key)) return;
+
+ GameObject prefab = await AddressableManager.Instance.LoadPrefabAsync(szPath);
+ if (prefab == null)
+ {
+ BMLogger.LogWarning($"[NPC GFX] Failed to load prefab: {szPath}");
+ return;
+ }
+
+ // [中文] 检查 NPC 是否仍然存在(异步加载期间可能被销毁)
+ // [English] Guard against the NPC being destroyed during async load
+ if (m_pNPC == null) return;
+
+ // [中文] 查找挂点,找不到则回退到 NPC 根节点
+ // [English] Locate hook bone; fall back to NPC root if not found
+ Transform parent = FindHookTransform(szHook) ?? m_pNPC.transform;
+
+ GameObject vfx = Object.Instantiate(prefab, parent);
+ if (vfx == null) return;
+
+ vfx.transform.localPosition = Vector3.zero;
+ vfx.transform.localRotation = Quaternion.Euler(-180f, -90f, 90f);
+ _stateGfxObjects[key] = vfx;
+
+ BMLogger.Log($"[NPC GFX] Playing: {szPath}, hook: {szHook}");
+ }
+
+ // [中文] 销毁并移除指定状态效果 GFX
+ // [English] Destroy and untrack a state-effect GFX
+ public override void RemoveGfx(string szPath, string szHook)
+ {
+ string key = szPath + szHook;
+ if (_stateGfxObjects.TryGetValue(key, out GameObject vfx) && vfx != null)
+ {
+ Object.Destroy(vfx);
+ _stateGfxObjects.Remove(key);
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ // Hook lookup — child-name traversal (no SkeletonBuilder on NPC)
+ // 挂点查找 —— 遍历子节点名称(NPC 无 SkeletonBuilder)
+ // -----------------------------------------------------------------------
+
+ // [中文] 在 NPC GameObject 的子节点中按名称递归查找挂点,结果缓存以提升性能
+ // [English] Recursively find a child transform by name under the NPC; results are cached
+ private Transform FindHookTransform(string hookName)
+ {
+ if (string.IsNullOrEmpty(hookName)) return null;
+
+ if (_hookCache.TryGetValue(hookName, out Transform cached) && cached != null)
+ return cached;
+
+ Transform root = m_pNPC?.transform;
+ if (root == null) return null;
+
+ Transform found = FindChildByName(root, hookName);
+ if (found != null)
+ _hookCache[hookName] = found;
+
+ return found;
+ }
+
+ // [中文] 深度优先递归遍历子节点,按名称查找
+ // [English] Depth-first recursive child search by name
+ private static Transform FindChildByName(Transform parent, string name)
+ {
+ foreach (Transform child in parent)
+ {
+ if (child.name == name) return child;
+ Transform found = FindChildByName(child, name);
+ if (found != null) return found;
+ }
+ return null;
}
}
diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPCModelPolicy.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPCModelPolicy.cs
index 490dcb8114..aa9a634bd8 100644
--- a/Assets/PerfectWorld/Scripts/NPC/CECNPCModelPolicy.cs
+++ b/Assets/PerfectWorld/Scripts/NPC/CECNPCModelPolicy.cs
@@ -16,5 +16,17 @@ namespace BrewMonster
public abstract bool GetCHAABB(ref A3DAABB ab);
public abstract void StopChannelAction();
public abstract void SetDefaultPickAABBExt(CSNetwork.GPDataType.A3DVECTOR3 vExt);
+
+ // [中文] 模型是否已加载完毕(用于状态效果 GFX 的显示守卫)
+ // [English] Whether the NPC model is loaded (guard for state-effect GFX display)
+ public abstract bool IsModelLoaded();
+
+ // [中文] 在 NPC 模型挂点上播放状态效果 GFX
+ // [English] Play a state-effect GFX on the NPC model at the given hook
+ public abstract void PlayGfx(string szPath, string szHook);
+
+ // [中文] 移除 NPC 模型上的状态效果 GFX
+ // [English] Remove a state-effect GFX from the NPC model
+ public abstract void RemoveGfx(string szPath, string szHook);
}
}
\ No newline at end of file
diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs
index 2f91fcde21..5d2449ed24 100644
--- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs
+++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs
@@ -1546,6 +1546,11 @@ namespace CSNetwork
break;
}
+ case CommandID.HOST_NOTIFY_ROOT:
+ case CommandID.HOST_DISPEL_ROOT:
+
+ EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_ROOTNOTIFY, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader);
+ break;
default:
#if UNITY_EDITOR
if (isDebug)
diff --git a/Assets/PerfectWorld/Scripts/World/AddressableObject.cs b/Assets/PerfectWorld/Scripts/World/AddressableObject.cs
index ae97a06678..f0ad2fabd1 100644
--- a/Assets/PerfectWorld/Scripts/World/AddressableObject.cs
+++ b/Assets/PerfectWorld/Scripts/World/AddressableObject.cs
@@ -1,6 +1,8 @@
using BrewMonster.Scripts;
using Cysharp.Threading.Tasks;
using UnityEngine;
+using System;
+
#if UNITY_EDITOR
using UnityEditor;
@@ -35,7 +37,7 @@ namespace BrewMonster
}
- public async UniTask LoadAsset()
+ public async UniTask LoadAsset(Action actDone = null)
{
if (string.IsNullOrEmpty(assetPath))
{
@@ -50,7 +52,7 @@ namespace BrewMonster
_isLoading = true;
int requestId = ++_loadRequestId;
var model = await AddressableManager.Instance.LoadPrefabAsync(assetPath);
-
+ actDone?.Invoke();
// Object might have been destroyed while awaiting.
if (this == null || gameObject == null)
{
diff --git a/Assets/PerfectWorld/Scripts/World/LitModelHolder.cs b/Assets/PerfectWorld/Scripts/World/LitModelHolder.cs
index 8651386e9a..70038d877f 100644
--- a/Assets/PerfectWorld/Scripts/World/LitModelHolder.cs
+++ b/Assets/PerfectWorld/Scripts/World/LitModelHolder.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@@ -288,10 +289,12 @@ public class LitModelHolder : MonoSingleton
private void ProcessLoadAndUnloadObjects()
{
+ _currentIdxAsset = 0;
+ _maxIdxAsset = _candidatesForLoading.Count;
// load the objects that are in the loading range long enough. (_candidateWaitTimeSeconds)
foreach (var kvp in _candidatesForLoading)
{
- kvp.Key.LoadAsset().Forget();
+ kvp.Key.LoadAsset(CallBackAssetLoadingDone).Forget();
_loadedObjects.Add(kvp.Key);
}
_candidatesForLoading.Clear();
@@ -307,6 +310,28 @@ public class LitModelHolder : MonoSingleton
_objectsToUnload.Clear();
}
+ int _currentIdxAsset = 0; // The current counter for loaded assets.
+ int _maxIdxAsset = 0; // Limit the number of assets that have finished loading.
+
+ ///
+ /// isLitToReady is a condition used by _hostPlayer to wait until the Lit assets have finished loading.
+ /// This function counts the number of assets successfully loaded from the Addressable system,
+ /// and once the required number is reached, it sets _hostPlayer.isLitToReady = true.
+ ///
+ private void CallBackAssetLoadingDone()
+ {
+ _currentIdxAsset++;
+ if (_currentIdxAsset >= _maxIdxAsset)
+ {
+ if (_hostPlayer != null)
+ {
+ _hostPlayer.isLitToReady = true;
+ }
+ _currentIdxAsset = -1;
+ _maxIdxAsset = 0;
+ }
+ }
+
///
/// Get the Host Player instance.
///
@@ -444,4 +469,4 @@ public class LitModelHolder : MonoSingleton
$"- anchorsWithMoreThanOneChild={multiChildCount}");
}
#endif
-}
\ No newline at end of file
+}
diff --git a/Assets/PerfectWorld/Scripts/World/TerrainHolder.cs b/Assets/PerfectWorld/Scripts/World/TerrainHolder.cs
index d7b6142b0c..8cfe0ed009 100644
--- a/Assets/PerfectWorld/Scripts/World/TerrainHolder.cs
+++ b/Assets/PerfectWorld/Scripts/World/TerrainHolder.cs
@@ -174,6 +174,11 @@ namespace BrewMonster
}
_needToProcessLoadAndUnload = true;
+ //if (_hostPlayer != null)
+ //{
+ // Debug.LogError("ProcessLoadAndUnload Terain _hostPlayer.isTerrainToReady = false");
+ // _hostPlayer.isTerrainToReady = false;
+ //}
}
}
@@ -183,9 +188,11 @@ namespace BrewMonster
///
private void ProcessLoadAndUnload()
{
+ _currentIdxAsset = 0;
+ _maxIdxAsset = _candidatesForLoading.Count;
for (int i = 0; i < _candidatesForLoading.Count; i++)
{
- _candidatesForLoading[i].LoadAsset().Forget();
+ _candidatesForLoading[i].LoadAsset(CallBackAssetLoadingDone).Forget();
}
_candidatesForLoading.Clear();
@@ -196,6 +203,28 @@ namespace BrewMonster
_objectsToUnload.Clear();
}
+ int _currentIdxAsset = 0; // The current counter for loaded assets.
+ int _maxIdxAsset = 0; // Limit the number of assets that have finished loading.
+
+ ///
+ /// isLitToReady is a condition used by _hostPlayer to wait until the Terrain assets have finished loading.
+ /// This function counts the number of assets successfully loaded from the Addressable system,
+ /// and once the required number is reached, it sets _hostPlayer.isLitToReady = true.
+ ///
+ private void CallBackAssetLoadingDone()
+ {
+ _currentIdxAsset++;
+ if (_currentIdxAsset >= _maxIdxAsset)
+ {
+ if (_hostPlayer != null)
+ {
+ _hostPlayer.isTerrainToReady = true;
+ }
+ _currentIdxAsset = -1;
+ _maxIdxAsset = 0;
+ }
+ }
+
///
/// Main-thread anchor for terrain streaming: host position, or navigate clone when force-navigate is active (same idea as LitModelHolder).
/// 地形流式锚点:普通用宿主;强制导航用导航克隆(与 LitModelHolder 一致)。
diff --git a/Assets/Resources/DebugCmdHistory.json b/Assets/Resources/DebugCmdHistory.json
index 49637133fb..5da8d2d05a 100644
--- a/Assets/Resources/DebugCmdHistory.json
+++ b/Assets/Resources/DebugCmdHistory.json
@@ -1,11 +1,18 @@
{
"items": [
+ {
+ "header": 1992,
+ "param": 0,
+ "hasParam": false,
+ "describe": "Buff rage",
+ "lastUsedUtcTicks": 639138321717437357
+ },
{
"header": 8903,
"param": 73125,
"hasParam": true,
"describe": "NoCooldown",
- "lastUsedUtcTicks": 639137253458330904
+ "lastUsedUtcTicks": 639138321659072960
},
{
"header": 2000,
@@ -14,13 +21,6 @@
"describe": "Up Level",
"lastUsedUtcTicks": 639136623463073402
},
- {
- "header": 1992,
- "param": 0,
- "hasParam": false,
- "describe": "Buff rage",
- "lastUsedUtcTicks": 639136573213427110
- },
{
"header": 1988,
"param": 0,
diff --git a/Assets/Scripts/CECHostPlayer.World.cs b/Assets/Scripts/CECHostPlayer.World.cs
index c7839afe91..ac98b65b39 100644
--- a/Assets/Scripts/CECHostPlayer.World.cs
+++ b/Assets/Scripts/CECHostPlayer.World.cs
@@ -230,6 +230,8 @@ namespace BrewMonster
m_MoveCtrl.SetHostLastPos(EC_Utility.ToA3DVECTOR3(vPos));
m_MoveCtrl.SetLastSevPos(EC_Utility.ToA3DVECTOR3(vPos));
+ isLitToReady = false;
+ isTerrainToReady = false;
// Update camera if available
// 如果可用则更新相机
// UpdateFollowCamera(false, 10); // Uncomment if UpdateFollowCamera method exists
diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs
index af988a5e55..653898cb8f 100644
--- a/Assets/Scripts/CECHostPlayer.cs
+++ b/Assets/Scripts/CECHostPlayer.cs
@@ -169,6 +169,8 @@ namespace BrewMonster
Ray ray;
RaycastHit[] hits = new RaycastHit[5];
bool isDataAwaitToReady = false;
+ public bool isTerrainToReady = false;
+ public bool isLitToReady = false;
private BaseVfxObject m_pSelectedGFX;
private BaseVfxObject m_pHoverGFX;
@@ -395,7 +397,7 @@ namespace BrewMonster
{
base.Update();
- if (!isDataAwaitToReady)
+ if (!isDataAwaitToReady || !isTerrainToReady || !isLitToReady)
{
return;
}
@@ -607,7 +609,7 @@ namespace BrewMonster
private void OnMsgHstRootNotify(in ECMSG Msg)
{
- if ((int)Msg.dwParam2 == CommandID.HOST_NOTIFY_ROOT)
+ if (Convert.ToInt32(Msg.dwParam2) == CommandID.HOST_NOTIFY_ROOT)
{
cmd_host_notify_root pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1);
m_dwLIES |=(uint) (1 << pCmd.type);
@@ -631,7 +633,7 @@ namespace BrewMonster
}
}
}
- else if ((int)Msg.dwParam2 == CommandID.HOST_DISPEL_ROOT)
+ else if (Convert.ToInt32(Msg.dwParam2) == CommandID.HOST_DISPEL_ROOT)
{
cmd_host_dispel_root pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1);
m_dwLIES &=(uint) ~(1 << pCmd.type);