Merge branch 'develop' of https://git.pthub.vn/Unity/perfect-world-unity into feature/update-ui
This commit is contained in:
@@ -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"
|
||||
|
||||
Executable → Regular
+1361
-2
File diff suppressed because it is too large
Load Diff
Executable → Regular
+56
-14
@@ -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
|
||||
|
||||
@@ -9743,6 +9743,7 @@ MonoBehaviour:
|
||||
currentTargetNPCID: 0
|
||||
dialogResouce: {fileID: 11400000, guid: 540bc8e61556ba4479407a2d68e17580, type: 2}
|
||||
canvasDlg: {fileID: 7894129013412138377}
|
||||
_emotionLibrarySpriteMap: {fileID: 11400000, guid: f634ecf63ca3d004f82af9b17c966fc9, type: 2}
|
||||
btnSecondClick: {fileID: 1330222957695115484}
|
||||
m_pDlgQuickBar1: {fileID: 8338623026378970694}
|
||||
ChangeSkillShortcutButton: {fileID: 335905991743982376}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7245ad76b42e0f3f97f2cc7990d79ff171b5f78e64bad057b5acae21bed80395
|
||||
size 321521
|
||||
oid sha256:543e09f5571b2d48dd57646eee06f8efbc71e6aaa62d6e8a98a529dec44b7364
|
||||
size 322591
|
||||
|
||||
@@ -37,7 +37,7 @@ MonoBehaviour:
|
||||
prefix:
|
||||
- channel: 1
|
||||
iconName:
|
||||
icon: {fileID: 0}
|
||||
icon: {fileID: 21300000, guid: 4c42fa6e60df2184fa1a7d606bdbac8c, type: 3}
|
||||
prefix: '!@'
|
||||
- channel: 7
|
||||
iconName:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3011939e4e9c0ce4e83bc03a748fcf96
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: af2fa24fb63c4aa45bb99a711c857114, type: 3}
|
||||
m_Name: EmotionLibrarySpriteMap
|
||||
m_EditorClassIdentifier:
|
||||
Library: {fileID: 11400000, guid: 3011939e4e9c0ce4e83bc03a748fcf96, type: 2}
|
||||
TmpSpriteAsset: {fileID: 11400000, guid: c41005c129ba4d66911b75229fd70b45, type: 2}
|
||||
PreferSpriteNameTag: 1
|
||||
DefaultAnimFps: 10
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f634ecf63ca3d004f82af9b17c966fc9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
using CSNetwork;
|
||||
|
||||
namespace BrewMonster.Scripts.Chat
|
||||
{
|
||||
/// <summary>
|
||||
/// Chat 表情与内联富文本 — Emotion set + TMP conversion for chat (ported from CECGameUIMan::AddChatMessage).
|
||||
/// Keeps channel emotion filtering and Unmarshal/Convert-to-TMP in one place.
|
||||
/// </summary>
|
||||
public sealed class ChatEmotionDisplayPipeline
|
||||
{
|
||||
private IEmotionSpriteMap _spriteMap = new StubEmotionSpriteMap();
|
||||
|
||||
public ChatEmotionDisplayPipeline(IEmotionSpriteMap spriteMap = null)
|
||||
{
|
||||
if (spriteMap != null)
|
||||
_spriteMap = spriteMap;
|
||||
}
|
||||
|
||||
public void SetSpriteMap(IEmotionSpriteMap spriteMap)
|
||||
{
|
||||
_spriteMap = spriteMap ?? new StubEmotionSpriteMap();
|
||||
}
|
||||
|
||||
/// <summary>C++: FilterEmotionSet — map inline emotion codes to the correct set for this channel.</summary>
|
||||
public string ApplyChannelEmotionFilter(string pszMsg, int cEmotion)
|
||||
{
|
||||
return AUICommon.FilterEmotionSet(pszMsg, cEmotion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TMP: Unmarshal edit-box item codes and convert emotion / coord / inventory links to TMP rich text.
|
||||
/// Call after <see cref="CECUIManager.FilterBadWords"/> when the message is from a player channel.
|
||||
/// </summary>
|
||||
public string ConvertInlineItemsToTmp(string pszMsgAfterBadWordFilter)
|
||||
{
|
||||
EditBoxItemsSet itemsSet = new EditBoxItemsSet();
|
||||
string displayText = AUICommon.UnmarshalEditBoxText(pszMsgAfterBadWordFilter, itemsSet);
|
||||
if (itemsSet.GetItemCount() <= 0)
|
||||
return pszMsgAfterBadWordFilter;
|
||||
|
||||
string tmpText = displayText;
|
||||
tmpText = AUICommon.ConvertEmotionsToTMP(tmpText, itemsSet, _spriteMap);
|
||||
tmpText = AUICommon.ConvertCoordsToTMP(tmpText, itemsSet);
|
||||
tmpText = AUICommon.ConvertIvtrItemsToTMP(tmpText, itemsSet);
|
||||
tmpText = AUICommon.StripRemainingItemCodes(tmpText);
|
||||
return tmpText;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 017020ee87cf87d40abfd39726e185c0
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b434da58bb8623f439f5cbf37342f155
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Chat.EmotionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Một dòng định nghĩa emotion trong Emotions{N}.txt (port từ AUITEXTAREA_EMOTION).
|
||||
/// One emotion definition line from Emotions{N}.txt (ported from AUITEXTAREA_EMOTION).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class EmotionEntryData
|
||||
{
|
||||
[Tooltip("Chỉ số ô bắt đầu trong lưới cell (nStartPos) — Starting cell index in the atlas grid.")]
|
||||
public int StartPos;
|
||||
|
||||
[Tooltip("Số frame animation (nNumFrames), tối đa 20 như C++.")]
|
||||
public int NumFrames;
|
||||
|
||||
[Tooltip("Tooltip / hint text từ file txt.")]
|
||||
public string Hint = "";
|
||||
|
||||
/// <summary>
|
||||
/// Thời điểm tick cho từng frame (nFrameTick[i]), độ dài = NumFrames.
|
||||
/// </summary>
|
||||
public int[] FrameTicks = Array.Empty<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Sprite đã cắt cho từng frame (gán bởi tool), độ dài = NumFrames khi đã convert.
|
||||
/// </summary>
|
||||
public Sprite[] FrameSprites = Array.Empty<Sprite>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0e42b4b83e3a6f40a2a7737f584fdc6
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Chat.EmotionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Snapshot một bộ Emotions{N} (dùng embed trong EmotionLibrarySO hoặc copy sang EmotionSetDataSO).
|
||||
/// One Emotions{N} snapshot (embedded in EmotionLibrarySO or copied to EmotionSetDataSO).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class EmotionSetSnapshot
|
||||
{
|
||||
public int EmotionSetIndex;
|
||||
public int CellWidth = 32;
|
||||
public int CellHeight = 32;
|
||||
public Texture2D SourceAtlas;
|
||||
public string SourceTxtAssetPath = "";
|
||||
public List<EmotionEntryData> Entries = new List<EmotionEntryData>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Một ScriptableObject chứa nhiều bộ emotion (vd. emotions0–emotions7).
|
||||
/// Single SO holding multiple emotion sets (e.g. all 8 atlases).
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "EmotionLibrary", menuName = "Perfect World/Chat/Emotion Library (All Sets)", order = 1)]
|
||||
public class EmotionLibrarySO : ScriptableObject
|
||||
{
|
||||
[Tooltip("Danh sách các bộ theo EmotionSetIndex (0,1,2,…).")]
|
||||
public List<EmotionSetSnapshot> Sets = new List<EmotionSetSnapshot>();
|
||||
|
||||
public EmotionSetSnapshot GetSetOrNull(int emotionSetIndex)
|
||||
{
|
||||
if (Sets == null) return null;
|
||||
foreach (var s in Sets)
|
||||
{
|
||||
if (s != null && s.EmotionSetIndex == emotionSetIndex)
|
||||
return s;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3805edc4ea793a54eabafdd3e7e48581
|
||||
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Chat.EmotionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Ánh xạ (emotionSet, emotionIndex) từ <see cref="EmotionLibrarySO"/> sang tag TMP.
|
||||
/// Gán asset này vào <see cref="CECUIManager"/> (field emotion) — <see cref="BrewMonster.UI.CECGameUIMan"/> không phải MonoBehaviour nên không kéo SO trên Inspector được.
|
||||
///
|
||||
/// Cách dùng:
|
||||
/// 1) Tạo <see cref="EmotionLibrarySO"/> bằng Emotion Atlas Converter.
|
||||
/// 2) Tạo <see cref="TMP_SpriteAsset"/> từ cùng atlas (Window → TextMeshPro → Sprite Importer),
|
||||
/// đảm bảo tên sub-sprite khớp (vd. cell_0000) với atlas Multiple từ tool.
|
||||
/// 3) Gán TMP_SpriteAsset vào ô chat <see cref="TMPro.TextMeshProUGUI"/> (Sprite Asset / Additional).
|
||||
/// 4) Kéo SO này vào field trên GameObject có <see cref="CECUIManager"/> (Awake gọi SetEmotionSpriteMap).
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "EmotionLibrarySpriteMap", menuName = "Perfect World/Chat/Emotion Library Sprite Map", order = 2)]
|
||||
public class EmotionLibrarySpriteMap : ScriptableObject, IEmotionSpriteMap
|
||||
{
|
||||
[Tooltip("Dữ liệu emotion đã convert (Entries + FrameSprites).")]
|
||||
public EmotionLibrarySO Library;
|
||||
|
||||
[Tooltip("Sprite Asset dùng cho chat TMP — cùng tên sub-sprite với atlas (cell_XXXX). Bắt buộc cho emoji động (anim) hoặc khi không dùng name tag.")]
|
||||
public TMP_SpriteAsset TmpSpriteAsset;
|
||||
|
||||
[Tooltip("Nếu true và chỉ 1 frame: thử <sprite name=\"...\"> (không cần tra index). Động (nhiều frame) vẫn cần TmpSpriteAsset để tra index.")]
|
||||
public bool PreferSpriteNameTag = true;
|
||||
|
||||
[Tooltip("FPS mặc định cho <sprite anim> khi không suy ra được từ FrameTicks.")]
|
||||
public int DefaultAnimFps = 10;
|
||||
|
||||
public bool TryGetSprite(int emotionSet, int emotionIndex, out EmotionSpriteInfo info)
|
||||
{
|
||||
info = default;
|
||||
|
||||
if (Library == null)
|
||||
return false;
|
||||
|
||||
EmotionSetSnapshot set = Library.GetSetOrNull(emotionSet);
|
||||
if (set == null || emotionIndex < 0 || emotionIndex >= set.Entries.Count)
|
||||
return false;
|
||||
|
||||
EmotionEntryData entry = set.Entries[emotionIndex];
|
||||
Sprite[] frames = entry.FrameSprites;
|
||||
if (frames == null || frames.Length == 0)
|
||||
return false;
|
||||
|
||||
if (frames.Length == 1)
|
||||
{
|
||||
Sprite s0 = frames[0];
|
||||
if (s0 == null)
|
||||
return false;
|
||||
|
||||
if (PreferSpriteNameTag && !string.IsNullOrEmpty(s0.name))
|
||||
{
|
||||
info = new EmotionSpriteInfo
|
||||
{
|
||||
UseSpriteName = true,
|
||||
SpriteName = s0.name,
|
||||
IsAnimated = false
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
int idx = FindSpriteIndexInTmpAsset(s0.name);
|
||||
if (idx < 0)
|
||||
return false;
|
||||
|
||||
info = new EmotionSpriteInfo { SpriteIndex = idx, IsAnimated = false };
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TmpSpriteAsset == null)
|
||||
return false;
|
||||
|
||||
int start = FindSpriteIndexInTmpAsset(frames[0]?.name);
|
||||
int end = FindSpriteIndexInTmpAsset(frames[frames.Length - 1]?.name);
|
||||
if (start < 0 || end < 0)
|
||||
return false;
|
||||
|
||||
int fps = EstimateFps(entry.FrameTicks, frames.Length);
|
||||
info = new EmotionSpriteInfo
|
||||
{
|
||||
SpriteIndex = start,
|
||||
IsAnimated = true,
|
||||
AnimEndFrame = end,
|
||||
AnimFPS = fps > 0 ? fps : DefaultAnimFps
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
private int FindSpriteIndexInTmpAsset(string spriteName)
|
||||
{
|
||||
if (TmpSpriteAsset == null || string.IsNullOrEmpty(spriteName))
|
||||
return -1;
|
||||
|
||||
if (TmpSpriteAsset.spriteInfoList != null)
|
||||
{
|
||||
for (int i = 0; i < TmpSpriteAsset.spriteInfoList.Count; i++)
|
||||
{
|
||||
var s = TmpSpriteAsset.spriteInfoList[i];
|
||||
if (s != null && s.name == spriteName)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int EstimateFps(int[] frameTicks, int numFrames)
|
||||
{
|
||||
if (frameTicks == null || numFrames < 2 || frameTicks.Length < numFrames)
|
||||
return 0;
|
||||
int last = frameTicks[numFrames - 1];
|
||||
int first = frameTicks[0];
|
||||
int span = last - first;
|
||||
if (span <= 0)
|
||||
return 0;
|
||||
return Mathf.Max(1, Mathf.RoundToInt((numFrames - 1) * 60f / span));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af2fa24fb63c4aa45bb99a711c857114
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Chat.EmotionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Dữ liệu một bộ emotion (tương ứng Emotions{N}.dds + Emotions{N}.txt).
|
||||
/// Data for one emotion group (matches Emotions{N}.dds + Emotions{N}.txt).
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "EmotionSetData", menuName = "Perfect World/Chat/Emotion Set Data", order = 0)]
|
||||
public class EmotionSetDataSO : ScriptableObject
|
||||
{
|
||||
[Tooltip("N trong Emotions{N} (0..31 như AUIMANAGER_MAX_EMOTIONGROUPS).")]
|
||||
public int EmotionSetIndex;
|
||||
|
||||
[Tooltip("Kích thước ô lưới giống C++ (mặc định 32x32).")]
|
||||
public int CellWidth = 32;
|
||||
|
||||
[Tooltip("Kích thước ô lưới giống C++ (mặc định 32x32).")]
|
||||
public int CellHeight = 32;
|
||||
|
||||
[Tooltip("Texture nguồn (atlas PNG/DDS import) dùng khi convert.")]
|
||||
public Texture2D SourceAtlas;
|
||||
|
||||
[Tooltip("Đường dẫn asset của file txt nguồn (optional, để trace).")]
|
||||
public string SourceTxtAssetPath;
|
||||
|
||||
public List<EmotionEntryData> Entries = new List<EmotionEntryData>();
|
||||
|
||||
/// <summary>
|
||||
/// Số ô theo chiều ngang trong atlas (texture width / CellWidth).
|
||||
/// </summary>
|
||||
public int GridCellsX => SourceAtlas != null && CellWidth > 0
|
||||
? SourceAtlas.width / CellWidth
|
||||
: 0;
|
||||
|
||||
/// <summary>
|
||||
/// Số ô theo chiều dọc.
|
||||
/// </summary>
|
||||
public int GridCellsY => SourceAtlas != null && CellHeight > 0
|
||||
? SourceAtlas.height / CellHeight
|
||||
: 0;
|
||||
|
||||
public int TotalCells => GridCellsX * GridCellsY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2143882ad81a4ac4ea7e23512f481104
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace BrewMonster.Scripts.Chat.EmotionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Parser token giống thứ tự đọc trong AUIManager.cpp (Emotions{N}.txt).
|
||||
/// Token order matches AUIManager.cpp when loading Emotions{N}.txt.
|
||||
/// </summary>
|
||||
public static class EmotionTxtParser
|
||||
{
|
||||
public const int MaxFrames = 20; // AUITEXTAREA_EMOTHION_MAXFRAME
|
||||
|
||||
public readonly struct ParseResult
|
||||
{
|
||||
public readonly List<EmotionEntryData> Entries;
|
||||
public readonly string ErrorMessage;
|
||||
|
||||
public bool Success => string.IsNullOrEmpty(ErrorMessage);
|
||||
|
||||
public ParseResult(List<EmotionEntryData> entries, string error)
|
||||
{
|
||||
Entries = entries;
|
||||
ErrorMessage = error ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Đọc toàn bộ nội dung file txt; token tách bằng whitespace (giống GetNextToken cơ bản).
|
||||
/// Reads full txt; tokens split by whitespace (basic GetNextToken behavior).
|
||||
/// </summary>
|
||||
public static ParseResult Parse(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return new ParseResult(new List<EmotionEntryData>(), "Empty text.");
|
||||
|
||||
var tokens = Tokenize(text);
|
||||
var entries = new List<EmotionEntryData>();
|
||||
int t = 0;
|
||||
|
||||
while (t < tokens.Count)
|
||||
{
|
||||
if (!TryParseInt(tokens[t], out int startPos))
|
||||
return new ParseResult(null, $"Invalid nStartPos at token index {t}: '{tokens[t]}'");
|
||||
|
||||
t++;
|
||||
if (t >= tokens.Count)
|
||||
return new ParseResult(null, "Unexpected EOF after nStartPos.");
|
||||
|
||||
if (!TryParseInt(tokens[t], out int numFramesRaw))
|
||||
return new ParseResult(null, $"Invalid nNumFrames at token index {t}.");
|
||||
|
||||
int numFrames = Math.Min(Math.Max(0, numFramesRaw), MaxFrames);
|
||||
t++;
|
||||
|
||||
if (t >= tokens.Count)
|
||||
return new ParseResult(null, "Unexpected EOF after nNumFrames (missing hint).");
|
||||
|
||||
string hint = tokens[t];
|
||||
t++;
|
||||
|
||||
var frameTicks = new int[numFrames];
|
||||
for (int i = 0; i < numFrames; i++)
|
||||
{
|
||||
if (t >= tokens.Count)
|
||||
return new ParseResult(null,
|
||||
$"Unexpected EOF: need {numFrames} frame tick values for entry starting at StartPos={startPos}.");
|
||||
|
||||
if (!TryParseInt(tokens[t], out frameTicks[i]))
|
||||
return new ParseResult(null, $"Invalid nFrameTick[{i}] at token index {t}.");
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
entries.Add(new EmotionEntryData
|
||||
{
|
||||
StartPos = startPos,
|
||||
NumFrames = numFrames,
|
||||
Hint = hint,
|
||||
FrameTicks = frameTicks
|
||||
});
|
||||
}
|
||||
|
||||
return new ParseResult(entries, null);
|
||||
}
|
||||
|
||||
private static bool TryParseInt(string s, out int v)
|
||||
{
|
||||
return int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out v);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tách token: khoảng trắng; hỗ trợ chuỗi trong dấu ngoặc kép cho hint nếu sau này cần.
|
||||
/// </summary>
|
||||
private static List<string> Tokenize(string text)
|
||||
{
|
||||
var list = new List<string>();
|
||||
var sb = new StringBuilder();
|
||||
bool inQuotes = false;
|
||||
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
{
|
||||
char c = text[i];
|
||||
|
||||
if (inQuotes)
|
||||
{
|
||||
if (c == '"')
|
||||
inQuotes = false;
|
||||
else
|
||||
sb.Append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
list.Add(sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
|
||||
inQuotes = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char.IsWhiteSpace(c))
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
{
|
||||
list.Add(sb.ToString());
|
||||
sb.Clear();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.Append(c);
|
||||
}
|
||||
|
||||
if (sb.Length > 0)
|
||||
list.Add(sb.ToString());
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 656924d32be0e3c469b409078941188e
|
||||
@@ -0,0 +1,29 @@
|
||||
/// <summary>
|
||||
/// Stub实现 — 在没有真实TMP_SpriteAsset(emotion atlas)时使用的占位映射。
|
||||
/// Stub implementation used when no real TMP_SpriteAsset (emotion atlas) is available yet.
|
||||
///
|
||||
/// 当准备好atlas后,创建一个新的IEmotionSpriteMap实现,替换掉这个stub。
|
||||
/// When atlas is ready, create a real IEmotionSpriteMap implementation and swap it in
|
||||
/// ChatEmotionDisplayPipeline / CECGameUIMan emotion pipeline.
|
||||
/// </summary>
|
||||
public class StubEmotionSpriteMap : IEmotionSpriteMap
|
||||
{
|
||||
private const int EMOTIONS_PER_SET = 50;
|
||||
private const int FRAMES_PER_EMOTION = 4;
|
||||
private const int DEFAULT_FPS = 10;
|
||||
|
||||
public bool TryGetSprite(int emotionSet, int emotionIndex, out EmotionSpriteInfo info)
|
||||
{
|
||||
int startFrame = (emotionSet * EMOTIONS_PER_SET + emotionIndex) * FRAMES_PER_EMOTION;
|
||||
|
||||
info = new EmotionSpriteInfo
|
||||
{
|
||||
SpriteIndex = startFrame,
|
||||
IsAnimated = true,
|
||||
AnimEndFrame = startFrame + FRAMES_PER_EMOTION - 1,
|
||||
AnimFPS = DEFAULT_FPS
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b0342124b298f0428adfc94c9d6d972
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63ad32ae8f64ef1449e51fe4460570a8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,348 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BrewMonster.Scripts.Chat.EmotionData;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert một bộ: ghi atlas (hoặc slice tại chỗ) + TextureImporter Sprite Multiple full lưới,
|
||||
/// gán FrameSprites theo tên cell_XXXX khớp C++ (row-major, hàng trên = row 0).
|
||||
/// </summary>
|
||||
public static class EmotionAtlasConverterCore
|
||||
{
|
||||
public const string CellSpriteNamePrefix = "cell_";
|
||||
|
||||
public static string CellSpriteName(int cellIndex) => $"{CellSpriteNamePrefix}{cellIndex:D4}";
|
||||
|
||||
/// <param name="sliceInPlace">true = chỉnh importer trên asset atlas hiện tại (ghi đè import settings). false = copy PNG vào thư mục output rồi slice (an toàn hơn).</param>
|
||||
public static bool ConvertOneSet(
|
||||
Texture2D sourceAtlas,
|
||||
TextAsset txtAsset,
|
||||
int emotionSetIndex,
|
||||
int cellW,
|
||||
int cellH,
|
||||
string outputRootFolder,
|
||||
bool sliceInPlace,
|
||||
out EmotionSetSnapshot snapshot,
|
||||
out string error)
|
||||
{
|
||||
snapshot = null;
|
||||
error = null;
|
||||
|
||||
if (sourceAtlas == null)
|
||||
{
|
||||
error = "Atlas null.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (txtAsset == null)
|
||||
{
|
||||
error = "TextAsset null.";
|
||||
return false;
|
||||
}
|
||||
|
||||
string sourceAtlasPath = AssetDatabase.GetAssetPath(sourceAtlas);
|
||||
if (string.IsNullOrEmpty(sourceAtlasPath))
|
||||
{
|
||||
error = "Atlas không phải asset trong project.";
|
||||
return false;
|
||||
}
|
||||
|
||||
var parseResult = EmotionTxtParser.Parse(txtAsset.text);
|
||||
if (!parseResult.Success)
|
||||
{
|
||||
error = parseResult.ErrorMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cellW <= 0 || cellH <= 0)
|
||||
{
|
||||
error = "Cell size phải > 0.";
|
||||
return false;
|
||||
}
|
||||
|
||||
Texture2D readable = GetReadableTexture(sourceAtlas);
|
||||
if (readable == null)
|
||||
{
|
||||
error = "Không đọc được pixel từ atlas.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int texW = readable.width;
|
||||
int texH = readable.height;
|
||||
if (texW % cellW != 0 || texH % cellH != 0)
|
||||
{
|
||||
error = $"Texture ({texW}x{texH}) không chia hết cho cell ({cellW}x{cellH}).";
|
||||
return false;
|
||||
}
|
||||
|
||||
int nNumX = texW / cellW;
|
||||
int nNumY = texH / cellH;
|
||||
int totalCells = nNumX * nNumY;
|
||||
|
||||
foreach (var e in parseResult.Entries)
|
||||
{
|
||||
if (e.NumFrames > 0 && e.StartPos + e.NumFrames - 1 >= totalCells)
|
||||
{
|
||||
error = $"Set {emotionSetIndex}: StartPos={e.StartPos}, NumFrames={e.NumFrames} vượt lưới ({totalCells} ô).";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EnsureFolder(outputRootFolder);
|
||||
string setFolder = $"{outputRootFolder}/Emotions{emotionSetIndex}";
|
||||
if (!AssetDatabase.IsValidFolder(setFolder))
|
||||
AssetDatabase.CreateFolder(outputRootFolder, $"Emotions{emotionSetIndex}");
|
||||
|
||||
string atlasAssetPath;
|
||||
Texture2D atlasForSo;
|
||||
|
||||
if (sliceInPlace)
|
||||
{
|
||||
atlasAssetPath = sourceAtlasPath;
|
||||
if (!ApplyMultipleSpriteSheet(atlasAssetPath, texW, texH, cellW, cellH, nNumX, nNumY, out error))
|
||||
return false;
|
||||
atlasForSo = AssetDatabase.LoadAssetAtPath<Texture2D>(atlasAssetPath);
|
||||
if (atlasForSo == null)
|
||||
{
|
||||
error = "Không load lại Texture2D sau slice.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string fileName = $"Emotions{emotionSetIndex}_atlas.png";
|
||||
atlasAssetPath = $"{setFolder}/{fileName}";
|
||||
byte[] png = readable.EncodeToPNG();
|
||||
File.WriteAllBytes(atlasAssetPath, png);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
if (!ApplyMultipleSpriteSheet(atlasAssetPath, texW, texH, cellW, cellH, nNumX, nNumY, out error))
|
||||
return false;
|
||||
|
||||
atlasForSo = AssetDatabase.LoadAssetAtPath<Texture2D>(atlasAssetPath);
|
||||
if (atlasForSo == null)
|
||||
{
|
||||
error = $"Không load texture tại {atlasAssetPath}";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var spriteByName = LoadSpritesByName(atlasAssetPath);
|
||||
if (spriteByName.Count < totalCells)
|
||||
{
|
||||
error = $"Chỉ tìm thấy {spriteByName.Count}/{totalCells} sprite sau import.";
|
||||
return false;
|
||||
}
|
||||
|
||||
snapshot = new EmotionSetSnapshot
|
||||
{
|
||||
EmotionSetIndex = emotionSetIndex,
|
||||
CellWidth = cellW,
|
||||
CellHeight = cellH,
|
||||
SourceAtlas = atlasForSo,
|
||||
SourceTxtAssetPath = AssetDatabase.GetAssetPath(txtAsset),
|
||||
Entries = new List<EmotionEntryData>()
|
||||
};
|
||||
|
||||
foreach (var src in parseResult.Entries)
|
||||
{
|
||||
var copy = new EmotionEntryData
|
||||
{
|
||||
StartPos = src.StartPos,
|
||||
NumFrames = src.NumFrames,
|
||||
Hint = src.Hint,
|
||||
FrameTicks = (int[])src.FrameTicks.Clone(),
|
||||
FrameSprites = new Sprite[src.NumFrames]
|
||||
};
|
||||
|
||||
for (int f = 0; f < src.NumFrames; f++)
|
||||
{
|
||||
int cellIndex = src.StartPos + f;
|
||||
string key = CellSpriteName(cellIndex);
|
||||
if (!spriteByName.TryGetValue(key, out var spr) || spr == null)
|
||||
{
|
||||
error = $"Thiếu sprite '{key}' trong atlas.";
|
||||
return false;
|
||||
}
|
||||
|
||||
copy.FrameSprites[f] = spr;
|
||||
}
|
||||
|
||||
snapshot.Entries.Add(copy);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (readable != null && readable != sourceAtlas)
|
||||
Object.DestroyImmediate(readable);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ApplyMultipleSpriteSheet(
|
||||
string assetPath,
|
||||
int texW,
|
||||
int texH,
|
||||
int cellW,
|
||||
int cellH,
|
||||
int nNumX,
|
||||
int nNumY,
|
||||
out string error)
|
||||
{
|
||||
error = null;
|
||||
var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
if (importer == null)
|
||||
{
|
||||
error = $"Không mở TextureImporter: {assetPath}";
|
||||
return false;
|
||||
}
|
||||
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.spriteImportMode = SpriteImportMode.Multiple;
|
||||
importer.spritePixelsPerUnit = 100;
|
||||
importer.mipmapEnabled = false;
|
||||
importer.alphaIsTransparency = true;
|
||||
importer.maxTextureSize = Mathf.Max(importer.maxTextureSize, Mathf.Max(texW, texH));
|
||||
importer.spritesheet = BuildSpriteMetaData(texW, texH, cellW, cellH, nNumX, nNumY);
|
||||
|
||||
importer.SetPlatformTextureSettings(new TextureImporterPlatformSettings
|
||||
{
|
||||
name = "Default",
|
||||
overridden = false
|
||||
});
|
||||
|
||||
importer.SaveAndReimport();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static SpriteMetaData[] BuildSpriteMetaData(int texW, int texH, int cellW, int cellH, int nNumX, int nNumY)
|
||||
{
|
||||
var list = new List<SpriteMetaData>(nNumX * nNumY);
|
||||
for (int row = 0; row < nNumY; row++)
|
||||
{
|
||||
for (int col = 0; col < nNumX; col++)
|
||||
{
|
||||
int cellIndex = row * nNumX + col;
|
||||
float x = col * cellW;
|
||||
float y = texH - (row + 1) * cellH;
|
||||
list.Add(new SpriteMetaData
|
||||
{
|
||||
name = CellSpriteName(cellIndex),
|
||||
rect = new Rect(x, y, cellW, cellH),
|
||||
pivot = new Vector2(0.5f, 0.5f),
|
||||
alignment = (int)SpriteAlignment.Center,
|
||||
border = Vector4.zero
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
private static Dictionary<string, Sprite> LoadSpritesByName(string atlasAssetPath)
|
||||
{
|
||||
var map = new Dictionary<string, Sprite>();
|
||||
foreach (var o in AssetDatabase.LoadAllAssetsAtPath(atlasAssetPath))
|
||||
{
|
||||
if (o is Sprite sp && !string.IsNullOrEmpty(sp.name))
|
||||
map[sp.name] = sp;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public static void EnsureFolder(string folder)
|
||||
{
|
||||
if (AssetDatabase.IsValidFolder(folder))
|
||||
return;
|
||||
|
||||
string parent = "Assets";
|
||||
foreach (var part in folder.Replace('\\', '/').Split('/'))
|
||||
{
|
||||
if (string.IsNullOrEmpty(part) || part == "Assets")
|
||||
continue;
|
||||
string newPath = parent + "/" + part;
|
||||
if (!AssetDatabase.IsValidFolder(newPath))
|
||||
AssetDatabase.CreateFolder(parent, part);
|
||||
parent = newPath;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ApplySnapshotToSetSO(EmotionSetDataSO so, EmotionSetSnapshot snap)
|
||||
{
|
||||
if (so == null || snap == null) return;
|
||||
so.EmotionSetIndex = snap.EmotionSetIndex;
|
||||
so.CellWidth = snap.CellWidth;
|
||||
so.CellHeight = snap.CellHeight;
|
||||
so.SourceAtlas = snap.SourceAtlas;
|
||||
so.SourceTxtAssetPath = snap.SourceTxtAssetPath;
|
||||
so.Entries.Clear();
|
||||
foreach (var e in snap.Entries)
|
||||
so.Entries.Add(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kiểm tra trùng EmotionSetIndex giữa các slot đang có đủ Atlas+Txt.
|
||||
/// </summary>
|
||||
public static bool TryValidateBatchIndices(IReadOnlyList<EmotionBatchSlot> slots, out string error)
|
||||
{
|
||||
error = null;
|
||||
var used = new HashSet<int>();
|
||||
foreach (var s in slots)
|
||||
{
|
||||
if (s?.Atlas == null && s?.Txt == null)
|
||||
continue;
|
||||
if (s.Atlas == null || s.Txt == null)
|
||||
continue;
|
||||
if (!used.Add(s.EmotionSetIndex))
|
||||
{
|
||||
error = $"Trùng Emotion set index: {s.EmotionSetIndex}";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Texture2D GetReadableTexture(Texture2D atlas)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dup = new Texture2D(atlas.width, atlas.height, TextureFormat.RGBA32, false);
|
||||
var prev = RenderTexture.active;
|
||||
var rt = RenderTexture.GetTemporary(atlas.width, atlas.height, 0, RenderTextureFormat.ARGB32);
|
||||
Graphics.Blit(atlas, rt);
|
||||
RenderTexture.active = rt;
|
||||
dup.ReadPixels(new Rect(0, 0, atlas.width, atlas.height), 0, 0);
|
||||
dup.Apply(false, false);
|
||||
RenderTexture.active = prev;
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
return dup;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Một dòng batch: index bộ (N) + atlas + txt — có thể thêm/bớt trong cửa sổ tool.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class EmotionBatchSlot
|
||||
{
|
||||
[Tooltip("N trong Emotions{N} (thư mục output & tên file atlas copy).")]
|
||||
public int EmotionSetIndex;
|
||||
|
||||
public Texture2D Atlas;
|
||||
public TextAsset Txt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38dfc1555b7238a4c99647d8d8dcb7e4
|
||||
@@ -0,0 +1,229 @@
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.Scripts.Chat.EmotionData;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Tool: atlas + txt → Sprite Mode Multiple (một PNG/bộ) + SO; batch linh hoạt số slot.
|
||||
/// </summary>
|
||||
public class EmotionAtlasConverterWindow : EditorWindow
|
||||
{
|
||||
private Texture2D _sourceAtlas;
|
||||
private TextAsset _txtAsset;
|
||||
private int _emotionSetIndex;
|
||||
private int _cellW = 32;
|
||||
private int _cellH = 32;
|
||||
private string _outputFolder = "Assets/PerfectWorld/UI/Chat/GeneratedEmotions";
|
||||
private bool _sliceInPlace;
|
||||
|
||||
private List<EmotionBatchSlot> _batchSlots = new List<EmotionBatchSlot>();
|
||||
private Vector2 _batchScroll;
|
||||
|
||||
private string _libraryAssetPath = "Assets/PerfectWorld/UI/Chat/GeneratedEmotions/EmotionLibrary.asset";
|
||||
|
||||
[MenuItem("Tools/Perfect World/ChatSystem/Emotion Atlas Converter…")]
|
||||
public static void Open()
|
||||
{
|
||||
GetWindow<EmotionAtlasConverterWindow>(true, "Emotion Atlas Converter", true);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_batchSlots == null)
|
||||
_batchSlots = new List<EmotionBatchSlot>();
|
||||
if (_batchSlots.Count == 0)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
_batchSlots.Add(new EmotionBatchSlot { EmotionSetIndex = i });
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Chung / Shared", EditorStyles.boldLabel);
|
||||
_cellW = EditorGUILayout.IntField("Cell width (W)", _cellW);
|
||||
_cellH = EditorGUILayout.IntField("Cell height (H)", _cellH);
|
||||
_outputFolder = EditorGUILayout.TextField("Output folder", _outputFolder);
|
||||
_sliceInPlace = EditorGUILayout.ToggleLeft(
|
||||
"Slice tại asset nguồn (ghi đè import Multiple lên atlas đang chọn) — Slice in-place on source asset",
|
||||
_sliceInPlace);
|
||||
if (_sliceInPlace)
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
"Cảnh báo: Unity sẽ đổi import của file atlas gốc thành Sprite Multiple full lưới.\n" +
|
||||
"Warning: overwrites source texture import settings.",
|
||||
MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
"Mặc định: copy atlas vào Output/Emotions{N}/Emotions{N}_atlas.png rồi Multiple slice (giữ nguyên file nguồn).\n" +
|
||||
"Default: copy atlas to output folder then slice (source unchanged).",
|
||||
MessageType.None);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(8f);
|
||||
EditorGUILayout.LabelField("Một bộ / Single set", EditorStyles.boldLabel);
|
||||
_sourceAtlas = (Texture2D)EditorGUILayout.ObjectField("Atlas", _sourceAtlas, typeof(Texture2D), false);
|
||||
_txtAsset = (TextAsset)EditorGUILayout.ObjectField("EmotionsN.txt", _txtAsset, typeof(TextAsset), false);
|
||||
_emotionSetIndex = EditorGUILayout.IntField("Emotion set index (N)", _emotionSetIndex);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button("Convert → EmotionSetData + Atlas (Multiple)"))
|
||||
{
|
||||
RunConvertSingle();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(12f);
|
||||
EditorGUILayout.LabelField("Batch → EmotionLibrary", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("+ Thêm slot", GUILayout.Width(100)))
|
||||
_batchSlots.Add(new EmotionBatchSlot { EmotionSetIndex = NextSuggestedSetIndex() });
|
||||
if (GUILayout.Button("− Xóa slot cuối", GUILayout.Width(120)) && _batchSlots.Count > 0)
|
||||
_batchSlots.RemoveAt(_batchSlots.Count - 1);
|
||||
EditorGUILayout.LabelField($"Số slot: {_batchSlots.Count}");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
_batchScroll = EditorGUILayout.BeginScrollView(_batchScroll, GUILayout.MinHeight(160f));
|
||||
for (int i = 0; i < _batchSlots.Count; i++)
|
||||
{
|
||||
var slot = _batchSlots[i];
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField($"#{i}", GUILayout.Width(24));
|
||||
slot.EmotionSetIndex = EditorGUILayout.IntField("Set N", slot.EmotionSetIndex, GUILayout.Width(120));
|
||||
slot.Atlas = (Texture2D)EditorGUILayout.ObjectField(slot.Atlas, typeof(Texture2D), false);
|
||||
slot.Txt = (TextAsset)EditorGUILayout.ObjectField(slot.Txt, typeof(TextAsset), false);
|
||||
if (GUILayout.Button("×", GUILayout.Width(22)))
|
||||
{
|
||||
_batchSlots.RemoveAt(i);
|
||||
i--;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
continue;
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
_libraryAssetPath = EditorGUILayout.TextField("Library .asset path", _libraryAssetPath);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
if (GUILayout.Button("Convert batch → EmotionLibrary.asset"))
|
||||
{
|
||||
RunConvertLibrary();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(8f);
|
||||
EditorGUILayout.HelpBox(
|
||||
"Mỗi bộ: một texture **Sprite Multiple**, tên sub-sprite `cell_0000` … theo chỉ số ô (giống C++).\n" +
|
||||
"Each set: one **Sprite Multiple** texture; sub-sprite names `cell_0000` … by cell index.",
|
||||
MessageType.Info);
|
||||
}
|
||||
|
||||
private int NextSuggestedSetIndex()
|
||||
{
|
||||
int max = -1;
|
||||
foreach (var s in _batchSlots)
|
||||
{
|
||||
if (s.EmotionSetIndex > max)
|
||||
max = s.EmotionSetIndex;
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
private void RunConvertSingle()
|
||||
{
|
||||
if (!EmotionAtlasConverterCore.ConvertOneSet(
|
||||
_sourceAtlas, _txtAsset, _emotionSetIndex, _cellW, _cellH, _outputFolder, _sliceInPlace,
|
||||
out var snapshot, out string err))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", err, "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
var so = ScriptableObject.CreateInstance<EmotionSetDataSO>();
|
||||
EmotionAtlasConverterCore.ApplySnapshotToSetSO(so, snapshot);
|
||||
string setFolder = $"{_outputFolder}/Emotions{_emotionSetIndex}";
|
||||
string soPath = $"{setFolder}/EmotionSetData_{_emotionSetIndex}.asset";
|
||||
AssetDatabase.CreateAsset(so, soPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
EditorUtility.DisplayDialog("Done", $"Đã tạo:\n{soPath}\nAtlas (Multiple) trong thư mục set (hoặc đã slice tại nguồn).", "OK");
|
||||
EditorGUIUtility.PingObject(so);
|
||||
}
|
||||
|
||||
private void RunConvertLibrary()
|
||||
{
|
||||
if (!EmotionAtlasConverterCore.TryValidateBatchIndices(_batchSlots, out string dupErr))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", dupErr, "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
var library = ScriptableObject.CreateInstance<EmotionLibrarySO>();
|
||||
library.Sets.Clear();
|
||||
|
||||
int ok = 0;
|
||||
int total = _batchSlots.Count;
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
var slot = _batchSlots[i];
|
||||
if (slot.Atlas == null && slot.Txt == null)
|
||||
continue;
|
||||
|
||||
if (slot.Atlas == null || slot.Txt == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error",
|
||||
$"Slot #{i} (Set N={slot.EmotionSetIndex}): cần cả Atlas và TXT.",
|
||||
"OK");
|
||||
Object.DestroyImmediate(library);
|
||||
return;
|
||||
}
|
||||
|
||||
EditorUtility.DisplayProgressBar("Emotion Library", $"Set {slot.EmotionSetIndex}…", (float)i / Mathf.Max(1, total));
|
||||
|
||||
if (!EmotionAtlasConverterCore.ConvertOneSet(
|
||||
slot.Atlas, slot.Txt, slot.EmotionSetIndex, _cellW, _cellH, _outputFolder, _sliceInPlace,
|
||||
out var snapshot, out string err))
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Error", $"Set {slot.EmotionSetIndex}: {err}", "OK");
|
||||
Object.DestroyImmediate(library);
|
||||
return;
|
||||
}
|
||||
|
||||
library.Sets.Add(snapshot);
|
||||
ok++;
|
||||
}
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
if (ok == 0)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", "Không có cặp Atlas+TXT hợp lệ.", "OK");
|
||||
Object.DestroyImmediate(library);
|
||||
return;
|
||||
}
|
||||
|
||||
string dir = System.IO.Path.GetDirectoryName(_libraryAssetPath)?.Replace('\\', '/') ?? _outputFolder;
|
||||
if (!string.IsNullOrEmpty(dir))
|
||||
EmotionAtlasConverterCore.EnsureFolder(dir);
|
||||
|
||||
AssetDatabase.CreateAsset(library, _libraryAssetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
EditorUtility.DisplayDialog("Done",
|
||||
$"EmotionLibrary: {ok} bộ.\n{_libraryAssetPath}",
|
||||
"OK");
|
||||
EditorGUIUtility.PingObject(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd89b10678fe79046af39970b5c83b4c
|
||||
@@ -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,9 @@ 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));
|
||||
pClone.ResetHookPosition();
|
||||
if(pNaviCtrl.GetCurrentNavigateInfo().bezierDir)
|
||||
{
|
||||
pClone.ChangeModelMoveDirAndUp(vDir, vUp);
|
||||
@@ -1016,86 +1046,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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user