convert continue :)))
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public class CECTaoistRank
|
||||
{
|
||||
private int m_id; // ���漶���ID
|
||||
private string m_name; // ���漶���ID
|
||||
private CECTaoistRank m_next;
|
||||
|
||||
static bool initComplete = false;
|
||||
public static CECTaoistRank[] s_allTaoistRanks = new CECTaoistRank[(int)ToaistRank.TotalRankCount];
|
||||
public static readonly int[] TaoistRankIDs = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 20, 21, 22, 30, 31, 32 };
|
||||
|
||||
public bool IsGodRank()
|
||||
{
|
||||
|
||||
CECTaoistRank GodRank;
|
||||
for (GodRank = GetGodRankBegin(); GodRank != GetGodRankEnd();
|
||||
GodRank = GodRank.GetNext())
|
||||
{
|
||||
if (this == GodRank)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public CECTaoistRank GetGodRankBegin()
|
||||
{
|
||||
init();
|
||||
return s_allTaoistRanks[(int)ToaistRank.BaseRankCount];
|
||||
}
|
||||
|
||||
public CECTaoistRank GetGodRankEnd()
|
||||
{
|
||||
init();
|
||||
return GetLastGodRank().m_next;
|
||||
}
|
||||
public CECTaoistRank GetLastGodRank()
|
||||
{
|
||||
init();
|
||||
return s_allTaoistRanks[(int)ToaistRank.BaseRankCount + (int)ToaistRank.GodRankCount - 1];
|
||||
}
|
||||
public bool IsEvilRank()
|
||||
{
|
||||
CECTaoistRank EvilRank;
|
||||
for (EvilRank = GetEvilRankBegin(); EvilRank != GetEvilRankEnd();
|
||||
EvilRank = EvilRank.GetNext())
|
||||
{
|
||||
if (this == EvilRank)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public CECTaoistRank GetNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
public static CECTaoistRank GetEvilRankBegin()
|
||||
{
|
||||
init();
|
||||
return s_allTaoistRanks[(int)ToaistRank.BaseRankCount + (int)ToaistRank.GodRankCount];
|
||||
}
|
||||
public static CECTaoistRank GetEvilRankEnd()
|
||||
{
|
||||
init();
|
||||
return GetLastEvilRank().m_next;
|
||||
}
|
||||
public static CECTaoistRank GetLastEvilRank()
|
||||
{
|
||||
init();
|
||||
return s_allTaoistRanks[(int)ToaistRank.TotalRankCount - 1];
|
||||
}
|
||||
public static CECTaoistRank GetTaoistRank(int id)
|
||||
{
|
||||
init();
|
||||
for (int i = 0; i < (int)ToaistRank.TotalRankCount; i++)
|
||||
{
|
||||
if (TaoistRankIDs[i] == id)
|
||||
{
|
||||
return s_allTaoistRanks[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static void init()
|
||||
{
|
||||
if (initComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < (int)ToaistRank.TotalRankCount; i++)
|
||||
{
|
||||
s_allTaoistRanks[i].m_id = TaoistRankIDs[i];
|
||||
/* s_allTaoistRanks[i].m_name =
|
||||
g_pGame->GetGameRun()->GetUIManager()->GetInGameUIMan()->GetStringFromTable(1001 + s_allTaoistRanks[i].m_id);*/
|
||||
if (i != (int)ToaistRank.BaseRankCount - 1 &&
|
||||
i != (int)ToaistRank.BaseRankCount + (int)ToaistRank.GodRankCount - 1 &&
|
||||
i != (int)ToaistRank.TotalRankCount - 1)
|
||||
{
|
||||
s_allTaoistRanks[i].m_next = s_allTaoistRanks[i + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
s_allTaoistRanks[i].m_next = null;
|
||||
}
|
||||
}
|
||||
initComplete = true;
|
||||
}
|
||||
|
||||
}
|
||||
public enum ToaistRank
|
||||
{
|
||||
TotalRankCount = 15,
|
||||
BaseRankCount = 9,
|
||||
GodRankCount = 3,
|
||||
EvilRankCount = 3,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0af7ab2d9c8f26f409468880e8e6e951
|
||||
@@ -1109,7 +1109,19 @@ namespace CSNetwork.GPDataType
|
||||
public const float MIN_MOVELEN_ON_GROUND = 0.5f;
|
||||
public const float MIN_MOVELEN_FOR_DETECT_VIBRATION = 0.05f;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_scene_service_npc_list
|
||||
{
|
||||
public uint count;
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct NpcEntry
|
||||
{
|
||||
public int tid; // npc template id
|
||||
public int nid; // npc id
|
||||
}
|
||||
public NpcEntry[] list;
|
||||
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct cmd_npc_info_list
|
||||
{
|
||||
|
||||
@@ -17,7 +17,10 @@ namespace CSNetwork
|
||||
_buffer = new byte[capacity];
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_size = 0; // reset logical length
|
||||
}
|
||||
public Octets(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d8aa48b7719fb24ea83a779c1bf10eb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public class CECObservableChange : IDisposable
|
||||
{
|
||||
public virtual void Dispose()
|
||||
{
|
||||
// Cleanup logic here
|
||||
}
|
||||
};
|
||||
|
||||
public class CECObserver
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85f9d76b7820b1445aefd08f3f700001
|
||||
@@ -1,12 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using ModelRenderer.Scripts.GameData;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BrewMonster.Scripts.Skills
|
||||
{
|
||||
class CECHostSkillModel
|
||||
{
|
||||
public static CECHostSkillModel instance;
|
||||
public static CECHostSkillModel Instance {
|
||||
public static CECHostSkillModel Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
@@ -20,23 +25,243 @@ namespace BrewMonster.Scripts.Skills
|
||||
}
|
||||
Dictionary<int, ElementSkill> m_allProfSkills = new Dictionary<int, ElementSkill>();
|
||||
Dictionary<int, List<int>> m_allRankProfSkills = new Dictionary<int, List<int>>();
|
||||
private HashSet<int> m_allProfNPCs = new HashSet<int>();
|
||||
private Dictionary<int, int> m_treeHeightMap = new Dictionary<int, int>();
|
||||
private Dictionary<int, int> m_evilRootMap = new Dictionary<int, int>();
|
||||
private Dictionary<int, int> m_godRootMap = new Dictionary<int, int>();
|
||||
private Dictionary<int, int> m_baseRootMap = new Dictionary<int, int>();
|
||||
private int m_skillLearnNPCNID;
|
||||
private bool m_bInitialized;
|
||||
private Octets m_npcListData;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Çå¿ÕËùÓм¼ÄÜ£¬·ÀÖ¹ÒòΪ¶à¸ö½ÇÉ«µÇ¼µ¼ÖÂÖØ¸´¼ÓÔØ¼¼ÄÜ
|
||||
Release();
|
||||
|
||||
InitAllSkillsOfCurProf();
|
||||
/*FindAllNPCsOfCurProf();
|
||||
std::set<int> rootSkills = GetRootSkillSet();
|
||||
FindAllNPCsOfCurProf();
|
||||
HashSet<int> rootSkills = GetRootSkillSet();
|
||||
InitSkillTreeHeightMap(rootSkills);
|
||||
InitSkillTreeRootMap(rootSkills);
|
||||
|
||||
m_bInitialized = true;
|
||||
|
||||
// ÖØÐ´¦ÀíNPCLIST
|
||||
ProcessServiceList();*/
|
||||
ProcessServiceList();
|
||||
}
|
||||
public void ProcessServiceList()
|
||||
{
|
||||
if (m_npcListData.Size > 0)
|
||||
{
|
||||
byte[] data = m_npcListData.RawBuffer;
|
||||
int headerSize = Marshal.SizeOf(typeof(cmd_header));
|
||||
|
||||
int offset = headerSize;
|
||||
int bodySize = m_npcListData.Size - offset;
|
||||
byte[] bodyBytes = new byte[bodySize];
|
||||
Buffer.BlockCopy(data, offset, bodyBytes, 0, bodySize);
|
||||
|
||||
cmd_scene_service_npc_list npcList = GPDataTypeHelper.FromBytes<cmd_scene_service_npc_list>(bodyBytes);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < npcList.count; i++)
|
||||
{
|
||||
int tid = npcList.list[i].tid;
|
||||
|
||||
if (m_allProfNPCs.Contains(tid))
|
||||
{
|
||||
if (m_skillLearnNPCNID != npcList.list[i].nid)
|
||||
{
|
||||
m_skillLearnNPCNID = npcList.list[i].nid;
|
||||
SetCurServiceSkills(tid);
|
||||
var change = new CECSkillPanelChange(CECSkillPanelChange.enumChangeMask.CHANGE_SKILL_NPC, 0, 0);
|
||||
//NotifyObservers(change);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == npcList.count && m_skillLearnNPCNID != 0)
|
||||
{
|
||||
m_skillLearnNPCNID = 0;
|
||||
SetCurServiceSkills(0);
|
||||
var change = new CECSkillPanelChange(CECSkillPanelChange.enumChangeMask.CHANGE_SKILL_NPC, 0, 0);
|
||||
//NotifyObservers(change);
|
||||
}
|
||||
|
||||
m_npcListData.Clear();
|
||||
}
|
||||
}
|
||||
private readonly HashSet<int> m_curServiceSkills = new HashSet<int>();
|
||||
|
||||
public void SetCurServiceSkills(int tid)
|
||||
{
|
||||
m_curServiceSkills.Clear();
|
||||
if (tid == 0)
|
||||
return;
|
||||
|
||||
var pDB = ElementDataManProvider.GetElementDataMan();
|
||||
|
||||
// Read NPC_ESSENCE from element data
|
||||
DATA_TYPE dt = default;
|
||||
var dataprt = pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
if (dataprt == null)
|
||||
return;
|
||||
var npcEssence = (NPC_ESSENCE)dataprt;
|
||||
|
||||
// Get skill service block from id_skill_service
|
||||
var dataprt2 = pDB.get_data_ptr((uint)tid, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
if (dataprt2 == null)
|
||||
return;
|
||||
|
||||
var skillService = (NPC_SKILL_SERVICE)dataprt2;
|
||||
// Copy all non-zero skill ids into m_curServiceSkills
|
||||
foreach (int skillId in skillService.id_skills)
|
||||
{
|
||||
if (skillId != 0)
|
||||
m_curServiceSkills.Add(skillId);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitSkillTreeRootMap(IEnumerable<int> rootSkills)
|
||||
{
|
||||
foreach (int rootSkillID in rootSkills)
|
||||
{
|
||||
InitializeRootOfSkillTree(rootSkillID);
|
||||
}
|
||||
}
|
||||
private void InitializeRootOfSkillTree(int rootSkillID)
|
||||
{
|
||||
var skillRootMap = GetSkillRootMap(rootSkillID);
|
||||
var toTravelSkills = new Queue<int>();
|
||||
toTravelSkills.Enqueue(rootSkillID);
|
||||
|
||||
while (toTravelSkills.Count > 0)
|
||||
{
|
||||
int skillID = toTravelSkills.Dequeue();
|
||||
var juniors = GetJunior(skillID);
|
||||
|
||||
foreach (var (id, level) in juniors)
|
||||
{
|
||||
int juniorSkillID = (int)id;
|
||||
skillRootMap[juniorSkillID] = rootSkillID;
|
||||
toTravelSkills.Enqueue(juniorSkillID);
|
||||
}
|
||||
}
|
||||
}
|
||||
private Dictionary<int, int> GetSkillRootMap(int rootSkillID)
|
||||
{
|
||||
var skill = m_allProfSkills[rootSkillID];
|
||||
var taoistRank = CECTaoistRank.GetTaoistRank(skill.GetRank());
|
||||
|
||||
if (taoistRank.IsEvilRank())
|
||||
return m_evilRootMap;
|
||||
else if (taoistRank.IsGodRank())
|
||||
return m_godRootMap;
|
||||
else
|
||||
return m_baseRootMap;
|
||||
}
|
||||
|
||||
private void InitSkillTreeHeightMap(IEnumerable<int> rootSkills)
|
||||
{
|
||||
foreach (var rootSkillID in rootSkills)
|
||||
{
|
||||
m_treeHeightMap[rootSkillID] = GetSkillTreeHeight(rootSkillID);
|
||||
}
|
||||
}
|
||||
private int GetSkillTreeHeight(int rootSkillID)
|
||||
{
|
||||
var juniors = GetJunior(rootSkillID);
|
||||
int maxHeight = 0;
|
||||
|
||||
for (int i = 0; i < juniors.Count; i++)
|
||||
{
|
||||
int subHeight = GetSkillTreeHeight((int)juniors[i].id);
|
||||
if (subHeight > maxHeight)
|
||||
{
|
||||
maxHeight = subHeight;
|
||||
}
|
||||
}
|
||||
|
||||
return 1 + maxHeight;
|
||||
}
|
||||
private List<(uint id, int level)> GetJunior(int skillID)
|
||||
{
|
||||
if (!m_allProfSkills.TryGetValue(skillID, out var skill))
|
||||
{
|
||||
throw new Exception($"Skill {skillID} not found in m_allProfSkills");
|
||||
}
|
||||
|
||||
var juniors = skill.GetJunior();
|
||||
var ret = new List<(uint id, int level)>();
|
||||
|
||||
foreach (var (id, level) in juniors)
|
||||
{
|
||||
if (id != 0)
|
||||
ret.Add((id, level));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
private HashSet<int> GetRootSkillSet()
|
||||
{
|
||||
var rootSkills = new HashSet<int>();
|
||||
|
||||
foreach (var kvp in m_allProfSkills)
|
||||
if (kvp.Value.GetJunior().Count != 0)
|
||||
rootSkills.Add(kvp.Key);
|
||||
|
||||
foreach (var kvp in m_allProfSkills)
|
||||
foreach (var (id, level) in kvp.Value.GetJunior())
|
||||
rootSkills.Remove((int)id);
|
||||
|
||||
return rootSkills;
|
||||
}
|
||||
private void FindAllNPCsOfCurProf()
|
||||
{
|
||||
DATA_TYPE dt = DATA_TYPE.DT_NPC_ESSENCE;
|
||||
elementdataman pDB = ElementDataManProvider.GetElementDataMan();
|
||||
var map = pDB.GetMap<Dictionary<uint, DATA_TYPE>>(ID_SPACE.ID_SPACE_ESSENCE);
|
||||
uint id;
|
||||
foreach (var item in map)
|
||||
{
|
||||
if (item.Value == dt)
|
||||
{
|
||||
id = item.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NPC_ESSENCE npcEssence = (NPC_ESSENCE)pDB.get_data_ptr(id, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
if (npcEssence.id_skill_service != 0 &&
|
||||
(npcEssence.combined_switch & (uint)NPC_COMBINED_SWITCH.NCS_IGNORE_DISTANCE_CHECK) != 0)
|
||||
{
|
||||
NPC_SKILL_SERVICE skillService = (NPC_SKILL_SERVICE)pDB.get_data_ptr(npcEssence.id_skill_service, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
bool profCorrect = false;
|
||||
for (int i = 0; i < skillService.id_skills.Length; i++)
|
||||
{
|
||||
if (skillService.id_skills[i] != 0)
|
||||
{
|
||||
ElementSkill pSkill = ElementSkill.Create(skillService.id_skills[i], 1);
|
||||
if (pSkill.GetCls() == GameController.Instance.GetHostPlayer().GetProfession())
|
||||
{
|
||||
// ��NPC������ǰְҵ���ܣ���Ҫ��¼��NPC��ID
|
||||
profCorrect = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (profCorrect)
|
||||
{
|
||||
m_allProfNPCs.Add((int)npcEssence.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public void InitAllSkillsOfCurProf()
|
||||
{
|
||||
// --- B1: Thu thập toàn bộ skill từ các NPC có cung cấp dịch vụ học skill ---
|
||||
@@ -57,13 +282,13 @@ namespace BrewMonster.Scripts.Skills
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NPC_ESSENCE npcEssence = (NPC_ESSENCE)pDB.get_data_ptr(id, ID_SPACE.ID_SPACE_ESSENCE,ref dt);
|
||||
|
||||
NPC_ESSENCE npcEssence = (NPC_ESSENCE)pDB.get_data_ptr(id, ID_SPACE.ID_SPACE_ESSENCE, ref dt);
|
||||
if (npcEssence.id_skill_service != 0 &&
|
||||
(npcEssence.combined_switch & (uint)NPC_COMBINED_SWITCH.NCS_IGNORE_DISTANCE_CHECK) != 0)
|
||||
{
|
||||
NPC_SKILL_SERVICE skillService = (NPC_SKILL_SERVICE)pDB.get_data_ptr(
|
||||
npcEssence.id_skill_service, ID_SPACE. ID_SPACE_ESSENCE, ref dt
|
||||
npcEssence.id_skill_service, ID_SPACE.ID_SPACE_ESSENCE, ref dt
|
||||
);
|
||||
|
||||
for (int i = 0; i < skillService.id_skills.Length; i++)
|
||||
@@ -85,7 +310,7 @@ namespace BrewMonster.Scripts.Skills
|
||||
{
|
||||
ElementSkill pSkill = ElementSkill.Create(curID, 1);
|
||||
int cls = pSkill.GetCls();
|
||||
int playerCls = GameController.Instance.GetHostPlayer().GetProfession();
|
||||
int playerCls = GameController.Instance.GetHostPlayer().GetProfession();
|
||||
|
||||
bool isSameClass = (cls == playerCls || cls == 255);
|
||||
bool isProvidedByNPC = npcSkills.Contains(curID);
|
||||
@@ -155,4 +380,25 @@ namespace BrewMonster.Scripts.Skills
|
||||
SKILL_EVIL, // �ɼ��� / Immortal skill
|
||||
SKILL_GOD, // ħ���� / Demonic skill
|
||||
}
|
||||
public class CECSkillPanelChange : CECObservableChange
|
||||
{
|
||||
public enum enumChangeMask
|
||||
{
|
||||
CHANGE_SKILL_LEVEL_UP, // Skill level up
|
||||
CHANGE_SKILL_OVERRIDDEN, // Skill overridden
|
||||
CHANGE_SKILL_NPC // NPC providing skill changed
|
||||
}
|
||||
|
||||
public enumChangeMask m_changeMask;
|
||||
public int m_skillID;
|
||||
public int m_skillLevel;
|
||||
|
||||
public CECSkillPanelChange(enumChangeMask mask, int id, int level)
|
||||
{
|
||||
m_changeMask = mask;
|
||||
m_skillID = id;
|
||||
m_skillLevel = level;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -141,7 +141,10 @@ namespace BrewMonster.Scripts.Skills
|
||||
{
|
||||
return Skill.Create(id, n);
|
||||
}
|
||||
// ��������
|
||||
public virtual List<(uint id, int level)> GetJunior()
|
||||
{
|
||||
return new List<(uint, int)>();
|
||||
}
|
||||
public virtual ushort[] GetName() { return null;}
|
||||
public virtual byte[] GetNativeName() { return null;}
|
||||
// �������?,��skill_type
|
||||
|
||||
Reference in New Issue
Block a user