diff --git a/Assets/Addressable/badwords.txt b/Assets/Addressable/badwords.txt new file mode 100644 index 0000000000..7a1a1a5f5a Binary files /dev/null and b/Assets/Addressable/badwords.txt differ diff --git a/Assets/Addressable/badwords.txt.meta b/Assets/Addressable/badwords.txt.meta new file mode 100644 index 0000000000..d3e1f77b69 --- /dev/null +++ b/Assets/Addressable/badwords.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 97d5bf1c2fec02844993b30c645fe286 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/AddressableAssetsData/AssetGroups/configuration.asset b/Assets/AddressableAssetsData/AssetGroups/configuration.asset index 818c5cfa69..6ac918714b 100644 --- a/Assets/AddressableAssetsData/AssetGroups/configuration.asset +++ b/Assets/AddressableAssetsData/AssetGroups/configuration.asset @@ -90,6 +90,11 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: 97d5bf1c2fec02844993b30c645fe286 + m_Address: Assets/Addressable/badwords.txt + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 - m_GUID: 98b87a70ddccda2459742976c2b90262 m_Address: Assets/Addressable/gshop1.txt m_ReadOnly: 0 diff --git a/Assets/PerfectWorld/Scripts/Common/EC_C2SCmdCache.cs b/Assets/PerfectWorld/Scripts/Common/EC_C2SCmdCache.cs index c2884e59bc..55de3a0f3b 100644 --- a/Assets/PerfectWorld/Scripts/Common/EC_C2SCmdCache.cs +++ b/Assets/PerfectWorld/Scripts/Common/EC_C2SCmdCache.cs @@ -639,7 +639,7 @@ namespace BrewMonster.Common UnityGameSession.Instance.GameSession.c2s_SendCmdCancelAction(); } } - void SendCmdPetCtrl(int idTarget, int cmd, byte[] pParamBuf, int iParamLen) + public void SendCmdPetCtrl(int idTarget, int cmd, byte[] pParamBuf, int iParamLen) { CECCounter pCnt = m_CounterMap[(int)CommandID.PET_CTRL]; if (pCnt.IsFull()) diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs index 61b616ef62..1e90bc32f8 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GPDataType.cs @@ -2195,5 +2195,85 @@ namespace CSNetwork.GPDataType return buf_size >= sz; } }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_summon_plant_pet + { + public int plant_tid; + public int plant_nid; + public int life_time; + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct cmd_plant_pet_hp_notify + { + public int plant_nid; + public float hp_factor; + public int cur_hp; + public float mp_factor; + public int cur_mp; + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct _evo_prop + { + public int r_attack; + public int r_defense; + public int r_hp; + public int r_atk_lvl; + public int r_def_lvl; + public int nature; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct _skills + { + public int skill; + public int level; + } + + public enum eGP_PET_SKILL + { + GP_PET_SKILL_NUM = 8 + }; + + public enum eGP_PET_NATURE_SKILL + { + GP_PET_NATURE_SKILL_NUM = 2 + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct info_pet + { + public int honor_point; // ºÃ¸Ð¶È + public int hunger; // ¼¢¶ö¶È + public int feed_time; // ÉÏ´ÎÎ¹Ñøµ½ÏÖÔÚµÄʱ¼ä + public int pet_tid; // ³èÎïµÄÄ£°åID + public int pet_vis_tid; // ³èÎïµÄ¿É¼ûID£¨Èç¹ûΪ0£¬Ôò±íʾÎÞÌØÊâ¿É¼ûID£© + public int pet_egg_tid; // ³èÎïµ°µÄID + public int pet_class; // ³èÎïÀàÐÍ Õ½³è£¬Æï³è£¬¹ÛÉͳè + public float hp_factor; // ѪÁ¿±ÈÀý£¨¸´»îºÍÊÕ»ØÊ±Ê¹Óã© 0ÔòΪËÀÍö + public short level; // ³èÎï¼¶±ð + public ushort color; // ³èÎïÑÕÉ«£¬×î¸ßλΪ1±íʾÓÐЧ£¬Ä¿Ç°½ö¶ÔÆï³èÓÐЧ + public int exp; // ³èÎﵱǰ¾­Ñé + public int skill_point; // Ê£Ó༼Äܵã + public char is_bind; // ÊÇ·ñÌìÈ˺ÏÒ»£¬ÏÖÔÚÊÇÒ»¸öMask£¬0x01 ÌìÈ˺ÏÒ»£¬0x02 Ѱ±¦Íø¿É½»Ò× + public char unused; // Ŀǰ´ËÏîÎÞЧ + public ushort name_len; // Ãû×Ö³¤¶È Ŀǰ´ËÏîÎÞЧ£¨ÒòΪ²ß»®ÉÐÎÞÃû×ÖÐèÇó£© + public _evo_prop evo_prop; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public char[] name; // Ãû×ÖÄÚÈÝ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)eGP_PET_SKILL.GP_PET_SKILL_NUM)] + public _skills[] skills; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public int[] reserved; // δÓà + }; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct CMDPARAM + { + public int idSkill; + public byte byPVPMask; + }; } diff --git a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs index adef4669ff..79a939192b 100644 --- a/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs @@ -1517,5 +1517,10 @@ namespace CSNetwork gamedatasend.Data = C2SCommandFactory.CreateQueryFactionPVPInfo(faction_id); SendProtocol(gamedatasend); } + + public void SendCmdPetCtrl(int idTarget, int cmd, object pParamBuf, int iParamLen) + { + m_CmdCache.SendCmdPetCtrl(idTarget, cmd, pParamBuf, iParamLen); + } } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs index 04382a78c6..6d8600e7b6 100644 --- a/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs +++ b/Assets/PerfectWorld/Scripts/Network/UnityGameSession.cs @@ -441,5 +441,10 @@ namespace BrewMonster.Network { _gameSession?.CmdCache?.Tick(Time.deltaTime); } + + public static void c2s_CmdPetCtrl(int idTarget, int cmd, object pParamBuf, int iParamLen) + { + Instance._gameSession.SendCmdPetCtrl(idTarget, cmd, pParamBuf, iParamLen); + } } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/Pet.meta b/Assets/PerfectWorld/Scripts/Pet.meta new file mode 100644 index 0000000000..f56f875eb2 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Pet.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 64353be2a0c1d704cb4392f919960f91 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PerfectWorld/Scripts/Pet/EC_PetCorral.cs b/Assets/PerfectWorld/Scripts/Pet/EC_PetCorral.cs new file mode 100644 index 0000000000..9f3dfbb162 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Pet/EC_PetCorral.cs @@ -0,0 +1,672 @@ +using BrewMonster.Network; +using BrewMonster.Scripts.Skills; +using CSNetwork.GPDataType; +using ModelRenderer.Scripts.GameData; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using UnityEngine; + +namespace BrewMonster.Scripts.Pet +{ + using PlantVec = System.Collections.Generic.List; + + // ֲ + // + public struct CECPlantPetData + { + public void Init(cmd_summon_plant_pet rhs) + { + m_tid = rhs.plant_tid; + m_nid = rhs.plant_nid; + m_lifeTime = rhs.life_time; + m_lifeTimeLeft = m_lifeTime * 1000; + } + public void Info(cmd_plant_pet_hp_notify rhs) + { + if (rhs.plant_nid == m_nid) + { + m_HPFactor = rhs.hp_factor; + m_HP = rhs.cur_hp; + m_MPFactor = rhs.mp_factor; + m_MP = rhs.cur_mp; + } + } + public void Tick(float dwDeltaTime) + { + if (m_lifeTime <= 0 || m_lifeTimeLeft <= 0) + return; + if (m_lifeTimeLeft >= (int)dwDeltaTime) + m_lifeTimeLeft -= (int)dwDeltaTime; + else + m_lifeTimeLeft = 0; + } + + int GetLifeTime() { return m_lifeTime * 1000; } // ܴʱ䣨룩 + int GetLifeTimeLeft() { return m_lifeTimeLeft; } // ʣʱ䣨룩 + + int m_tid; // ģID + int m_nid; // ID + int m_lifeTime; // ʱ䣨0Ϊ + int m_lifeTimeLeft; // ʱ䵹ʱ + float m_HPFactor; // ǰ HP ռ HP ı + int m_HP; // ǰ HP + float m_MPFactor; // ǰ MP ռ MP ı + int m_MP; // ǰ MP + + public CECPlantPetData(int tid = 0, int nid = 0, int lifeTime = 0, int lifeTimeLeft = 0, float hPFactor = 1f, int hP = 0, float mPFactor = 1f, int mP = 0) + { + m_tid = tid; + m_nid = nid; + m_lifeTime = lifeTime; + m_lifeTimeLeft = lifeTimeLeft; + m_HPFactor = hPFactor; + m_HP = hP; + m_MPFactor = mPFactor; + m_MP = mP; + } + }; + + public class CECPetCorral + { + public enum ePet_MaxSlot + { + MAX_SLOTNUM = 20, // Number of normal pet slots + MAX_SLOTNUM2 = 21, // Total number of pet slots + }; + + // Moving mode + public enum ePet_MovingMode + { + MOVE_FOLLOW = 0, + MOVE_STAND, + }; + + // Attacking mode + public enum ePet_AttackingMode + { + ATK_DEFENSE = 0, + ATK_POSITIVE, + ATK_PASSIVE, + }; + + public bool m_bHasInit; // Flag indicates whether we have init the data by calling MagnifyPetSlots + + public int m_iActivePet; // Index of current active pet + public int m_iPetSlotNum; // Number of current active pet slots + public CECPetData[] m_aPetSlots = new CECPetData[(int)ePet_MaxSlot.MAX_SLOTNUM2]; // Pet slots + + public int m_nidPet; // ID of Pet as a NPC in world + public int m_iMoveMode; // Current moving mode of pet + public int m_iAttackMode; // Current attacking mode of pet + + public int m_iPetLifeTime; // ǰĴڣ0ʾã + + public PlantVec m_Plants; + + PET_EVOLVE_CONFIG m_pDBEvoConfig; + + // Get / Set ID of active pet as a NPC in world + public int GetActivePetNPCID() { return m_nidPet; } + } + + public class CECPetData + { + // Hunger level + public enum ePetData_HUNGER_LEVEL + { + HUNGER_LEVEL_0, // ʳ + HUNGER_LEVEL_1, // + HUNGER_LEVEL_2, // ̶һ + HUNGER_LEVEL_3, + HUNGER_LEVEL_4, // ̶ȶ + HUNGER_LEVEL_5, + HUNGER_LEVEL_6, + HUNGER_LEVEL_7, // ̶ + HUNGER_LEVEL_8, + HUNGER_LEVEL_9, + HUNGER_LEVEL_10, + HUNGER_LEVEL_11, // ̶ļ + HUNGER_LEVEL_COUNT, + }; + + // Intimacy level + public enum ePetData_INTIMACY_LEVEL + { + INTIMACY_LEVEL_0, // Ұѱ, 0-50 + INTIMACY_LEVEL_1, // ޳, 51-150 + INTIMACY_LEVEL_2, // , 151-500 + INTIMACY_LEVEL_3, // Ĺ, 501-999 + INTIMACY_LEVEL_COUNT, + INTIMACY_POINT_MAX = 999, + }; + + // enum + // { + // MAX_SKILLNUM = 4, // Ը + // }; + + public struct PETSKILL + { + public int idSkill; + public int iLevel; + public int iCoolCnt; + public int iCoolMax; + }; + + public enum SKILLTYPE + { + EM_SKILL_DEFAULT = 0, // Ը + EM_SKILL_NORMAL, // ͨ + EM_SKILL_NATURE, // Ը + EM_SKILL_SPECIAL, // ר + }; + + int m_iIntimacy; // øж + int m_iHunger; // + int m_tid; // ģID + int m_tidVis; // ģIDΪ0ʾɼID + int m_idEgg; // ﵰID + int m_iClass; // ս裬裬ͳ + float m_fHPFactor; // Ѫջʱʹã 0Ϊ + float m_fMPFactor; + int m_iLevel; // V + bool m_isBind; // Ƿ˺һ + bool m_canWebTrade; // ǷѰɽ + ushort m_color; // ȾɫɫλΪ1ʱЧ + int m_iExp; // ﵱǰ + int m_iSkillPt; // ʣ༼ܵ + string m_strName; + + int m_iHP; // Only fight pets have this + int m_iMP; + PETSKILL[] m_aSkills = new PETSKILL[(int)eGP_PET_SKILL.GP_PET_SKILL_NUM]; + + List m_vecNorSkillIndex = new List(); // ֹԸܺͨ˳ҵ漼 m_aSkills + List m_vecDynSkillIndex = new List(); + int m_iSpecialSkillIndex; // רm_aSkillsţֻнһ˼ + + CECCounter m_cntAutoSkill; + List m_aAutoSkills = new List(); + + ROLEEXTPROP m_ExtProps; + PET_ESSENCE? m_pDBEssence; + + int m_iAtkRation; + int m_iDefRation; + int m_iHpRation; + int m_iAtkLvlRation; + int m_iDefLvlRation; + int m_iNature; + + public CECPetData() + { + m_iIntimacy = 0; + m_iHunger = 0; + m_tid = 0; + m_tidVis = 0; + m_idEgg = 0; + m_iClass = GP_PET_CLASS_INVALID; + m_fHPFactor = 0.0f; + m_fMPFactor = 0.0f; + m_iLevel = 0; + m_isBind = false; + m_canWebTrade = false; + m_color = 0; + m_iExp = 0; + m_iSkillPt = 0; + m_iHP = 0; + m_iMP = 0; + + m_vecDynSkillIndex.Clear(); + m_vecNorSkillIndex.Clear(); + m_iSpecialSkillIndex = -1; + + m_pDBEssence = null; + m_cntAutoSkill.SetPeriod(500); + + m_iAtkRation = 0; + m_iDefRation = 0; + m_iHpRation = 0; + m_iAtkLvlRation = 0; + m_iDefLvlRation = 0; + m_iNature = 0; + } + + // Initialize object + bool Init(info_pet Info) + { + m_iIntimacy = Info.honor_point; + m_iHunger = Info.hunger; + m_tid = Info.pet_tid; + m_tidVis = Info.pet_vis_tid; + m_idEgg = Info.pet_egg_tid; + m_iClass = Info.pet_class; + m_fHPFactor = Info.hp_factor; + m_iLevel = Info.level; + m_isBind = (Info.is_bind & 0x01) != 0; + m_canWebTrade = (Info.is_bind & 0x02) != 0; + m_color = Info.color; + m_iExp = Info.exp; + m_iSkillPt = Info.skill_point; + + m_strName = new string(Info.name, 0, Info.name_len); + + elementdataman pDB = ElementDataManProvider.GetElementDataMan(); + + DATA_TYPE DataType = new DATA_TYPE(); + if (m_strName.Length == 0) + { + object pe = pDB.get_data_ptr((uint)m_tid, ID_SPACE.ID_SPACE_ESSENCE,ref DataType); + if (pe != null) + { + PET_ESSENCE petEs = (PET_ESSENCE)pe; + m_strName = new string((char[])(Array)petEs.name); + EC_Game.GetGameRun().GetUIManager().FilterBadWords(ref m_strName); + } + } + // Ըñ + object pDBData = pDB.get_data_ptr((uint)Info.evo_prop.nature, ID_SPACE.ID_SPACE_CONFIG, ref DataType); + PET_EVOLVED_SKILL_CONFIG? pDynSkills = null; + if (pDBData != null && DataType == DATA_TYPE.DT_PET_EVOLVED_SKILL_CONFIG) + { + PET_EVOLVED_SKILL_CONFIG? pSkillConfig = (PET_EVOLVED_SKILL_CONFIG)pDBData; + if (pSkillConfig != null) + pDynSkills = pSkillConfig; + } + + // Get database data + pDBData = pDB.get_data_ptr((uint)m_tid, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + if (pDBData != null) + { + if (DataType == DATA_TYPE.DT_MONSTER_ESSENCE) + { + MONSTER_ESSENCE pMonsterData = (MONSTER_ESSENCE)pDBData; + PET_EGG_ESSENCE? pEggData = (PET_EGG_ESSENCE)pDB.get_data_ptr(pMonsterData.id_pet_egg_captured, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + if (pEggData != null) + m_pDBEssence = (PET_ESSENCE)pDB.get_data_ptr((uint)pEggData.Value.id_pet, ID_SPACE.ID_SPACE_ESSENCE, ref DataType); + } + else if (DataType == DATA_TYPE.DT_PET_ESSENCE) + { + m_pDBEssence = (PET_ESSENCE)pDBData; + } + } + + m_vecDynSkillIndex.Clear(); + m_vecNorSkillIndex.Clear(); + m_iSpecialSkillIndex = -1; + + int i = 0; + for (i = 0; i < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM; i++) + { + int skill_id = Info.skills[i].skill; + + m_aSkills[i].idSkill = skill_id; + m_aSkills[i].iLevel = Info.skills[i].level; + + if (m_pDBEssence != null && (skill_id > 0)) + { + if(skill_id == m_pDBEssence.Value.specific_skill) + { + m_iSpecialSkillIndex = i; + continue; + } + } + + bool bNormal = true; + if (pDynSkills != null) + { + for (int j = 0; j < 2; j++) // Ը + { + if (pDynSkills?.skills[j].id == skill_id) + { + m_vecDynSkillIndex.Add(i); + bNormal = false; + break; // + } + } + } + if (bNormal) + m_vecNorSkillIndex.Add(i); + } + + m_iAtkRation = Info.evo_prop.r_attack; + m_iDefRation = Info.evo_prop.r_defense; + m_iHpRation = Info.evo_prop.r_hp; + m_iAtkLvlRation = Info.evo_prop.r_atk_lvl; + m_iDefLvlRation = Info.evo_prop.r_def_lvl; + m_iNature = Info.evo_prop.nature; + + return true; + } + + // Add experience + public int AddExp(int iExp) + { + m_iExp += iExp; + return m_iExp; + } + // Level up + int LevelUp(int iLevel, int iNewExp) + { + m_iLevel = iLevel; + m_iExp = iNewExp; + return m_iLevel; + } + + // Get properties + public int GetIntimacy() { return m_iIntimacy; } + public void SetIntimacy(int iValue) { m_iIntimacy = iValue; } + public int GetHunger() { return m_iHunger; } + public void SetHunger(int iValue) { m_iHunger = iValue; } + public int GetTemplateID() { return m_tid; } + public int GetVisibleID() { return m_tidVis; } + public int GetEggID() { return m_idEgg; } + public int GetClass() { return m_iClass; } + public int GetLevel() { return m_iLevel; } + public ushort GetColor() { return m_color; } + public bool IsBind() { return m_isBind; } + public bool CanWebTrade(){ return m_canWebTrade; } + public int GetExp() { return m_iExp; } + public int GetSkillPt() { return m_iSkillPt; } + public string GetName() { return m_strName; } + + public float GetHPFactor() { return m_fHPFactor; } + public void SetHPFactor(float fFactor) { m_fHPFactor = fFactor; } + + public void SetMPFactor(float fFactor) { m_fMPFactor = fFactor; } + public float GetMPFactor() { return m_fMPFactor; } + + public int GetHP() { return m_iHP; } + public void SetHP(int iHP) { m_iHP = iHP; } + + public int GetMP() { return m_iMP; } + public void SetMP(int iMP) { m_iMP = iMP; } + + // Set skill cool time + public void SetSkillCoolTime(int iCoolIdx, int iTime) + { + if (iCoolIdx <= (int)CoolTimeIndex.GP_CT_SKILL_START) + return; + + int idSkill = iCoolIdx - (int)CoolTimeIndex.GP_CT_SKILL_START; + int i = 0; + for (i = 0; i < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM; i++) + { + PETSKILL s = m_aSkills[i]; + if (s.idSkill == idSkill) + { + s.iCoolMax = iTime; + s.iCoolCnt = iTime; + return; + } + } + } + + // Get skill cool time + public int GetSkillCoolTime(SKILLTYPE iType, int iSkillIdx, ref int? piMax) + { + if (iType == SKILLTYPE.EM_SKILL_DEFAULT) + { + if (iSkillIdx >= 0 && iSkillIdx < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM) + { + PETSKILL s = m_aSkills[iSkillIdx]; + if (piMax != null) piMax = s.iCoolMax; + return s.iCoolCnt; + } + } + else if (iType == SKILLTYPE.EM_SKILL_NORMAL) + { + if (iSkillIdx >= 0 && iSkillIdx < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM && iSkillIdx < m_vecNorSkillIndex.Count) + { + PETSKILL s = m_aSkills[m_vecNorSkillIndex[iSkillIdx]]; + if (piMax != null) piMax = s.iCoolMax; + return s.iCoolCnt; + } + } + else if (iType == SKILLTYPE.EM_SKILL_NATURE) + { + if (iSkillIdx >= 0 && iSkillIdx < (int)eGP_PET_NATURE_SKILL.GP_PET_NATURE_SKILL_NUM && iSkillIdx < m_vecDynSkillIndex.Count) + { + PETSKILL s = m_aSkills[m_vecDynSkillIndex[iSkillIdx]]; + if (piMax != null) piMax = s.iCoolMax; + return s.iCoolCnt; + } + } + else if (iType == SKILLTYPE.EM_SKILL_SPECIAL) + { + if (m_iSpecialSkillIndex >= 0) + { + PETSKILL s = m_aSkills[m_iSpecialSkillIndex]; + if (piMax != null) piMax = s.iCoolMax; + return s.iCoolCnt; + } + } + + if (piMax != null) piMax = 0; + return 0; + } + + // Check whether pet is dead + public bool IsDead() { return Math.Abs(m_fHPFactor - 0f) < float.Epsilon; } + + // Calculate max hp of pet + public int CalcMaxHP() + { + int iVal = 1; + if (GetHPFactor() > 1e-6f) + iVal = (int)(GetHP() / GetHPFactor()); + return iVal; + } + + // Get skill by index + public PETSKILL? GetSkill(SKILLTYPE iType, int n) + { + if (iType == SKILLTYPE.EM_SKILL_DEFAULT) + { + if (n >= 0 && n < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM) + return m_aSkills[n]; + } + else if (iType == SKILLTYPE.EM_SKILL_NORMAL) + { + if (n >= 0 && n < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM && n < m_vecNorSkillIndex.Count) + return m_aSkills[m_vecNorSkillIndex[n]]; + } + else if (iType == SKILLTYPE.EM_SKILL_NATURE) + { + if (n >= 0 && n < (int)eGP_PET_NATURE_SKILL.GP_PET_NATURE_SKILL_NUM && n < (int)m_vecDynSkillIndex.Count) + return m_aSkills[m_vecDynSkillIndex[n]]; + } + else if (iType == SKILLTYPE.EM_SKILL_SPECIAL) + { + if (m_iSpecialSkillIndex >= 0) + return m_aSkills[m_iSpecialSkillIndex]; + } + + return null; + } + + // Get skill by id + public PETSKILL? GetSkillByID(int id) + { + int i = 0; + for (i = 0; i < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM; i++) + { + PETSKILL s = m_aSkills[i]; + if (s.idSkill == id) + { + return s; + } + } + + return null; + } + // Get valid skill number + public int GetSkillNum(SKILLTYPE iType) + { + int i, iCount = 0; + + if (iType == SKILLTYPE.EM_SKILL_DEFAULT) + { + for (i = 0; i < (int)eGP_PET_SKILL.GP_PET_SKILL_NUM; i++) + { + if (m_aSkills[i].idSkill != 0) + iCount++; + } + + return iCount; + } + else if (iType == SKILLTYPE.EM_SKILL_NORMAL) + { + return m_vecNorSkillIndex.Count; + } + else if (iType == SKILLTYPE.EM_SKILL_NATURE) + { + return m_vecDynSkillIndex.Count; + } + else if (iType == SKILLTYPE.EM_SKILL_SPECIAL) + { + return 1; + } + + return 0; // + } + + // ȡʾ + public ROLEEXTPROP GetExtendProps() { return m_ExtProps; } + public void SetExtendProps(ROLEEXTPROP prop) { m_ExtProps = prop; } + + public bool IsFollowPet() + { + if(m_pDBEssence == null) + { + return false; + } + return m_pDBEssence?.id_type == 8783; + } + public bool IsMountPet() + { + if (m_pDBEssence == null) + { + return false; + } + return m_pDBEssence?.id_type == 8781; + } + public bool IsCombatPet() + { + if (m_pDBEssence == null) + { + return false; + } + return m_pDBEssence?.id_type == 8782; + } + public bool IsSummonPet() + { + if (m_pDBEssence == null) + { + return false; + } + return m_pDBEssence?.id_type == 28752; + } + public bool IsPlantPet() + { + if (m_pDBEssence == null) + { + return false; + } + return m_pDBEssence?.id_type == 28913; + } + public bool IsEvolutionPet() + { + if (m_pDBEssence == null) + { + return false; + } + return m_pDBEssence?.id_type == 37698; + } + + public int GetAtkRation() {return m_iAtkRation;} + int GetDefRation() { return m_iDefRation;} + int GetHpRation() { return m_iHpRation;} + int GetAtkLvlRation() { return m_iAtkLvlRation;} + int GetDefLvlRation() { return m_iDefLvlRation;} + int GetNatureID() { return m_iNature;} + public string GetNature() + { + elementdataman pDB = ElementDataManProvider.GetElementDataMan(); + DATA_TYPE DataType = new DATA_TYPE(); + object pDBData = pDB.get_data_ptr((uint)m_iNature, ID_SPACE.ID_SPACE_CONFIG, ref DataType); + if (pDBData != null) + { + if (DataType == DATA_TYPE.DT_PET_EVOLVED_SKILL_CONFIG) + { + PET_EVOLVED_SKILL_CONFIG? pSkillConfig = (PET_EVOLVED_SKILL_CONFIG)pDBData; + if (pSkillConfig != null) + { + return new string((char[])(Array)pSkillConfig?.name); + } + } + } + return ""; + } + + // Զͷż + public void AddAutoSkill(int skill_id) + { + m_aAutoSkills.Add(skill_id); + } + public void CastAutoSkill() + { + if (m_aAutoSkills.Count == 0) + return; + + int skill_id = m_aAutoSkills[m_aAutoSkills.Count - 1]; + CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer(); + int idPet = pHost.GetPetCorral().GetActivePetNPCID(); + + CMDPARAM param = new CMDPARAM(); + param.idSkill = skill_id; + param.byPVPMask = EC_Utility.glb_BuildPVPMask(EC_Utility.glb_GetForceAttackFlag(null)); + + int iSkillType = ElementSkill.GetType((uint)param.idSkill); + int idTarget = 0; + + if (iSkillType == (int)skill_type.TYPE_BLESSPET) + { + idTarget = idPet; + } + else + { + idTarget = pHost.GetSelectedTarget(); + + if (iSkillType == (int)skill_type.TYPE_ATTACK || iSkillType == (int)skill_type.TYPE_CURSE) + { + bool bForctAttack = EC_Utility.glb_GetForceAttackFlag(null); + if (pHost.AttackableJudge(idTarget, bForctAttack) != 1) + { + OnAutoCastOver(skill_id); + return; + } + } + } + + UnityGameSession.c2s_CmdPetCtrl(idTarget, 4, param, Marshal.SizeOf(param)); + } +void OnAutoCastOver(int skill_id); +void OnPetDead(); + +bool CanEvolution()const ; +int GetEvolutionID() const ; +static int GetEvolutionID(int pet_tid); + +PET_ESSENCE* GetPetEssence() { return m_pDBEssence; } + +int GetMaxExp(); + + + + +bool Tick(DWORD dwDeltaTime); +}; +} diff --git a/Assets/PerfectWorld/Scripts/Pet/EC_PetCorral.cs.meta b/Assets/PerfectWorld/Scripts/Pet/EC_PetCorral.cs.meta new file mode 100644 index 0000000000..7fa4798c6c --- /dev/null +++ b/Assets/PerfectWorld/Scripts/Pet/EC_PetCorral.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9d73d6ebcbf227b478aec9344986734f \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/UI/AUIManager.cs b/Assets/PerfectWorld/Scripts/UI/AUIManager.cs index d3b94653b2..894e60a18b 100644 --- a/Assets/PerfectWorld/Scripts/UI/AUIManager.cs +++ b/Assets/PerfectWorld/Scripts/UI/AUIManager.cs @@ -15,6 +15,7 @@ namespace BrewMonster.UI protected Dictionary m_StringTable = new Dictionary(); protected Dictionary m_auiDialog_stringTable = new Dictionary(); public Dictionary m_DlgName = new Dictionary(); + public List m_vecBadWords = new List(); public string GetStringFromTable(int idString) { @@ -41,6 +42,7 @@ namespace BrewMonster.UI { ImportStringTable("Assets/Addressable/ingame.txt"); ImportAuiDialogStringTable("Assets/Addressable/msgbox.txt"); + ImportStringBadWords("Assets/Addressable/badwords.txt"); } public string Translate(ushort[] str) @@ -339,5 +341,41 @@ namespace BrewMonster.UI return null; } + + public bool ImportStringBadWords(string pszFilename) + { + //AWScriptFile s = new AWScriptFile(); + var ta = LoadStringTableTextAssetByAddressables(pszFilename); + if (ta == null || string.IsNullOrEmpty(ta.text)) + { + BMLogger.LogError($"[AUIManager] ImportStringTable failed: cannot load Addressables TextAsset for key='{pszFilename}'"); + return false; + } + + using (var sr = new StringReader(ta.text)) + { + string line; + while ((line = sr.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + + var parts = line.Split('\t', StringSplitOptions.RemoveEmptyEntries); + if (parts.Length < 2) + continue; + + if (int.TryParse(parts[0], out int key)) + { + string value = parts[1].Trim(); + if (value.StartsWith("\"") && value.EndsWith("\"")) + value = value.Substring(1, value.Length - 2); + + m_vecBadWords[key] = value; + } + } + } + + return true; + } } } diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgPetList.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgPetList.cs new file mode 100644 index 0000000000..3c475b9c95 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgPetList.cs @@ -0,0 +1,140 @@ +using System; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +namespace BrewMonster.UI +{ + public class CDlgPetList : AUIDialog + { + public const int CDLGPETLIST_SLOT_MAX = 10; + public const int CDLGPETLIST_PAGE_MAX = 2; + + [SerializeField] private Button[] m_pBtn_Summon = new Button[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private Button[] m_pBtn_Recall = new Button[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private Button[] m_pBtn_Detail = new Button[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private Button[] m_pBtn_Banish = new Button[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private Button[] m_pBtn_Evolution = new Button[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private Image[] m_pImg_Icon = new Image[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private TextMeshProUGUI[] m_pLab_Name = new TextMeshProUGUI[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private TextMeshProUGUI[] m_pLab_Level = new TextMeshProUGUI[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private TextMeshProUGUI[] m_pTxt_Name = new TextMeshProUGUI[CDLGPETLIST_SLOT_MAX]; + [SerializeField] private TextMeshProUGUI[] m_pTxt_Level = new TextMeshProUGUI[CDLGPETLIST_SLOT_MAX]; + + + public void OnInitDialog() + { + //string szText = ""; + //int i; + //for (i = 0; i < CDLGPETLIST_SLOT_MAX; i++) + //{ + // szText = string.Format("Img_Icon{0}", i + 1); + // m_pImg_Icon[i] = (PAUIIMAGEPICTURE)GetDlgItem(szText); + // sprintf(szText, "Lab_Name%d", i + 1); + // m_pLab_Name[i] = (PAUILABEL)GetDlgItem(szText); + // sprintf(szText, "Lab_Level%d", i + 1); + // m_pLab_Level[i] = (PAUILABEL)GetDlgItem(szText); + // sprintf(szText, "Txt_Name%d", i + 1); + // m_pTxt_Name[i] = (PAUILABEL)GetDlgItem(szText); + // sprintf(szText, "Txt_Level%d", i + 1); + // m_pTxt_Level[i] = (PAUILABEL)GetDlgItem(szText); + // sprintf(szText, "Btn_Recall%d", i + 1); + // m_pBtn_Recall[i] = (PAUIIMAGEPICTURE)GetDlgItem(szText); + // sprintf(szText, "Btn_Summon%d", i + 1); + // m_pBtn_Summon[i] = (PAUIIMAGEPICTURE)GetDlgItem(szText); + // sprintf(szText, "Btn_Detail%d", i + 1); + // m_pBtn_Detail[i] = (PAUIIMAGEPICTURE)GetDlgItem(szText); + // sprintf(szText, "Btn_Banish%d", i + 1); + // m_pBtn_Banish[i] = (PAUIIMAGEPICTURE)GetDlgItem(szText); + // sprintf(szText, "Btn_P%d", i + 1); + // m_pBtn_Evolution[i] = (PAUIIMAGEPICTURE)GetDlgItem(szText); + //} + //for (i = 0; i < CDLGPETLIST_PAGE_MAX; i++) + //{ + // m_pBtn_Page[i] = NULL; + // DDX_Control(AString().Format("Btn_Page%d", i + 1), m_pBtn_Page[i]); + // m_pBtn_Page[i]->SetPushed(false); + //} + //m_nPageIndex = 0; + //m_pBtn_Page[0]->SetPushed(true); + + //return true; + } + + void UpdateList() + { + string strText = ""; + CECPetCorral pPetCorral = GetHostPlayer()->GetPetCorral(); + elementdataman* pDB = GetGame()->GetElementDataMan(); + DATA_TYPE DataType; + int i; + for (i = 0; i < CDLGPETLIST_SLOT_MAX; i++) + { + int nPetSlot = i + m_nPageIndex * CDLGPETLIST_SLOT_MAX; + if (nPetSlot < pPetCorral->GetPetSlotNum()) + { + m_pLab_Level[i]->SetColor(A3DCOLORRGB(255, 203, 74)); + m_pLab_Name[i]->SetColor(A3DCOLORRGB(255, 203, 74)); + } + else + { + m_pLab_Level[i]->SetColor(A3DCOLORRGB(128, 128, 128)); + m_pLab_Name[i]->SetColor(A3DCOLORRGB(128, 128, 128)); + } + CECPetData* pPet = pPetCorral->GetPetData(nPetSlot); + if (pPet) + { + bool bEnable = (pPetCorral->GetActivePetIndex() == nPetSlot && GetHostPlayer()->IsOperatingPet() == 0); + m_pBtn_Recall[i]->Enable(bEnable); + + bEnable = (pPetCorral->GetActivePetIndex() != nPetSlot && GetHostPlayer()->IsOperatingPet() == 0); + m_pBtn_Summon[i]->Enable(bEnable); + + m_pBtn_Detail[i]->Enable(true); + + strText.Format(GetStringFromTable(801), pPet->GetLevel()); + m_pTxt_Level[i]->SetText(strText); + m_pTxt_Name[i]->SetText(pPet->GetName()); + if ((pPet->GetClass() == GP_PET_CLASS_COMBAT || pPet->GetClass() == GP_PET_CLASS_EVOLUTION) && pPet->GetHPFactor() == 0.0f || IsPetDye(nPetSlot)) + m_pImg_Icon[i]->SetColor(A3DCOLORRGB(128, 128, 128)); + else + m_pImg_Icon[i]->SetColor(A3DCOLORRGB(255, 255, 255)); + m_pImg_Icon[i]->SetData(1); + m_pImg_Icon[i]->SetDataPtr((void*)1); + PET_ESSENCE* pDBEssence = (PET_ESSENCE*)pDB->get_data_ptr(pPet->GetTemplateID(), + ID_SPACE_ESSENCE, DataType); + + if (pDBEssence) + { + AString strFile; + af_GetFileTitle(pDBEssence->file_icon, strFile); + strFile.MakeLower(); + m_pImg_Icon[i]->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_INVENTORY], + GetGameUIMan()->m_IconMap[CECGameUIMan::ICONS_INVENTORY][strFile]); + } + else + { + m_pImg_Icon[i]->ClearCover(); + m_pImg_Icon[i]->SetHint(_AL("")); + } + + m_pBtn_Evolution[i]->Show(pPet->GetClass() == GP_PET_CLASS_COMBAT || pPet->GetClass() == GP_PET_CLASS_EVOLUTION); + } + else + { + m_pBtn_Summon[i]->Enable(false); + m_pBtn_Recall[i]->Enable(false); + m_pBtn_Detail[i]->Enable(false); + m_pBtn_Evolution[i]->Show(false); + // m_pBtn_Banish[i]->Enable(false); + m_pImg_Icon[i]->SetDataPtr(NULL); + m_pTxt_Level[i]->SetText(_AL("")); + m_pTxt_Name[i]->SetText(_AL("")); + m_pImg_Icon[i]->ClearCover(); + m_pImg_Icon[i]->SetHint(_AL("")); + m_pImg_Icon[i]->SetData(0); + } + } + } + } +} diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgPetList.cs.meta b/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgPetList.cs.meta new file mode 100644 index 0000000000..f46e558c64 --- /dev/null +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgPetList.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 29fc8c9fd1814f144aec0fee5da5d8a5 \ No newline at end of file diff --git a/Assets/Scenes/a61.unity b/Assets/Scenes/a61.unity index 32a405e47a..404e33a5cc 100644 --- a/Assets/Scenes/a61.unity +++ b/Assets/Scenes/a61.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c76c39b1f6f2ca8de739551935e1461ca08857855d1319c19619dd05b7e35b3 -size 200530484 +oid sha256:aaa8a431afcdc74fff7d2dec7f9815dcd3decc1e5b34b44df03f376d04b9179c +size 200530485 diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index f6e7227a3e..201b41ea80 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -6,6 +6,7 @@ using BrewMonster.PerfectWorld.Scripts.Vfx; using BrewMonster.PerfectWorld.Scripts.Vfx; using BrewMonster.Scripts; using BrewMonster.Scripts.Managers; +using BrewMonster.Scripts.Pet; using BrewMonster.Scripts.Skills; using BrewMonster.Scripts.World; using BrewMonster.UI; @@ -108,6 +109,7 @@ namespace BrewMonster private CECCounter m_GatherCnt; // Gather counter Dictionary m_skillCoolTime = new Dictionary(); COOLTIME[] m_aCoolTimes = new COOLTIME[(int)CoolTimeIndex.GP_CT_MAX]; // Cool times + CECPetCorral m_pPetCorral = null; // Host config data version const int HOSTCFG_VERSION = 11; @@ -2632,6 +2634,7 @@ namespace BrewMonster // roleName = Encoding.UTF8.GetString(role.name.ByteArray, 0, role.name.Length); //} SetPlayerInfor(new INFO(role.cid, role.crc_e, role.crc_c)); + m_pPetCorral = new CECPetCorral(); LoadResources(); await SetPlayerModel(UnityGameSession.Instance.GetRoleInfo().occupation, UnityGameSession.Instance.GetRoleInfo().gender); @@ -6879,5 +6882,8 @@ namespace BrewMonster } return iReason == 0? true : false; } + + // Get pet corral object + public CECPetCorral GetPetCorral() { return m_pPetCorral; } } } diff --git a/Assets/Scripts/CECUIManager.cs b/Assets/Scripts/CECUIManager.cs index cd04fb06b6..14aa3a2075 100644 --- a/Assets/Scripts/CECUIManager.cs +++ b/Assets/Scripts/CECUIManager.cs @@ -359,4 +359,31 @@ public class CECUIManager : MonoSingleton pDlg = dlg; } } + + public void FilterBadWords(ref string str) + { + if (string.IsNullOrEmpty(str)) + return; + + string strLwr = str.ToLower(); + + char[] chars = str.ToCharArray(); + + foreach (string bad in gameUI.m_vecBadWords) + { + int pos = 0; + string badLwr = bad.ToLower(); + + while ((pos = strLwr.IndexOf(badLwr, pos, StringComparison.Ordinal)) >= 0) + { + for (int j = 0; j < badLwr.Length; j++) + { + chars[pos + j] = '*'; + } + pos += badLwr.Length; + } + } + + str = new string(chars); + } } \ No newline at end of file diff --git a/Assets/Scripts/EC_Utility.cs b/Assets/Scripts/EC_Utility.cs index 19d370eb96..d942bd3ce7 100644 --- a/Assets/Scripts/EC_Utility.cs +++ b/Assets/Scripts/EC_Utility.cs @@ -322,4 +322,19 @@ public static class EC_Utility return Color.white; } } + + // Get force attack flag + public static bool glb_GetForceAttackFlag(uint? pdwParam) + { + + bool bForceAttack = false; + // CECInputCtrl* pInputCtrl = g_pGame->GetGameRun()->GetInputCtrl(); + + //if (pdwParam) + // bForceAttack = pInputCtrl->IsCtrlPressed(*pdwParam); + //else + // bForceAttack = pInputCtrl->KeyIsBeingPressed(VK_CONTROL); + + return bForceAttack; + } }