diff --git a/Assets/PerfectWorld/Scripts/Common/ListExtensions.cs b/Assets/PerfectWorld/Scripts/Common/ListExtensions.cs new file mode 100644 index 0000000000..d0f9c93ce9 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Common/ListExtensions.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace BrewMonster +{ + public static class ListExtensions + { + public static int UniquelyAdd(this List list, T item) + { + int index = list.IndexOf(item); + if (index >= 0) + return index; + + list.Add(item); + return list.Count - 1; + } + } +} diff --git a/Assets/PerfectWorld/Scripts/Common/ListExtensions.cs.meta b/Assets/PerfectWorld/Scripts/Common/ListExtensions.cs.meta new file mode 100644 index 0000000000..c75dcf3739 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Common/ListExtensions.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: db1eed55761115545b7046325b4ab7f7 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/MainFiles/CECGameRun.cs b/Assets/PerfectWorld/Scripts/MainFiles/CECGameRun.cs index a9c86dc519..6eb2ace1d7 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/CECGameRun.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/CECGameRun.cs @@ -4,7 +4,7 @@ using CSNetwork.GPDataType; using System; using UnityEngine; -public class CECGameRun +public partial class CECGameRun { private CECWorld m_pWorld; public CECWorld GetWorld() { return m_pWorld; } diff --git a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs index ec08f8f7ca..797df2d886 100644 --- a/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs +++ b/Assets/PerfectWorld/Scripts/MainFiles/EC_Game.cs @@ -59,7 +59,7 @@ namespace BrewMonster.Network Debug.LogError("[Dat]- CECGame::Init, Storage task Init Failed!"); return false; } - m_pGameRun = new CECGameRun(); + m_pGameRun = CECGameRun.Instance; if (m_pGameRun == null) { BMLogger.LogError("CECGame::Init"); diff --git a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs index 3337bc63f4..53bbffc1ec 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECAttacksMan.cs @@ -322,9 +322,9 @@ bool DoFire() BMLogger.LogError("Target is null!"); return false; } - var vfx = GameController.Instance.GetTestVfx(); + var vfx = CECGameRun.Instance.GetTestVfx(); vfx.transform.position = target.position; - GameController.Instance.DestroyTestVfx(vfx, 1f); + CECGameRun.Instance.DestroyTestVfx(vfx, 1f); } } } diff --git a/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs index c3fccf240d..12a8b45717 100644 --- a/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs +++ b/Assets/PerfectWorld/Scripts/Managers/CECNPCMan.cs @@ -99,7 +99,7 @@ public class CECNPCMan : IMsgHandler RemoveNPCFromMiniMap(pNPC);*/ pNPC.m_iMMIndex = -1; - var hostplayer = GameController.Instance.GetHostPlayer(); + var hostplayer = CECGameRun.Instance.GetHostPlayer(); // If this NPC is selected by host, cancel the selection if (pNPC.GetNPCID() == hostplayer.GetSelectedTarget()) hostplayer.SelectTarget(0); @@ -128,7 +128,7 @@ public class CECNPCMan : IMsgHandler if (pNPC) { // Remove tab-selected array - CECHostPlayer pHost = GameController.Instance.GetHostPlayer(); + CECHostPlayer pHost = CECGameRun.Instance.GetHostPlayer(); if (pHost) pHost.RemoveObjectFromTabSels(pNPC); @@ -454,10 +454,10 @@ public class CECNPCMan : IMsgHandler switch (dataType) { case DATA_TYPE.DT_NPC_ESSENCE: - pNPC = GameController.Instance.GetNPCServer(); + pNPC = CECGameRun.Instance.GetNPCServer(); break; case DATA_TYPE.DT_MONSTER_ESSENCE: - pNPC = GameController.Instance.GetMonster(); + pNPC = CECGameRun.Instance.GetMonster(); break; case DATA_TYPE.DT_PET_ESSENCE:/* pNPC = new CECPet(this);*/ break; default: diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs index b8a7eef174..fbfd78838b 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs @@ -186,7 +186,7 @@ namespace PerfectWorld.Scripts.Managers } // Get the host player - var hostPlayer = GameController.Instance?.GetHostPlayer(); + var hostPlayer = CECGameRun.Instance?.GetHostPlayer(); if (hostPlayer == null) { Debug.LogWarning("Host player not found"); diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs index f8a29d7045..e9ba998a9b 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManPlayer.cs @@ -29,9 +29,9 @@ namespace PerfectWorld.Scripts.Managers { if (Msg.iSubID == 0) { - if (GameController.Instance == null) return true; - if (GameController.Instance.GetHostPlayer() == null) return true; - GameController.Instance.GetHostPlayer().ProcessMessage(Msg); + if (CECGameRun.Instance == null) return true; + if (CECGameRun.Instance.GetHostPlayer() == null) return true; + CECGameRun.Instance.GetHostPlayer().ProcessMessage(Msg); } else if (Msg.iSubID < 0) { @@ -89,7 +89,7 @@ namespace PerfectWorld.Scripts.Managers info_player_1 info_Player_1 = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); RoleInfo roleInfo = (RoleInfo)Msg.dwParam4; ElsePlayerEnter(info_Player_1, commandID, roleInfo); - GameController.Instance.Log("ElsePlayer has join"); + CECGameRun.Instance.Log("ElsePlayer has join"); } break; } @@ -256,7 +256,7 @@ namespace PerfectWorld.Scripts.Managers // isDoneWorldRender = value; // actLoadChar?.Invoke(); //}); - GameController.Instance.InitCharacter(info); + CECGameRun.Instance.InitCharacter(info); return true; } @@ -306,7 +306,7 @@ namespace PerfectWorld.Scripts.Managers private EC_ElsePlayer CreateElsePlayer(RoleInfo roleInfo, info_player_1 info, int iAppearFlag) { - GameObject ob = GameController.Instance.InitCharacter(info); + GameObject ob = CECGameRun.Instance.InitCharacter(info); EC_ElsePlayer elsePlayer = ob.AddComponent(); elsePlayer.Init(roleInfo, info); @@ -412,7 +412,7 @@ namespace PerfectWorld.Scripts.Managers public bool TransmitMessage(ECMSG msg) { int cid = 0; - var host = GameController.Instance.GetHostPlayer(); + var host = CECGameRun.Instance.GetHostPlayer(); switch (msg.dwMsg) { @@ -483,7 +483,7 @@ namespace PerfectWorld.Scripts.Managers public CECHostPlayer GetHostPlayer() { - return GameController.Instance.GetHostPlayer(); + return CECGameRun.Instance.GetHostPlayer(); } } } diff --git a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs index fb153bbfea..bda13c3e0c 100644 --- a/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs +++ b/Assets/PerfectWorld/Scripts/NPC/CECNPC.cs @@ -160,7 +160,7 @@ public class CECNPC : CECObject m_cdr.fStepHeight = 0.4f; m_cdr.vVelocity.Clear(); - var pHost = GameController.Instance.GetHostPlayer(); + var pHost = CECGameRun.Instance.GetHostPlayer(); if (pHost != null) { m_fDistToHost = Vector3.Distance(m_vServerPos, pHost.transform.position); @@ -232,7 +232,7 @@ public class CECNPC : CECObject } } - var pHost = GameController.Instance.GetHostPlayer(); + var pHost = CECGameRun.Instance.GetHostPlayer(); int iDamage = -1; // Attacker is host's pet diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index e48f211ab5..41a433bc4a 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -1,22 +1,23 @@ -using System.Text; -using System; +using BrewMonster; +using BrewMonster.Managers; +using BrewMonster.Scripts.Player; +using BrewMonster.Scripts.Skills; +using CSNetwork.C2SCommand; +using CSNetwork.GPDataType; using CSNetwork.Protocols; using CSNetwork.Protocols.RPCData; using System; +using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; +using System.IO; +using System.Numerics; using System.Runtime.InteropServices; using System.Text; +using System.Text; using System.Threading.Tasks; using CommandID = CSNetwork.GPDataType.CommandID; -using System.IO; -using System.Diagnostics; -using System.Numerics; -using CSNetwork.C2SCommand; -using CSNetwork.GPDataType; -using BrewMonster; -using BrewMonster.Managers; -using BrewMonster.Scripts.Player; namespace CSNetwork { @@ -410,21 +411,21 @@ namespace CSNetwork break; case CommandID.OBJECT_STOP_MOVE: - { - int id1 = GPDataTypeHelper.FromBytes(pDataBuf); - if (ISPLAYERID(id1)) { - EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERSTOPMOVE, (int)MANAGER_INDEX.MAN_PLAYER, -1, - pDataBuf, pCmdHeader); - } - else if (ISNPCID(id1)) - { - EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCSTOPMOVE, (int)MANAGER_INDEX.MAN_NPC, 0, pDataBuf, - pCmdHeader); - } + int id1 = GPDataTypeHelper.FromBytes(pDataBuf); + if (ISPLAYERID(id1)) + { + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERSTOPMOVE, (int)MANAGER_INDEX.MAN_PLAYER, -1, + pDataBuf, pCmdHeader); + } + else if (ISNPCID(id1)) + { + EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCSTOPMOVE, (int)MANAGER_INDEX.MAN_NPC, 0, pDataBuf, + pCmdHeader); + } - break; - } + break; + } case CommandID.OWN_IVTR_DATA: case CommandID.OWN_IVTR_DETAIL_DATA: case CommandID.GET_OWN_MONEY: @@ -444,11 +445,11 @@ namespace CSNetwork pDataBuf, pCmdHeader); break; case CommandID.PLAYER_CASH: - { - EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_IVTRINFO, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, - pCmdHeader, iHostID); - break; - } + { + EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_IVTRINFO, (int)MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, + pCmdHeader, iHostID); + break; + } case CommandID.MATTER_INFO_LIST: EC_ManMessage.PostMessage(EC_MsgDef.MSG_MM_MATTERINFO, (int)MANAGER_INDEX.MAN_MATTER, 0, pDataBuf, pCmdHeader); @@ -589,23 +590,29 @@ namespace CSNetwork EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCDIED, MANAGER_INDEX.MAN_NPC, 0, pDataBuf, pCmdHeader); break; case CommandID.OBJECT_DISAPPEAR: - { - int lenghtDataType1 = Marshal.SizeOf(); - byte[] arrByteData1 = GetBytes(pDataBuf, lenghtDataType1, 0); - int idObjMove1 = BitConverter.ToInt32(arrByteData1); - if (ISPLAYERID(idObjMove1)) - EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERDISAPPEAR, MANAGER_INDEX.MAN_PLAYER, -1, - pDataBuf, pCmdHeader); - else if (ISNPCID(idObjMove1)) - EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCDISAPPEAR, MANAGER_INDEX.MAN_NPC, 0, pDataBuf, - pCmdHeader); + { + int lenghtDataType1 = Marshal.SizeOf(); + byte[] arrByteData1 = GetBytes(pDataBuf, lenghtDataType1, 0); + int idObjMove1 = BitConverter.ToInt32(arrByteData1); + if (ISPLAYERID(idObjMove1)) + EC_ManMessage.PostMessage(EC_MsgDef.MSG_PM_PLAYERDISAPPEAR, MANAGER_INDEX.MAN_PLAYER, -1, + pDataBuf, pCmdHeader); + else if (ISNPCID(idObjMove1)) + EC_ManMessage.PostMessage(EC_MsgDef.MSG_NM_NPCDISAPPEAR, MANAGER_INDEX.MAN_NPC, 0, pDataBuf, + pCmdHeader); - break; - } + break; + } case CommandID.SELF_INFO_00: EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_INFO00, MANAGER_INDEX.MAN_PLAYER, 0, pDataBuf, pCmdHeader); break; + case CommandID.SCENE_SERVICE_NPC_LIST: + { + cmd_scene_service_npc_list npcList = GPDataTypeHelper.FromBytes(pDataBuf); + CECHostSkillModel.Instance.RecvNPCServiceList(protocol.Data); + break; + } } } @@ -630,14 +637,14 @@ namespace CSNetwork case CommandID.PLAYER_INFO_1: case CommandID.PLAYER_ENTER_WORLD: case CommandID.PLAYER_ENTER_SLICE: - { - if (cid != iHostID) { - _logger.Info("### OnMsgPlayerInfo: ElsePlayer join"); - } + if (cid != iHostID) + { + _logger.Info("### OnMsgPlayerInfo: ElsePlayer join"); + } - break; - } + break; + } } } else diff --git a/Assets/PerfectWorld/Scripts/Players/CECActionSwitcherBase.cs b/Assets/PerfectWorld/Scripts/Players/CECActionSwitcherBase.cs new file mode 100644 index 0000000000..95da98e3b0 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Players/CECActionSwitcherBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BrewMonster.Assets.PerfectWorld.Scripts.Players +{ + public class CECActionSwitcherBase + { + CECHostPlayer m_pHostPlayer; + bool m_bCanAddMsg; + List<(int,int)> m_msgs = new List<(int,int)>(); + public CECActionSwitcherBase(CECHostPlayer pHost) + { + m_pHostPlayer = pHost; + } + public virtual bool OnRideToSkillAction(int skill, bool bCom, int iSel, int iForceAtk) { return false; } + public bool CanAddMessage() {return m_bCanAddMsg;} + public void PostMessge(int msg) + { + /* if (CanAddMessage()) + m_msgs.UniquelyAdd(msg);*/ + } + } + public enum EMsgActionSwitcher + +{ + MSG_FLY = 0, + MSG_MOUNTPET, + MSG_CASTSKILL, +}; +} diff --git a/Assets/PerfectWorld/Scripts/Players/CECActionSwitcherBase.cs.meta b/Assets/PerfectWorld/Scripts/Players/CECActionSwitcherBase.cs.meta new file mode 100644 index 0000000000..0532eadeed --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Players/CECActionSwitcherBase.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 89b7392ff459f7446843305c44b262dd \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Skills/CECSCSkill.cs b/Assets/PerfectWorld/Scripts/Skills/CECSCSkill.cs new file mode 100644 index 0000000000..0283b80f15 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/CECSCSkill.cs @@ -0,0 +1,57 @@ +using BrewMonster.Network; +using BrewMonster.Scripts.Skills; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity.VisualScripting; + +namespace BrewMonster.Assets.PerfectWorld.Scripts.Skills +{ + public class CECSCSkill + { + CECSkill m_pSkill; + public bool Excute() + { + if (m_pSkill == null) + return false; + CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); + + if (ElementSkill.IsGoblinSkill((uint)m_pSkill.GetSkillID())) + { + + /* int idSelected = pHost->GetSelectedTarget(); + bool bForctAttack = glb_GetForceAttackFlag(NULL); + CECHostGoblin* pHostGoblin = (CECHostGoblin*)pHost->GetGoblinModel(); + int i; + for (i = 0; i < pHostGoblin->GetSkillNum(); i++) + { + if (m_pSkill == pHostGoblin->GetSkill(i)) + { + break; + } + } + if (i < pHostGoblin->GetSkillNum()) + { + a_LogOutput(1, "HoangDev: Shortcut: pHostGoblin->GetSkillNum()"); + + pHostGoblin->CastSkill(i, idSelected, bForctAttack); + }*/ + } + else + { + BMLogger.LogError("HoangDev: Shortcut: IsGoblinSkill else"); + + if (pHost.GetActionSwitcher() == null || !pHost.GetActionSwitcher().OnRideToSkillAction(m_pSkill.GetSkillID(), false, 0, -1)) + { + BMLogger.LogError("HoangDev: Shortcut: pHost->GetActionSwitcher()"); + + pHost.ApplySkillShortcut(m_pSkill.GetSkillID()); + } + } + + return true; + } + } +} diff --git a/Assets/PerfectWorld/Scripts/Skills/CECSCSkill.cs.meta b/Assets/PerfectWorld/Scripts/Skills/CECSCSkill.cs.meta new file mode 100644 index 0000000000..b43e5644f5 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/CECSCSkill.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 521292c25e4a79a40b44eb732d0faa91 \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Skills/CECSkill.cs b/Assets/PerfectWorld/Scripts/Skills/CECSkill.cs new file mode 100644 index 0000000000..ba5171e72f --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/CECSkill.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BrewMonster.Assets.PerfectWorld.Scripts.Skills +{ + public class CECSkill + { + public int m_idSkill; + public int m_iLevel; // Skill level + public int m_iCoolCnt; // Cooling time counter + public int m_iCoolTime; // Total cooling time + public bool m_bCooling; // In cooling state + public int m_iChargeCnt; // Charging time counter + public int m_iChargeMax; + public bool m_bCharging; + + public CECSkill(int id, int iLevel) + { + m_idSkill = id; + } + + public int GetSkillID() { return m_idSkill; } + } +} diff --git a/Assets/PerfectWorld/Scripts/Skills/CECSkill.cs.meta b/Assets/PerfectWorld/Scripts/Skills/CECSkill.cs.meta new file mode 100644 index 0000000000..2a638e39e7 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Skills/CECSkill.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a8ba4073670fa0344912b466d9ad7cba \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Skills/EC_HostSkillModel.cs b/Assets/PerfectWorld/Scripts/Skills/EC_HostSkillModel.cs index 7fd6e7b440..dd7b165925 100644 --- a/Assets/PerfectWorld/Scripts/Skills/EC_HostSkillModel.cs +++ b/Assets/PerfectWorld/Scripts/Skills/EC_HostSkillModel.cs @@ -123,7 +123,19 @@ namespace BrewMonster.Scripts.Skills m_curServiceSkills.Add(skillId); } } + public void RecvNPCServiceList(Octets Data) + { + m_npcListData = Data; + if (!m_bInitialized) + { + return; + } + else + { + ProcessServiceList(); + } + } private void InitSkillTreeRootMap(IEnumerable rootSkills) { foreach (int rootSkillID in rootSkills) @@ -236,7 +248,10 @@ namespace BrewMonster.Scripts.Skills if (skillService.id_skills[i] != 0) { ElementSkill pSkill = ElementSkill.Create(skillService.id_skills[i], 1); - if (pSkill.GetCls() == GameController.Instance.GetHostPlayer().GetProfession()) + + if (pSkill == null) return; + + if (pSkill.GetCls() == CECGameRun.Instance.GetHostPlayer().GetProfession()) { // ��NPC������ǰְҵ���ܣ���Ҫ��¼��NPC��ID profCorrect = true; @@ -277,7 +292,7 @@ namespace BrewMonster.Scripts.Skills if (skillId != 0 && CECComboSkillState.Instance.GetInherentSkillByID(skillId) == null) { - npcSkills.Add(skillId); + npcSkills.Add(skillId); } } } @@ -290,7 +305,7 @@ namespace BrewMonster.Scripts.Skills { ElementSkill pSkill = ElementSkill.Create(curID, 1); int cls = pSkill.GetCls(); - int playerCls = GameController.Instance.GetHostPlayer().GetProfession(); + int playerCls = CECGameRun.Instance.GetHostPlayer().GetProfession(); bool isSameClass = (cls == playerCls || cls == 255); bool isProvidedByNPC = npcSkills.Contains(curID); diff --git a/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs b/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs index cb03c3fd27..917c7b295f 100644 --- a/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs +++ b/Assets/PerfectWorld/Scripts/Skills/ElementSkill.cs @@ -4,28 +4,30 @@ using System.Runtime.InteropServices; using Unity.VisualScripting; namespace BrewMonster.Scripts.Skills - { - public enum skill_type{ - TYPE_ATTACK = 1, // Attack // �������� - TYPE_BLESS = 2, // Blessing // ����ף�� - TYPE_CURSE = 3, // Curse // �������� - TYPE_SUMMON = 4, // Summon // ��Ʒ���� - TYPE_PASSIVE = 5, // Passive // ���� - TYPE_ENABLED = 6, // Enabled // �������� - TYPE_LIVE = 7, // Live // ���� - TYPE_JUMP = 8, // Jump // ˲�� - TYPE_PRODUCE = 9, // Production (Crafting) // ����(����) +{ + public enum skill_type + { + TYPE_ATTACK = 1, // Attack // �������� + TYPE_BLESS = 2, // Blessing // ����ף�� + TYPE_CURSE = 3, // Curse // �������� + TYPE_SUMMON = 4, // Summon // ��Ʒ���� + TYPE_PASSIVE = 5, // Passive // ���� + TYPE_ENABLED = 6, // Enabled // �������� + TYPE_LIVE = 7, // Live // ���� + TYPE_JUMP = 8, // Jump // ˲�� + TYPE_PRODUCE = 9, // Production (Crafting) // ����(����) TYPE_BLESSPET = 10, // Pet Blessing // ����ף�� TYPE_NEUTRALBLESS = 11, // Neutral Blessing // ����ף�� }; - public enum range_type{ + public enum range_type + { TYPE_POINT = 0, // �� - TYPE_LINE = 1, // �� - TYPE_SELFSPHERE = 2, // ����Ϊ���ĵ��� + TYPE_LINE = 1, // �� + TYPE_SELFSPHERE = 2, // ����Ϊ���ĵ��� TYPE_TARGETSPHERE = 3, // Ŀ��Ϊ���ĵ��� - TYPE_TAPER = 4, // Բ׶ - TYPE_SLEF = 5, // ���� + TYPE_TAPER = 4, // Բ׶ + TYPE_SLEF = 5, // ���� }; [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -97,20 +99,20 @@ namespace BrewMonster.Scripts.Skills public class SkillStr { - public virtual ushort[] Find(int id) {return new ushort[0];} + public virtual ushort[] Find(int id) { return new ushort[0]; } } public enum SKILL_STATE { SKILL_PERFORM, - SKILL_DONE, + SKILL_DONE, } public class ElementSkill { - public const byte FORM_MASK_HIGH = 0xC0; - public const byte FORM_NORMAL = 0; //��ͨ��̬ - public const byte FORM_CLASS = 1; //ְҵ���� - public const byte FORM_BEASTIE = 2; //��С���� + public const byte FORM_MASK_HIGH = 0xC0; + public const byte FORM_NORMAL = 0; //��ͨ��̬ + public const byte FORM_CLASS = 1; //ְҵ���� + public const byte FORM_BEASTIE = 2; //��С���� public static uint NextSkill(uint id = 0) { //TODO: Implement this @@ -137,22 +139,22 @@ namespace BrewMonster.Scripts.Skills var nextKey = keys[index + 1]; return map[nextKey].GetId(); } - public static ElementSkill Create(uint id, int n) + public static ElementSkill Create(uint id, int n) { return Skill.Create(id, n); } - public virtual List<(uint id, int level)> GetJunior() + public virtual Dictionary GetJunior() { - return new List<(uint, int)>(); + return new Dictionary(); } - public virtual ushort[] GetName() { return null;} - public virtual byte[] GetNativeName() { return null;} + public virtual ushort[] GetName() { return null; } + public virtual byte[] GetNativeName() { return null; } // �������?,��skill_type - public virtual byte GetType() { return 1; } + public virtual byte GetType() { return 1; } // ����ͼ�� public virtual byte[] GetIcon() { return null; } // ����˵�� - public virtual ushort[] GetIntroduction(string buf,int len,SkillStr table) { return new ushort[0]; } + public virtual ushort[] GetIntroduction(string buf, int len, SkillStr table) { return new ushort[0]; } // ����ְҵ���� public virtual int GetCls() { return -1; } // ������ȴʱ�䣬��λ���� @@ -160,20 +162,24 @@ namespace BrewMonster.Scripts.Skills // ����ִ��ʱ�䣬��λ���� public virtual int GetExecuteTime() { return 1000; } // Ŀ����������, 0:����Ŀ�꣬1:��ҪĿ�꣬2:Ŀ��������?��, 3:Ŀ������?����, 4:Ŀ������?���� - public virtual int GetTargetType(){return 0;} + public virtual int GetTargetType() { return 0; } // ������Ч�ͷž���: <-0.001����Ŀ�� -0.001-0.001 Ĭ�Ϲ������룬>0.001 �ͷž��� - public virtual float GetPrayRange(float range, float prayplus) { return 0; } - + public virtual float GetPrayRange(float range, float prayplus) { return 0; } + public static bool IsGoblinSkill(uint id) + { + SkillStub s = SkillStub.GetStub(id); + return s != null && (s.GetCls() == 258); + } // �������漶�� public virtual int GetRank() { return 0; } // ѧϰn������Ҫ�����Ҽ��� - public virtual int GetRequiredLevel() { return 0;} + public virtual int GetRequiredLevel() { return 0; } // ѧϰn��������Ҫ�ļ��ܵ� - public virtual int GetRequiredSp() { return 0;} + public virtual int GetRequiredSp() { return 0; } // ѧϰn����Ҫ�ļ����� - public virtual int GetRequiredBook() { return 0;} + public virtual int GetRequiredBook() { return 0; } // ѧϰ��Ҫ��Ǯ - public virtual int GetRequiredMoney() { return 0;} + public virtual int GetRequiredMoney() { return 0; } // ѧϰ���󾳽�ȼ�? public virtual int GetRequiredRealmLevel() { return 0; } // ǰ�Ἴ�� @@ -181,37 +187,37 @@ namespace BrewMonster.Scripts.Skills // ��ʾ˳�� public virtual int GetShowOrder() { return 0; } // ���ü��ܼ��� - public virtual int SetLevel(int level) { return 0; } + public virtual int SetLevel(int level) { return 0; } // ������󼶱�? public virtual int GetMaxLevel() { return 0; } // �Ƿ��������� public virtual bool IsWarmup() { return false; } // ʹ�ú��Ƿ��Զ����� - public virtual bool IsAutoAttack(){return false;} + public virtual bool IsAutoAttack() { return false; } // ˲������ - public virtual bool IsInstant(){return false;} + public virtual bool IsInstant() { return false; } // �Ƿ��������? public virtual bool IsDurative() { return false; } // ɱ�˷�Χ������ - public virtual int GetRangeType() { return 0; } + public virtual int GetRangeType() { return 0; } // �ͷŻ��������С����桢ˮ�� - public virtual int GetCastEnv() { return 0; } + public virtual int GetCastEnv() { return 0; } // ��ȡС����ѧϰ���ͷż��������츳�� public virtual int GetRequiredGenius(int idSkill) { return 0; } // Ч���ļ��� - public virtual byte[] GetEffect() { return null;} - public virtual byte[] GetElseEffect() { return null;} + public virtual byte[] GetEffect() { return null; } + public virtual byte[] GetElseEffect() { return null; } // ʹ����ҪMP - public virtual int GetMpCost(){return 1;} + public virtual int GetMpCost() { return 1; } // ʹ����ҪAP - public virtual int GetApCost(){return 0;} + public virtual int GetApCost() { return 0; } // ��֧���� - public virtual int GetArrowCost(){return 0;} + public virtual int GetArrowCost() { return 0; } // ���������ж� public virtual bool ValidWeapon(int w) { return true; } @@ -221,19 +227,19 @@ namespace BrewMonster.Scripts.Skills return 0; } - public virtual bool IsAllowLand(){ return true; } - public virtual bool IsAllowWater(){ return true; } - public virtual bool IsAllowAir(){ return true; } - public virtual bool GetNotuseInCombat(){ return false; } + public virtual bool IsAllowLand() { return true; } + public virtual bool IsAllowWater() { return true; } + public virtual bool IsAllowAir() { return true; } + public virtual bool GetNotuseInCombat() { return false; } //�Ƿ��ƶ�ʩ�� public virtual bool IsMovingSkill() { return false; } // �����ܷ��ڵ�ǰ����״̬��ʹ�� public bool IsValidForm(byte form) { byte form_type = (byte)((form & FORM_MASK_HIGH) >> 6); - return ((GetAllowForms() & (1 << form_type))!=0); + return ((GetAllowForms() & (1 << form_type)) != 0); } public virtual byte GetAllowForms() { return 0; } public virtual bool Interrupt() { return true; } } - } \ No newline at end of file +} \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Skills/skill.cs b/Assets/PerfectWorld/Scripts/Skills/skill.cs index e9d07591d9..b2ec3b37e8 100644 --- a/Assets/PerfectWorld/Scripts/Skills/skill.cs +++ b/Assets/PerfectWorld/Scripts/Skills/skill.cs @@ -54,6 +54,10 @@ namespace BrewMonster.Scripts.Skills { return stub.GetCls(); } + public override Dictionary GetJunior() + { + return stub.is_senior != 0 ? stub.pre_skills : new Dictionary(); + } } public abstract class SkillStub diff --git a/Assets/Scripts/GameController.cs b/Assets/Scripts/CECGameRun.cs similarity index 95% rename from Assets/Scripts/GameController.cs rename to Assets/Scripts/CECGameRun.cs index 500b807049..13487ec84e 100644 --- a/Assets/Scripts/GameController.cs +++ b/Assets/Scripts/CECGameRun.cs @@ -6,9 +6,9 @@ using Unity.VisualScripting; using UnityEngine; using UnityEngine.UIElements; -public class GameController : MonoBehaviour +public partial class CECGameRun : MonoBehaviour { - private static GameController instance; + private static CECGameRun instance; [SerializeField] private GameObject characterPrefab; [SerializeField] private CECMonster monsterPrefab; @@ -23,13 +23,13 @@ public class GameController : MonoBehaviour public float rotateSpeedY = 2f; // tốc độ xoay dọc - public static GameController Instance + public static CECGameRun Instance { get { if (instance == null) { - instance = FindAnyObjectByType(); + instance = FindAnyObjectByType(); } return instance; } diff --git a/Assets/Scripts/CECGameRun.cs.meta b/Assets/Scripts/CECGameRun.cs.meta new file mode 100644 index 0000000000..96acc12e8f --- /dev/null +++ b/Assets/Scripts/CECGameRun.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5de219a5b9756ae4ebf01e2919b92cde \ No newline at end of file diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index 61a9aea88a..e3e0b2c298 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -1,4 +1,5 @@ using BrewMonster; +using BrewMonster.Assets.PerfectWorld.Scripts.Players; using BrewMonster.Managers; using BrewMonster.Network; using BrewMonster.Scripts; @@ -20,6 +21,8 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; using TMPro; +using Unity.VisualScripting; +using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; @@ -68,6 +71,7 @@ public class CECHostPlayer : CECPlayer public GNDINFO m_GndInfo; private int m_idUCSelTarget; // Uncertificately selected object's ID public float m_fVertSpeed = 0f; + CECActionSwitcherBase m_pActionSwitcher; // ====== Ground cast config ====== [Header("Ground Cast")] @@ -960,6 +964,13 @@ public class CECHostPlayer : CECPlayer { return; } + + if (false /*CECUIConfig::Instance().GetGameUI().bEnableActionSwitch*/) + { //m_pActionSwitcher = new CECActionSwitcher(this); + + } + else + m_pActionSwitcher = new CECActionSwitcherBase(this); } private void JoystickStartDrag(JoystickPressEvent joystickPressEvent) @@ -1286,7 +1297,7 @@ public class CECHostPlayer : CECPlayer return iRet; } - + public CECActionSwitcherBase GetActionSwitcher() { return m_pActionSwitcher; } private float A3d_Magnitude(A3DVECTOR3 v) { return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z); @@ -1444,7 +1455,274 @@ public class CECHostPlayer : CECPlayer { return m_ExtProps.mv.swim_speed; } + public bool ApplySkillShortcut(int idSkill, bool bCombo = false /* false */, + int idSelTarget = 0/* 0 */, int iForceAtk = -1/* -1 */) + { + //StackChecker::ACTrace(4); + /* if (m_pActionSwitcher != null) + m_pActionSwitcher.PostMessge(EMsgActionSwitcher.MSG_CASTSKILL); + + // Return-town skill is very special, handle it separately + if (idSkill == ID_RETURNTOWN_SKILL) + return ReturnToTargetTown(0, bCombo); + + if (idSkill == ID_SUMMONPLAYER_SKILL) + return SummonPlayer(idSelTarget, bCombo); + + if (!CanDo(CANDO_SPELLMAGIC)) + return false; + + if (InSlidingState()) + return false; + + if (!bCombo) + ClearComboSkill(); + + if (!idSelTarget) + idSelTarget = m_idSelTarget; + + CECSkill* pSkill = GetPositiveSkillByID(idSkill); + if (!pSkill) pSkill = GetEquipSkillByID(idSkill); + if (!pSkill) pSkill = CECComboSkillState::Instance().GetInherentSkillByID(idSkill); + if (!pSkill) + { + ASSERT(0); + return false; + } + + // If we press a chargeable skill again when it's being charged, + // we cast it out at once + if (IsSpellingMagic() && m_pCurSkill && m_pCurSkill->IsCharging() && + m_pCurSkill->GetSkillID() == pSkill->GetSkillID()) + { + m_pCurSkill->EndCharging(); + g_pGame->GetGameSession()->c2s_CmdContinueAction(); + return true; + } + + int iCon = CheckSkillCastCondition(pSkill); + if (iCon) + { + ProcessSkillCondition(iCon); + return false; + } + + // Get force attack flag + bool bForceAttack; + if (iForceAtk < 0) + bForceAttack = glb_GetForceAttackFlag(NULL); + else + bForceAttack = iForceAtk > 0 ? true : false; + + // Check negative effect skill + if (pSkill->GetType() == CECSkill::TYPE_ATTACK || pSkill->GetType() == CECSkill::TYPE_CURSE) + { + if (idSelTarget == m_PlayerInfo.cid) + { + // Host cannot spell negative effect magic to himself. + g_pGame->GetGameRun()->AddFixedChannelMsg(FIXMSG_TARGETWRONG, GP_CHAT_FIGHT); + return false; + } + else if (idSelTarget) + { + if (AttackableJudge(idSelTarget, bForceAttack) != 1) + return false; + } + } + + // Check whether target type match + int idCastTarget = idSelTarget; + int iTargetType = pSkill->GetTargetType(); + + if (pSkill->GetType() == CECSkill::TYPE_BLESS || + pSkill->GetType() == CECSkill::TYPE_NEUTRALBLESS) + { + if (!iTargetType || !ISPLAYERID(idSelTarget)) + idCastTarget = m_PlayerInfo.cid; + + // In some case, we shouldn't add bless effect to other players + if (ISPLAYERID(idCastTarget) && idCastTarget != m_PlayerInfo.cid) + { + // If host has set bless skill filter only to himself, bless skill couldn't add to other players + BYTE byBLSMask = glb_BuildBLSMask(); + + if (pSkill->GetRangeType() == CECSkill::RANGE_POINT) + { + if (!IsTeamMember(idCastTarget)) + { + if (byBLSMask & GP_BLSMASK_SELF) + idCastTarget = m_PlayerInfo.cid; + else + { + CECElsePlayer* pPlayer = (CECElsePlayer*)g_pGame->GetGameRun()->GetWorld()->GetPlayerMan()->GetPlayer(idCastTarget); + if (!pPlayer) + { + // Ä¿±êÏûʧ + return false; + } + + if (pPlayer->IsInvader() || pPlayer->IsPariah()) + { + if (byBLSMask & GP_BLSMASK_NORED) + idCastTarget = m_PlayerInfo.cid; + } + + if (!IsFactionMember(pPlayer->GetFactionID())) + { + if (byBLSMask & GP_BLSMASK_NOMAFIA) + idCastTarget = m_PlayerInfo.cid; + } + + if (!IsFactionAllianceMember(pPlayer->GetFactionID())) + { + if (byBLSMask & GP_BLSMASK_NOALLIANCE) + idCastTarget = m_PlayerInfo.cid; + } + if (GetForce() != pPlayer->GetForce()) + { + if (byBLSMask & GP_BLSMASK_NOFORCE) + idCastTarget = m_PlayerInfo.cid; + } + } + } + } + + // If host is in duel, bless skill couldn't add to opponent + if (IsInDuel() && idSelTarget == m_pvp.idDuelOpp) + idCastTarget = m_PlayerInfo.cid; + + // If host is in battle, bless skill couldn't add to enemies + if (IsInBattle()) + { + CECElsePlayer* pPlayer = m_pPlayerMan->GetElsePlayer(idCastTarget); + if (!InSameBattleCamp(pPlayer)) + idCastTarget = m_PlayerInfo.cid; + } + } + } + else if (pSkill->GetType() == CECSkill::TYPE_BLESSPET) + { + CECPet* pPet = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetPetByID(idSelTarget); + if (!pPet || pPet->GetMasterID() == GetCharacterID()) + { + // Spell skill on host's pet + CECPetData* pPetData = m_pPetCorral->GetActivePet(); + if (!pPetData || + pPetData->GetClass() != GP_PET_CLASS_COMBAT && + pPetData->GetClass() != GP_PET_CLASS_SUMMON && + pPetData->GetClass() != GP_PET_CLASS_EVOLUTION) + return false; + + idCastTarget = m_pPetCorral->GetActivePetNPCID(); + } + // Only fighting pet can be blessed. + if (pPet && !pPet->CanBeAttacked()) + return false; + } + else + { + if (iTargetType != 0 && !idCastTarget) + return false; + } + + // iTargetType == 4 means target must be pet. The problem is that pet will + // disappear from world after it died, so GetWorld()->GetObject() will return + // NULL when host spells revive-pet skill on his dead pet. So, the target + // type of revive-pet skill should be 0 + if (iTargetType) + { + // Target shoundn't be a corpse ? + int iAliveFlag = 0; + if (iTargetType == 1) + iAliveFlag = 1; + else if (iTargetType == 2) + iAliveFlag = 2; + + CECObject* pObject = g_pGame->GetGameRun()->GetWorld()->GetObject(idCastTarget, iAliveFlag); + if (!pObject) + return false; + } + + if (!IsMeleeing() && !IsSpellingMagic() && + (!iTargetType || idCastTarget == m_PlayerInfo.cid)) + { + // Cast this skill need't checking cast distance + if (!pSkill->ReadyToCast()) + return false; + + // Prepare to cast skill, if skill isn't INSTANT and FLASHMOVE, + // we must stop moving and stand + if (!pSkill->IsInstant() && pSkill->GetType() != CECSkill::TYPE_FLASHMOVE) + { + if (!NaturallyStopMoving()) + return false; // Couldn't stop naturally, so cancel casting skill + } + else if (pSkill->GetType() == CECSkill::TYPE_FLASHMOVE) + { + if (!CanDo(CANDO_FLASHMOVE)) + return false; + } + + m_pPrepSkill = pSkill; + CastSkill(m_PlayerInfo.cid, bForceAttack); + } + else if (IsSpellingMagic() && m_pCurSkill == pSkill) + { + // If we are casting the same skill and it's in cooling time + return false; + } + else // Have to trace selected object before cast skill + { + if (!pSkill->ReadyToCast()) + return false; + + if (CECCastSkillWhenMove::Instance().IsSkillSupported(pSkill->GetSkillID(), this) && + m_pWorkMan->IsMovingToPosition() && + m_pWorkMan->CanCastSkillImmediately(pSkill->GetSkillID())) + { + m_pPrepSkill = pSkill; + return CastSkill(idCastTarget, bForceAttack); + } + else + { + bool bTraceOK = false; + bool bUseAutoPF = false; + CECPlayerWrapper* pWrapper = CECAutoPolicy::GetInstance().GetPlayerWrapper(); + if (CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() && pWrapper->GetAttackError() >= 2) + bUseAutoPF = true; + + if (!idCastTarget) + { + idCastTarget = GetCharacterID(); // ±ÜÃâË²ÒÆµÈ¼¼ÄÜʱ idCastTarget Ϊ0µ¼Ö CECWorkTrace::CreateTraceTarget ·µ»Ø¿Õ + } + if (CECHPWork * pWork = m_pWorkMan->GetWork(CECHPWork::WORK_TRACEOBJECT)) + { + CECHPWorkTrace* pWorkTrace = dynamic_cast(pWork); + if (pWorkTrace->GetTraceReason() == CECHPWorkTrace::TRACE_SPELL && + pWorkTrace->GetTarget() == idCastTarget && + pWorkTrace->GetPrepSkill() == pSkill) + return false; // We are just doing the same thing + + pWorkTrace->SetTraceTarget(pWorkTrace->CreatTraceTarget(idCastTarget, CECHPWorkTrace::TRACE_SPELL, bForceAttack), bUseAutoPF); + pWorkTrace->SetPrepSkill(pSkill); + bTraceOK = true; + } + else if (m_pWorkMan->CanStartWork(CECHPWork::WORK_TRACEOBJECT)) + { + CECHPWorkTrace* pWork = (CECHPWorkTrace*)m_pWorkMan->CreateWork(CECHPWork::WORK_TRACEOBJECT); + pWork->SetTraceTarget(pWork->CreatTraceTarget(idCastTarget, CECHPWorkTrace::TRACE_SPELL, bForceAttack), bUseAutoPF); + pWork->SetPrepSkill(pSkill); + m_pWorkMan->StartWork_p1(pWork); + bTraceOK = true; + } + + if (!bTraceOK) return false; + } + }*/ + + return true; + } public bool SelectTarget(int idTarget) { BMLogger.LogError("HoangDev: HostPlayer SelectTarget"); diff --git a/Assets/Scripts/CanvasController.cs b/Assets/Scripts/CanvasController.cs index a63b381e24..6ae7d57c10 100644 --- a/Assets/Scripts/CanvasController.cs +++ b/Assets/Scripts/CanvasController.cs @@ -12,7 +12,7 @@ namespace BrewMonster.Managers [SerializeField] private ScreenLogin screenLogin; [SerializeField] private SelecScreenCharacter screenCharacter; [SerializeField] private GameObject bgr; - [SerializeField] private GameController gameController; + [SerializeField] private CECGameRun gameController; GameObject screenLoginOb; GameObject screenCharacterOb; diff --git a/Assets/Scripts/GameController.cs.meta b/Assets/Scripts/GameController.cs.meta deleted file mode 100644 index 88764591f0..0000000000 --- a/Assets/Scripts/GameController.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 839d10a1a7b2c4a44a99e77558b12d02 \ No newline at end of file