Add Animation phoenix fly in the lv 10 quest.

This commit is contained in:
Chomper9981
2026-04-06 13:39:39 +07:00
parent eb058237fa
commit ff03d7d0eb
102 changed files with 2846 additions and 402 deletions
+7 -7
View File
@@ -1,9 +1,9 @@
// taskID,bezierID,speed,angle,dir,model file path
"32220,-1001,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32221,-1003,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32222,-1002,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32223,-1004,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32224,-1005,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32428,-1006,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32225,-1007,30,30.0,1,Models\NPCs\³èÎï\Æï³è\·ï»Ë\·ï»Ë.ecm"
"32220,-1001,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
"32221,-1003,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
"32222,-1002,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
"32223,-1004,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
"32224,-1005,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
"32428,-1006,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
"32225,-1007,30,30.0,1,Models/npcs/宠物/骑宠/凤凰/凤凰.ecm"
File diff suppressed because it is too large Load Diff
+56 -14
View File
@@ -215,7 +215,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 700879706879584381}
serializedVersion: 2
m_LocalRotation: {x: 0.0000000011722103, y: -0.26373407, z: -0.00000023176595, w: 0.9645954}
m_LocalRotation: {x: 0.0000000011722104, y: -0.2637341, z: -0.00000023176597, w: 0.96459544}
m_LocalPosition: {x: 0.16233289, y: -0.00000004810146, z: -0.000000061758335}
m_LocalScale: {x: 1, y: 1.0000001, z: 0.9999999}
m_ConstrainProportionsScale: 0
@@ -408,7 +408,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 870105474783592799}
serializedVersion: 2
m_LocalRotation: {x: -0.116904, y: 0.52980244, z: -0.18870111, w: 0.8185564}
m_LocalRotation: {x: -0.116904005, y: 0.5298025, z: -0.18870112, w: 0.8185565}
m_LocalPosition: {x: 0.012014532, y: -0.0000000867314, z: -0.000000065188935}
m_LocalScale: {x: 1, y: 0.9999999, z: 0.99999994}
m_ConstrainProportionsScale: 0
@@ -792,7 +792,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2090055399504802636}
serializedVersion: 2
m_LocalRotation: {x: -0.000000007450579, y: 0.05836967, z: 0.000000015279507, w: 0.998295}
m_LocalRotation: {x: -0.0000000074505793, y: 0.058369674, z: 0.00000001527951, w: 0.99829507}
m_LocalPosition: {x: 0.97464234, y: -0.0000001192093, z: -0.00000017881396}
m_LocalScale: {x: 1.0000001, y: 0.99999994, z: 0.9999999}
m_ConstrainProportionsScale: 0
@@ -857,7 +857,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2273991754805310631}
serializedVersion: 2
m_LocalRotation: {x: 0.000000015328007, y: 0.021831421, z: -0.000000014805245, w: 0.99976164}
m_LocalRotation: {x: 0.000000015328009, y: 0.021831423, z: -0.000000014805246, w: 0.9997617}
m_LocalPosition: {x: 0.7527077, y: 0.000000009196029, z: -0.00045834482}
m_LocalScale: {x: 0.9999999, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -1290,6 +1290,8 @@ GameObject:
m_Component:
- component: {fileID: 3453975982983096240}
- component: {fileID: 7816700123729441629}
- component: {fileID: 2347288213418982541}
- component: {fileID: 3641089161220139568}
m_Layer: 0
m_Name: "\u51E4\u51F0"
m_TagString: Untagged
@@ -1305,7 +1307,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3590142514949932151}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -1315,7 +1317,7 @@ Transform:
- {fileID: 6224603219712910697}
- {fileID: 1727233940975520613}
m_Father: {fileID: 1649783502964571937}
m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!95 &7816700123729441629
Animator:
serializedVersion: 7
@@ -1338,6 +1340,46 @@ Animator:
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
--- !u!114 &2347288213418982541
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3590142514949932151}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d449242bb6214e81944862a05b7aed33, type: 3}
m_Name:
m_EditorClassIdentifier:
bones: []
bindPoses: []
rootBone: {fileID: 4586536927667645884}
--- !u!114 &3641089161220139568
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3590142514949932151}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c75c0dcb6d50eb64abd727a90406ca2b, type: 3}
m_Name:
m_EditorClassIdentifier:
_Animator: {fileID: 7816700123729441629}
_ActionOnDisable: 0
_PlayAutomatically: 1
_Animations:
- {fileID: 7400000, guid: b612aa9768334a9438221e9ef67ab618, type: 2}
- {fileID: 7400000, guid: e7ff2fce14cfa304facf9adad5a885c1, type: 2}
- {fileID: 7400000, guid: 2335e6ff21363fe4682d43a44fb4e949, type: 2}
- {fileID: 7400000, guid: 4f487a471c7278b40bcd6a5cb13032b9, type: 2}
- {fileID: 7400000, guid: f54de864134717c47a4034684dc5d443, type: 2}
- {fileID: 7400000, guid: b612aa9768334a9438221e9ef67ab618, type: 2}
- {fileID: 7400000, guid: c80c98c187e5e4f4b8720cb0817760e4, type: 2}
- {fileID: 7400000, guid: e16a16712d922464e8a9d173dacffde4, type: 2}
- {fileID: 7400000, guid: f22348ccca70b4e408607ad52dc2d01e, type: 2}
--- !u!1 &3602394898410287554
GameObject:
m_ObjectHideFlags: 0
@@ -1393,7 +1435,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3786118911675041934}
serializedVersion: 2
m_LocalRotation: {x: 0.054106675, y: -0.048505306, z: 0.6238828, w: 0.7781325}
m_LocalRotation: {x: 0.054106668, y: -0.0485053, z: 0.6238827, w: 0.7781324}
m_LocalPosition: {x: 1.4803655, y: -0.038035985, z: -0.024959266}
m_LocalScale: {x: 1, y: 0.9999999, z: 0.9999998}
m_ConstrainProportionsScale: 0
@@ -1716,7 +1758,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4424724211710365003}
serializedVersion: 2
m_LocalRotation: {x: 0.00000008940696, y: -0.01583224, z: -0.00000006705522, w: 0.99987465}
m_LocalRotation: {x: 0.00000008940697, y: -0.015832242, z: -0.000000067055225, w: 0.9998747}
m_LocalPosition: {x: 1.4131434, y: -0.00000023841852, z: 0.00000008940699}
m_LocalScale: {x: 1, y: 1.0000001, z: 0.9999999}
m_ConstrainProportionsScale: 0
@@ -1877,7 +1919,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4713013740437862723}
serializedVersion: 2
m_LocalRotation: {x: 0.1315189, y: 0.9698584, z: 0.027563425, w: 0.20326757}
m_LocalRotation: {x: 0.13151892, y: 0.96985847, z: 0.027563427, w: 0.20326759}
m_LocalPosition: {x: 0.28217787, y: 0.14113632, z: -0.10175801}
m_LocalScale: {x: 0.9999998, y: 1, z: 0.99999994}
m_ConstrainProportionsScale: 0
@@ -2066,7 +2108,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5061385977300445428}
serializedVersion: 2
m_LocalRotation: {x: 0.000000054307304, y: -0.12958188, z: 0.00000052682435, w: 0.9915687}
m_LocalRotation: {x: 0.000000054307307, y: -0.1295819, z: 0.0000005268244, w: 0.99156874}
m_LocalPosition: {x: 0.21596491, y: -0.000000013746504, z: -0.00022520378}
m_LocalScale: {x: 0.9999999, y: 1.0000001, z: 0.99999994}
m_ConstrainProportionsScale: 0
@@ -2098,7 +2140,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5127379530201908994}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalRotation: {x: -0, y: -0, z: 0.000000014901161, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -2345,7 +2387,7 @@ GameObject:
m_Component:
- component: {fileID: 4767090072160652241}
m_Layer: 0
m_Name: HH_ride
m_Name: HH_Ride
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -2518,7 +2560,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6367996995571276794}
serializedVersion: 2
m_LocalRotation: {x: 0.00000007823107, y: 0.05836964, z: -0.00000001660373, w: 0.998295}
m_LocalRotation: {x: 0.000000078231075, y: 0.058369644, z: -0.000000016603732, w: 0.99829507}
m_LocalPosition: {x: 0.9746428, y: 0.00000035762793, z: -0.0000007152559}
m_LocalScale: {x: 0.99999976, y: 0.9999999, z: 0.99999976}
m_ConstrainProportionsScale: 0
@@ -3312,7 +3354,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8731122315004283578}
serializedVersion: 2
m_LocalRotation: {x: 0.54609156, y: 0.11095586, z: -0.8185872, w: 0.13923995}
m_LocalRotation: {x: 0.5460916, y: 0.110955864, z: -0.81858724, w: 0.13923997}
m_LocalPosition: {x: -0.17678149, y: -0.22698992, z: 0.037154097}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -98,5 +98,12 @@ namespace BrewMonster
}
}
}
public void UpdateFollowObject(Transform followObject)
{
_cinemachineCamera.Follow = followObject;
_cinemachineCamera.ForceCameraPosition(followObject.position, Quaternion.identity);
orbital.HorizontalAxis.Value = 208;
orbital.VerticalAxis.Value = -268;
}
}
}
@@ -1249,10 +1249,6 @@ public static class generate_item_temp
return 0;
}
public struct PetSkill {
public int skill;
public int level;
}
public static int generate_pet_egg<RAND_CLASS>(uint id, ID_SPACE idspace, out byte[] data, out uint size, RAND_CLASS cls)
{
DATA_TYPE datatype = DATA_TYPE.DT_INVALID;
@@ -1,5 +1,5 @@
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.C2SCommand;
using CSNetwork.Protocols;
using CSNetwork.S2CCommand;
@@ -455,6 +455,10 @@ namespace BrewMonster.Scripts
{
pWorkNavigate.Finish();
}
else
{
pWorkNavigate.Cancel();
}
}
else
{
@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Globalization;
using System.Threading.Tasks;
using UnityEngine;
using CSNetwork.GPDataType;
using BrewMonster.Scripts.Task;
@@ -151,6 +152,34 @@ namespace BrewMonster.Scripts
private const string DEFAULT_FORCE_NAVIGATE_CONFIG_ADDRESS = "Assets/Addressable/force_navigate.txt";
private bool m_bConfigLoaded = false;
// Decode raw file bytes: UTF-8 (optional BOM), else strict UTF-8; on invalid UTF-8 fall back to GBK (code page 936) for legacy PC exports.
// 解码原始文件字节:UTF-8(可选 BOM),否则严格 UTF-8;非法 UTF-8 时回退到 GBK(代码页 936)以兼容老 PC 导出。
private static string DecodeNavigateConfigText(byte[] bytes)
{
if (bytes == null || bytes.Length == 0)
{
return string.Empty;
}
int offset = 0;
if (bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
{
offset = 3;
}
int len = bytes.Length - offset;
var utf8Strict = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
try
{
return utf8Strict.GetString(bytes, offset, len);
}
catch (DecoderFallbackException)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
return Encoding.GetEncoding(936).GetString(bytes, offset, len);
}
}
// Ensure default config is loaded (safe to call multiple times).
// 确保默认配置已加载(可重复调用)。
private void EnsureDefaultConfigLoaded()
@@ -184,13 +213,20 @@ namespace BrewMonster.Scripts
{
Addressables.InitializeAsync().WaitForCompletion();
var ta = Addressables.LoadAssetAsync<TextAsset>(address).WaitForCompletion();
if (ta == null || string.IsNullOrEmpty(ta.text))
if (ta == null || ta.bytes == null || ta.bytes.Length == 0)
{
Debug.LogWarning($"CECNavigateCtrl::LoadConfigAddressable, failed to load '{address}'");
return false;
}
return LoadConfigFromText(ta.text);
string text = DecodeNavigateConfigText(ta.bytes);
if (string.IsNullOrEmpty(text))
{
Debug.LogWarning($"CECNavigateCtrl::LoadConfigAddressable, decoded empty text '{address}'");
return false;
}
return LoadConfigFromText(text);
}
catch (Exception ex)
{
@@ -293,7 +329,8 @@ namespace BrewMonster.Scripts
return false;
}
string text = File.ReadAllText(filePath);
byte[] raw = File.ReadAllBytes(filePath);
string text = DecodeNavigateConfigText(raw);
return LoadConfigFromText(text);
}
catch (Exception)
@@ -318,7 +355,7 @@ namespace BrewMonster.Scripts
}
// Prepare navigation // 准备导航
public void OnPrepareNavigate(int task)
public async void OnPrepareNavigate(int task)
{
m_bForceNavigateState = true;
m_taskID = task;
@@ -329,27 +366,18 @@ namespace BrewMonster.Scripts
INFO naviInfo = new INFO();
if (GetNavigateInfo(task, ref naviInfo))
{
Debug.Log($"CECNavigateCtrl::OnPrepareNavigate, GetNavigateInfo: {task} success");
m_curNavigateInfo = naviInfo;
// Set navigate model file // 设置导航模型文件
CECHostNavigatePlayer player = m_pHost != null ? m_pHost.GetNavigatePlayer() : null;
if (player != null)
{
player.SetNavigateModelFile(m_curNavigateInfo.strModelPath);
player.Init();
}
CECHostNavigatePlayer player = m_pHost.GetNavigatePlayer();
player.SetNavigateModelFile(m_curNavigateInfo.strModelPath);
await player.Init();
}
else
{
// Give up task if no navigation info found // 如果找不到导航信息则放弃任务
if (m_pHost != null && m_pHost.GetTaskInterface() != null)
{
m_pHost.GetTaskInterface().GiveUpTask((uint)m_taskID);
}
m_pHost.GetTaskInterface().GiveUpTask((uint)m_taskID);
}
//TODO: Refine Logic.
//This is work around. It need to create a clone and make it do the animation.
m_pHost.OnNaviageEvent(task,(int)CECNavigateCtrl.NavigateEvent.EM_BEGIN);
}
// Begin navigation // 开始导航
@@ -403,6 +431,7 @@ namespace BrewMonster.Scripts
if (m_pHost != null && m_pHost.GetWorkMan() != null)
{
m_pHost.GetWorkMan().FinishRunningWork(CECHPWork.Host_work_ID.WORK_FORCENAVIGATEMOVE);
CameraController.Instance.UpdateFollowObject(m_pHost.PointCam);
}
// TODO: Implement UI helper
// CECUIHelper::GetGameUIMan()->SetShowAllPanlesFlag(true);
@@ -567,8 +596,8 @@ namespace BrewMonster.Scripts
CECHostNavigatePlayer pClone = m_pHost.GetNavigatePlayer();
if (pClone != null)
{
pClone.SetPos(vCurPos);
pClone.SetPos(new Vector3(vCurPos.x, vCurPos.y, vCurPos.z));
pClone.SetDirAndUp(new A3DVECTOR3(vDir.x, vDir.y, vDir.z), new A3DVECTOR3(vUp.x, vUp.y, vUp.z));
if(pNaviCtrl.GetCurrentNavigateInfo().bezierDir)
{
pClone.ChangeModelMoveDirAndUp(vDir, vUp);
@@ -1016,86 +1045,7 @@ namespace BrewMonster.Scripts
public bool GetLoopFlag() { return m_bLoop; }
}
// CECHostNavigatePlayer class - Basic implementation for navigation player // CECHostNavigatePlayer类 - 导航玩家的基本实现
public class CECHostNavigatePlayer
{
private CECNavigateCtrl m_pNavigateCtrl; // Force navigate // 强制导航
private CECHostPlayer m_pHost = null; // Reference to host player // 对宿主玩家的引用
public CECHostNavigatePlayer(CECHostPlayer pHost)
{
// Initialize navigate control // 初始化导航控制
m_pHost = pHost;
m_pNavigateCtrl = new CECNavigateCtrl(pHost);
}
public A3DVECTOR3 GetDir()
{
if (m_pHost != null)
{
// Get direction from host's transform // 从宿主的变换获取方向
Transform hostTransform = m_pHost.transform;
if (hostTransform != null)
{
Vector3 forward = hostTransform.forward;
return new A3DVECTOR3(forward.x, forward.y, forward.z);
}
}
return new A3DVECTOR3(0, 0, 1);
}
public void SetPos(A3DVECTOR3 vPos)
{
if (m_pHost != null)
{
// Actually move the host player // 实际移动宿主玩家
Vector3 newPos = new Vector3(vPos.x, vPos.y, vPos.z);
m_pHost.SetPos(newPos);
}
}
public void ChangeModelMoveDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp)
{
if (m_pHost != null && m_pHost.transform != null)
{
// Update host's rotation based on direction // 根据方向更新宿主的旋转
Vector3 dir = new Vector3(vDir.x, vDir.y, vDir.z);
Vector3 up = new Vector3(vUp.x, vUp.y, vUp.z);
if (dir.magnitude > 0.01f)
{
Quaternion rotation = Quaternion.LookRotation(dir, up);
m_pHost.transform.rotation = rotation;
}
}
}
public void SetNavigateModelFile(string szFile) { } // Stub
public bool Init() { return true; } // Stub
public CECNavigateCtrl GetNavigateCtrl() { return m_pNavigateCtrl; }
// Handle navigation event // 处理导航事件
public void OnNavigateEvent(int task, int e)
{
if (m_pNavigateCtrl == null)
{
return;
}
if (e == (int)CECNavigateCtrl.NavigateEvent.EM_PREPARE)
{
m_pNavigateCtrl.OnPrepareNavigate(task);
}
else if (e == (int)CECNavigateCtrl.NavigateEvent.EM_BEGIN)
{
m_pNavigateCtrl.OnBeginNavigate();
}
else if (e == (int)CECNavigateCtrl.NavigateEvent.EM_END)
{
m_pNavigateCtrl.OnEndNavigate();
}
}
}
//////////////////////////////////////////////////////////////////////////
//
// CECBezierPoint class - Bezier curve point // 贝塞尔曲线点类
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
namespace BrewMonster.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// C# mirror of C++ CECInventory (EC_Inventory.h / EC_Inventory.cpp).
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Arrow item class (cac loai mui ten)
@@ -62,7 +62,7 @@ using BrewMonster.Scripts;
// ///////////////////////////////////////////////////////////////////////////
#endregion
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Weapon item class (cac loai vu khi)
@@ -62,7 +62,7 @@ using BrewMonster.Scripts;
// ///////////////////////////////////////////////////////////////////////////
#endregion
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Armor item class (Mu + Ao + Quan + Giay) / Armor item class (Helmet + Armor + Pants + Boots)
@@ -1,6 +1,6 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrArmorrune : EC_IvtrItem
{
@@ -40,7 +40,7 @@ using BrewMonster.Scripts;
using System.Runtime.InteropServices;
using System;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Auto HP item class (tu dong hoi mau). This is a part of CEC_IvtrEquipMatter(C++)
@@ -40,7 +40,7 @@ using BrewMonster.Scripts;
using System.Runtime.InteropServices;
using System;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Auto MP item class (tu dong hoi mana). This is a part of CEC_IvtrEquipMatter(C++)
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrBible : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrCertificate : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrCongregate : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrDamagerune : EC_IvtrItem
{
@@ -37,7 +37,7 @@ using System.Collections.Generic;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Decoration item class (boi + nhan + ) / Decoration item class (various types of decorations)
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrDestroyingEssence : EC_IvtrItem
{
@@ -1,6 +1,6 @@
using BrewMonster;
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrDoubleExp : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrDyeTicket : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrDynSkillEquip : EC_IvtrEquip
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrElement : EC_IvtrItem
{
@@ -14,7 +14,7 @@ using System.Text.RegularExpressions;
using System.Reflection;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Equipment item class that handles all equipment-specific functionality
@@ -496,6 +496,7 @@ namespace PerfectWorld.Scripts.Managers
m_strDesc = oldDesc;
return result;
}
public ushort GetStoneMask() { return StoneMask; }
private static object TryFindElementByScanningArraysLocal(object edm, uint id)
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrFacePill : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrFaceTicket : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrFactionMaterial : EC_IvtrItem
{
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrFashion : EC_IvtrEquip
{
@@ -115,6 +115,7 @@ namespace PerfectWorld.Scripts.Managers
{
return new Color(((color & (0x1f << 10)) >> 7), ((color & (0x1f << 5)) >> 2), ((color & 0x1f) << 3));
}
public ushort GetWordColor() { return m_wColor; }
public string GetSubTypeName()
{
// Try Unicode first (for Vietnamese/wide char names), then fallback to CP936
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrFirework : EC_IvtrItem
{
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrForceToken : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrGeneralCard : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrGeneralCardDice : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrGmGenerator : EC_IvtrItem
{
@@ -14,7 +14,7 @@ using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Skills;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// The goblin item class (cac loai tinh linh).(not completed, need generate class).
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrGoblinEquip : EC_IvtrEquip
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrGoblinExpPill : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrIncSkillAbility : EC_IvtrItem
{
@@ -7,10 +7,9 @@ using BrewMonster;
using ModelRenderer.Scripts.Common;
using ModelRenderer.Scripts.GameData;
using UnityEngine;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
namespace BrewMonster.Scripts.Managers
namespace BrewMonster.Scripts
{
// NOTE: The original lightweight EC_IvtrItem packet struct has been merged into the
// EC_IvtrItem class below (which mirrors C++ CECIvtrItem). Network-only fields such as
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrLookInfoItem : EC_IvtrItem
{
@@ -4,7 +4,7 @@ using BrewMonster.Scripts;
using ModelRenderer.Scripts.GameData;
using ModelRenderer.Scripts.Common;
using BrewMonster.Network;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrMaterial : EC_IvtrItem
{
@@ -5,7 +5,7 @@ using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Medicine item class (cac loai thuoc).
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrMoneyConvertible : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrMonsterSpirit : EC_IvtrItem
{
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public struct PETSKILL
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrPetFaceTicket : EC_IvtrItem
{
@@ -13,7 +13,7 @@ using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
using BrewMonster.Scripts.Pet;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrPetFood : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrRecipe : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrRefineTicket : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrRevScroll : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrSharpener : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrShopToken : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrSkillMat : EC_IvtrItem
{
@@ -11,7 +11,7 @@ using PerfectWorld.Scripts.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Skill tome item class(sach ky nang). This is a part of CEC_IvtrScroll(C++)
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrSpeaker : EC_IvtrItem
{
@@ -2,7 +2,7 @@ using BrewMonster;
using BrewMonster.Scripts.Managers;
using ModelRenderer.Scripts.GameData;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrStone : EC_IvtrItem
{
@@ -1,6 +1,6 @@
using BrewMonster;
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrTargetItem : EC_IvtrItem
{
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Task Dice Item (Tui qua random).
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrTaskItem : EC_IvtrItem
{
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Task Normal Matter Item.(non interactable quest item). it is a part of IvtrTaskItem(C++)
@@ -1,6 +1,6 @@
using BrewMonster;
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrTossMat : EC_IvtrItem
{
@@ -4,7 +4,7 @@ using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Town scroll item class (hoi thanh phu). It is a part of EC_IvtrScroll(c++)
@@ -4,7 +4,7 @@ using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
/// <summary>
/// Transmit scroll item(Da dich chuyen). It is a part of EC_IvtrConsume(c++)
@@ -4,7 +4,7 @@ using UnityEngine;
using ModelRenderer.Scripts.GameData;
using BrewMonster;
namespace BrewMonster.Scripts.Managers
namespace BrewMonster.Scripts
{
public enum IndexOfIteminEquipmentInventory : byte
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrUnionscroll : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrUniversalToken : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrUnknown : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrWarTankCallin : EC_IvtrItem
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrWeddingBookCard : EC_IvtrEquip
{
@@ -1,5 +1,5 @@
using BrewMonster.Scripts.Managers;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrWeddingInviteCard : EC_IvtrEquip
{
@@ -12,7 +12,7 @@ using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using System.Runtime.InteropServices;
namespace PerfectWorld.Scripts.Managers
namespace BrewMonster.Scripts
{
public class EC_IvtrWing : EC_IvtrEquip
@@ -2,6 +2,7 @@ using System.Collections;
using System.Threading.Tasks;
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using CSNetwork.Protocols;
using PerfectWorld.Scripts;
@@ -13,7 +14,7 @@ using UnityEngine;
//
///////////////////////////////////////////////////////////////////////////
public partial class CECObject : MonoBehaviour
public partial class CECObject : MonoBehaviour, ITickable
{
protected static int ALPHA_HASH = Shader.PropertyToID("_Alpha");
protected Quaternion targetRotation;
@@ -76,6 +77,7 @@ public partial class CECObject : MonoBehaviour
public virtual void SetUpCECObject()
{
TickInvoker.Instance.RegisterTickable(this);
m_dwBornStamp = 0;
m_bBornInSight = false;
//m_bSelectable = false;
@@ -85,7 +87,7 @@ public partial class CECObject : MonoBehaviour
public void SetSelectable(bool bSelectable) { m_bSelectable = bSelectable; }
// Tick routine
public bool Tick(float dwDeltaTime)
public virtual bool Tick(uint dwDeltaTime)
{
if (m_bAdjustOrient)
AdjustOrientation(dwDeltaTime);
@@ -116,6 +118,9 @@ public partial class CECObject : MonoBehaviour
m_bAdjustOrient = false;
}
// Set destination orientation of model
public virtual void SetDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp){
SetDirAndUp(EC_Utility.ToVector3(vDir), EC_Utility.ToVector3(vUp));
}
public void SetDestDirAndUp(A3DVECTOR3 vDir, Vector3 vUp, float dwTime)
{
m_bAdjustOrient = true;
+516 -25
View File
@@ -32,7 +32,7 @@ namespace BrewMonster
private static PLAYER_ACTION[] _default_actions;
[ResetStatic]
private static PLAYER_ACTION[] _turning_actions;
PLAYER_ACTION[] m_PlayerActions;
protected PLAYER_ACTION[] m_PlayerActions;
[SerializeField] internal INFO m_PlayerInfo;
public CECModel m_pPlayerCECModel;
protected GameObject m_pPlayerModel => m_pPlayerCECModel.m_pPlayerModel;
@@ -66,6 +66,7 @@ namespace BrewMonster
public bool m_bInSanctuary = true;
public A3DAABB m_aabbServer = new A3DAABB(); // Óë·þÎñÆ÷±£³ÖÒ»ÖµÄaabb£¬ ²»ÊÜËõ·ÅÓ°Ïì
public A3DAABB m_aabb = new A3DAABB(); // Player's aabb£¬ÓÃÓÚÏÔʾµÄaabb£¬ÊÜËõ·ÅÓ°Ïì
protected bool m_bCastShadow; // flag indicates whether it will cast shadow
public int m_iProfession; // Profession
public float m_fScaleBySkill;
public int m_iGender; // Gender
@@ -75,7 +76,7 @@ namespace BrewMonster
public uint[] m_aExtStatesShown = new uint[OBJECT_EXT_STATE_COUNT]; // Visible extend states currently shown
private QueueActionEvent queueActionEvent;
protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp;
private CECPlayerActionController m_pActionController;
protected CECPlayerActionController m_pActionController;
protected enumWingType m_wingType = enumWingType.WINGTYPE_FLYSWORD;
protected int m_idCurSkillTarget;
protected CECSkill m_pCurSkill;
@@ -102,7 +103,7 @@ namespace BrewMonster
protected bool m_bAboutToDie = false;
public bool m_bCandHangerOn = false;
public bool m_bPetInSanctuary = false; // true, the pet pet of the player is in sanctuary
//The ID of the currently summoned pet
//The ID of the currently summoned pet
protected int m_idCurPet = 0;
public List<IconState> m_aIconStates = new List<IconState>();
protected byte m_byPariahLvl = 0; // Pariah level
@@ -114,9 +115,9 @@ namespace BrewMonster
// ÒÀ¸½ÀàÐÍ
AttachMode m_AttachMode = AttachMode.enumAttachNone;
// ÒÀ¸½Õß»ò±»ÒÀ¸½Õßid
protected int m_iBuddyId;
protected int m_iBuddyId;
protected int m_idCandBuddy; // ID of candidate buddy
EC_ManPlayer m_pPlayerMan => EC_ManMessageMono.Instance?.GetECManPlayer; // Player manager
protected EC_ManPlayer m_pPlayerMan => EC_ManMessageMono.Instance?.GetECManPlayer; // Player manager
protected Transform playerTransform => _objectTransform ??= transform;
protected Transform m_HH_chibang = null;
@@ -292,6 +293,7 @@ namespace BrewMonster
protected GameObject GetDummyModel(int i) => (i!=(int)PLAYERMODEL_TYPE.PLAYERMODEL_MAJOR&&i<(int)PLAYERMODEL_TYPE.PLAYERMODEL_MAX) ? m_pModels[i]:null;
protected GameObject GetMajorModel() => m_pModels[(int)PLAYERMODEL_TYPE.PLAYERMODEL_MAJOR];
protected GameObject GetPetModel() => m_pPetModel;
protected CECModel GetPlayerModel() => m_pPlayerCECModel;
protected const int OBJECT_EXT_STATE_COUNT = 6;
protected bool IsMajorModel(GameObject pModel) => GetMajorModel() != null && pModel == GetMajorModel();
public enum WeaponHangerPosition
@@ -311,7 +313,13 @@ namespace BrewMonster
/// <summary>This function will get the coressponding model player for the player based on the profession and gender </summary>
public async Task SetPlayerModel(byte profession, byte gender)
{
parentModel = transform.GetChild(0);
// PC prefab used first child as model root; runtime spawns may have no children — avoid GetChild(0) OOB.
// PC 预制体用第一个子物体作模型根;运行时生成可能没有子物体 — 避免 GetChild(0) 越界
if (transform.childCount > 0)
parentModel = transform.GetChild(0);
else
parentModel = transform;
txtName = GetComponentInChildren<TextMeshProUGUI>();
if (transform.childCount >= 3)
{
@@ -580,7 +588,7 @@ namespace BrewMonster
}
return result;
}
bool IsShapeModelChanged()
protected virtual bool IsShapeModelChanged()
{
return m_pModels[(int)PLAYERMODEL_TYPE.PLAYERMODEL_MAJOR] != m_pPlayerModel;
}
@@ -2966,7 +2974,7 @@ namespace BrewMonster
}
}
public void SetPos(Vector3 pos)
public virtual void SetPos(Vector3 pos)
{
playerTransform.position = pos;
@@ -3123,30 +3131,201 @@ namespace BrewMonster
return result;
}
protected bool LoadPlayerSkeleton(bool bAtOnce)
protected async Task<bool> LoadPlayerSkeleton(bool bAtOnce)
{
EC_PLAYERLOADRESULT Ret = default;
if (bAtOnce /*|| !IsLoadThreadReady()*/)
int[] aEnabledEquips = new int[InventoryConst.SIZE_ALL_EQUIPIVTR];
for (int i = 0; i < InventoryConst.SIZE_ALL_EQUIPIVTR; i++)
{
// Under normal circumstances, only HostPlayer can reach here
/* if (!LoadPlayerModel(m_iProfession, m_iGender, m_CustomizeData.bodyID, aEquips, szPetPath, Ret, false, false))
{
a_LogOutput(1, "CECPlayer::Init, failed to call LoadPlayerModel() !");
return false;
}*/
SetPlayerLoadedResult(Ret);
/* if (IsShapeChanged() && !QueueLoadDummyModel(m_iShape, true))
{
// ignore the dummy model loading failure
a_LogOutput(1, "CECPlayer::Init, failed to call QueueLoadDummyModel() !");
}*/
// TODO: m_i64EquipDisabled — zero slot when disabled: ((1L << i) & m_i64EquipDisabled) != 0 ? 0 : m_aEquips[i]
aEnabledEquips[i] = m_aEquips[i];
}
string szPetPath = null;
if (m_RidingPet.id != 0)
szPetPath = GetRidingPetFileName(m_RidingPet.id);
int[] aEquips = new int[InventoryConst.IVTRSIZE_EQUIPPACK];
uint EquipMask = 0;
if (aEnabledEquips[InventoryConst.EQUIPIVTR_WEAPON] > 0)
EquipMask |= 1 << InventoryConst.EQUIPIVTR_WEAPON;
if (aEnabledEquips[InventoryConst.EQUIPIVTR_FASHION_WEAPON] > 0)
EquipMask |= 1 << InventoryConst.EQUIPIVTR_FASHION_WEAPON;
Array.Copy(aEnabledEquips, aEquips, InventoryConst.IVTRSIZE_EQUIPPACK);
DecideWeaponLoad(aEquips, EquipMask);
// Same pipeline as SetPlayerModel / TransformShape: NPCManager model load + optional pet + dummy shape.
int shapeSnapshot = m_iShape;
try
{
await SetPlayerModel((byte)m_iProfession, (byte)m_iGender);
}
catch (Exception ex)
{
BMLogger.LogError($"CECPlayer::LoadPlayerSkeleton, SetPlayerModel failed: {ex.Message}");
return false;
}
SetPlayerLoadedResult(default(EC_PLAYERLOADRESULT));
if (!string.IsNullOrEmpty(szPetPath))
{
GameObject petGo = await LoadPetModel(szPetPath);
SetPetLoadResult(petGo);
}
if (shapeSnapshot != 0 && !await QueueLoadDummyModel(shapeSnapshot, bAtOnce))
{
BMLogger.LogError("CECPlayer::LoadPlayerSkeleton, failed to call QueueLoadDummyModel() !");
return false;
}
BMLogger.Log($"CECPlayer::LoadPlayerSkeleton completed, shapeSnapshot: {shapeSnapshot}");
return true;
}
void DecideWeaponLoad(int[] pEquipmentID, uint Mask)
{
bool bNormalWeaponChanged = ((1 << InventoryConst.EQUIPIVTR_WEAPON) & Mask) != 0;
bool bFashionWeaponChanged = ((1 << InventoryConst.EQUIPIVTR_FASHION_WEAPON) & Mask) != 0;
WEAPON_ESSENCE pWeapon = new WEAPON_ESSENCE();
FASHION_ESSENCE pFashion = new FASHION_ESSENCE();
WEAPON_SUB_TYPE pSubType = new WEAPON_SUB_TYPE();
int[] Index = {InventoryConst.EQUIPIVTR_WEAPON, InventoryConst.EQUIPIVTR_FASHION_WEAPON};
for (int i = 0; i < 2; ++i)
{
int idEquipment = pEquipmentID[Index[i]];
idEquipment &= 0x0000ffff;
DATA_TYPE dt = DATA_TYPE.DT_INVALID;
if (idEquipment != 0)
{
var pEquip =ElementDataManProvider.GetElementDataMan().get_data_ptr( // TODO: Implement this
(uint)idEquipment,
ID_SPACE.ID_SPACE_ESSENCE,
ref dt);
if (dt == DATA_TYPE.DT_WEAPON_ESSENCE)
{
pWeapon = (WEAPON_ESSENCE)pEquip;
pSubType =(WEAPON_SUB_TYPE)ElementDataManProvider.GetElementDataMan().get_data_ptr(
pWeapon.id_sub_type,
ID_SPACE.ID_SPACE_ESSENCE,
ref dt);
if (dt != DATA_TYPE.DT_WEAPON_SUB_TYPE) pSubType = new WEAPON_SUB_TYPE();
}
else if (dt == DATA_TYPE.DT_FASHION_ESSENCE) pFashion = (FASHION_ESSENCE)pEquip;
}
}
// bool bCanShowFashionWeaponBefore = CanShowFashionWeapon((int)m_uAttackType, m_iFashionWeaponType);
// bool bCanShowFashionWeapon = false;
//var pGameUI = GameUIManagerProvider.GetGameUIManager().GetInGameUIMan();
// ͨı
// if (bNormalWeaponChanged)
// {
// // ʱװı
// if (bFashionWeaponChanged)
// {
// // װʱװͨ
// if (pSubType != null && pFashion != null)
// {
// if (CanShowFashionWeapon((int)pSubType.action_type, (int)pFashion.action_type))
// {
// CLEAR_WEAPON(InventoryConst.EQUIPIVTR_WEAPON);
// }
// else
// {
// CLEAR_WEAPON(InventoryConst.EQUIPIVTR_FASHION_WEAPON);
// }
// }
// // װͨ
// else if(pSubType && !pFashion)
// {
// }
// // װʱװ
// else if (!pSubType && pFashion)
// {
// if (CanShowFashionWeapon(m_uAttackType, pFashion->action_type))
// {
// CLEAR_WEAPON(EQUIPIVTR_WEAPON);
// }
// else
// {
// CLEAR_WEAPON(EQUIPIVTR_FASHION_WEAPON);
// }
// }
// // ûװ
// else
// {
// }
// if (pSubType) RECORD_NORMAL_WEAPON(
// pWeapon->file_model_left, pWeapon->file_model_right, pSubType->action_type);
// if (pFashion) RECORD_FASHION_WEAPON(
// pFashion->file_model_left, pFashion->file_model_right, pFashion->action_type);
// }
// else
// {
// // װͨ
// if (pSubType)
// {
// bCanShowFashionWeapon = CanShowFashionWeapon(pSubType->action_type, m_iFashionWeaponType);
// if (bCanShowFashionWeapon)
// {
// CLEAR_WEAPON(EQUIPIVTR_WEAPON);
// if (!bCanShowFashionWeaponBefore)
// SET_WEAPON(EQUIPIVTR_FASHION_WEAPON, m_aEquips[EQUIPIVTR_FASHION_WEAPON]);
// }
// RECORD_NORMAL_WEAPON(
// pWeapon->file_model_left, pWeapon->file_model_right, pSubType->action_type);
// }
// // ͨ
// else
// {
// bCanShowFashionWeapon = CanShowFashionWeapon(DEFAULT_ACTION_TYPE, m_iFashionWeaponType);
// if (bCanShowFashionWeapon)
// {
// CLEAR_WEAPON(EQUIPIVTR_WEAPON);
// if (!bCanShowFashionWeaponBefore)
// SET_WEAPON(EQUIPIVTR_FASHION_WEAPON, m_aEquips[EQUIPIVTR_FASHION_WEAPON]);
// }
// RECORD_NORMAL_WEAPON((char*)NULL, (char*)NULL, DEFAULT_ACTION_TYPE);
// }
// }
// }
// else if (bFashionWeaponChanged)
// {
// // װʱװ
// if (pFashion)
// {
// bCanShowFashionWeapon = CanShowFashionWeapon(m_uAttackType, pFashion->action_type);
// if (!bCanShowFashionWeapon)
// {
// if (pGameUI && this == g_pGame->GetGameRun()->GetHostPlayer() && InFashionMode())
// pGameUI->AddChatMessage(pGameUI->GetStringFromTable(906), GP_CHAT_SYSTEM);
// CLEAR_WEAPON(EQUIPIVTR_FASHION_WEAPON);
// if (bCanShowFashionWeaponBefore)
// SET_WEAPON(EQUIPIVTR_WEAPON, m_aEquips[EQUIPIVTR_WEAPON]);
// }
// // ʾʱװ˴Ҫm_stoneWeapon
// else CLEAR_WEAPON(EQUIPIVTR_WEAPON);
// RECORD_FASHION_WEAPON(
// pFashion->file_model_left, pFashion->file_model_right, pFashion->action_type);
// }
// // ʱװ
// else
// {
// if (0 != m_aEquips[EQUIPIVTR_WEAPON])
// {
// CLEAR_WEAPON(EQUIPIVTR_FASHION_WEAPON);
// if (bCanShowFashionWeaponBefore)
// SET_WEAPON(EQUIPIVTR_WEAPON, m_aEquips[EQUIPIVTR_WEAPON]);
// }
// RECORD_FASHION_WEAPON((char*)NULL, (char*)NULL, DEFAULT_ACTION_TYPE);
// }
// }
// if (bCanShowFashionWeaponBefore && !bCanShowFashionWeapon
// && pGameUI && !bFashionWeaponChanged && bNormalWeaponChanged && this == g_pGame->GetGameRun()->GetHostPlayer())
// pGameUI->AddChatMessage(pGameUI->GetStringFromTable(906), GP_CHAT_SYSTEM);
}
protected bool SetPlayerLoadedResult(EC_PLAYERLOADRESULT ret)
{
OnAllResourceReady();
@@ -3171,6 +3350,318 @@ namespace BrewMonster
else
m_dwResFlags &= ~dwFlag;
}
public virtual void Release()
{
//TODO: Implement this latter
// DetachBuddy();
// // Clear extend states before model is released
// ClearShowExtendStates();
// ::memset(m_aExtStates, 0, sizeof(m_aExtStates));
// m_aIconStates.clear();
// if (m_pPateName)
// {
// delete m_pPateName;
// m_pPateName = NULL;
// }
// if (m_pPateMarry)
// {
// delete m_pPateMarry;
// m_pPateMarry = NULL;
// }
// if (m_pPateForce)
// {
// delete m_pPateForce;
// m_pPateForce = NULL;
// }
// if (m_pPateTitle)
// {
// delete m_pPateTitle;
// m_pPateTitle = NULL;
// }
// if (m_pPateLastWords1)
// {
// delete m_pPateLastWords1;
// m_pPateLastWords1 = NULL;
// }
// if (m_pPateLastWords2)
// {
// delete m_pPateLastWords2;
// m_pPateLastWords2 = NULL;
// }
// if (m_pPateTeamReq)
// {
// delete m_pPateTeamReq;
// m_pPateTeamReq = NULL;
// }
// if (m_pPateBooth)
// {
// delete m_pPateBooth;
// m_pPateBooth = NULL;
// }
// if (m_pPateFaction)
// {
// delete m_pPateFaction;
// m_pPateFaction = NULL;
// }
// if (m_pFactionDecal)
// {
// delete m_pFactionDecal;
// m_pFactionDecal = NULL;
// }
// if (m_pPateCountry)
// {
// delete m_pPateCountry;
// m_pPateCountry = NULL;
// }
// if (m_pCountryDecal)
// {
// delete m_pCountryDecal;
// m_pCountryDecal = NULL;
// }
// if (m_pBubbleTexts)
// {
// delete m_pBubbleTexts;
// m_pBubbleTexts = NULL;
// }
// if (m_pLevelUpGFX)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pLevelUpGFX);
// m_pLevelUpGFX = NULL;
// }
// if (m_pPetCureGFX)
// {
// A3DGFXExMan *pGFXExMan = g_pGame->GetA3DGFXExMan();
// if (pGFXExMan)
// pGFXExMan->CacheReleasedGfx(m_pPetCureGFX);
// m_pPetCureGFX = NULL;
// m_pPetCureGFXtate = -1;
// }
// for (int i = 0; i < sizeof(m_pMonsterSpiritGFX) / sizeof(m_pMonsterSpiritGFX[0]); ++i) {
// A3DGFXExMan *pGFXExMan = g_pGame->GetA3DGFXExMan();
// if (pGFXExMan)
// pGFXExMan->CacheReleasedGfx(m_pMonsterSpiritGFX[i]);
// m_pMonsterSpiritGFX[i] = NULL;
// }
// if (m_pWaterWaveStill)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pWaterWaveStill);
// m_pWaterWaveStill = NULL;
// }
// if (m_pWaterWaveMove)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pWaterWaveMove);
// m_pWaterWaveMove = NULL;
// }
// if (m_pAirBubble)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pAirBubble);
// m_pAirBubble = NULL;
// }
// if (m_pSwimBubble)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pSwimBubble);
// m_pSwimBubble = NULL;
// }
// if (m_pTransformGfx)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pTransformGfx);
// m_pTransformGfx = NULL;
// }
// if (m_pDuelStateGFX)
// {
// g_pGame->GetGFXCaster()->ReleaseGFXEx(m_pDuelStateGFX);
// m_pDuelStateGFX = NULL;
// }
// if (m_pPetModel)
// {
// m_pPetModel->RemoveChildModel(_hanger_ride, false);
// A3DRELEASE(m_pPetModel);
// }
// ClearBoothModel();
// for (MOEffectMAP::iterator it = m_mapMOEffect.begin();it != m_mapMOEffect.end();++it)
// {
// A3DGFXExMan *pGFXExMan = g_pGame->GetA3DGFXExMan();
// pGFXExMan->CacheReleasedGfx(it->second);
// }
// m_mapMOEffect.clear();
// // Release face model
// ReleaseFaceModel();
// // Release player model
// ReleasePlayerModel();
// // Clear resource ready flags
// SetResReadyFlag(RESFG_ALL, false);
// m_bAboutToDie = false;
}
public void CloneSimplePropertyTo(CECPlayer player)
{
//TOdo: Complete this function(remove all commented code)
player.transform.position = m_pPlayerModel.transform.position;
player.transform.rotation = m_pPlayerModel.transform.rotation;
player.SetGroundNormal(GetGroundNormal());
player.SetUseGroundNormal(GetUseGroundNormal());
// CECPlayer
player.m_PlayerInfo = GetPlayerInfo();
player.SetBornStamp(GetBornStamp());
player.name = GetName();
//player.SetProps(&GetBasicProps(), &GetExtendProps());
player.m_iGender = GetGender();
player.m_iProfession = GetProfession();
//player.m_pvp = GetPVPInfo();
//player.m_aIconStates = GetIconStates();
player.SetMoneyAmount(GetMoneyAmount());
player.m_iMaxMoney = GetMaxMoneyAmount();
//player.m_i64EquipDisabled = m_i64EquipDisabled;
//player.SetBoothState(GetBoothState());
//player.m_factionPVPMask= m_factionPVPMask;
//player.m_RidingPet = GetRidingPetInfo();
//player.m_iBattleCamp = GetBattleCamp();
//player.m_dwGMFlags = m_dwGMFlags;
//player.SetSpouse(GetSpouse());
player.m_idForce = GetForce();
//player.SetCountry(GetCountry());
//player.SetMoveMode(GetMoveMode());
//player.SetMoveEnv(GetMoveEnv());
//player.SetWalkRunFlag(GetWalkRunFlag());
player.m_MoveConst = m_MoveConst;
player.m_aabbServer = m_aabbServer;
player.m_aabb = m_aabb;
player.m_dwStates = m_dwStates;
//player.m_dwStates2 = m_dwStates2;
player.m_fTouchRad = GetTouchRadius();
//player.m_byPariahLvl = GetPariahLevel();
//player.SetBoothName(GetBoothName());
// player.m_CustomizeFactor = m_CustomizeFactor;
// player.ChangeCustomizeData(m_CustomizeData);
// for (int i=0; i < GetEffectCount(); i++)
// player.ApplyEffect(GetEffect(i), true);
// player.SetFactionID(GetFactionID());
player.SetCurPetID(GetCurPetID());
// player.SetCurrentTitle(GetCurrentTitle());
// player.SetReputation(GetReputation());
// player.SetFashionMode(InFashionMode());
// player.SetFRoleID(GetFRoleID());
// player.SetMeridiansProp(GetMeridiansProp());
// player->SetReincarnationCount(GetReincarnationCount());
// player.SetRealmLevel(GetRealmLevel());
// player.ScaleBody(GetScaleBySkill());
// player.SetTeamRequire(GetTeamRequire(), false);
player.SetNewExtendStates(0, m_aExtStates, OBJECT_EXT_STATE_COUNT);
// player.m_GoblinRenderCnt = m_GoblinRenderCnt;
// player.m_bRenderGoblin = m_bRenderGoblin;
}
public int GetOriginalShapeID()
{
return m_iShape;
}
public async Task TransformShape(byte iShape, bool bLoadAtOnce = false/* =false */)
{
SetShape(iShape);
//a_LogOutput(1, "CECPlayer::TransformShape(iShape=%d)(iShapeType=%d,iShapeID=%d)", iShape, PLAYERMODEL_GETTYPE(iShape), PLAYERMODEL_GETID(iShape));
if (!GetMajorModel()) return;
if (IsShapeChanged())
{
m_bWeaponAttached = false;
// change to a dummy model, may cause an asynchronous loading
await QueueLoadDummyModel(m_iShape, bLoadAtOnce);
}
else
{
m_bWeaponAttached = true;
// back to major model is a synchronous operation
ApplyShapeModelChange(GetMajorModel());
}
OnModelChange(GetMajorModel());
}
void SetShape(byte iShape)
{
// The shape id from the server is a 8-bit number
// The meaning of each bit:
// | 7 6 | 5 4 3 2 1 0 |
// |-TYPE-|-----Model ID-----|
int iNewShape = (iShape & 0xff); // only accept 8bit
// ԾɵShapeݽ
FixOldShapeInfo(ref iNewShape);
// ְҵModel IDҪת
if( PLAYERMODEL_GETTYPE(iNewShape) == (int)PLAYERMODEL_TYPE.PLAYERMODEL_PROFESSION )
{
int iRealID = _GetProfessionTransformModelID(
m_iProfession, m_iGender, PLAYERMODEL_GETID(iNewShape));
iNewShape = 0x40 | iRealID;
}
// ְҵModel IDΪEC_Resource.hֵʲ
else
{
}
// store the original data into 8~15 bit
m_iShape = iNewShape | ((iShape & 0xff) << 8);
}
void FixOldShapeInfo(ref int iShape)
{
// ǸʱshapeΪ0ûб0ְҵ
if(iShape != 0 && PLAYERMODEL_GETTYPE(iShape) == 0)
iShape |= 0x40;
}
public int _GetProfessionTransformModelID(int nChar, int nGender, int nModelID)
{
int result = 0;
switch (nChar){
case (int)PROFESSION.PROF_HAG: //
result = (2 == nModelID) ? (int)ModelResourceType.RES_MOD_ORC_FOX2 : (int)ModelResourceType.RES_MOD_ORC_FOX;
break;
case (int)PROFESSION.PROF_ORC: //
result = (2 == nModelID) ? (int)ModelResourceType.RES_MOD_ORC_PANDER : (int)ModelResourceType.RES_MOD_ORC_TIGER;
break;
case (int)PROFESSION.PROF_MONK: // ʦ
case (int)PROFESSION.PROF_GHOST: // ̿
result = ((int)Gender.GENDER_MALE == nGender) ? (int)ModelResourceType.RES_MOD_SHADOW_FISH_M : (int)ModelResourceType.RES_MOD_SHADOW_FISH_F;
break;
case (int)PROFESSION.PROF_YEYING: // ҹӰ
result = ((int)Gender.GENDER_MALE == nGender) ? (int)ModelResourceType.RES_MOD_YEYING_RESHAPE_M : (int)ModelResourceType.RES_MOD_YEYING_RESHAPE_F;
break;
case (int)PROFESSION.PROF_YUEXIAN: //
result = ((int)Gender.GENDER_MALE == nGender) ? (int)ModelResourceType.RES_MOD_YUEXIAN_RESHAPE_M : (int)ModelResourceType.RES_MOD_YUEXIAN_RESHAPE_F;
break;
}
return result;
}
}
public struct PlayActionEvent
@@ -363,6 +363,9 @@ public class CLuaMemTbl
public class CECModel
{
private bool m_bInheritParentId = true;
private int m_nId = 0;
public GameObject m_pPlayerModel;
private const uint COMACT_FLAG_MODE_NONE = 0;
protected CECModelStaticData m_pMapModel;
@@ -370,6 +373,8 @@ public class CECModel
private Dictionary<string, Transform> m_hookCache = new Dictionary<string, Transform>();
private Dictionary<string, CECModel> m_childModels = new Dictionary<string, CECModel>();
private Transform m_transform;
public bool InheritParentId() => m_bInheritParentId;
public void SetId(int nId) => m_nId = nId;
public void ClearComActFlag(bool bSignalCurrent) { ClearComActFlag(0, bSignalCurrent); }
public void ClearComActFlag(int nChannel, bool bSignalCurrent)
{
@@ -586,6 +591,62 @@ public class CECModel
return m_childModels.TryGetValue(hangerName, out CECModel child) ? child : null;
}
public bool AddChildModel(
string szHangerName,
bool bOnBone,
string szHookName,
CECModel pChild,
string szCCName)
{
if (m_childModels.TryGetValue(szHangerName, out _))
return false;
if (pChild == null)
{
Debug.LogError($"CECModel::AddChildModel, pChild is null");
return false;
}
Transform hook = m_skeletonBuilder.GetHook(szHookName, true);
Transform hangger = pChild.m_skeletonBuilder.GetHook(szCCName, true);
if (hook == null || hangger == null)
{
Debug.LogError($"CECModel::AddChildModel, hook or hanger missing (hook={szHookName}, cc={szCCName})");
return false;
}
// Align child CC/hanger to parent hook in world space, then parent with world pose preserved.
// 先在世界里对齐子模型挂点与父挂点,再挂接并保持世界坐标不变。
Vector3 worldAlign = hook.position - hangger.position;
pChild.transform.position += worldAlign;
pChild.transform.SetParent(hook.transform, true);
// if (m_pA3DSkinModel && pChild->m_pA3DSkinModel)
// {
// if (!m_pA3DSkinModel->AddChildModel(
// szHangerName,
// bOnBone,
// szHookName,
// pChild->m_pA3DSkinModel,
// szCCName))
// return false;
// pChild->m_pA3DSkinModel->SetAutoAABBType(A3DSkinModel::AUTOAABB_INITMESH);
// pChild->m_bLoadSkinModel = false;
// }
// pChild->m_strHookName = szHookName;
// pChild->m_strCC = szCCName;
// pChild->SetGfxUseLOD(m_bGfxUseLod, false);
// pChild->SetDisableCamShake(m_bDisableCamShake);
// pChild->SetCreatedByGfx(m_bCreatedByGfx);
if (pChild.InheritParentId())
pChild.SetId(m_nId);
m_childModels[szHangerName] = pChild;
return true;
}
public void PlayGfx(string szPath, string szHook, float fScale, bool bFadeOut, A3DVECTOR3 vOffset, float fPitch, float fYaw, float fRot, bool bUseECMHook, uint dwFadeOutTime)
{
if (!bFadeOut)
+53 -53
View File
@@ -15,7 +15,7 @@ namespace BrewMonster.Scripts.Pet
{
using PlantVec = System.Collections.Generic.List<CECPlantPetData>;
// 植物宠数据
// ֲ
//
public struct CECPlantPetData
{
@@ -46,17 +46,17 @@ namespace BrewMonster.Scripts.Pet
m_lifeTimeLeft = 0;
}
int GetLifeTime() { return m_lifeTime * 1000; } // 总存活时间(毫秒)
int GetLifeTimeLeft() { return m_lifeTimeLeft; } // 剩余存活时间(毫秒)
int GetLifeTime() { return m_lifeTime * 1000; } // ܴʱ
int GetLifeTimeLeft() { return m_lifeTimeLeft; } // ʣʱ
int m_tid; // 宠物的模板ID
public int m_nid; // 宠物的世界ID
int m_lifeTime; // 存活时间(秒数),0为永久
int m_lifeTimeLeft; // 存活时间倒计时(毫秒数)
float m_HPFactor; // 当前 HP 占总 HP 的比例
int m_HP; // 当前 HP
float m_MPFactor; // 当前 MP 占总 MP 的比例
int m_MP; // 当前 MP
int m_tid; // ģID
public int m_nid; // ID
int m_lifeTime; // ʱ
int m_lifeTimeLeft; // ʱʱ
float m_HPFactor; // ǰ HP ռ HP ı
int m_HP; // ǰ HP
float m_MPFactor; // ǰ MP ռ MP ı
int m_MP; // ǰ MP
public CECPlantPetData(int tid = 0, int nid = 0, int lifeTime = 0, int lifeTimeLeft = 0, float hPFactor = 1f, int hP = 0, float mPFactor = 1f, int mP = 0)
{
@@ -104,7 +104,7 @@ namespace BrewMonster.Scripts.Pet
public int m_iMoveMode; // Current moving mode of pet
public int m_iAttackMode; // Current attacking mode of pet
public int m_iPetLifeTime; // 当前宠物的存活期(0表示永久)
public int m_iPetLifeTime; // ǰĴڣ0ʾã
public PlantVec m_Plants;
@@ -348,7 +348,7 @@ namespace BrewMonster.Scripts.Pet
public void SetActivePetNPCID(int nid) { m_nidPet = nid; }
// 查询、设置当前宠物的生存时长
// ѯõǰʱ
public int GetActivePetLifeTime() { return m_iPetLifeTime; }
public void SetActivePetLifetime(int lifetime) { m_iPetLifeTime = lifetime; }
@@ -402,14 +402,14 @@ namespace BrewMonster.Scripts.Pet
return m_pDBEvoConfig;
}
bool CheckRebuildPetItemCond(int iPetIndex, int iSel, int type) // 宠物索引,选择的物品序号,type:0(进化),1(性格技能),2(洗髓系数)
bool CheckRebuildPetItemCond(int iPetIndex, int iSel, int type) // ѡƷţtype0(),1(Ը),2(ϴϵ)
{
CECPetData pPet = GetPetData(iPetIndex);
if (pPet == null) return false;
//int(*p)[2] = NULL;
int[,] p = null;
if (type == 0) // 进化
if (type == 0) //
{
if(pPet.GetPetEssence() != null)
{
@@ -424,7 +424,7 @@ namespace BrewMonster.Scripts.Pet
}
}
}
else if (type == 1) // 性格
else if (type == 1) // Ը
{
if (pPet.GetPetEssence() != null)
{
@@ -439,7 +439,7 @@ namespace BrewMonster.Scripts.Pet
}
}
}
else if (type == 2) // 洗髓
else if (type == 2) // ϴ
{
if (pPet.GetPetEssence() != null)
{
@@ -467,13 +467,13 @@ namespace BrewMonster.Scripts.Pet
{
// TO DO: fix later
//pGameUI.MessageBox("", pGameUI.GetStringFromTable(10110), MB_OK, A3DCOLORRGBA(255, 255, 255, 160));
return false; // 麝灵珠不够
return false; //
}
if (pack.GetItemTotalNum(12980) < p[iSel,1])
{
// TO DO: fix later
//pGameUI.MessageBox("", pGameUI.GetStringFromTable(10111), MB_OK, A3DCOLORRGBA(255, 255, 255, 160));
return false; // 乾坤石不够
return false; // Ǭʯ
}
return true;
@@ -495,35 +495,35 @@ namespace BrewMonster.Scripts.Pet
// Hunger level
public enum ePetData_HUNGER_LEVEL
{
HUNGER_LEVEL_0, // 饱食
HUNGER_LEVEL_1, // 正常
HUNGER_LEVEL_2, // 饿程度一级
HUNGER_LEVEL_0, // ʳ
HUNGER_LEVEL_1, //
HUNGER_LEVEL_2, // ̶һ
HUNGER_LEVEL_3,
HUNGER_LEVEL_4, // 饿程度二级
HUNGER_LEVEL_4, // ̶ȶ
HUNGER_LEVEL_5,
HUNGER_LEVEL_6,
HUNGER_LEVEL_7, // 饿程度三级
HUNGER_LEVEL_7, // ̶
HUNGER_LEVEL_8,
HUNGER_LEVEL_9,
HUNGER_LEVEL_10,
HUNGER_LEVEL_11, // 饿程度四级
HUNGER_LEVEL_11, // ̶ļ
HUNGER_LEVEL_COUNT,
};
// Intimacy level
public enum ePetData_INTIMACY_LEVEL
{
INTIMACY_LEVEL_0, // 野性难驯, 0-50
INTIMACY_LEVEL_1, // 反复无偿, 51-150
INTIMACY_LEVEL_2, // 乖巧听话, 151-500
INTIMACY_LEVEL_3, // 忠心耿耿, 501-999
INTIMACY_LEVEL_0, // Ұѱ, 0-50
INTIMACY_LEVEL_1, // ޳, 51-150
INTIMACY_LEVEL_2, // , 151-500
INTIMACY_LEVEL_3, // Ĺ, 501-999
INTIMACY_LEVEL_COUNT,
INTIMACY_POINT_MAX = 999,
};
// enum
// {
// MAX_SKILLNUM = 4, // 不包括性格技能
// MAX_SKILLNUM = 4, // Ը
// };
public struct PETSKILL
@@ -536,35 +536,35 @@ namespace BrewMonster.Scripts.Pet
public enum SKILLTYPE
{
EM_SKILL_DEFAULT = 0, // 不区分性格技能
EM_SKILL_NORMAL, // 普通技能
EM_SKILL_NATURE, // 性格技能
EM_SKILL_SPECIAL, // 专属技能
EM_SKILL_DEFAULT = 0, // Ը
EM_SKILL_NORMAL, // ͨ
EM_SKILL_NATURE, // Ը
EM_SKILL_SPECIAL, // ר
};
int m_iIntimacy; // 好感度
int m_iHunger; // 饥饿度
int m_tid; // 宠物的模板ID
int m_tidVis; // 宠物形象的模板ID(如果为0,则表示无特殊可见ID)
int m_idEgg; // 宠物蛋的ID
int m_iClass; // 宠物类型 战宠,骑宠,观赏宠
float m_fHPFactor; // 血量比例(复活和收回时使用) 0则为死亡
int m_iIntimacy; // øж
int m_iHunger; //
int m_tid; // ģID
int m_tidVis; // ģIDΪ0ʾɼID
int m_idEgg; // ID
int m_iClass; // սͳ
float m_fHPFactor; // Ѫջʱʹã 0Ϊ
float m_fMPFactor;
int m_iLevel; // 宠物级别
bool m_isBind; // 是否天人合一
bool m_canWebTrade; // 是否寻宝网可交易
ushort m_color; // 骑宠染色颜色,高位为1时有效
int m_iExp; // 宠物当前经验
int m_iSkillPt; // 剩余技能点
int m_iLevel; //
bool m_isBind; // Ƿ˺һ
bool m_canWebTrade; // ǷѰɽ
ushort m_color; // ȾɫɫλΪ1ʱЧ
int m_iExp; // ﵱǰ
int m_iSkillPt; // ʣܵ
string m_strName;
int m_iHP; // Only fight pets have this
int m_iMP;
PETSKILL[] m_aSkills = new PETSKILL[(int)GP_PET_SKILL_NUM.GP_PET_SKILL_NUM];
List<int> m_vecNorSkillIndex = new List<int>(); // 防止性格技能和普通技能顺序混乱的情况,保存技能在 m_aSkills里的序号
List<int> m_vecNorSkillIndex = new List<int>(); // ֹԸܺͨ˳ҵ m_aSkills
List<int> m_vecDynSkillIndex = new List<int>();
int m_iSpecialSkillIndex; // 保存专属技能在m_aSkills里的序号,只有进化宠有一个此技能
int m_iSpecialSkillIndex; // רm_aSkillsţֻнһ˼
CECCounter m_cntAutoSkill = new CECCounter();
List<int> m_aAutoSkills = new List<int>();
@@ -648,7 +648,7 @@ namespace BrewMonster.Scripts.Pet
EC_Game.GetGameRun().GetUIManager().FilterBadWords(ref m_strName);
}
}
// 进化宠性格技能配置表
// Ըñ
object pDBData = pDB.get_data_ptr((uint)Info.evo_prop.nature, ID_SPACE.ID_SPACE_CONFIG, ref DataType);
PET_EVOLVED_SKILL_CONFIG? pDynSkills = null;
if (pDBData != null && DataType == DATA_TYPE.DT_PET_EVOLVED_SKILL_CONFIG)
@@ -699,7 +699,7 @@ namespace BrewMonster.Scripts.Pet
bool bNormal = true;
if (pDynSkills != null)
{
for (int j = 0; j < 2; j++) // 俩个性格技能
for (int j = 0; j < 2; j++) // Ը
{
if (pDynSkills?.skills[j].id == skill_id)
{
@@ -915,7 +915,7 @@ namespace BrewMonster.Scripts.Pet
return 0; //
}
// 获取用于显示的属性
// ȡʾ
public ROLEEXTPROP GetExtendProps() { return m_ExtProps; }
public void SetExtendProps(ROLEEXTPROP prop) { m_ExtProps = prop; }
@@ -993,7 +993,7 @@ namespace BrewMonster.Scripts.Pet
return "";
}
// 添加自动释放技能
// Զͷż
public void AddAutoSkill(int skill_id)
{
m_aAutoSkills.Add(skill_id);
@@ -0,0 +1,391 @@
using BrewMonster;
using BrewMonster.Scripts;
using System.Threading.Tasks;
using UnityEngine;
using CSNetwork.GPDataType;
using Cysharp.Threading.Tasks;
namespace BrewMonster.Scripts
{
// CECHostNavigatePlayer class - Basic implementation for navigation player // CECHostNavigatePlayer类 - 导航玩家的基本实现
public class CECHostNavigatePlayer : CECClonePlayer
{
protected CECNavigateCtrl m_pNavigateCtrl; // Force navigate // 强制导航
protected CECHostPlayer m_pHostPlayer = null; // Reference to host player // 对宿主玩家的引用
protected string m_szNavigateModelFile;
protected CECModel m_pNavigateModel;
protected CECModel playerModel;
protected bool m_bNavigateModelApplied; // Whether navigate model has been applied // 移动模型是否已应用
/// <summary>
/// MonoBehaviour must not be constructed with <c>new</c>; use <c>AddComponent</c> then call this.
/// MonoBehaviour 不能用 <c>new</c> 构造;请用 <c>AddComponent</c> 再调用本方法。
/// </summary>
public void InitializeHost(CECHostPlayer pHost)
{
m_szNavigateModelFile = null;
m_bNavigateModelApplied = false;
m_pNavigateModel = null;
m_iCID = (int)Class_ID.OCID_CLONED_PLAYER;
m_bCastShadow = true;
m_bShowCustomize = true;
m_pHostPlayer = pHost;
m_pNavigateCtrl = pHost != null ? new CECNavigateCtrl(pHost) : null;
}
public A3DVECTOR3 GetDir()
{
if (m_pHostPlayer != null)
{
// Get direction from host's transform // 从宿主的变换获取方向
Transform hostTransform = m_pHostPlayer.transform;
if (hostTransform != null)
{
Vector3 forward = hostTransform.forward;
return new A3DVECTOR3(forward.x, forward.y, forward.z);
}
}
return new A3DVECTOR3(0, 0, 1);
}
public A3DVECTOR3 GetUp()
{
Transform hostTransform = m_pHostPlayer.transform;
if (hostTransform != null)
{
Vector3 up = hostTransform.up;
return new A3DVECTOR3(up.x, up.y, up.z);
}
return new A3DVECTOR3(0, 1, 0);
}
public void ChangeModelMoveDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp)
{
if (m_pHostPlayer != null && m_pHostPlayer.transform != null)
{
// Update host's rotation based on direction // 根据方向更新宿主的旋转
Vector3 dir = new Vector3(vDir.x, vDir.y, vDir.z);
Vector3 up = new Vector3(vUp.x, vUp.y, vUp.z);
if (dir.magnitude > 0.01f)
{
Quaternion rotation = Quaternion.LookRotation(dir, up);
m_pHostPlayer.transform.rotation = rotation;
}
}
}
public void SetNavigateModelFile(string szFile)
{
m_szNavigateModelFile = szFile;
}
public CECNavigateCtrl GetNavigateCtrl() { return m_pNavigateCtrl; }
// Handle navigation event // 处理导航事件
public void OnNavigateEvent(int task, int e)
{
if (m_pNavigateCtrl == null)
{
return;
}
if (e == (int)CECNavigateCtrl.NavigateEvent.EM_PREPARE)
{
m_pNavigateCtrl.OnPrepareNavigate(task);
}
else if (e == (int)CECNavigateCtrl.NavigateEvent.EM_BEGIN)
{
m_pNavigateCtrl.OnBeginNavigate();
}
else if (e == (int)CECNavigateCtrl.NavigateEvent.EM_END)
{
m_pNavigateCtrl.OnEndNavigate();
}
}
public bool LoadConfig()
{
m_pNavigateCtrl = new CECNavigateCtrl(m_pHostPlayer);
if (m_pNavigateCtrl != null)
return m_pNavigateCtrl.LoadConfig("configs\\force_navigate.txt");
else
{
BMLogger.LogError("CECHostNavigatePlayer::Init, Failed to load config.");
}
return false;
}
public override CECModel GetRenderModel()
{
return m_pNavigateModel != null ? m_pNavigateModel : base.GetRenderModel();
}
public bool IsNavigateMoving()
{
if (m_pNavigateCtrl != null && m_pNavigateCtrl.GetBezierWalker() != null)
return m_pNavigateCtrl.GetBezierWalker().IsWalking();
return false;
}
public override void Release()
{
TeardownNavigatePlayerVisual();
base.Release();
if (m_pNavigateModel != null && m_pNavigateModel.m_pPlayerModel != null)
{
Transform hhRide = m_pNavigateModel.m_pPlayerModel.transform.Find("HH_ride");
if (hhRide != null)
{
Destroy(hhRide.gameObject);
}
Destroy(m_pNavigateModel.m_pPlayerModel);
m_pNavigateModel = null;
}
if (m_pNavigateCtrl != null)
{
m_pNavigateCtrl = null;
}
m_bNavigateModelApplied = false;
TickInvoker.Instance.UnregisterTickable(this);
}
/// <summary>
/// Load optional force-navigate dummy model via Addressables, then clone host visuals.
/// 通过 Addressables 加载可选的强制导航替身模型,再克隆宿主外观。
/// </summary>
public async Task<bool> Init()
{
if (m_pHostPlayer == null)
{
return false;
}
int debugStep = 0;
m_bNavigateModelApplied = false;
// Load navigate model // 加载导航模型
if (!string.IsNullOrEmpty(m_szNavigateModelFile))
{
if (m_pNavigateModel != null)
{
if (m_pNavigateModel.m_pPlayerModel != null)
{
Transform hhRide = m_pNavigateModel.m_pPlayerModel.transform.Find("HH_ride");
if (hhRide != null)
foreach (Transform child in hhRide)
{
Destroy(child.gameObject);
}
Destroy(m_pNavigateModel.m_pPlayerModel);
}
m_pNavigateModel = null;
}
string address = AFile.NormalizePath(m_szNavigateModelFile.ToLower(), true);
GameObject prefab = await AddressableManager.Instance.LoadPrefabAsync(address);
if (prefab == null)
{
BMLogger.LogError($"CECHostNavigatePlayer::InitAsync, Failed to load navigate model: {address}");
}
else
{
GameObject instance = ObjectSpawner.Instance.InstantiateObject(prefab);
instance.transform.localPosition = Vector3.zero;
instance.transform.localRotation = Quaternion.identity;
instance.transform.localScale = Vector3.one;
m_pNavigateModel = new CECModel();
m_pNavigateModel.m_pPlayerModel = instance;
SkeletonBuilder skeletonBuilder = instance.GetComponentInChildren<SkeletonBuilder>(true);
if (skeletonBuilder != null)
{
m_pNavigateModel.SetSkeletonBuilder(skeletonBuilder);
m_pNavigateModel.SetTransform(instance.transform);
m_pNavigateModel.InitializeSkeletonBuilder();
}
else
{
m_pNavigateModel.SetTransform(instance.transform);
}
AddressableManager.Instance.ReleaseAsset(address);
}
}
CameraController.Instance.UpdateFollowObject(m_pNavigateModel.transform);
TickInvoker.Instance.RegisterTickable(this);
// Clone host player model/equipment // 克隆宿主玩家模型与装备
BMLogger.Log($"CECHostNavigatePlayer::InitAsync, debugStep: {debugStep++}");
bool loaded = await LoadFrom(m_pHostPlayer, false);
if (loaded)
SetupNavigatePlayerVisual();
return loaded;
}
/// <summary>
/// Subscribe navigate clone to the same cid animation channel as the host (host unsubscribes first).
/// 与宿主相同 cid 的动画通道:先取消宿主订阅,再初始化导航克隆的 PlayerVisual。
/// </summary>
void SetupNavigatePlayerVisual()
{
if (!TryGetComponent<PlayerVisual>(out var navigateVisual))
return;
if (m_pHostPlayer != null && m_pHostPlayer.TryGetComponent<PlayerVisual>(out var hostVisual))
hostVisual.UnregisterPlayerEventHandlers();
navigateVisual.InitPlayerEventDoneHandler();
}
/// <summary>
/// Restore host PlayerVisual subscriptions when force navigate ends.
/// 强制导航结束时恢复宿主的 PlayerVisual 订阅。
/// </summary>
void TeardownNavigatePlayerVisual()
{
if (TryGetComponent<PlayerVisual>(out var navigateVisual))
navigateVisual.UnregisterPlayerEventHandlers();
if (m_pHostPlayer != null && m_pHostPlayer.TryGetComponent<PlayerVisual>(out var hostVisual))
hostVisual.InitPlayerEventDoneHandler();
}
public bool IsReadyNavigate()
{
return IsAllResReady() && m_bNavigateModelApplied;
}
public bool PlayNavigateAction()
{
if (m_pNavigateModel != null)
{
string szPetAct = null;
szPetAct = CECNPC.GetBaseActionName((int)PLAYER_ACTION_TYPE.ACT_WALK);
EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szPetAct, 200, true));
}
PLAYER_ACTION action = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_STAND];
string szAct = $"{action.data.ActionPrefix}_骑乘_通用";
PlayNonSkillActionWithName(szAct);
return true;
}
public bool PlayNonSkillActionWithName(string szAct)
{
if (m_pActionController != null)
{
Debug.Log($"CECHostNavigatePlayer::PlayNonSkillActionWithName, szAct: {szAct} of object {m_pActionController.PlayerModel.transform.parent.name}");
return m_pActionController.PlayNonSkillActionWithName(GetMoveStandAction(false, IsFighting()), szAct);
}
return false;
}
public override bool Tick(uint dwDeltatime)
{
base.Tick(dwDeltatime);
Debug.Log($"CECHostNavigatePlayer::Tick, m_bNavigateModelApplied: {m_bNavigateModelApplied}");
if (!m_bNavigateModelApplied /*&& IsAllResReady()*/)
{
ApplyNavigateModel();
// if(!IsShapeChanged())
// ApplyNavigateModel();
// else if (IsShapeChanged() && IsShapeModelChanged() && m_pNavigateModel != null)
// ApplyNavigateModel();
}
return true;
}
public Vector3 GetNavigateModelPosition()
{
if (m_pNavigateModel == null || m_pNavigateModel.m_pPlayerModel == null)
return m_pHostPlayer.transform.position;
return m_pNavigateModel.m_pPlayerModel.transform.position;
}
/// <summary>
/// Safe world position for streaming when navigate model is not ready yet.
/// 导航模型未就绪时用于流式加载的安全世界坐标。
/// </summary>
public bool TryGetNavigateModelPosition(out Vector3 position)
{
position = default;
if (m_pNavigateModel == null || m_pNavigateModel.m_pPlayerModel == null)
return false;
position = m_pNavigateModel.m_pPlayerModel.transform.position;
return true;
}
// A3DAABB CECHostNavigatePlayer::GetShadowAABB(){
// A3DAABB shadowAABB;
// shadowAABB.Clear();
// shadowAABB.Merge(m_aabb);
//
// if(m_pNavigateModel)
// shadowAABB.Merge(m_pNavigateModel->GetModelAABB());
// else if (IsRidingOnPet() && m_pPetModel && m_pPetModel->GetA3DSkinModel())
// shadowAABB.Merge(m_pPetModel->GetModelAABB());
// else if (GetPlayerModel() && GetPlayerModel()->GetA3DSkinModel())
// shadowAABB.Merge(GetPlayerModel()->GetModelAABB());
//
// return shadowAABB;
// }
public override void SetDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp)
{
base.SetDirAndUp(vDir, vUp);
if (m_pNavigateModel != null)
{
Vector3 dir = new Vector3(vDir.x, vDir.y, vDir.z);
Vector3 up = new Vector3(vUp.x, vUp.y, vUp.z);
if (dir.magnitude > 0.01f)
{
Quaternion lookRot = Quaternion.LookRotation(dir, up);
m_pNavigateModel.m_pPlayerModel.transform.rotation = lookRot;
}
m_bAdjustOrient = false;
}
}
protected override bool ShouldLoadEquipment(int index)
{
return index != InventoryConst.EQUIPIVTR_FLYSWORD;
}
protected override void OnCloneSimpleProperty()
{
// m_pNavigateModel needs mount hook on cloned model; duplicate attach/release — do not load riding pet again here // m_pNavigateModel 需要挂接克隆模型挂点,避免重复释放,故不再加载骑宠
m_RidingPet.Reset();
}
public override void SetPos(Vector3 vPos)
{
base.SetPos(vPos);
if (m_pNavigateModel != null)
{
m_pNavigateModel.m_pPlayerModel.transform.position =
vPos;
}
}
private bool ApplyNavigateModel()
{
// if ( !GetMajorModel() || m_pNavigateModel == null || m_bNavigateModelApplied)
// return false;
A3DVECTOR3 vCurPos = GetPos();
m_aabbServer.Center = vCurPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f);
m_aabbServer.CompleteMinsMaxs();
SetUseGroundNormal(true);
// Hang character model on force-navigate model // 把角色模型挂到强制移动模型上
// int iIndex;
// A3DSkeletonHook* pHook = GetMajorModel()->GetA3DSkinModel()->GetSkeleton()->GetHook(_cc_ride, &iIndex);
// if (pHook) pHook->SetFixDirFlag(true);
m_pNavigateModel.AddChildModel(_hanger_ride, false, _hh_ride, GetPlayerModel(), _cc_ride);
// if(IsShapeModelChanged())
// m_pNavigateModel.AddChildModel(_hanger_ride, false, _hh_ride, GetPlayerModel(), "HH_feijian");
// else
// m_pNavigateModel.AddChildModel(_hanger_ride, false, _hh_ride, GetMajorModel(), _cc_ride);
//m_pNavigateModel->GetA3DSkinModel()->Update(0);
// PlayAction(GetMoveStandAction(false, IsFighting()), 1.0f, true);
PlayNavigateAction();
m_bNavigateModelApplied = true;
OnNavigateEvent(0, (int)CECNavigateCtrl.NavigateEvent.EM_BEGIN);
return true;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 23d5d05595a4474cb298d23fe6e7c923
@@ -1,4 +1,4 @@
using System;
using System;
namespace BrewMonster
{
@@ -0,0 +1,142 @@
using BrewMonster.Scripts;
using System.Threading.Tasks;
using UnityEngine;
using CSNetwork.GPDataType;
namespace BrewMonster
{
public class CECClonePlayer : CECPlayer
{
protected bool m_bShowCustomize; // ʾԻ
protected bool m_bUseHintModel; // ʹ˵ģ
public CECClonePlayer(){
m_iCID = (int)Class_ID.OCID_CLONED_PLAYER;
m_bCastShadow = true;
m_bShowCustomize= true;
//Todo: add cofig feature to game
//m_bUseHintModel = GetConfigs().GetVideoSettings().bModelLimit;
}
public bool CanClone(CECPlayer player)
{
return player != null
&& (player.IsHostPlayer() || player.IsElsePlayer());
}
public async Task<bool> Clone(CECPlayer player, bool atOnce){
if (!player){
return false;
}
if (player.IsHostPlayer()){
if (await LoadFrom((CECHostPlayer)player, atOnce)){
return true;
}
}
if (player.IsElsePlayer()){
if (await LoadFrom((EC_ElsePlayer)player, atOnce)){
return true;
}
}
return false;
}
protected async Task<bool> LoadFrom(CECHostPlayer player, bool atOnce)
{
int i = 0;
EC_IvtrItem[] aEquipItems = new EC_IvtrItem[InventoryConst.SIZE_ALL_EQUIPIVTR];
// Create equipments
for (i=0; i < player.GetEquipment().GetSize(); i++){
if (!ShouldLoadEquipment(i)){
continue;
}
EC_IvtrItem Equip = player.GetEquipment().GetItem(i);
aEquipItems[i] = Equip;
}
// // Todo: Create goblin
// if( aEquipItems[EQUIPIVTR_GOBLIN] )
// {
// m_pGoblin = new CECGoblin();
// CECIvtrGoblin* pIvtrGoblin = (CECIvtrGoblin*)aEquipItems[EQUIPIVTR_GOBLIN];
// m_pGoblin->Init(pIvtrGoblin->GetTemplateID(), pIvtrGoblin, this);
// }
// Build new equipments id array (must match SIZE_ALL_EQUIPIVTR — LoadPlayerSkeleton iterates full range)
int[] aNewEquips = new int[InventoryConst.SIZE_ALL_EQUIPIVTR];
for (i=0; i < InventoryConst.IVTRSIZE_EQUIPPACK; i++) {
EC_IvtrItem pItem = aEquipItems[i];
if (pItem != null) {
aNewEquips[i] = pItem.GetTemplateID();
if( ((i >= InventoryConst.EQUIPIVTR_FASHION_BODY && i <= InventoryConst.EQUIPIVTR_FASHION_WRIST)
|| i == InventoryConst.EQUIPIVTR_FASHION_HEAD ) &&
pItem.GetClassID() == (int)EC_IvtrEquip.EQUIP_CLASS_ID.ICID_FASHION ) {
EC_IvtrFashion pFashionItem = (EC_IvtrFashion)pItem;
aNewEquips[i] |= (pFashionItem.GetWordColor() << 16) & 0x7fffffff;
}
else {
EC_IvtrEquip pEquip = (EC_IvtrEquip) pItem;
ushort stoneStatus = pEquip != null ? pEquip.GetStoneMask() : (ushort)0;
aNewEquips[i] |= (stoneStatus << 16) & 0x7fffffff;
}
}
else{
aNewEquips[i] = 0;
}
}
m_aEquips = aNewEquips;
return await Load(player, atOnce);
}
protected async Task<bool> LoadFrom(EC_ElsePlayer player, bool atOnce){
// Create equipments
for (int i=0; i < InventoryConst.SIZE_ALL_EQUIPIVTR; i++){
if (!ShouldLoadEquipment(i)){
continue;
}
m_aEquips[i] = player.GetEquipment(i);
}
return await Load(player, atOnce);
}
public override void SetDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp){
base.SetDirAndUp(vDir, vUp);
if(m_pPlayerCECModel != null)
{
Vector3 dir = new Vector3(vDir.x, vDir.y, vDir.z);
Vector3 up = new Vector3(vUp.x, vUp.y, vUp.z);
if (dir.magnitude > 0.01f)
{
Quaternion lookRot = Quaternion.LookRotation(dir, up);
m_pPlayerCECModel.m_pPlayerModel.transform.rotation = lookRot;
}
m_bAdjustOrient = false;
}
//m_pPlayerCECModel.SetDirAndUp(vDir,vUp);
}
protected async Task<bool> Load(CECPlayer player, bool atOnce){
player.CloneSimplePropertyTo(this);
OnCloneSimpleProperty();
if (!await LoadPlayerSkeleton(atOnce)){
BMLogger.LogError("CECCloneElsePlayer::Load, Failed to load skeleton.");
return false;
}
SetNewExtendStates(0, m_aExtStates, OBJECT_EXT_STATE_COUNT);
if (player.GetOriginalShapeID() != 0){
await TransformShape(player.GetShapeMask(), true);
}
return true;
}
protected virtual bool ShouldLoadEquipment(int index)
{
return true;
}
protected virtual void OnCloneSimpleProperty(){}
public virtual CECModel GetRenderModel(){
return m_pPlayerCECModel; //m_pPetModel ? m_pPetModel : m_pPlayerModel;
//Todo: add pet model when implement pet? system
}
public void PlayActionByName(string szActName){
m_pActionController.PlayNonSkillActionWithName((int)PLAYER_ACTION_TYPE.ACT_MAX, szActName);
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 938059b66516247539bb36cc9d80cf98
@@ -2,11 +2,10 @@
using BrewMonster;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using CSNetwork;
using CSNetwork.GPDataType;
using PerfectWorld.Scripts;
using PerfectWorld.Scripts.Managers;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
@@ -1164,6 +1164,10 @@ namespace BrewMonster
return true;
}
public int GetEquipment(int index)
{
return m_aEquips[index];
}
}
// Player appear flag
@@ -178,7 +178,7 @@ namespace BrewMonster
{
for (int i = 0; i < pPet.GetSkillNum(SKILLTYPE.EM_SKILL_DEFAULT); i++)
{
PETSKILL? pSkill = pPet.GetSkill(SKILLTYPE.EM_SKILL_DEFAULT, i);
CECPetData.PETSKILL? pSkill = pPet.GetSkill(SKILLTYPE.EM_SKILL_DEFAULT, i);
if (pSkill != null && EC_Game.IsPetAutoSkill(pSkill.Value.idSkill))
pPet.AddAutoSkill(pSkill.Value.idSkill);
}
@@ -2,7 +2,7 @@ using BrewMonster.Assets.PerfectWorld.Scripts.UI;
using BrewMonster.Common;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Task;
using CSNetwork;
using CSNetwork.Common;
@@ -12,7 +12,7 @@ using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using static BrewMonster.Scripts.Managers.EC_Inventory;
using static BrewMonster.Scripts.EC_Inventory;
namespace BrewMonster.UI
{
@@ -1,5 +1,5 @@
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using BrewMonster.Scripts.Task;
using BrewMonster.UI;
using ModelRenderer.Scripts.Common;
@@ -5,9 +5,7 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using PerfectWorld.Scripts.Shop;
using PerfectWorld.Scripts.Managers;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using BrewMonster.Network;
using CSNetwork.C2SCommand;
@@ -7,7 +7,7 @@ using UnityEngine.UI;
using TMPro;
using System.Collections;
using PerfectWorld.Scripts.Shop;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
public class NPCShopItemPanel : MonoBehaviour
{
@@ -5,11 +5,11 @@
using BrewMonster;
using BrewMonster.Network;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using BrewMonster.UI;
using CSNetwork.C2SCommand;
using ModelRenderer.Scripts.Common;
using PerfectWorld.Scripts.Managers;
using PerfectWorld.Scripts.Shop;
using System;
using System.Collections.Generic;
using TMPro;
@@ -1,5 +1,5 @@
using BrewMonster;
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using System.Collections;
using TMPro;
using UnityEngine;
@@ -12,7 +12,6 @@ public class ProduceItemPanel : MonoBehaviour
public Image icon;
public TextMeshProUGUI text_name;
public TextMeshProUGUI text_level;
private uint recipeId;
private Coroutine loadIconCoroutine;
private DlgProduce ownerDlg;
@@ -1,8 +1,7 @@
using BrewMonster.Scripts.Managers;
using BrewMonster.Scripts;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using PerfectWorld.Scripts.Managers;
public class ShopItemPanel : MonoBehaviour
{
@@ -148,7 +148,15 @@ public class LitModelHolder : MonoSingleton<LitModelHolder>
await Task.Delay(100, destroyToken); // wait for the host player to be initialized.
_currentHostPosOxz = _hostPlayer.GetPosVector3();
//In c++ version. clone object position is used as the host object position when force navigate.
if(_hostPlayer.IsInForceNavigateState())
{
_currentHostPosOxz = _hostPlayer.GetNavigatePlayer().GetNavigateModelPosition();
}
else
{
_currentHostPosOxz = _hostPlayer.GetPosVector3();
}
_currentHostPosOxz.y = 0;
LoadAllObjectsNearPosition(_currentHostPosOxz, destroyToken);
}
@@ -311,9 +319,18 @@ public class LitModelHolder : MonoSingleton<LitModelHolder>
private void UpdateHostPlayerPosition()
{
_hostPlayer = GetHostPlayer();
if (_hostPlayer != null)
{
_currentHostPosOxz = _hostPlayer.GetPosVector3(false);
if(_hostPlayer.IsInForceNavigateState())
{
_currentHostPosOxz = _hostPlayer.GetNavigatePlayer().GetNavigateModelPosition();
}
else
{
_currentHostPosOxz = _hostPlayer.GetPosVector3(false);
}
_currentHostPosOxz.y = 0;
_hostPosReady = true;
}
@@ -2,6 +2,7 @@ using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
using BrewMonster.Network;
using BrewMonster.Scripts;
using System;
using System.Collections.Generic;
@@ -195,16 +196,34 @@ namespace BrewMonster
_objectsToUnload.Clear();
}
/// <summary>
/// Main-thread anchor for terrain streaming: host position, or navigate clone when force-navigate is active (same idea as LitModelHolder).
/// 地形流式锚点:普通用宿主;强制导航用导航克隆(与 LitModelHolder 一致)。
/// </summary>
private void UpdateGlobalDataForStreaming()
{
_realTimeSinceStartUp = Time.realtimeSinceStartup;
if (_hostPlayer == null)
{
_hostPlayer = CECGameRun.Instance.GetHostPlayer();
if (_hostPlayer == null)
{
_hostPosReady = false;
return;
}
//In c++ version. clone object position is used as the host object position when force navigate.
if (_hostPlayer.IsInForceNavigateState())
{
CECHostNavigatePlayer nav = _hostPlayer.GetNavigatePlayer();
if (nav != null && nav.TryGetNavigateModelPosition(out Vector3 clonePos))
{
_currentHostPosOxz = clonePos;
}
}
else
{
_currentHostPosOxz = _hostPlayer.GetPosVector3(false);
}
if (_hostPlayer == null) return;
_currentHostPosOxz = _hostPlayer.GetPosVector3();
_currentHostPosOxz.y = 0f;
_hostPosReady = true;
}
+1 -1
View File
@@ -11,7 +11,7 @@ using BrewMonster.UI;
using PerfectWorld.Scripts.Managers;
using UnityEngine;
using static BrewMonster.Scripts.CECHPWork;
using static BrewMonster.Scripts.Managers.EC_Inventory;
using static BrewMonster.Scripts.EC_Inventory;
namespace BrewMonster
{
+1 -76
View File
@@ -16,59 +16,6 @@ namespace BrewMonster
TransformShape(pCmd.shape);
}
public async Task TransformShape(byte iShape, bool bLoadAtOnce = false/* =false */)
{
SetShape(iShape);
//a_LogOutput(1, "CECPlayer::TransformShape(iShape=%d)(iShapeType=%d,iShapeID=%d)", iShape, PLAYERMODEL_GETTYPE(iShape), PLAYERMODEL_GETID(iShape));
if (!GetMajorModel()) return;
if (IsShapeChanged())
{
m_bWeaponAttached = false;
// change to a dummy model, may cause an asynchronous loading
await QueueLoadDummyModel(m_iShape, bLoadAtOnce);
}
else
{
m_bWeaponAttached = true;
// back to major model is a synchronous operation
ApplyShapeModelChange(GetMajorModel());
}
OnModelChange(GetMajorModel());
}
void SetShape(byte iShape)
{
// The shape id from the server is a 8-bit number
// The meaning of each bit:
// | 7 6 | 5 4 3 2 1 0 |
// |-TYPE-|-----Model ID-----|
int iNewShape = (iShape & 0xff); // only accept 8bit
// ԾɵShapeݽ
FixOldShapeInfo(ref iNewShape);
// ְҵModel IDҪת
if( PLAYERMODEL_GETTYPE(iNewShape) == (int)PLAYERMODEL_TYPE.PLAYERMODEL_PROFESSION )
{
int iRealID = _GetProfessionTransformModelID(
m_iProfession, m_iGender, PLAYERMODEL_GETID(iNewShape));
iNewShape = 0x40 | iRealID;
}
// ְҵModel IDΪEC_Resource.hֵʲ
else
{
}
// store the original data into 8~15 bit
m_iShape = iNewShape | ((iShape & 0xff) << 8);
}
void FixOldShapeInfo(ref int iShape)
{
// ǸʱshapeΪ0ûб0ְҵ
if(iShape != 0 && PLAYERMODEL_GETTYPE(iShape) == 0)
iShape |= 0x40;
}
/// <summary>Origin: notify server of force-attack (PVP) state so it accepts/rejects attacks on players. Call when duel starts (true) or ends (false).</summary>
private void NotifyServerForceAttack(bool bForceAttack)
{
@@ -76,28 +23,6 @@ namespace BrewMonster
UnityGameSession.c2s_SendCmdNotifyForceAttack(glb_BuildPVPMask(bForceAttack), refuseBless);
}
public int _GetProfessionTransformModelID(int nChar, int nGender, int nModelID)
{
int result = 0;
switch (nChar){
case (int)PROFESSION.PROF_HAG: //
result = (2 == nModelID) ? (int)ModelResourceType.RES_MOD_ORC_FOX2 : (int)ModelResourceType.RES_MOD_ORC_FOX;
break;
case (int)PROFESSION.PROF_ORC: //
result = (2 == nModelID) ? (int)ModelResourceType.RES_MOD_ORC_PANDER : (int)ModelResourceType.RES_MOD_ORC_TIGER;
break;
case (int)PROFESSION.PROF_MONK: // ʦ
case (int)PROFESSION.PROF_GHOST: // ̿
result = ((int)Gender.GENDER_MALE == nGender) ? (int)ModelResourceType.RES_MOD_SHADOW_FISH_M : (int)ModelResourceType.RES_MOD_SHADOW_FISH_F;
break;
case (int)PROFESSION.PROF_YEYING: // ҹӰ
result = ((int)Gender.GENDER_MALE == nGender) ? (int)ModelResourceType.RES_MOD_YEYING_RESHAPE_M : (int)ModelResourceType.RES_MOD_YEYING_RESHAPE_F;
break;
case (int)PROFESSION.PROF_YUEXIAN: //
result = ((int)Gender.GENDER_MALE == nGender) ? (int)ModelResourceType.RES_MOD_YUEXIAN_RESHAPE_M : (int)ModelResourceType.RES_MOD_YUEXIAN_RESHAPE_F;
break;
}
return result;
}
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ using BrewMonster.Assets.PerfectWorld.Scripts.Players;
using UnityEngine;
using static BrewMonster.Scripts.Pet.CECPetData;
using BrewMonster.Scripts.Managers;
using static PerfectWorld.Scripts.Managers.EC_IvtrEquip;
using static BrewMonster.Scripts.EC_IvtrEquip;
using PerfectWorld.Scripts.Managers;
namespace BrewMonster
+3 -2
View File
@@ -259,8 +259,9 @@ namespace BrewMonster
// Update camera if available
// 如果可用则更新相机
// UpdateFollowCamera(false, 10); // Uncomment if UpdateFollowCamera method exists
LitModelHolder.Instance.LoadAllObjectsNearTargetPosition(vPos).Forget();
// Streaming anchor follows navigate clone when force-navigate is active (LitModelHolder.UpdateStreamingAnchorPosition).
// 强制导航时流式锚点跟随导航克隆(LitModelHolder.UpdateStreamingAnchorPosition)。
LitModelHolder.Instance.LoadAllObjectsNearTargetPosition(default, useHostPlayerPosition: true).Forget();
};
// Jump to instance (change world/instance)
// 跳转到实例(更改世界/实例)
+33 -18
View File
@@ -29,6 +29,7 @@ using cmd_player_chgshape = CSNetwork.GPDataType.cmd_player_chgshape;
using Host_work_ID = BrewMonster.Scripts.CECHPWork.Host_work_ID;
using ObjectCoords = System.Collections.Generic.List<CSNetwork.GPDataType.OBJECT_COORD>;
using Trace_reason = BrewMonster.CECHPWorkTrace.Trace_reason;
using System.Threading.Tasks;
namespace BrewMonster
{
@@ -249,12 +250,6 @@ namespace BrewMonster
private CECHostNavigatePlayer m_pNavigatePlayer = null;
public CECHostNavigatePlayer GetNavigatePlayer()
{
if (m_pNavigatePlayer == null)
{
// Create navigate player on-demand (C++: host owns a navigate/clone player + controller)
// 按需创建导航玩家(C++:宿主玩家持有导航/克隆玩家 + 控制器)
m_pNavigatePlayer = new CECHostNavigatePlayer(this);
}
return m_pNavigatePlayer;
}
@@ -273,15 +268,37 @@ namespace BrewMonster
public void OnNaviageEvent(int task, int e)
{
UnityEngine.Debug.Log($"[CECHostPlayer] OnNaviageEvent: Task={task}, Event={e} ({(BrewMonster.Scripts.CECNavigateCtrl.NavigateEvent)e})");
CECHostNavigatePlayer pNavigatePlayer = GetNavigatePlayer();
if (pNavigatePlayer != null)
if (e == (int)CECNavigateCtrl.NavigateEvent.EM_PREPARE)
{
UnityEngine.Debug.Log($"[CECHostPlayer] OnNaviageEvent: Forwarding to NavigatePlayer");
pNavigatePlayer.OnNavigateEvent(task, e);
CreateNavigatePlayer();
}
else
if (m_pNavigatePlayer != null)
{
UnityEngine.Debug.LogWarning($"[CECHostPlayer] OnNaviageEvent: NavigatePlayer is null");
m_pNavigatePlayer.OnNavigateEvent(task, e);
}
if(e == (int)CECNavigateCtrl.NavigateEvent.EM_END)
{
ReleaseNavigatePlayer();
}
}
private void CreateNavigatePlayer()
{
ReleaseNavigatePlayer();
GameObject navigateGo = new GameObject("HostNavigatePlayer");
navigateGo.transform.SetParent(transform, false);
navigateGo.transform.localScale = Vector3.one;
navigateGo.AddComponent<PlayerVisual>();
CECHostNavigatePlayer navigatePlayer = navigateGo.AddComponent<CECHostNavigatePlayer>();
navigatePlayer.InitializeHost(this);
//navigatePlayer.LoadConfig();
m_pNavigatePlayer = navigatePlayer;
}
private void ReleaseNavigatePlayer()
{
if (m_pNavigatePlayer != null)
{
m_pNavigatePlayer.Release();
m_pNavigatePlayer = null;
}
}
@@ -331,7 +348,7 @@ namespace BrewMonster
TickTask().Forget();
}
public bool LoadResources()
public async Task<bool> LoadResources()
{
//BMLogger.LogError("HoangDev: CECHostPlayer::LoadResources");
RoleInfo RoleInfo = UnityGameSession.Instance.GetRoleInfo();
@@ -344,7 +361,7 @@ namespace BrewMonster
EC_Game.GetGameRun().AddPlayerName(m_PlayerInfo.cid, m_strName);
if (!LoadPlayerSkeleton(true))
if (!await LoadPlayerSkeleton(true))
{
BMLogger.LogError("HoangDev CECHostPlayer::LoadResources, Failed to load skeleton");
return false;
@@ -1471,7 +1488,7 @@ namespace BrewMonster
m_bEnterGame = false;
}
public async void InitCharacter(cmd_self_info_1 role)
public async Task InitCharacter(cmd_self_info_1 role)
{
SetUpPlayer();
m_dwStates = (uint)role.state;
@@ -1486,9 +1503,7 @@ namespace BrewMonster
// roleName = Encoding.UTF8.GetString(role.name.ByteArray, 0, role.name.Length);
//}
SetPlayerInfor(new INFO(role.cid, role.crc_e, role.crc_c));
LoadResources();
await SetPlayerModel(UnityGameSession.Instance.GetRoleInfo().occupation,
UnityGameSession.Instance.GetRoleInfo().gender);
await LoadResources();
isDataAwaitToReady = true;
Vector3 pos = new Vector3(role.pos.x, role.pos.y, role.pos.z);
string roleName = Encoding.Unicode.GetString(UnityGameSession.Instance.GetRoleInfo().name.ByteArray);

Some files were not shown because too many files have changed in this diff Show More