From a166d721a3d7ff6cd2339983214e718c7a6a0ffe Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 11 六月 2025 11:00:36 +0800
Subject: [PATCH] 121 【武将】武将系统-服务端(武将招募;武将背包;武将养成系统;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py | 71 +
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 21
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py | 520 +++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 112 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py | 15
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py | 1
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_HeroSkin.py | 28
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItemCount.py | 8
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py | 135 +++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py | 923 ++++++++++++++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini | 39 +
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 242 ++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py | 5
PySysDB/PySysDBPY.h | 85 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 14
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 18
18 files changed, 2,226 insertions(+), 22 deletions(-)
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 23cd4f0..772f55b 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -26,6 +26,91 @@
BYTE OPLimitInAct; //活动期间限制队伍操作
};
+//武将表
+struct Hero
+{
+ DWORD _HeroID; //英雄ID
+ WORD HeroIndex; // 记录索引
+ BYTE Country; // 国家
+ BYTE Quality; // 品质
+ list SkinNPCIDList; // 皮肤NPCID列表
+ DWORD AtkSkillID; //普攻技能ID
+ DWORD AngerSkillID; //怒气技能ID
+};
+
+//武将星级天赋表
+struct HeroTalent
+{
+ DWORD _TalentID; //天赋ID
+ BYTE AttrID; // 属性ID
+ DWORD AttrValue; // 属性值
+ DWORD InitWeight; // 初始权重
+ DWORD WashWeight; // 洗炼权重
+ DWORD AweakWeight; // 觉醒权重
+};
+
+//武将突破潜能表
+struct HeroBreak
+{
+ DWORD _HeroID; //英雄ID
+ BYTE BreakLV; // 突破等级
+ list AttrIDList; // 属性ID列表
+ list AttrValueList; // 属性值列表
+ DWORD SkillID; // 激活技能ID
+};
+
+//武将觉醒天赋表
+struct HeroAwake
+{
+ DWORD _HeroID; //英雄ID
+ BYTE AwakeLV; // 觉醒等级
+ list AttrIDList; // 属性ID列表
+ list AttrValueList; // 属性值列表
+ DWORD SkillID; // 激活技能ID
+ BYTE UnlockTalentSlot; // 解锁第x槽位
+ BYTE AddStarUpper; // 增加星级上限
+};
+
+//武将皮肤表
+struct HeroSkin
+{
+ DWORD _SkinNPCID; //皮肤NPCID
+ list WearAttrIDList; // 穿戴属性ID列表
+ list WearAttrValueList; // 穿戴属性值列表
+ list AllBatAttrIDList; // 全体上阵属性ID列表
+ list AllBatAttrValueList; // 全体上阵属性值列表
+};
+
+//武将品质表
+struct HeroQuality
+{
+ DWORD _Quality; //品质
+ list UPCostItem; // 升级消耗道具
+ list InitTalentWeight; // 初始天赋数权重
+ BYTE InitStarUpper; // 初始星级上限
+ DWORD InitAddPer; // 初始加成万分率
+ DWORD LVAddPer; // 每等级加成
+ DWORD BreakLVAddPer; // 每突破等级加成
+ DWORD StarAddPer; // 每星级加成
+};
+
+//武将品质突破表
+struct HeroQualityBreak
+{
+ DWORD _Quality; //品质
+ DWORD _BreakLV; //突破等级
+ WORD LVMax; // 等级上限
+ list UPCostItem; // 突破到下级消耗道具
+};
+
+//武将品质觉醒表
+struct HeroQualityAwake
+{
+ DWORD _Quality; //品质
+ DWORD _AwakeLV; //觉醒等级
+ list UPCostItem; // 觉醒到下级消耗道具
+};
+
//称号表 #tagDienstgrad
struct tagDienstgrad
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini
index 1fe370c..117a69d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini
@@ -1,7 +1,7 @@
[RolePackConfig]
;2000///<所有背包总量限制
;玩家背包配置
-PackTypeCnt=35
+PackTypeCnt=36
;已删除物品rptDeleted//已无用
PackCnt00=0
@@ -72,4 +72,6 @@
;神兽装备背包
PackCnt33=150
;垃圾分类背包
-PackCnt34=30
\ No newline at end of file
+PackCnt34=30
+;武将英雄背包
+PackCnt35=500
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 3baff6f..c847a2f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1904,3 +1904,42 @@
PacketSubCMD_4=0x27
PacketCallFunc_4=OnFamilyGCZSQ
+;武将
+[PlayerHero]
+ScriptName = Player\PlayerHero.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 8
+
+PacketCMD_1=0xB2
+PacketSubCMD_1=0x30
+PacketCallFunc_1=OnHeroLVUP
+
+PacketCMD_2=0xB2
+PacketSubCMD_2=0x31
+PacketCallFunc_2=OnHeroStarUP
+
+PacketCMD_3=0xB2
+PacketSubCMD_3=0x32
+PacketCallFunc_3=OnHeroBreak
+
+PacketCMD_4=0xB2
+PacketSubCMD_4=0x33
+PacketCallFunc_4=OnHeroAwake
+
+PacketCMD_5=0xB2
+PacketSubCMD_5=0x34
+PacketCallFunc_5=OnHeroAwakeSelectTalent
+
+PacketCMD_6=0xB2
+PacketSubCMD_6=0x35
+PacketCallFunc_6=OnHeroWash
+
+PacketCMD_7=0xB2
+PacketSubCMD_7=0x36
+PacketCallFunc_7=OnHeroWearSkin
+
+PacketCMD_8=0xB4
+PacketSubCMD_8=0x12
+PacketCallFunc_8=OnHeroBattlePosSave
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 38ae491..5f25ed4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -463,6 +463,8 @@
Def_ItemType_CanUseByCDTime = 145 # 创建后根据CDTime到后可开启
+Def_ItemType_Hero = 150 # 武将英雄
+
#以下定义物品类型下次删除
Def_Item_Type_Horse = 1000036 #坐骑
@@ -555,6 +557,7 @@
Def_Effect_EmojiPack = 276 #表情包物品;A值-表情包ID
Def_Effect_RecycleItemMoney = 277 #回收物品转化为货币; A值-直接给货币物品ID;B值-货币数量
Def_Effect_FamilyEmblem = 278 #激活仙盟徽章; A值-徽章ID;
+Def_Effect_HeroSkin = 279 #激活武将皮肤; A值-武将ID;B值-皮肤索引
#----以下未使用或代码依然存在的---
Def_Effect_ItemGiveGongXun = 1920 #使用道具给予功勋
Def_Effect_ItemGiveRuneJH = 1925 #使用道具给予符印精华
@@ -1153,6 +1156,7 @@
ShareDefine.rptDogzItem,
ShareDefine.rptDogzEquip,
ShareDefine.rptGarbage,
+ ShareDefine.rptHero,
]
#装备可强化背包列表
@@ -1510,7 +1514,7 @@
#自动恢复计算间隔
Def_HPRestoreInterval = 5000
#允许重置的背包索引
-Def_CanItemResetPack = [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse, ShareDefine.rptTreasure, ShareDefine.rptGarbage]
+Def_CanItemResetPack = [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse, ShareDefine.rptTreasure, ShareDefine.rptGarbage, ShareDefine.rptHero]
#仓库分页个数
Def_ItemReset_WarehousePageCnt = 56
#玩家捡起物品的距离 8
@@ -3444,6 +3448,7 @@
Def_Player_Dict_CabinetCount_Horse = "CabinetCount_Horse_42" #马匹收纳柜
Def_Player_Dict_PackCount_Item = "PackCount_Item_72" #玩家物品背包格子数
Def_Player_Dict_PackCount_Warehouse = "PackCount_Warehouse_73" #仓库背包格子数
+Def_Player_Dict_PackCount_Hero = "PackCount_Hero" #武将背包格子数
Def_Player_Dict_PlayerMapSignCnt = "PlayerMapSignCnt_75" # 大地图标记数量
Def_Player_Dict_PlayerBuyZhenQiCnt = "PlayerBuyZhenQiCnt_76" # 购买真气次数
Def_Player_Dict_PlayChangeLineID = "PlayChangeLineID" # 玩家主动切换线路记录
@@ -4414,6 +4419,10 @@
Def_PDict_TiandaoQiyun = "TiandaoQiyun" # 天道树当前气运
Def_PDict_TiandaoAward = "TiandaoAward_%s" # 天道树领奖记录,按奖励索引记录是否已领取,参数(key编号)
+#武将
+Def_PDict_HeroActState = "HeroActState_%s" # 武将解锁状态,按记录索引二进制存储,参数(key编号)
+Def_PDict_HeroSkin = "HeroSkin_%s" # 武将皮肤解锁状态,按皮肤索引二进制存储,参数(武将ID)
+
#-------------------------------------------------------------------------------
#可以从07 41封包购买的背包类型,和对应字典{背包类型:[字典key, 默认格子数]}
@@ -4445,6 +4454,10 @@
IPY_GameWorld.rptWarehouse:[
Def_Player_Dict_PackCount_Warehouse,
+ 0],
+
+ ShareDefine.rptHero:[
+ Def_Player_Dict_PackCount_Hero,
0],
#IPY_GameWorld.rptFineSoulSlot:[
@@ -5733,8 +5746,9 @@
ntMonsterTime, #按时间掉血的怪物 22 废弃,以是否有配置在时间掉血怪物表为准
ntPriWoodPilePVE, #专属私有木桩 - PVE 23
ntPriWoodPilePVP, #专属私有木桩 - PVP 24
+ntHero, #武将英雄 25
ntMax
-) = range(26)
+) = range(27)
(Def_SkillFuncType_Common, #0为通用技能
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index e95e85e..cae4322 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -17264,6 +17264,411 @@
#------------------------------------------------------
+# B2 33 武将觉醒 #tagCSHeroAwake
+
+class tagCSHeroAwake(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB2
+ self.SubCmd = 0x33
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xB2
+ self.SubCmd = 0x33
+ self.ItemIndex = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroAwake)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B2 33 武将觉醒 //tagCSHeroAwake:
+ Cmd:%s,
+ SubCmd:%s,
+ ItemIndex:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ItemIndex
+ )
+ return DumpString
+
+
+m_NAtagCSHeroAwake=tagCSHeroAwake()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroAwake.Cmd,m_NAtagCSHeroAwake.SubCmd))] = m_NAtagCSHeroAwake
+
+
+#------------------------------------------------------
+# B2 34 武将觉醒选择天赋 #tagCSHeroAwakeSelectTalent
+
+class tagCSHeroAwakeSelectTalent(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ("SelectIndex", c_ubyte), #选择新解锁槽位的天赋索引
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB2
+ self.SubCmd = 0x34
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xB2
+ self.SubCmd = 0x34
+ self.ItemIndex = 0
+ self.SelectIndex = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroAwakeSelectTalent)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B2 34 武将觉醒选择天赋 //tagCSHeroAwakeSelectTalent:
+ Cmd:%s,
+ SubCmd:%s,
+ ItemIndex:%d,
+ SelectIndex:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ItemIndex,
+ self.SelectIndex
+ )
+ return DumpString
+
+
+m_NAtagCSHeroAwakeSelectTalent=tagCSHeroAwakeSelectTalent()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroAwakeSelectTalent.Cmd,m_NAtagCSHeroAwakeSelectTalent.SubCmd))] = m_NAtagCSHeroAwakeSelectTalent
+
+
+#------------------------------------------------------
+# B2 32 武将突破 #tagCSHeroBreak
+
+class tagCSHeroBreak(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB2
+ self.SubCmd = 0x32
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xB2
+ self.SubCmd = 0x32
+ self.ItemIndex = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroBreak)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B2 32 武将突破 //tagCSHeroBreak:
+ Cmd:%s,
+ SubCmd:%s,
+ ItemIndex:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ItemIndex
+ )
+ return DumpString
+
+
+m_NAtagCSHeroBreak=tagCSHeroBreak()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroBreak.Cmd,m_NAtagCSHeroBreak.SubCmd))] = m_NAtagCSHeroBreak
+
+
+#------------------------------------------------------
+# B2 30 武将升级 #tagCSHeroLVUP
+
+class tagCSHeroLVUP(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB2
+ self.SubCmd = 0x30
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xB2
+ self.SubCmd = 0x30
+ self.ItemIndex = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroLVUP)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B2 30 武将升级 //tagCSHeroLVUP:
+ Cmd:%s,
+ SubCmd:%s,
+ ItemIndex:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ItemIndex
+ )
+ return DumpString
+
+
+m_NAtagCSHeroLVUP=tagCSHeroLVUP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroLVUP.Cmd,m_NAtagCSHeroLVUP.SubCmd))] = m_NAtagCSHeroLVUP
+
+
+#------------------------------------------------------
+# B2 31 武将升星 #tagCSHeroStarUP
+
+class tagCSHeroStarUP(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ("UseItemIndex", c_ushort), #使用武将材料物品所在武将背包位置索引
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB2
+ self.SubCmd = 0x31
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xB2
+ self.SubCmd = 0x31
+ self.ItemIndex = 0
+ self.UseItemIndex = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroStarUP)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B2 31 武将升星 //tagCSHeroStarUP:
+ Cmd:%s,
+ SubCmd:%s,
+ ItemIndex:%d,
+ UseItemIndex:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ItemIndex,
+ self.UseItemIndex
+ )
+ return DumpString
+
+
+m_NAtagCSHeroStarUP=tagCSHeroStarUP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroStarUP.Cmd,m_NAtagCSHeroStarUP.SubCmd))] = m_NAtagCSHeroStarUP
+
+
+#------------------------------------------------------
+# B2 35 武将洗炼 #tagCSHeroWash
+
+class tagCSHeroWash(Structure):
+ Head = tagHead()
+ ItemIndex = 0 #(WORD ItemIndex)//武将物品所在武将背包位置索引
+ LockCnt = 0 #(BYTE LockCnt)
+ LockTalentIndexs = list() #(vector<BYTE> LockTalentIndexs)//锁定天赋索引列表
+ OPType = 0 #(BYTE OPType)// 操作类型:0-执行洗炼;1-替换原天赋;2-保留原天赋
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB2
+ self.Head.SubCmd = 0x35
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.ItemIndex,_pos = CommFunc.ReadWORD(_lpData, _pos)
+ self.LockCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.LockCnt):
+ value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+ self.LockTalentIndexs.append(value)
+ self.OPType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB2
+ self.Head.SubCmd = 0x35
+ self.ItemIndex = 0
+ self.LockCnt = 0
+ self.LockTalentIndexs = list()
+ self.OPType = 0
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 2
+ length += 1
+ length += 1 * self.LockCnt
+ length += 1
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteWORD(data, self.ItemIndex)
+ data = CommFunc.WriteBYTE(data, self.LockCnt)
+ for i in range(self.LockCnt):
+ data = CommFunc.WriteBYTE(data, self.LockTalentIndexs[i])
+ data = CommFunc.WriteBYTE(data, self.OPType)
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ ItemIndex:%d,
+ LockCnt:%d,
+ LockTalentIndexs:%s,
+ OPType:%d
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.ItemIndex,
+ self.LockCnt,
+ "...",
+ self.OPType
+ )
+ return DumpString
+
+
+m_NAtagCSHeroWash=tagCSHeroWash()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroWash.Head.Cmd,m_NAtagCSHeroWash.Head.SubCmd))] = m_NAtagCSHeroWash
+
+
+#------------------------------------------------------
+# B2 36 武将换肤 #tagCSHeroWearSkin
+
+class tagCSHeroWearSkin(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ("SkinIndex", c_ubyte), #皮肤索引
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xB2
+ self.SubCmd = 0x36
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xB2
+ self.SubCmd = 0x36
+ self.ItemIndex = 0
+ self.SkinIndex = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroWearSkin)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B2 36 武将换肤 //tagCSHeroWearSkin:
+ Cmd:%s,
+ SubCmd:%s,
+ ItemIndex:%d,
+ SkinIndex:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.ItemIndex,
+ self.SkinIndex
+ )
+ return DumpString
+
+
+m_NAtagCSHeroWearSkin=tagCSHeroWearSkin()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroWearSkin.Cmd,m_NAtagCSHeroWearSkin.SubCmd))] = m_NAtagCSHeroWearSkin
+
+
+#------------------------------------------------------
# B2 07 重置加点 #tagCMResetAttrPoint
class tagCMResetAttrPoint(Structure):
@@ -18535,6 +18940,121 @@
#------------------------------------------------------
+# B4 12 战斗阵型保存 #tagCSHeroBattlePosSave
+
+class tagCSHeroBattlePos(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("ItemIndex", c_ushort), #武将物品所在武将背包位置索引
+ ("PosNum", c_ubyte), #1~n上阵位置编号
+ ]
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.ItemIndex = 0
+ self.PosNum = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCSHeroBattlePos)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B4 12 战斗阵型保存 //tagCSHeroBattlePosSave:
+ ItemIndex:%d,
+ PosNum:%d
+ '''\
+ %(
+ self.ItemIndex,
+ self.PosNum
+ )
+ return DumpString
+
+
+class tagCSHeroBattlePosSave(Structure):
+ Head = tagHead()
+ FuncType = 0 #(BYTE FuncType)//布阵功能类型:0-默认主阵型;其他待扩展,如某个活动的防守阵型
+ PosCnt = 0 #(BYTE PosCnt)
+ HeroPosList = list() #(vector<tagCSHeroBattlePos> HeroPosList)// 保存的阵型,只要发送最终的阵型武将位置即可
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB4
+ self.Head.SubCmd = 0x12
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.FuncType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.PosCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.PosCnt):
+ temHeroPosList = tagCSHeroBattlePos()
+ _pos = temHeroPosList.ReadData(_lpData, _pos)
+ self.HeroPosList.append(temHeroPosList)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB4
+ self.Head.SubCmd = 0x12
+ self.FuncType = 0
+ self.PosCnt = 0
+ self.HeroPosList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 1
+ length += 1
+ for i in range(self.PosCnt):
+ length += self.HeroPosList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteBYTE(data, self.FuncType)
+ data = CommFunc.WriteBYTE(data, self.PosCnt)
+ for i in range(self.PosCnt):
+ data = CommFunc.WriteString(data, self.HeroPosList[i].GetLength(), self.HeroPosList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ FuncType:%d,
+ PosCnt:%d,
+ HeroPosList:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.FuncType,
+ self.PosCnt,
+ "..."
+ )
+ return DumpString
+
+
+m_NAtagCSHeroBattlePosSave=tagCSHeroBattlePosSave()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroBattlePosSave.Head.Cmd,m_NAtagCSHeroBattlePosSave.Head.SubCmd))] = m_NAtagCSHeroBattlePosSave
+
+
+#------------------------------------------------------
# B4 11 镜像战斗 #tagCMMirrorFight
class tagCMMirrorFight(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 0b5955d..50f951f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -44094,6 +44094,118 @@
#------------------------------------------------------
+# B1 22 武将信息 #tagSCHeroInfo
+
+class tagSCHero(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("HeroID", c_int), # 武将ID
+ ("IsActive", c_ubyte), # 是否已激活
+ ("SkinState", c_int), # 武将皮肤已解锁状态信息,按皮肤所在索引二进制位运算判断是否解锁,0索引位默认皮肤,不用验证
+ ]
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.HeroID = 0
+ self.IsActive = 0
+ self.SkinState = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagSCHero)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// B1 22 武将信息 //tagSCHeroInfo:
+ HeroID:%d,
+ IsActive:%d,
+ SkinState:%d
+ '''\
+ %(
+ self.HeroID,
+ self.IsActive,
+ self.SkinState
+ )
+ return DumpString
+
+
+class tagSCHeroInfo(Structure):
+ Head = tagHead()
+ HeroCnt = 0 #(WORD HeroCnt)
+ HeroInfoList = list() #(vector<tagSCHero> HeroInfoList)
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB1
+ self.Head.SubCmd = 0x22
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.HeroCnt,_pos = CommFunc.ReadWORD(_lpData, _pos)
+ for i in range(self.HeroCnt):
+ temHeroInfoList = tagSCHero()
+ _pos = temHeroInfoList.ReadData(_lpData, _pos)
+ self.HeroInfoList.append(temHeroInfoList)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB1
+ self.Head.SubCmd = 0x22
+ self.HeroCnt = 0
+ self.HeroInfoList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 2
+ for i in range(self.HeroCnt):
+ length += self.HeroInfoList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteWORD(data, self.HeroCnt)
+ for i in range(self.HeroCnt):
+ data = CommFunc.WriteString(data, self.HeroInfoList[i].GetLength(), self.HeroInfoList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ HeroCnt:%d,
+ HeroInfoList:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.HeroCnt,
+ "..."
+ )
+ return DumpString
+
+
+m_NAtagSCHeroInfo=tagSCHeroInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCHeroInfo.Head.Cmd,m_NAtagSCHeroInfo.Head.SubCmd))] = m_NAtagSCHeroInfo
+
+
+#------------------------------------------------------
# B1 06 通知玩家向目标点移动 #tagMCNotifyPlayerMove
class tagMCNotifyPlayerMove(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
new file mode 100644
index 0000000..cb4faeb
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.Hero
+#
+# @todo:武将英雄
+# @author hxp
+# @date 2025-06-11
+# @version 1.0
+#
+# 详细描述: 武将英雄
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-11 11:00"""
+#-------------------------------------------------------------------------------
+
+import PlayerHero
+import ShareDefine
+import IpyGameDataPY
+import GameWorld
+import ChConfig
+
+## GM命令执行入口
+# @param curPlayer 当前玩家
+# @param msgList 参数列表
+# @return None
+# @remarks 函数详细说明.
+def OnExec(curPlayer, msgList):
+
+ if not msgList:
+ GameWorld.DebugAnswer(curPlayer, "武将重置: Hero 0 背包位置")
+ GameWorld.DebugAnswer(curPlayer, "武将等级: Hero l 背包位置 设置等级")
+ GameWorld.DebugAnswer(curPlayer, "武将升星: Hero s 背包位置 升x星")
+ GameWorld.DebugAnswer(curPlayer, "武将突破: Hero b 背包位置 设置等级")
+ GameWorld.DebugAnswer(curPlayer, "武将觉醒: Hero a 背包位置 设置等级")
+ GameWorld.DebugAnswer(curPlayer, "武将图鉴: Hero t 武将ID 是否激活")
+ GameWorld.DebugAnswer(curPlayer, "重置图鉴: Hero t 0")
+ GameWorld.DebugAnswer(curPlayer, "武将皮肤: Hero sk 武将ID 皮肤索引 是否解锁")
+ GameWorld.DebugAnswer(curPlayer, "清空武将: ClearPack 35")
+ GameWorld.DebugAnswer(curPlayer, "新增武将: MakeItemCount 英雄ID [个数]")
+ return
+
+ value = msgList[0]
+ value2 = msgList[1] if len(msgList) > 1 else 0
+
+ # 图鉴
+ if value == "t":
+ isAct = 0
+ if not value2:
+ heroIDList = []
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for index in range(ipyDataMgr.GetHeroCount()):
+ ipyData = ipyDataMgr.GetHeroByIndex(index)
+ heroIDList.append(ipyData.GetHeroID())
+ else:
+ isAct = msgList[2] if len(msgList) > 2 else 0
+ heroIDList = [value2]
+
+ syncHeroIDList = []
+ for heroID in heroIDList:
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ continue
+ heroIndex = heroIpyData.GetHeroIndex()
+ if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HeroActState, heroIndex) == isAct:
+ continue
+ GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HeroActState, heroIndex, isAct)
+ syncHeroIDList.append(heroID)
+
+ PlayerHero.Sync_HeroInfo(curPlayer, syncHeroIDList)
+ if not value2:
+ GameWorld.DebugAnswer(curPlayer, "重置图鉴OK!")
+ else:
+ GameWorld.DebugAnswer(curPlayer, "设置武将(%s),激活(%s)" % (value2, isAct))
+ return
+
+ # 皮肤
+ if value == "sk":
+ heroID = value2
+ skinIndex = msgList[2] if len(msgList) > 2 else 0
+ isActive = msgList[3] if len(msgList) > 3 else 0
+ PlayerHero.ActiveHeroSkin(curPlayer, heroID, skinIndex, isActive)
+ return
+
+ itemIndex = value2
+ heroItem = PlayerHero.GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ GameWorld.DebugAnswer(curPlayer, "不存在武将: itemIndex=%s" % itemIndex)
+ return
+
+ if value == 0:
+ PlayerHero.InitHeroItem(heroItem.GetItem())
+ heroItem.Sync_Item()
+ GameWorld.DebugAnswer(curPlayer, "重置武将: itemIndex=%s" % (itemIndex))
+ return
+
+ # 等级
+ if value == "l":
+ heroLV = msgList[2] if len(msgList) > 2 else 1
+ LVMax = PlayerHero.GetHeroLVMax(heroItem)
+ heroLV = min(LVMax, heroLV)
+ heroItem.SetUserAttr(ShareDefine.Def_IudetHeroLV, heroLV)
+ GameWorld.DebugAnswer(curPlayer, "设置武将等级: %s,itemIndex=%s" % (heroLV, itemIndex))
+ return
+
+ # 星级
+ if value == "s":
+ addStar = msgList[2] if len(msgList) > 2 else 1
+ curStar = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ starMax = PlayerHero.GetHeroStarMax(heroItem)
+ if curStar >= starMax:
+ GameWorld.DebugAnswer(curPlayer, "武将已满星: %s,itemIndex=%s" % (curStar, itemIndex))
+ return
+ updStar = min(curStar + addStar, starMax)
+ PlayerHero.DoHeroUpdStar(curPlayer, heroItem, updStar)
+ GameWorld.DebugAnswer(curPlayer, "更新武将星级: %s,itemIndex=%s" % (updStar, itemIndex))
+ return
+
+ # 突破
+ if value == "b":
+ breakLV = msgList[2] if len(msgList) > 2 else 0
+ PlayerHero.SetHeroBreakLV(heroItem, breakLV)
+ GameWorld.DebugAnswer(curPlayer, "设置武将突破: %s,itemIndex=%s" % (breakLV, itemIndex))
+ return
+
+ # 觉醒
+ if value == "a":
+ awakeLV = msgList[2] if len(msgList) > 2 else 0
+ PlayerHero.SetHeroAwakeLV(heroItem, awakeLV)
+ GameWorld.DebugAnswer(curPlayer, "设置武将觉醒: %s,itemIndex=%s" % (awakeLV, itemIndex))
+ return
+
+ return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItemCount.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItemCount.py
index 913dd60..3f7467e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItemCount.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItemCount.py
@@ -66,12 +66,12 @@
if not ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, True, [IPY_GameWorld.rptItem], event=event):
GameWorld.DebugAnswer(curPlayer, "###放入物品失败!")
else:
- if not ItemCommon.GetIsEquip(itemData):
- if not ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, False, [IPY_GameWorld.rptItem], event=event):
- GameWorld.DebugAnswer(curPlayer, "###放入物品失败!")
- else:
+ if ItemCommon.GetIsEquip(itemData) or itemData.GetPackCount() <= 1:
for _ in xrange(itemCount):
__DoGMGivePlayerItem(curPlayer, playerItemControler, itemID, 1, False, isAllAttr, event)
+ else:
+ if not ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, False, [IPY_GameWorld.rptItem], event=event):
+ GameWorld.DebugAnswer(curPlayer, "###放入物品失败!")
return
def __DoGMGivePlayerItem(curPlayer, playerItemControler, itemID, count, isAuctionItem, isAllAttr, event):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index c1e5011..8244a79 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -56,6 +56,75 @@
("BYTE", "OPLimitInAct", 0),
),
+ "Hero":(
+ ("DWORD", "HeroID", 1),
+ ("WORD", "HeroIndex", 0),
+ ("BYTE", "Country", 0),
+ ("BYTE", "Quality", 0),
+ ("list", "SkinNPCIDList", 0),
+ ("DWORD", "AtkSkillID", 0),
+ ("DWORD", "AngerSkillID", 0),
+ ),
+
+ "HeroTalent":(
+ ("DWORD", "TalentID", 1),
+ ("BYTE", "AttrID", 0),
+ ("DWORD", "AttrValue", 0),
+ ("DWORD", "InitWeight", 0),
+ ("DWORD", "WashWeight", 0),
+ ("DWORD", "AweakWeight", 0),
+ ),
+
+ "HeroBreak":(
+ ("DWORD", "HeroID", 1),
+ ("BYTE", "BreakLV", 0),
+ ("list", "AttrIDList", 0),
+ ("list", "AttrValueList", 0),
+ ("DWORD", "SkillID", 0),
+ ),
+
+ "HeroAwake":(
+ ("DWORD", "HeroID", 1),
+ ("BYTE", "AwakeLV", 0),
+ ("list", "AttrIDList", 0),
+ ("list", "AttrValueList", 0),
+ ("DWORD", "SkillID", 0),
+ ("BYTE", "UnlockTalentSlot", 0),
+ ("BYTE", "AddStarUpper", 0),
+ ),
+
+ "HeroSkin":(
+ ("DWORD", "SkinNPCID", 1),
+ ("list", "WearAttrIDList", 0),
+ ("list", "WearAttrValueList", 0),
+ ("list", "AllBatAttrIDList", 0),
+ ("list", "AllBatAttrValueList", 0),
+ ),
+
+ "HeroQuality":(
+ ("DWORD", "Quality", 1),
+ ("list", "UPCostItem", 0),
+ ("list", "InitTalentWeight", 0),
+ ("BYTE", "InitStarUpper", 0),
+ ("DWORD", "InitAddPer", 0),
+ ("DWORD", "LVAddPer", 0),
+ ("DWORD", "BreakLVAddPer", 0),
+ ("DWORD", "StarAddPer", 0),
+ ),
+
+ "HeroQualityBreak":(
+ ("DWORD", "Quality", 1),
+ ("DWORD", "BreakLV", 1),
+ ("WORD", "LVMax", 0),
+ ("list", "UPCostItem", 0),
+ ),
+
+ "HeroQualityAwake":(
+ ("DWORD", "Quality", 1),
+ ("DWORD", "AwakeLV", 1),
+ ("list", "UPCostItem", 0),
+ ),
+
"Dienstgrad":(
("DWORD", "ID", 1),
("WORD", "Type", 0),
@@ -2689,6 +2758,115 @@
def GetSortType(self): return self.attrTuple[5] # 队伍列表排序方案 BYTE
def GetSortReverse(self): return self.attrTuple[6] # 是否倒序 BYTE
def GetOPLimitInAct(self): return self.attrTuple[7] # 活动期间限制队伍操作 BYTE
+
+# 武将表
+class IPY_Hero():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetHeroID(self): return self.attrTuple[0] # 英雄ID DWORD
+ def GetHeroIndex(self): return self.attrTuple[1] # 记录索引 WORD
+ def GetCountry(self): return self.attrTuple[2] # 国家 BYTE
+ def GetQuality(self): return self.attrTuple[3] # 品质 BYTE
+ def GetSkinNPCIDList(self): return self.attrTuple[4] # 皮肤NPCID列表 list
+ def GetAtkSkillID(self): return self.attrTuple[5] # 普攻技能ID DWORD
+ def GetAngerSkillID(self): return self.attrTuple[6] # 怒气技能ID DWORD
+
+# 武将星级天赋表
+class IPY_HeroTalent():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetTalentID(self): return self.attrTuple[0] # 天赋ID DWORD
+ def GetAttrID(self): return self.attrTuple[1] # 属性ID BYTE
+ def GetAttrValue(self): return self.attrTuple[2] # 属性值 DWORD
+ def GetInitWeight(self): return self.attrTuple[3] # 初始权重 DWORD
+ def GetWashWeight(self): return self.attrTuple[4] # 洗炼权重 DWORD
+ def GetAweakWeight(self): return self.attrTuple[5] # 觉醒权重 DWORD
+
+# 武将突破潜能表
+class IPY_HeroBreak():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetHeroID(self): return self.attrTuple[0] # 英雄ID DWORD
+ def GetBreakLV(self): return self.attrTuple[1] # 突破等级 BYTE
+ def GetAttrIDList(self): return self.attrTuple[2] # 属性ID列表 list
+ def GetAttrValueList(self): return self.attrTuple[3] # 属性值列表 list
+ def GetSkillID(self): return self.attrTuple[4] # 激活技能ID DWORD
+
+# 武将觉醒天赋表
+class IPY_HeroAwake():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetHeroID(self): return self.attrTuple[0] # 英雄ID DWORD
+ def GetAwakeLV(self): return self.attrTuple[1] # 觉醒等级 BYTE
+ def GetAttrIDList(self): return self.attrTuple[2] # 属性ID列表 list
+ def GetAttrValueList(self): return self.attrTuple[3] # 属性值列表 list
+ def GetSkillID(self): return self.attrTuple[4] # 激活技能ID DWORD
+ def GetUnlockTalentSlot(self): return self.attrTuple[5] # 解锁第x槽位 BYTE
+ def GetAddStarUpper(self): return self.attrTuple[6] # 增加星级上限 BYTE
+
+# 武将皮肤表
+class IPY_HeroSkin():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetSkinNPCID(self): return self.attrTuple[0] # 皮肤NPCID DWORD
+ def GetWearAttrIDList(self): return self.attrTuple[1] # 穿戴属性ID列表 list
+ def GetWearAttrValueList(self): return self.attrTuple[2] # 穿戴属性值列表 list
+ def GetAllBatAttrIDList(self): return self.attrTuple[3] # 全体上阵属性ID列表 list
+ def GetAllBatAttrValueList(self): return self.attrTuple[4] # 全体上阵属性值列表 list
+
+# 武将品质表
+class IPY_HeroQuality():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetQuality(self): return self.attrTuple[0] # 品质 DWORD
+ def GetUPCostItem(self): return self.attrTuple[1] # 升级消耗道具 list
+ def GetInitTalentWeight(self): return self.attrTuple[2] # 初始天赋数权重 list
+ def GetInitStarUpper(self): return self.attrTuple[3] # 初始星级上限 BYTE
+ def GetInitAddPer(self): return self.attrTuple[4] # 初始加成万分率 DWORD
+ def GetLVAddPer(self): return self.attrTuple[5] # 每等级加成 DWORD
+ def GetBreakLVAddPer(self): return self.attrTuple[6] # 每突破等级加成 DWORD
+ def GetStarAddPer(self): return self.attrTuple[7] # 每星级加成 DWORD
+
+# 武将品质突破表
+class IPY_HeroQualityBreak():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetQuality(self): return self.attrTuple[0] # 品质 DWORD
+ def GetBreakLV(self): return self.attrTuple[1] # 突破等级 DWORD
+ def GetLVMax(self): return self.attrTuple[2] # 等级上限 WORD
+ def GetUPCostItem(self): return self.attrTuple[3] # 突破到下级消耗道具 list
+
+# 武将品质觉醒表
+class IPY_HeroQualityAwake():
+
+ def __init__(self):
+ self.attrTuple = None
+ return
+
+ def GetQuality(self): return self.attrTuple[0] # 品质 DWORD
+ def GetAwakeLV(self): return self.attrTuple[1] # 觉醒等级 DWORD
+ def GetUPCostItem(self): return self.attrTuple[2] # 觉醒到下级消耗道具 list
# 称号表
class IPY_Dienstgrad():
@@ -6699,6 +6877,14 @@
self.__LoadFileData("DirtyList", onlyCheck)
self.__LoadFileData("DirtyName", onlyCheck)
self.__LoadFileData("FuncTeamSet", onlyCheck)
+ self.__LoadFileData("Hero", onlyCheck)
+ self.__LoadFileData("HeroTalent", onlyCheck)
+ self.__LoadFileData("HeroBreak", onlyCheck)
+ self.__LoadFileData("HeroAwake", onlyCheck)
+ self.__LoadFileData("HeroSkin", onlyCheck)
+ self.__LoadFileData("HeroQuality", onlyCheck)
+ self.__LoadFileData("HeroQualityBreak", onlyCheck)
+ self.__LoadFileData("HeroQualityAwake", onlyCheck)
self.__LoadFileData("Dienstgrad", onlyCheck)
self.__LoadFileData("TitleStarUp", onlyCheck)
self.__LoadFileData("PlayerFace", onlyCheck)
@@ -7202,6 +7388,62 @@
self.CheckLoadData("FuncTeamSet")
return self.ipyFuncTeamSetCache[index]
+ def GetHeroCount(self):
+ self.CheckLoadData("Hero")
+ return self.ipyHeroLen
+ def GetHeroByIndex(self, index):
+ self.CheckLoadData("Hero")
+ return self.ipyHeroCache[index]
+
+ def GetHeroTalentCount(self):
+ self.CheckLoadData("HeroTalent")
+ return self.ipyHeroTalentLen
+ def GetHeroTalentByIndex(self, index):
+ self.CheckLoadData("HeroTalent")
+ return self.ipyHeroTalentCache[index]
+
+ def GetHeroBreakCount(self):
+ self.CheckLoadData("HeroBreak")
+ return self.ipyHeroBreakLen
+ def GetHeroBreakByIndex(self, index):
+ self.CheckLoadData("HeroBreak")
+ return self.ipyHeroBreakCache[index]
+
+ def GetHeroAwakeCount(self):
+ self.CheckLoadData("HeroAwake")
+ return self.ipyHeroAwakeLen
+ def GetHeroAwakeByIndex(self, index):
+ self.CheckLoadData("HeroAwake")
+ return self.ipyHeroAwakeCache[index]
+
+ def GetHeroSkinCount(self):
+ self.CheckLoadData("HeroSkin")
+ return self.ipyHeroSkinLen
+ def GetHeroSkinByIndex(self, index):
+ self.CheckLoadData("HeroSkin")
+ return self.ipyHeroSkinCache[index]
+
+ def GetHeroQualityCount(self):
+ self.CheckLoadData("HeroQuality")
+ return self.ipyHeroQualityLen
+ def GetHeroQualityByIndex(self, index):
+ self.CheckLoadData("HeroQuality")
+ return self.ipyHeroQualityCache[index]
+
+ def GetHeroQualityBreakCount(self):
+ self.CheckLoadData("HeroQualityBreak")
+ return self.ipyHeroQualityBreakLen
+ def GetHeroQualityBreakByIndex(self, index):
+ self.CheckLoadData("HeroQualityBreak")
+ return self.ipyHeroQualityBreakCache[index]
+
+ def GetHeroQualityAwakeCount(self):
+ self.CheckLoadData("HeroQualityAwake")
+ return self.ipyHeroQualityAwakeLen
+ def GetHeroQualityAwakeByIndex(self, index):
+ self.CheckLoadData("HeroQualityAwake")
+ return self.ipyHeroQualityAwakeCache[index]
+
def GetDienstgradCount(self):
self.CheckLoadData("Dienstgrad")
return self.ipyDienstgradLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
index e4e12c9..398dd1f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -734,6 +734,7 @@
ChConfig.Def_Effect_ItemGiveWeekPartyPoint1:"Item_WeekPartyPoint", # 增加活动巡礼积分
ChConfig.Def_Effect_AddRealmExpRate:"Item_AddRealmExpRate", # 增加聚灵效率
ChConfig.Def_Effect_TouchMission:"Item_TouchMission", # 触发任务接口
+ ChConfig.Def_Effect_HeroSkin:"Item_HeroSkin", # 武将皮肤
#ChConfig.Def_Effect_FamilyImpeach:"Item_FamilyImpeach", # 弹劾符
#ChConfig.Def_Effect_ClothesCoatSkin:"Item_ClothesCoatSkin", #激活时装皮肤
#ChConfig.Def_Effect_AddOfficialExp:"Item_AddOfficialExp", # 增加爵位经验
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
index d75bf5e..4b2cec1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -41,6 +41,7 @@
import PyGameData
import PlayerVip
import ChEquip
+import PlayerHero
import math
import time
@@ -1346,6 +1347,10 @@
if isNeedRecord:
itemNoteDict = ItemCommon.GetItemNoteDict(item, curItemCount, packItemCount, GetItemCount(item))
ItemCommon.DR_GetItem(curPlayer, packIndex, eventName, itemNoteDict, addDict)
+
+ if item.GetType() == ChConfig.Def_ItemType_Hero:
+ PlayerHero.OnGiveHeroItem(curPlayer, item)
+
break
#放入东西
@@ -1663,7 +1668,14 @@
return
# 整理方式不同区分
- if packIndex == IPY_GameWorld.rptWarehouse:
+ if packIndex == ShareDefine.rptHero:
+ if tick - curPlayer.GetResetItemTick() <= ChConfig.Def_ItemPackResetInterval:
+ #GameWorld.DebugLog("重整背包时间间隔太短")
+ return
+ curPlayer.SetResetItemTick(tick)
+ ResetHeroPack(curPlayer, curPack, beingIndex, endIndex)
+
+ elif packIndex == IPY_GameWorld.rptWarehouse:
#验证间隔
if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_WareHouseSort) < \
ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_WareHouseSort]:
@@ -1968,7 +1980,60 @@
return
+def ResetHeroPack(curPlayer, curPack, beingIndex, endIndex):
+ itemList = []
+ for i in range(beingIndex, endIndex + 1):
+ curRoleItem = curPack.GetAt(i)
+ if curRoleItem.IsEmpty():
+ continue
+ curItem = curRoleItem.GetItem()
+ itemList.append(curItem)
+ itemList.sort(__CmpHeroPack)
+
+ curPack.WipePack(beingIndex, endIndex)
+ putPlace = beingIndex
+ for item in itemList:
+ curPack.GetAt(putPlace).AssignItem(item, False)
+ putPlace += 1
+
+ return
+def __CmpHeroPack(item1, item2):
+ '''排序规则:上阵武将排前,未上阵武将排后,再各自按照以下规则排序
+ 武将等级>突破等级>武将星级>武将品质>武将ID
+ '''
+
+ posNum1 = item1.GetUserAttr(ShareDefine.Def_IudetHeroPosNum)
+ posNum2 = item2.GetUserAttr(ShareDefine.Def_IudetHeroPosNum)
+ if (posNum1 and posNum2) or (not posNum1 and not posNum2):
+ lv1 = item1.GetUserAttr(ShareDefine.Def_IudetHeroLV)
+ lv2 = item2.GetUserAttr(ShareDefine.Def_IudetHeroLV)
+ if lv1 == lv2:
+ bLV1 = item1.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+ bLV2 = item2.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+ if bLV1 == bLV2:
+ star1 = item1.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ star2 = item2.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ if star1 == star2:
+ heroID1 = item1.GetItemTypeID()
+ heroID2 = item2.GetItemTypeID()
+ ipyData1 = IpyGameDataPY.GetIpyGameData("Hero", heroID1)
+ ipyData2 = IpyGameDataPY.GetIpyGameData("Hero", heroID2)
+ quality1 = ipyData1.GetQuality() if ipyData1 else 0
+ quality2 = ipyData2.GetQuality() if ipyData2 else 0
+ if quality1 == quality2:
+ return cmp(heroID1, heroID2)
+ return -cmp(quality1, quality2)
+ return -cmp(star1, star2)
+ return -cmp(bLV1, bLV2)
+ return -cmp(lv1, lv2)
+ elif posNum1:
+ return -1
+ elif posNum2:
+ return 1
+ else:
+ return cmp(item1.GetItemTypeID(), item2.GetItemTypeID())
+
#===============================================================================
#Python 版重整物品
# def ResetItem(curPlayer, curPackIndex, tick):
@@ -2575,6 +2640,10 @@
GameWorld.ErrLog("产出物品异常,无法创建物品 = %s" % (itemID))
return
+ # 英雄
+ if curItem.GetType() == ChConfig.Def_ItemType_Hero:
+ return curItem
+
# 非装备,无需设置属性
if not ItemCommon.CheckItemIsEquip(curItem):
return curItem
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
index c1508fb..8e688c2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
@@ -37,6 +37,7 @@
import PyGameData
import ChEquip
import SkillShell
+import PlayerHero
import random
import math
import time
@@ -360,6 +361,10 @@
if expireTime > 0:
curSingleItem.SetUserAttr(ShareDefine.Def_IudetExpireTime, expireTime)
+ # 英雄
+ if curSingleItem.GetType() == ChConfig.Def_ItemType_Hero:
+ PlayerHero.InitHeroItem(curSingleItem)
+
#这里返回的是SingleItem , 如果创建了,未使用,会找出C++内存泄露!!!
return curSingleItem
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_HeroSkin.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_HeroSkin.py
new file mode 100644
index 0000000..cce1865
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_HeroSkin.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package UseItem.Item_HeroSkin
+#
+# @todo:激活武将皮肤
+# @author hxp
+# @date 2025-06-11
+# @version 1.0
+#
+# 详细描述: 激活武将皮肤
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-11 11:00"""
+#-------------------------------------------------------------------------------
+
+import ItemCommon
+import PlayerHero
+
+
+def UseItem(curPlayer, curRoleItem, tick):
+ useItemEff = curRoleItem.GetEffectByIndex(0)
+ heroID = useItemEff.GetEffectValue(0)
+ skinIndex = useItemEff.GetEffectValue(1)
+ PlayerHero.ActiveHeroSkin(curPlayer, heroID, skinIndex, True)
+ ItemCommon.DelItem(curPlayer, curRoleItem, 1)
+ return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 897af83..12eae96 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -174,6 +174,7 @@
from PyMongoDB import RecvPackToMapDB
import PyMongoMain
import PlayerTalk
+import PlayerHero
import datetime
import time
@@ -874,6 +875,7 @@
else:
PyMongoMain.GetUserCtrlDB().OnPlayerLogin(curPlayer)
+ PlayerHero.OnPlayerLogin(curPlayer)
PlayerMail.OnPlayerLogin(curPlayer)
PlayerChatBox.OnPlayerLogin(curPlayer)
PlayerFace.OnPlayerLogin(curPlayer)
@@ -1481,6 +1483,9 @@
#初始化寻宝背包
PlayerControl.Init_TreasurePack(curPlayer)
+ #初始化英雄背包
+ PlayerControl.Init_HeroPack(curPlayer)
+
#初始化神兽物品背包
curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzItem)
curPack.SetCount(ItemCommon.GetPackInitCount(ShareDefine.rptDogzItem))
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index bcc26a4..647a9d6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -5676,8 +5676,20 @@
#通知客户端
curPack.Sync_PackCanUseCount()
return
-
+def Init_HeroPack(curPlayer):
+ packType = ShareDefine.rptHero
+ #获取玩家背包
+ curPack = curPlayer.GetItemManager().GetPack(packType)
+ initCount = ItemCommon.GetPackInitCount(packType)
+ if packType in ChConfig.Def_Type_CanBuyPack_PlayerDict.keys():
+ keyName = ChConfig.Def_Type_CanBuyPack_PlayerDict.get(packType)[ChConfig.Def_PlayerPackDict_Index_Key]
+ initCount += curPlayer.NomalDictGetProperty(keyName)
+ curPack.SetCount(initCount)
+ #通知客户端背包格子数目
+# curPlayer.Sync_ItemCount(curPack.GetCount())
+ curPack.Sync_PackCanUseCount()
+ return
##初始化寻宝背包
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
new file mode 100644
index 0000000..7540395
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -0,0 +1,923 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerHero
+#
+# @todo:武将英雄
+# @author hxp
+# @date 2025-06-11
+# @version 1.0
+#
+# 详细描述: 武将英雄
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-06-11 11:00"""
+#-------------------------------------------------------------------------------
+
+import ItemCommon
+import ShareDefine
+import IpyGameDataPY
+import IPY_GameWorld
+import ItemControler
+import ChPyNetSendPack
+import NetPackCommon
+import PlayerControl
+import GameWorld
+import ChConfig
+
+import random
+
+def OnPlayerLogin(curPlayer):
+ Sync_HeroInfo(curPlayer)
+ return
+
+def InitHeroItem(singleItem):
+ ## 武将卡牌初始化:初始等级1; 星级、突破等级、觉醒等级均为0
+ singleItem.SetUserAttr(ShareDefine.Def_IudetHeroLV, 1)
+ if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroStar):
+ singleItem.SetUserAttr(ShareDefine.Def_IudetHeroStar, 0)
+ if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV):
+ singleItem.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, 0)
+ if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV):
+ singleItem.SetUserAttr(ShareDefine.Def_IudetHeroAwakeLV, 0)
+ if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin):
+ singleItem.SetUserAttr(ShareDefine.Def_IudetHeroSkin, 0)
+ if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroPosNum):
+ singleItem.SetUserAttr(ShareDefine.Def_IudetHeroPosNum, 0)
+
+ if singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID):
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
+ if singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDLV):
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDLV)
+ if singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentWashLock):
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentWashLock)
+ if singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentWashID):
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentWashID)
+ if singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDAwakeRand):
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+
+ InitHeroTalent(singleItem)
+ return
+
+def InitHeroTalent(singleItem):
+ '''初始化槽位天赋,不同槽位天赋ID不能一样
+ '''
+ heroID = singleItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ quality = heroIpyData.GetQuality()
+ qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
+ if not qualityIpyData:
+ return
+
+ initTalentCnt = 1
+ initTalentWeight = qualityIpyData.GetInitTalentWeight() # 初始天赋数权重
+ if initTalentWeight:
+ initTalentCnt = GameWorld.GetResultByWeightList(initTalentWeight, 1)
+
+ talentIDDict = {}
+ talentWeightList = []
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for index in range(ipyDataMgr.GetHeroTalentCount()):
+ talentIpyData = ipyDataMgr.GetHeroTalentByIndex(index)
+ talentID = talentIpyData.GetTalentID()
+ initWeight = talentIpyData.GetInitWeight()
+ talentWeightList.append([initWeight, talentID])
+ talentIDDict[talentID] = initWeight
+
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDLV)
+ for _ in range(initTalentCnt):
+ randTalentID = GameWorld.GetResultByWeightList(talentWeightList)
+ if not randTalentID:
+ continue
+
+ # 移除确保不重复
+ randWeightID = [talentIDDict.get(randTalentID, 0), randTalentID]
+ if randWeightID in talentWeightList:
+ talentWeightList.remove(randWeightID)
+
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentID, randTalentID)
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentIDLV, 1)
+
+ return
+
+def OnGiveHeroItem(curPlayer, heroItem):
+ ## 获得某个武将
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ heroIndex = heroIpyData.GetHeroIndex()
+ heroActState = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HeroActState, heroIndex)
+ if not heroActState:
+ GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HeroActState, heroIndex, 1)
+ GameWorld.DebugLog("首次激活武将: heroID=%s,heroIndex=%s" % (heroID, heroIndex), curPlayer.GetPlayerID())
+ Sync_HeroInfo(curPlayer, [heroID])
+ return
+
+def GetHeroItem(curPlayer, itemIndex):
+ curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
+ if itemIndex < 0 or itemIndex >= curPack.GetCount():
+ return
+ heroItem = curPack.GetAt(itemIndex)
+ if not heroItem or heroItem.IsEmpty():
+ return
+ if heroItem.GetType() != ChConfig.Def_ItemType_Hero:
+ return
+ return heroItem
+
+#// B2 30 武将升级 #tagCSHeroLVUP
+#
+#struct tagCSHeroLVUP
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+#};
+def OnHeroLVUP(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ itemIndex = clientData.ItemIndex
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ return
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ quality = heroIpyData.GetQuality()
+ breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+ heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
+ LVMax = GetHeroLVMax(heroItem)
+ GameWorld.DebugLog("请求武将升级: itemIndex=%s,heroID=%s,heroLV=%s,quality=%s,breakLV=%s,LVMax=%s"
+ % (itemIndex, heroID, heroLV, quality, breakLV, LVMax), playerID)
+ if heroLV >= LVMax:
+ GameWorld.DebugLog("该武将已满级!LVMax=%s" % (LVMax), playerID)
+ return
+ qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
+ if not qualityIpyData:
+ return
+ costItemInfo = qualityIpyData.GetUPCostItem()
+ if not costItemInfo:
+ return
+ costItemID, costItemCount = costItemInfo
+ if not costItemID or not costItemCount:
+ return
+ itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+ hasEnough, itemIndexList = ItemCommon.GetItem_FromPack_ByID(costItemID, itemPack, costItemCount)
+ if not hasEnough:
+ GameWorld.DebugLog("材料不足,武将无法升级! costItemID=%s, costItemCount=%s" % (costItemID, costItemCount))
+ return
+ ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, costItemCount, True, "HeroLVUP")
+
+ updHeroLV = heroLV + 1
+ GameWorld.DebugLog("武将升级: itemIndex=%s,heroID=%s,updHeroLV=%s" % (itemIndex, heroID, updHeroLV), playerID)
+ heroItem.SetUserAttr(ShareDefine.Def_IudetHeroLV, updHeroLV)
+
+ # 刷属性,之后扩展
+
+ return
+
+def GetHeroLVMax(heroItem):
+ ## 获取武将当前最大等级
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return 0
+ quality = heroIpyData.GetQuality()
+ breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+ qualityBreakIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, breakLV)
+ if not qualityBreakIpyData:
+ return 0
+ LVMax = qualityBreakIpyData.GetLVMax()
+ return LVMax
+
+#// B2 31 武将升星 #tagCSHeroStarUP
+#
+#struct tagCSHeroStarUP
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+# WORD UseItemIndex; //使用武将材料物品所在武将背包位置索引
+#};
+def OnHeroStarUP(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ itemIndex = clientData.ItemIndex
+ useItemIndex = clientData.UseItemIndex
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ useItem = GetHeroItem(curPlayer, useItemIndex)
+ if not heroItem or not useItem or itemIndex == useItemIndex:
+ return
+ heroID = heroItem.GetItemTypeID()
+ useHeroID = useItem.GetItemTypeID()
+ GameWorld.DebugLog("请求武将升星: itemIndex=%s,heroID=%s,useItemIndex=%s,useHeroID=%s"
+ % (itemIndex, heroID, useItemIndex, useHeroID), playerID)
+ if heroID != useHeroID:
+ GameWorld.DebugLog("武将材料非本体,无法升星!", playerID)
+ return
+ washIDCnt = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentWashID)
+ if washIDCnt:
+ GameWorld.ErrLog("武将洗炼结果未处理,无法升星! itemIndex=%s,heroID=%s" % (itemIndex, heroID), playerID)
+ return
+ awakeRandCnt = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+ if awakeRandCnt:
+ GameWorld.ErrLog("武将觉醒解锁天赋未选择,无法升星! itemIndex=%s,heroID=%s" % (itemIndex, heroID), playerID)
+ return
+ useBreakLV = useItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+ useAwakeLV = useItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+ if useBreakLV or useAwakeLV:
+ GameWorld.DebugLog("材料卡突破或觉醒等级不为0暂时无法升星!useBreakLV=%s,useAwakeLV=%s" % (useBreakLV, useAwakeLV), playerID)
+ return
+
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ quality = heroIpyData.GetQuality()
+ star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+ starMax = GetHeroStarMax(heroItem)
+ GameWorld.DebugLog("heroID=%s,star=%s,quality=%s,awakeLV=%s,starMax=%s" % (heroID, star, quality, awakeLV, starMax), playerID)
+ if star >= starMax:
+ GameWorld.DebugLog("该武将已满星!starMax=%s" % (starMax), playerID)
+ return
+ useStar = useItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ addStar = useStar + 1
+ updStar = star + addStar
+ GameWorld.DebugLog("武将升星: itemIndex=%s,heroID=%s,star=%s,useStar=%s,addStar=%s,updStar=%s"
+ % (itemIndex, heroID, star, useStar, addStar, updStar), playerID)
+ ItemCommon.DelItem(curPlayer, useItem, useItem.GetCount(), False, "HeroStarUP")
+ DoHeroUpdStar(curPlayer, heroItem, updStar)
+ return
+
+def GetHeroStarMax(heroItem):
+ ## 获取武将当前最大星级
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return 0
+ quality = heroIpyData.GetQuality()
+ qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
+ if not qualityIpyData:
+ return 0
+ InitStarUpper = qualityIpyData.GetInitStarUpper()
+
+ addStarUpper = 0
+ heroAwakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID)
+ if heroAwakeIpyDataList:
+ awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+ for ipyData in heroAwakeIpyDataList:
+ if ipyData.GetAwakeLV() > awakeLV:
+ break
+ #ipyData.GetUnlockTalentSlot()
+ addStarUpper += ipyData.GetAddStarUpper()
+
+ starMax = InitStarUpper + addStarUpper
+ return starMax
+
+def DoHeroUpdStar(curPlayer, heroItem, updStar):
+ ## 执行武将星级更新
+ curStar = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ addStar = updStar - curStar
+ item = heroItem.GetItem()
+ item.SetUserAttr(ShareDefine.Def_IudetHeroStar, updStar)
+ if addStar > 0:
+ __DoHeroStarTalentUp(item, addStar)
+ heroItem.Sync_Item()
+
+ # 刷属性,之后扩展
+
+ return
+
+def __DoHeroStarTalentUp(singleItem, addLV):
+ ## 执行武将星级天赋等级提升
+
+ commTalentSlot = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 1) # 常规天赋槽个数
+ talentMaxLV = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 2) # 每个天赋最大等级
+ idCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID)
+ lvCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDLV)
+ idList, lvList = [], [] # 记录在物品上的值,有顺序
+ unfullLVIDList = [] # 未满级的天赋ID
+ haveUp = False
+ for index in range(min(idCount, lvCount)):
+ talentID = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, index)
+ talentLV = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentIDLV, index)
+ idList.append(talentID)
+ lvList.append(talentLV)
+ if talentLV < talentMaxLV:
+ unfullLVIDList.append(talentID)
+
+ if len(idList) < commTalentSlot:
+ idList += [0] * (commTalentSlot - len(idList))
+ lvList += [0] * (commTalentSlot - len(lvList))
+
+ GameWorld.DebugLog("执行武将星级天赋等级提升: addLV=%s" % addLV)
+ GameWorld.DebugLog("当前星级天赋: idList=%s,lvList=%s" % (idList, lvList))
+ GameWorld.DebugLog("未满级星级天赋ID: %s" % unfullLVIDList)
+
+ # 有空余槽位,优先给空余槽位天赋,额外解锁的槽位是需要先选择的,所以一定不为空,故这里只判断常规槽位即可
+ if 0 in idList:
+ idWeightDict = {}
+ talentWeightList = []
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for index in range(ipyDataMgr.GetHeroTalentCount()):
+ talentIpyData = ipyDataMgr.GetHeroTalentByIndex(index)
+ talentID = talentIpyData.GetTalentID()
+ if talentID in idList:
+ # 天赋ID不可重复
+ continue
+ weight = talentIpyData.GetWashWeight()
+ talentWeightList.append([weight, talentID])
+ idWeightDict[talentID] = weight
+
+ GameWorld.DebugLog("常规空槽位增加天赋数:%s" % addLV)
+ for _ in range(addLV):
+ if 0 not in idList:
+ break
+ randTalentID = GameWorld.GetResultByWeightList(talentWeightList)
+ if not randTalentID:
+ continue
+ # 移除确保不重复
+ randWeightID = [idWeightDict.get(randTalentID, 0), randTalentID]
+ if randWeightID in talentWeightList:
+ talentWeightList.remove(randWeightID)
+ zeroIndex = idList.index(0)
+ idList[zeroIndex] = randTalentID
+ lvList[zeroIndex] = 1
+ unfullLVIDList.append(randTalentID)
+ GameWorld.DebugLog("新增星级天赋ID: %s" % (randTalentID))
+ addLV -= 1
+ haveUp = True
+
+ # 剩下的等级次数对已有天赋进行升级
+ if addLV > 0:
+ for _ in range(addLV):
+ if not unfullLVIDList:
+ break
+ randID = random.choice(unfullLVIDList)
+ if randID not in idList:
+ unfullLVIDList.remove(randID)
+ continue
+ randIndex = idList.index(randID)
+ idLV = lvList[randIndex]
+
+ if idLV < talentMaxLV:
+ idLV += 1
+ lvList[randIndex] = idLV
+ GameWorld.DebugLog("升级星级天赋ID: %s,idLV=%s,index=%s" % (randID, idLV, randIndex))
+
+ if idLV >= talentMaxLV:
+ unfullLVIDList.remove(randID)
+ GameWorld.DebugLog(" 移除未满级ID: %s,unfullLVIDList=%s" % (randID, unfullLVIDList))
+
+ haveUp = True
+
+ if not haveUp:
+ return
+ GameWorld.DebugLog("更新星级天赋: idList=%s,lvList=%s" % (idList, lvList))
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDLV)
+ for index, talentID in enumerate(idList):
+ if not talentID:
+ break
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentID, talentID)
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentIDLV, lvList[index])
+ return
+
+#// B2 32 武将突破 #tagCSHeroBreak
+#
+#struct tagCSHeroBreak
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+#};
+def OnHeroBreak(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ itemIndex = clientData.ItemIndex
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ return
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ quality = heroIpyData.GetQuality()
+ breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+ GameWorld.DebugLog("请求武将突破: itemIndex=%s,heroID=%s,quality=%s,breakLV=%s"
+ % (itemIndex, heroID, quality, breakLV), playerID)
+ ipyData = IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, breakLV)
+ if not ipyData:
+ return
+ nextBreakLV = breakLV + 1
+ if not IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, nextBreakLV):
+ GameWorld.DebugLog("突破等级已满级: quality=%s,breakLV=%s" % (quality, breakLV), playerID)
+ return
+ costItemInfo = ipyData.GetUPCostItem()
+ if not costItemInfo:
+ return
+ costItemID, costItemCount = costItemInfo
+ if not costItemID or not costItemCount:
+ return
+ itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+ hasEnough, itemIndexList = ItemCommon.GetItem_FromPack_ByID(costItemID, itemPack, costItemCount)
+ if not hasEnough:
+ GameWorld.DebugLog("材料不足,武将无法突破! costItemID=%s, costItemCount=%s" % (costItemID, costItemCount))
+ return
+ ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, costItemCount, True, "HeroBreak")
+ GameWorld.DebugLog("武将突破: itemIndex=%s,heroID=%s,nextBreakLV=%s" % (itemIndex, heroID, nextBreakLV), playerID)
+ SetHeroBreakLV(heroItem, nextBreakLV)
+
+ # 刷属性,之后扩展
+
+ return
+
+def SetHeroBreakLV(heroItem, breakLV):
+ ## 设置武将突破等级
+ heroItem.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, breakLV)
+ return
+
+#// B2 33 武将觉醒 #tagCSHeroAwake
+#
+#struct tagCSHeroAwake
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+#};
+def OnHeroAwake(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ itemIndex = clientData.ItemIndex
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ return
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ quality = heroIpyData.GetQuality()
+ starLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+ awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+ GameWorld.DebugLog("请求武将觉醒: itemIndex=%s,heroID=%s,quality=%s,awakeLV=%s,starLV=%s"
+ % (itemIndex, heroID, quality, awakeLV, starLV), playerID)
+ awakeLimitStar = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 4)
+ commTalentSlot = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 1) # 常规天赋槽个数
+ if starLV < awakeLimitStar or starLV < commTalentSlot:
+ GameWorld.DebugLog("当前星级不可觉醒: starLV=%s < %s, %s" % (starLV, awakeLimitStar, commTalentSlot), playerID)
+ return
+ ipyData = IpyGameDataPY.GetIpyGameData("HeroQualityAwake", quality, awakeLV)
+ if not ipyData:
+ return
+ nextAwakeLV = awakeLV + 1
+ if not IpyGameDataPY.GetIpyGameData("HeroQualityAwake", quality, nextAwakeLV):
+ GameWorld.DebugLog("觉醒等级已满级: quality=%s,awakeLV=%s" % (quality, awakeLV), playerID)
+ return
+ costItemInfo = ipyData.GetUPCostItem()
+ if not costItemInfo:
+ return
+ costItemID, costItemCount = costItemInfo
+ if not costItemID or not costItemCount:
+ return
+ itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+ hasEnough, itemIndexList = ItemCommon.GetItem_FromPack_ByID(costItemID, itemPack, costItemCount)
+ if not hasEnough:
+ GameWorld.DebugLog("材料不足,武将无法觉醒! costItemID=%s, costItemCount=%s" % (costItemID, costItemCount))
+ return
+ ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, costItemCount, True, "HeroAwake")
+ GameWorld.DebugLog("武将觉醒: itemIndex=%s,heroID=%s,nextBreakLV=%s" % (itemIndex, heroID, nextAwakeLV), playerID)
+ SetHeroAwakeLV(heroItem, nextAwakeLV)
+
+ # 刷属性,之后扩展
+
+ return
+
+def SetHeroAwakeLV(heroItem, awakeLV):
+ ## 设置武将觉醒等级
+ item = heroItem.GetItem()
+ item.SetUserAttr(ShareDefine.Def_IudetHeroAwakeLV, awakeLV)
+ unlockTalentSlotByAwake(item)
+ heroItem.Sync_Item()
+ return
+
+def unlockTalentSlotByAwake(singleItem):
+ ## 觉醒解锁天赋槽
+ heroID = singleItem.GetItemTypeID()
+ awakeLV = singleItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+ awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID)
+ if not awakeIpyDataList:
+ return
+ maxUnlockSlot = 0
+ for ipyData in awakeIpyDataList[:awakeLV][::-1]: # 倒序遍历,第一个命中的就是最大的
+ unlockTalentSlot = ipyData.GetUnlockTalentSlot()
+ if unlockTalentSlot:
+ maxUnlockSlot = unlockTalentSlot
+ break
+ if not maxUnlockSlot:
+ return
+ idCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID)
+ if idCount >= maxUnlockSlot:
+ return
+ commTalentSlot = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 1) # 常规天赋槽个数
+ if maxUnlockSlot <= commTalentSlot:
+ return
+ awakeRandCnt = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+ if awakeRandCnt:
+ # 已经存在觉醒天赋随机选项,需要先选择后才能继续
+ return
+
+ # 随机觉醒天赋选项
+ idList = []
+ for index in range(idCount):
+ talentID = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, index)
+ idList.append(talentID)
+
+ GameWorld.DebugLog("觉醒解锁天赋槽: awakeLV=%s,maxUnlockSlot=%s,idList=%s" % (awakeLV, maxUnlockSlot, idList))
+
+ idWeightDict = {}
+ talentWeightList = []
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for index in range(ipyDataMgr.GetHeroTalentCount()):
+ talentIpyData = ipyDataMgr.GetHeroTalentByIndex(index)
+ talentID = talentIpyData.GetTalentID()
+ if talentID in idList:
+ # 天赋ID不可重复
+ continue
+ weight = talentIpyData.GetAweakWeight()
+ talentWeightList.append([weight, talentID])
+ idWeightDict[talentID] = weight
+
+ randTalentCnt = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 3)
+ for _ in range(randTalentCnt):
+ randTalentID = GameWorld.GetResultByWeightList(talentWeightList)
+ if not randTalentID:
+ continue
+ # 移除确保不重复
+ randWeightID = [idWeightDict.get(randTalentID, 0), randTalentID]
+ if randWeightID in talentWeightList:
+ talentWeightList.remove(randWeightID)
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentIDAwakeRand, randTalentID)
+ GameWorld.DebugLog("随机觉醒天赋选项: randTalentID=%s" % (randTalentID))
+
+ return
+
+#// B2 34 武将觉醒选择天赋 #tagCSHeroAwakeSelectTalent
+#
+#struct tagCSHeroAwakeSelectTalent
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+# BYTE SelectIndex; //选择新解锁槽位的天赋索引
+#};
+def OnHeroAwakeSelectTalent(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ itemIndex = clientData.ItemIndex
+ selectIndex = clientData.SelectIndex
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ return
+ heroID = heroItem.GetItemTypeID()
+ awakeRandCnt = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+ if not awakeRandCnt or selectIndex >= awakeRandCnt:
+ GameWorld.DebugLog("不存在该觉醒天赋随机选项! heroID=%s,selectIndex=%s,awakeRandCnt=%s" % (heroID, selectIndex, awakeRandCnt), playerID)
+ return
+ selectTalentID = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentIDAwakeRand, selectIndex)
+ if not selectTalentID:
+ return
+
+ singleItem = heroItem.GetItem()
+ idCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID)
+ lvCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDLV)
+ idList, lvList = [], [] # 记录在物品上的值,有顺序
+ for index in range(min(idCount, lvCount)):
+ talentID = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, index)
+ talentLV = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentIDLV, index)
+ idList.append(talentID)
+ lvList.append(talentLV)
+
+ commTalentSlot = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 1) # 常规天赋槽个数
+ if idCount < commTalentSlot:
+ idList += [0] * (commTalentSlot - idCount)
+ lvList += [0] * (commTalentSlot - idCount)
+
+ if selectTalentID in idList:
+ GameWorld.ErrLog("选择天赋ID不能重复! heroID=%s,selectIndex=%s,selectTalentID=%s in %s"
+ % (heroID, selectIndex, selectTalentID, idList), playerID)
+ return
+
+ idList.append(selectTalentID)
+ lvList.append(1)
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+
+ GameWorld.DebugLog("更新选择天赋: selectTalentID=%s,idList=%s,lvList=%s" % (selectTalentID, idList, lvList))
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDLV)
+ for index, talentID in enumerate(idList):
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentID, talentID)
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentIDLV, lvList[index])
+
+ unlockTalentSlotByAwake(singleItem)
+
+ heroItem.Sync_Item()
+
+ # 刷属性,之后扩展
+
+ return
+
+#// B2 35 武将洗炼 #tagCSHeroWash
+#
+#struct tagCSHeroWash
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+# BYTE LockCnt;
+# BYTE LockTalentIndexs[LockCnt]; //锁定天赋索引列表
+# BYTE OPType; // 操作类型:0-执行洗炼;1-替换原天赋;2-保留原天赋
+#};
+def OnHeroWash(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ itemIndex = clientData.ItemIndex
+ lockTalentIndexs = clientData.LockTalentIndexs
+ opType = clientData.OPType
+
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ return
+
+ if opType == 1:
+ HeroTalentWashReplace(curPlayer, itemIndex, heroItem)
+ elif opType == 2:
+ heroItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentWashID)
+ else:
+ HeroTalentWash(curPlayer, itemIndex, heroItem, lockTalentIndexs)
+
+ return
+
+def HeroTalentWash(curPlayer, itemIndex, heroItem, lockTalentIndexs):
+ ## 武将洗炼
+
+ heroID = heroItem.GetItemTypeID()
+ GameWorld.DebugLog("武将洗炼: itemIndex=%s,heroID=%s,lockTalentIndexs=%s" % (itemIndex, heroID, lockTalentIndexs))
+ washIDCnt = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentWashID)
+ if washIDCnt:
+ GameWorld.ErrLog("武将洗炼结果未处理,无法洗炼! washIDCnt=%s" % washIDCnt)
+ return
+
+ washCostItemInfo = IpyGameDataPY.GetFuncEvalCfg("HeroWash", 1)
+ lockCostItemInfo = IpyGameDataPY.GetFuncEvalCfg("HeroWash", 2)
+ if not washCostItemInfo or not lockCostItemInfo:
+ return
+ washItemID, washCostItemCount = washCostItemInfo
+ lockItemID, lockCostItemCount = lockCostItemInfo
+
+ itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+ hasEnough, washItemIndexList = ItemCommon.GetItem_FromPack_ByID(washItemID, itemPack, washCostItemCount)
+ if not hasEnough:
+ GameWorld.DebugLog("洗炼材料不足,武将无法洗炼! washItemID=%s,washCostItemCount=%s" % (washItemID, washCostItemCount))
+ return
+ lockItemIndexList = []
+ lockCostItemCountTotal = 0
+ if lockTalentIndexs:
+ lockCostItemCountTotal = len(lockTalentIndexs) * lockCostItemCount
+ hasEnough, lockItemIndexList = ItemCommon.GetItem_FromPack_ByID(lockItemID, itemPack, lockCostItemCountTotal)
+ if not hasEnough:
+ GameWorld.DebugLog("锁定材料不足,武将无法洗炼! lockItemID=%s,lockCostItemCount=%s,lockCostItemCountTotal=%s"
+ % (lockItemID, lockCostItemCount, lockCostItemCountTotal))
+ return
+
+ ItemCommon.ReduceItem(curPlayer, itemPack, washItemIndexList, washCostItemCount, True, "HeroTalentWash")
+ ItemCommon.ReduceItem(curPlayer, itemPack, lockItemIndexList, lockCostItemCountTotal, True, "HeroTalentWash")
+
+ singleItem = heroItem.GetItem()
+ idCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID)
+ washIDList = []
+ for index in range(idCount):
+ if index in lockTalentIndexs:
+ talentID = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, index)
+ washIDList.append(talentID)
+ else:
+ washIDList.append(0)
+
+ GameWorld.DebugLog("洗炼前: %s" % (washIDList))
+
+ idWeightDict = {}
+ talentWeightList = []
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for index in range(ipyDataMgr.GetHeroTalentCount()):
+ talentIpyData = ipyDataMgr.GetHeroTalentByIndex(index)
+ talentID = talentIpyData.GetTalentID()
+ if talentID in washIDList:
+ # 天赋ID不可重复
+ continue
+ weight = talentIpyData.GetWashWeight()
+ talentWeightList.append([weight, talentID])
+ idWeightDict[talentID] = weight
+
+ for index, talentID in enumerate(washIDList):
+ if talentID:
+ continue
+ randTalentID = GameWorld.GetResultByWeightList(talentWeightList)
+ if not randTalentID:
+ continue
+ # 移除确保不重复
+ randWeightID = [idWeightDict.get(randTalentID, 0), randTalentID]
+ if randWeightID in talentWeightList:
+ talentWeightList.remove(randWeightID)
+ washIDList[index] = randTalentID
+ GameWorld.DebugLog("洗炼后: %s" % (washIDList))
+
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentWashID)
+ for talentID in washIDList:
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentWashID, talentID)
+
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentWashLock)
+ for index in lockTalentIndexs:
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentWashLock, index)
+
+ heroItem.Sync_Item()
+ GameWorld.DebugLog("武将洗炼结果! itemIndex=%s,heroID=%s,washIDList=%s,lockTalentIndexs=%s"
+ % (itemIndex, heroID, washIDList, lockTalentIndexs))
+ return
+
+def HeroTalentWashReplace(curPlayer, itemIndex, heroItem):
+ ## 武将洗炼替换
+ heroID = heroItem.GetItemTypeID()
+ singleItem = heroItem.GetItem()
+
+ washIDList = []
+ idCount = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentWashID)
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
+ for index in range(idCount):
+ talentID = singleItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentWashID, index)
+ washIDList.append(talentID)
+ singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentID, talentID)
+
+ singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentWashID)
+
+ heroItem.Sync_Item()
+ GameWorld.DebugLog("武将洗炼替换! itemIndex=%s,heroID=%s,washIDList=%s" % (itemIndex, heroID, washIDList))
+
+ # 刷属性,之后扩展
+
+ return
+
+#// B2 36 武将换肤 #tagCSHeroWearSkin
+#
+#struct tagCSHeroWearSkin
+#{
+# tagHead Head;
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+# BYTE SkinIndex; //皮肤索引
+#};
+def OnHeroWearSkin(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ itemIndex = clientData.ItemIndex
+ skinIndex = clientData.SkinIndex
+ heroItem = GetHeroItem(curPlayer, itemIndex)
+ if not heroItem:
+ return
+ heroID = heroItem.GetItemTypeID()
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ return
+ skinNPCIDList = heroIpyData.GetSkinNPCIDList()
+ if skinIndex > 0: # 0的为默认皮肤,不做限制
+ if skinIndex >= len(skinNPCIDList):
+ GameWorld.DebugLog("该武将不存在该皮肤! heroID=%s,skinIndex=%s" % (heroID, skinIndex))
+ return
+ skinState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkin % heroID)
+ if not skinState & pow(2, skinIndex):
+ GameWorld.DebugLog("该武将皮肤未解锁! heroID=%s,skinIndex=%s,skinState=%s" % (heroID, skinIndex, skinState))
+ return
+ heroItem.SetUserAttr(ShareDefine.Def_IudetHeroSkin, skinIndex)
+
+ # 刷属性
+
+ return
+
+def ActiveHeroSkin(curPlayer, heroID, skinIndex, isActive=True):
+ skinState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkin % heroID)
+ if isActive:
+ updState = skinState | pow(2, skinIndex)
+ GameWorld.DebugLog("激活武将皮肤: heroID=%s,skinIndex=%s,skinState=%s,updState=%s"
+ % (heroID, skinIndex, skinState, updState), curPlayer.GetPlayerID())
+ else:
+ updState = GameWorld.SetBitValue(skinState, skinIndex, 0)
+ GameWorld.DebugLog("失效武将皮肤: heroID=%s,skinIndex=%s,skinState=%s,updState=%s"
+ % (heroID, skinIndex, skinState, updState), curPlayer.GetPlayerID())
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroSkin % heroID, updState)
+ Sync_HeroInfo(curPlayer, [heroID])
+ return
+
+#// B4 12 战斗阵型保存 #tagCSHeroBattlePosSave
+#
+#struct tagCSHeroBattlePos
+#{
+# WORD ItemIndex; //武将物品所在武将背包位置索引
+# BYTE PosNum; //1~n上阵位置编号
+#};
+#
+#struct tagCSHeroBattlePosSave
+#{
+# tagHead Head;
+# BYTE FuncType; //布阵功能类型:0-默认主阵型;其他待扩展,如某个活动的防守阵型
+# BYTE PosCnt;
+# tagCSHeroBattlePos HeroPosList[PosCnt]; // 保存的阵型,只要发送最终的阵型武将位置即可
+#};
+def OnHeroBattlePosSave(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ funcType = clientData.FuncType
+ heroPosList = clientData.HeroPosList
+
+ heroPosDict = {}
+ indexList = []
+ for posInfo in heroPosList:
+ posNum = posInfo.PosNum
+ itemIndex = posInfo.ItemIndex
+ if itemIndex in indexList:
+ # 单英雄只能一个位置,一个位置只能对应唯一英雄单位
+ continue
+ indexList.append(itemIndex)
+ heroPosDict[posNum] = itemIndex
+
+ # 主阵型
+ if funcType == 0:
+ MainBattlePosSave(curPlayer, heroPosDict)
+
+ # 其他待扩展
+ elif funcType == 1:
+ pass
+
+ return
+
+def MainBattlePosSave(curPlayer, heroPosDict):
+ GameWorld.DebugLog("保留主战斗阵型: %s" % heroPosDict, curPlayer.GetPlayerID())
+ curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
+ # 直接重置旧阵型
+ for index in range(curPack.GetCount()):
+ heroItem = curPack.GetAt(index)
+ if not heroItem or heroItem.IsEmpty():
+ continue
+ if not heroItem.GetUserAttr(ShareDefine.Def_IudetHeroPosNum):
+ continue
+ item = heroItem.GetItem()
+ item.ClearUserAttr(ShareDefine.Def_IudetHeroPosNum)
+
+ # 更新新阵型
+ for posNum, itemIndex in heroPosDict.items():
+ if itemIndex < 0 or itemIndex >= curPack.GetCount():
+ continue
+ heroItem = curPack.GetAt(itemIndex)
+ if not heroItem or heroItem.IsEmpty():
+ continue
+ item = heroItem.GetItem()
+ item.SetUserAttr(ShareDefine.Def_IudetHeroPosNum, posNum)
+
+ ResetHeroPack(curPlayer)
+ return
+
+def ResetHeroPack(curPlayer):
+ tick = GameWorld.GetGameWorld().GetTick()
+ curPlayer.SetResetItemTick(0)
+ ItemControler.ResetItem(curPlayer, ShareDefine.rptHero, 0, 0, tick)
+ return
+
+def Sync_HeroInfo(curPlayer, heroIDList=None):
+ if heroIDList != None:
+ syncHeroIDList = heroIDList
+ else:
+ syncHeroIDList = []
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for index in range(ipyDataMgr.GetHeroCount()):
+ ipyData = ipyDataMgr.GetHeroByIndex(index)
+ syncHeroIDList.append(ipyData.GetHeroID())
+
+ if not syncHeroIDList:
+ return
+
+ syncInfoList = []
+ for heroID in syncHeroIDList:
+ heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+ if not heroIpyData:
+ continue
+ heroIndex = heroIpyData.GetHeroIndex()
+ heroActState = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HeroActState, heroIndex)
+ if not heroActState and heroIDList == None:
+ continue
+
+ hero = ChPyNetSendPack.tagSCHero()
+ hero.HeroID = heroID
+ hero.IsActive = heroActState
+ hero.SkinState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkin % heroID)
+ syncInfoList.append(hero)
+
+ if not syncInfoList:
+ return
+
+ clientPack = ChPyNetSendPack.tagSCHeroInfo()
+ clientPack.HeroInfoList = syncInfoList
+ clientPack.HeroCnt = len(clientPack.HeroInfoList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py
index 97a2280..60faf07 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py
@@ -17,10 +17,7 @@
import GameWorld
import PlayerRune
-import ShareDefine
-import GameFuncComm
import IpyGameDataPY
-import IPY_GameWorld
import FormulaControl
import ChPyNetSendPack
import PlayerControl
@@ -29,7 +26,6 @@
import PlayerBossReborn
import PlayerFeastTravel
import PlayerFairyCeremony
-import PlayerNewFairyCeremony
import PlayerActLunhuidian
import PlayerActYunshi
import PlayerActTask
@@ -37,7 +33,6 @@
import ChConfig
import random
-import time
# 寻宝类型: >=100的为策划自行配置的自定义寻宝类型,<100的用于指定系统寻宝功能
TreasureTypeList = (
@@ -48,14 +43,16 @@
TreasureType_Gubao, # 古宝寻宝 5
) = range(1, 1 + 5)
+TreasureType_HeroComm = 11 # 英雄招募 - 普通
+TreasureType_HeroHigh = 12 # 英雄招募 - 高级
+TreasureType_HeroScore = 13 # 英雄招募 - 积分
+
def DoTreasureOpen(curPlayer):
## 寻宝开启
Sync_TreasureInfo(curPlayer)
return
def OnTreasureLogin(curPlayer):
- #if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Treasure):
- # return
Sync_TreasureInfo(curPlayer)
return
@@ -269,7 +266,7 @@
curRateList = [] # 可能会改变饼图,每次抽奖使用新的饼图对象,不要改变配置的饼图概率
# 满幸运必出
- if updLuck >= maxLuck and luckyGridNumList:
+ if maxLuck and updLuck >= maxLuck and luckyGridNumList:
if luckyItemRateList:
curRateList = GetRemoveLimitGridRateList(luckyItemRateList, gridNumCountInfo, gridNumMaxLimitInfo)
else:
@@ -403,7 +400,7 @@
addScoreType = setIpyData.GetAwardMoneyType() # 额外奖励货币类型
addScore = setIpyData.GetAwardMoneyValue() # 单次奖励货币数
if addScoreType and addScore:
- PlayerControl.GiveMoney(curPlayer, addScoreType, addScore)
+ PlayerControl.GiveMoney(curPlayer, addScoreType, addScore * treasureCount)
if treasureType == TreasureType_Rune:
PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_RuneTreasure, treasureCount)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index edb33eb..42cde85 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1161,7 +1161,8 @@
CDBPlayerRefresh_PayCoinDay, # 代币时效 269
CDBPlayerRefresh_XianyuanScore, # 仙缘积分 270
CDBPlayerRefresh_HuanjinggeScore, # 幻境阁积分 271
-) = range(146, 272)
+CDBPlayerRefresh_HeroScore, # 招募积分 272
+) = range(146, 273)
TYPE_Price_Gold_Paper_Money = 5 # 金钱类型,(先用礼券,再用金子)
TYPE_Price_Family_Contribution = 6 # 战盟贡献度(活跃度转换得来)
@@ -1200,6 +1201,7 @@
TYPE_Price_Tuijinbi = 48 # 推金币
TYPE_Price_XianyuanScore = 49 # 仙缘积分
TYPE_Price_HuanjinggeScore = 50 # 幻境阁积分
+TYPE_Price_HeroScore = 51 # 招募积分
TYPE_Price_PayCoinDay = 98 # 代币时效,每日过天重置
TYPE_Price_PayCoin = 99 # 代币
@@ -1209,7 +1211,7 @@
16:"助战积分", 18:"荣誉", 19:"Boss积分", 23:"符印精华", 24:"符印碎片", 25:"寻宝积分", 26:"集市额度", 27:"丹精", 28:"魂尘",
29:"聚魂碎片", 30:"核心环", 31:"功能特权令", 32:"环保值", 33:"GM令", 34:"古神币", 35:"功德点",
39:"成就积分", 40:"万界积分", 41:"战锤", 42:"结晶", 43:"凭证积分", 44:"聚魂精华", 45:"骑宠养成积分", 46:"古宝养成积分", 47:"天道果",
- 49:"仙缘积分", 50:"幻境阁积分",
+ 49:"仙缘积分", 50:"幻境阁积分", 51:"招募积分",
98:"代币时效", 99:"代币"
}
@@ -1254,6 +1256,7 @@
TYPE_Price_TiandaoFruit:CDBPlayerRefresh_TiandaoFruit,
TYPE_Price_XianyuanScore:CDBPlayerRefresh_XianyuanScore,
TYPE_Price_HuanjinggeScore:CDBPlayerRefresh_HuanjinggeScore,
+ TYPE_Price_HeroScore:CDBPlayerRefresh_HeroScore,
TYPE_Price_PayCoinDay:CDBPlayerRefresh_PayCoinDay,
}
@@ -1333,8 +1336,9 @@
rptDogzItem, # 神兽物品背包 32
rptDogzEquip, # 神兽装备背包 33
rptGarbage, # 垃圾分类背包 34
+rptHero, # 武将英雄背包 35
rptMax, # 最大背包类型数量,放在最后一个
-) = range(28, 28 + 8) #C++定义的枚举到27
+) = range(28, 28 + 9) #C++定义的枚举到27
#虚拟背包类型, 从255递减
Def_VPack_TypeList = (
@@ -1752,6 +1756,11 @@
Def_IudetLegendAttrValueXian = 63 # 物品传奇属性值列表 - 仙
Def_IudetLegendAttrIDJi = 55 # 物品传奇属性ID列表 - 极
Def_IudetLegendAttrValueJi = 65 # 物品传奇属性值列表 - 极
+Def_IudetHeroTalentID = 71 # 英雄天赋ID列表
+Def_IudetHeroTalentIDLV = 73 # 英雄天赋ID等级列表
+Def_IudetHeroTalentWashLock = 75 # 英雄天赋洗炼锁定索引列表
+Def_IudetHeroTalentWashID = 77 # 英雄天赋洗炼随机ID列表
+Def_IudetHeroTalentIDAwakeRand = 79 # 英雄觉醒时随机天赋选项ID列表
Def_IudetItemColor = 16 # 物品颜色,如果该值没有就取物品
Def_IudetItemCount = 18 # 物品个数,支持20亿,目前仅特殊转化物品会用到
@@ -1768,6 +1777,12 @@
Def_IudetGatherSoulLV = 46 # 聚魂等级
Def_IudetExpireTime = 48 # 时效物品指定有效时间,时间单位由时效类型决定
Def_IudetAuctionItemCreateTime = 50 # 拍品创建时间
+Def_IudetHeroLV = 70 # 英雄等级
+Def_IudetHeroStar = 72 # 英雄星级
+Def_IudetHeroBreakLV = 74 # 英雄突破等级
+Def_IudetHeroAwakeLV = 76 # 英雄觉醒等级
+Def_IudetHeroSkin = 78 # 英雄使用的皮肤索引
+Def_IudetHeroPosNum = 80 # 主阵型上阵位置
# 200~300 宠物数据用
Def_IudetPet_NPCID = 200 # npcID
--
Gitblit v1.8.0