From 6aeee7efd261fc1f553a4f3a748402f6dbb3cd79 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 27 二月 2026 16:07:54 +0800
Subject: [PATCH] 501 【武将】武将时装-服务端(武将时装激活、升级、穿戴、属性;武将战斗预览;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py           |  120 +++++-----
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py       |  100 ++++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py           |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py     |   45 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py      |   12 -
 /dev/null                                                                                    |   28 --
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py     |  257 ++++++++++++----------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py   |   30 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                   |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py         |   40 ++-
 PySysDB/PySysDBPY.h                                                                          |   12 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/TurnFight.py |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py              |   10 
 13 files changed, 392 insertions(+), 268 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index e73cfd8..f3129c5 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -208,14 +208,18 @@
 	list		AttrValueList;	// 属性值列表
 };
 
-//皮肤表
-struct	HeroSkin
+//皮肤时装属性表
+struct	HeroSkinAttr
 {
 	DWORD		_SkinID;	//皮肤NPCID
+    DWORD		NeedItemID;	//所需道具
+	BYTE		StarMax;	//最高星级
 	list		WearAttrIDList;	// 穿戴属性ID列表
 	list		WearAttrValueList;	// 穿戴属性值列表
-	list		AllBatAttrIDList;	// 全体上阵属性ID列表
-	list		AllBatAttrValueList;	// 全体上阵属性值列表
+    list		WearAttrPerStarAddList;	//穿戴每星加成值列表
+	list		RoleAttrIDList;	// 主公属性ID列表
+	list		RoleAttrValueList;	// 主公属性初始值列表
+    list		RoleAttrPerStarAddList;	//主公每星加成值列表
 };
 
 //武将品质表
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 3f9c875..a70516d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -964,7 +964,7 @@
 
 PacketCMD_7=0xB2
 PacketSubCMD_7=0x36
-PacketCallFunc_7=OnHeroWearSkin
+PacketCallFunc_7=OnHeroSkinOP
 
 PacketCMD_8=0xB2
 PacketSubCMD_8=0x37
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
index fb0f5cf..64aeebf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -701,6 +701,40 @@
         lineupInfo["MGSkillIDList"] = mgSkillIDList
     return lineupInfo
 
+def GetPlayerHeroBatViewLineupInfo(curPlayer, heroID, skinIndex):
+    ## 获取玩家战斗预览阵容信息
+    playerID = curPlayer.GetPlayerID()
+    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+    if not heroIpyData:
+        return
+    skinIDList = heroIpyData.GetSkinIDList()
+    skinID = skinIDList[skinIndex] if len(skinIDList) > skinIndex else 0
+    
+    heroBatAttrDict = IpyGameDataPY.GetFuncEvalCfg("HeroBatView", 1, {})
+    heroViewInfo = IpyGameDataPY.GetFuncEvalCfg("HeroBatView", 2) # 预览时的武将 站位|等级|星级|突破等级|觉醒等级
+    posNum = heroViewInfo[0] if len(heroViewInfo) > 0 else 2
+    heroLV = heroViewInfo[1] if len(heroViewInfo) > 1 else 100
+    star = heroViewInfo[2] if len(heroViewInfo) > 2 else 0
+    breakLV = heroViewInfo[3] if len(heroViewInfo) > 3 else 0
+    awakeLV = heroViewInfo[4] if len(heroViewInfo) > 4 else 0
+    fightPower = 0
+    
+    skillIDlist = GetNPCHeroSkillIDList(heroID, heroIpyData, breakLV, awakeLV)
+    
+    heroDict = {}
+    heroDict[str(posNum)] = {
+                             "HeroID":heroID,
+                             "SkinID":skinID,
+                             "LV":heroLV,
+                             "Star":star,
+                             "BreakLV":breakLV,
+                             "AwakeLV":awakeLV,
+                             "FightPower":fightPower,
+                             "AttrDict":{str(k):v for k, v in heroBatAttrDict.items() if v > 0},
+                             "SkillIDList":skillIDlist,
+                             }
+    return {"PlayerID":playerID, "Hero":heroDict}
+
 def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0, isLog=True, viewNPCID=0):
     ## 获取NPC阵容信息
     # @param lineupID: 阵容ID
@@ -1200,8 +1234,15 @@
     playerServerID = GameWorld.GetPlayerServerID(curPlayer)
     guid = GameWorld.GetGUID()
     
-    atkBatPresetType = ChConfig.MapAtkBatPresetTypeDict.get(mapID, ShareDefine.BatPreset_Main)
-    atkLineupInfo = GetPlayerLineupInfo(curPlayer, atkBatPresetType, exclusiveMapID=mapID)
+    if mapID == ChConfig.Def_FBMapID_HeroBatView:
+        if not valueList:
+            return
+        heroID = valueList[0]
+        skinIndex = valueList[1] if len(valueList) > 1 else 0
+        atkLineupInfo = GetPlayerHeroBatViewLineupInfo(curPlayer, heroID, skinIndex)
+    else:
+        atkBatPresetType = ChConfig.MapAtkBatPresetTypeDict.get(mapID, ShareDefine.BatPreset_Main)
+        atkLineupInfo = GetPlayerLineupInfo(curPlayer, atkBatPresetType, exclusiveMapID=mapID)
     if not atkLineupInfo:
         GameWorld.DebugLogEx("玩家没有主线阵容数据! mapID=%s", mapID, playerID)
         return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index b85a86e..d773435 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -241,12 +241,14 @@
 Def_CalcAttr_Beauty, # 红颜 7
 Def_CalcAttr_Dingjunge, # 定军阁 8
 Def_CalcAttr_Mingge, # 命格 9
-) = range(10)
+Def_CalcAttr_HeroSkin, # 武将时装 10
+) = range(11)
 
 CalcAttrName = {
                 Def_CalcAttr_LV:"主公等级",
                 Def_CalcAttr_MainEquip:"主装备",
                 Def_CalcAttr_HeroFates:"武将宿缘",
+                Def_CalcAttr_HeroSkin:"武将时装",
                 Def_CalcAttr_Realm:"官职",
                 Def_CalcAttr_Gubao:"古宝",
                 Def_CalcAttr_HJG:"幻境阁",
@@ -651,7 +653,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_HeroSkin = 279   #激活武将皮肤; A值-武将ID;B值-皮肤索引 废弃,直接按物品ID处理
 Def_Effect_FamilyTaofaCnt = 280   #增加公会讨伐次数; A值-讨伐次数
 Def_Effect_AddActivity = 281   #给活跃度
 
@@ -1882,6 +1884,7 @@
 Def_FBMapID_MainBoss = 2 # 主线Boss
 Def_FBMapID_ArenaBattle = 3 # 演武场
 
+Def_FBMapID_HeroBatView = 30000 # 武将战斗预览
 Def_FBMapID_Zhanchui = 30010 # 白骨盈野/战锤秘境
 Def_FBMapID_Tianzi = 30020 # 天子考验
 Def_FBMapID_Dingjunge = 30030 # 定军阁
@@ -3663,9 +3666,8 @@
 Def_PDict_GoldRushAutoEndTime = "GoldRushAutoEndTime" # 自动淘金到期时间戳
 
 #武将
-Def_PDict_HeroSkin = "HeroSkin_%s" # 武将皮肤解锁状态,按皮肤索引二进制存储,参数(武将ID)
+Def_PDict_HeroSkinInfo = "HeroSkinInfo_%s" # 武将皮肤,参数(武将ID) 皮肤星级*10 + 是否解锁
 Def_PDict_HeroBook = "HeroBook_%s" # 武将图鉴激活等级,参数(武将ID) cccbbba a-初始激活状态1-英雄激活,2-初始图鉴激活; bbb-存星级图鉴激活等级;ccc-存突破图鉴激活等级
-Def_PDict_HeroBookH = "HeroBookH_%s" # 武将图鉴历史最高等级,参数(武将ID) cccbbba: bbb-存星级图鉴最高等级;ccc-存突破图鉴最高等级
 Def_PDict_HeroAwakeRebirthCnt = "HeroAwakeRebirthCnt" # 已觉醒过的武将今日已重生次数,共享次数
 Def_PDict_HeroRecommend = "HeroRecommend_%s" # 阵容推荐领奖状态,参数(推荐ID) 根据武将ID所在索引位记录是否领取
 Def_PDict_HeroFatesInfo = "HeroFatesInfo_%s" # 武将宿缘信息,参数(宿缘ID) 宿缘等级*10 + 宿缘状态
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 64697d5..35da850 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -10307,6 +10307,70 @@
 
 
 #------------------------------------------------------
+# B2 36 武将皮肤操作 #tagCSHeroSkinOP
+
+class  tagCSHeroSkinOP(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("HeroID", c_int),    #武将ID
+                  ("SkinID", c_int),    #时装ID
+                  ("OPType", c_ubyte),    #操作 1-激活;2-佩戴;3-升星
+                  ("ItemIndex", c_ushort),    #武将物品所在武将背包位置索引,仅佩戴时有效
+                  ]
+
+    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.HeroID = 0
+        self.SkinID = 0
+        self.OPType = 0
+        self.ItemIndex = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSHeroSkinOP)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 36 武将皮肤操作 //tagCSHeroSkinOP:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                HeroID:%d,
+                                SkinID:%d,
+                                OPType:%d,
+                                ItemIndex:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.HeroID,
+                                self.SkinID,
+                                self.OPType,
+                                self.ItemIndex
+                                )
+        return DumpString
+
+
+m_NAtagCSHeroSkinOP=tagCSHeroSkinOP()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSHeroSkinOP.Cmd,m_NAtagCSHeroSkinOP.SubCmd))] = m_NAtagCSHeroSkinOP
+
+
+#------------------------------------------------------
 # B2 31 武将升星 #tagCSHeroStarUP
 
 class  tagCSHeroStarUP(Structure):
@@ -10441,62 +10505,6 @@
 
 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
 
 
 #------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index cd9d3ff..22c353f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -22496,16 +22496,12 @@
 #------------------------------------------------------
 # B1 22 武将信息 #tagSCHeroInfo
 
-class  tagSCHero(Structure):
+class  tagSCHeroSkin(Structure):
     _pack_ = 1
     _fields_ = [
-                  ("HeroID", c_int),    # 武将ID
-                  ("SkinState", c_int),    # 武将皮肤已解锁状态信息,按皮肤所在索引二进制位运算判断是否解锁,0索引位默认皮肤,不用验证
-                  ("BookInitState", c_ubyte),    # 图鉴激活状态:0-未激活;1-可激活;2-已激活
-                  ("BookStarLV", c_ushort),    # 图鉴星级等级
-                  ("BookBreakLV", c_ushort),    # 图鉴突破等级
-                  ("BookStarLVH", c_ushort),    # 图鉴星级历史最高等级
-                  ("BookBreakLVH", c_ushort),    # 图鉴突破历史最高等级
+                  ("SkinID", c_int),    #皮肤ID,只通知非默认皮肤
+                  ("State", c_ubyte),    #是否已激活
+                  ("Star", c_ubyte),    #星级
                   ]
 
     def __init__(self):
@@ -22518,39 +22514,91 @@
         return _pos + self.GetLength()
 
     def Clear(self):
-        self.HeroID = 0
-        self.SkinState = 0
-        self.BookInitState = 0
-        self.BookStarLV = 0
-        self.BookBreakLV = 0
-        self.BookStarLVH = 0
-        self.BookBreakLVH = 0
+        self.SkinID = 0
+        self.State = 0
+        self.Star = 0
         return
 
     def GetLength(self):
-        return sizeof(tagSCHero)
+        return sizeof(tagSCHeroSkin)
 
     def GetBuffer(self):
         return string_at(addressof(self), self.GetLength())
 
     def OutputString(self):
         DumpString = '''// B1 22 武将信息 //tagSCHeroInfo:
+                                SkinID:%d,
+                                State:%d,
+                                Star:%d
+                                '''\
+                                %(
+                                self.SkinID,
+                                self.State,
+                                self.Star
+                                )
+        return DumpString
+
+
+class  tagSCHero(Structure):
+    HeroID = 0    #(DWORD HeroID)// 武将ID
+    BookInitState = 0    #(BYTE BookInitState)// 图鉴激活状态:0-未激活;1-可激活;2-已激活
+    SkinCnt = 0    #(BYTE SkinCnt)
+    SkinList = list()    #(vector<tagSCHeroSkin> SkinList)// 非默认皮肤信息列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.HeroID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.BookInitState,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.SkinCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.SkinCnt):
+            temSkinList = tagSCHeroSkin()
+            _pos = temSkinList.ReadData(_lpData, _pos)
+            self.SkinList.append(temSkinList)
+        return _pos
+
+    def Clear(self):
+        self.HeroID = 0
+        self.BookInitState = 0
+        self.SkinCnt = 0
+        self.SkinList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 4
+        length += 1
+        length += 1
+        for i in range(self.SkinCnt):
+            length += self.SkinList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteDWORD(data, self.HeroID)
+        data = CommFunc.WriteBYTE(data, self.BookInitState)
+        data = CommFunc.WriteBYTE(data, self.SkinCnt)
+        for i in range(self.SkinCnt):
+            data = CommFunc.WriteString(data, self.SkinList[i].GetLength(), self.SkinList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
                                 HeroID:%d,
-                                SkinState:%d,
                                 BookInitState:%d,
-                                BookStarLV:%d,
-                                BookBreakLV:%d,
-                                BookStarLVH:%d,
-                                BookBreakLVH:%d
+                                SkinCnt:%d,
+                                SkinList:%s
                                 '''\
                                 %(
                                 self.HeroID,
-                                self.SkinState,
                                 self.BookInitState,
-                                self.BookStarLV,
-                                self.BookBreakLV,
-                                self.BookStarLVH,
-                                self.BookBreakLVH
+                                self.SkinCnt,
+                                "..."
                                 )
         return DumpString
 
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
index 3188e94..a50e4e3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
@@ -38,11 +38,9 @@
         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 r")
         GameWorld.DebugAnswer(curPlayer, "武将皮肤: Hero sk 武将ID 皮肤索引 是否解锁")
-        GameWorld.DebugAnswer(curPlayer, "切换皮肤: Hero ss 背包位置 皮肤索引")
         GameWorld.DebugAnswer(curPlayer, "重置宿缘: Hero sy 0")
         GameWorld.DebugAnswer(curPlayer, "设置宿缘: Hero sy 宿缘ID 等级 [是否激活]")
         GameWorld.DebugAnswer(curPlayer, "新增武将: MakeItemCount 英雄ID [个数]")
@@ -119,7 +117,7 @@
         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)
+        PlayerHero.GMSetHeroSkin(curPlayer, heroID, skinIndex, isActive)
         return
     
     if value == "clear":
@@ -233,14 +231,6 @@
         PlayerHero.SetHeroAwakeLV(heroItem, awakeLV)
         GameWorld.DebugAnswer(curPlayer, "设置武将觉醒: %s,itemIndex=%s" % (awakeLV, itemIndex))
         
-    # 切换皮肤
-    elif value == "ss":
-        skinIndex = msgList[2] if len(msgList) > 2 else 0
-        PlayerHero.ActiveHeroSkin(curPlayer, heroID, skinIndex, 1)
-        if not PlayerHero.DoHeroWearSkin(curPlayer, itemIndex, skinIndex):
-            GameWorld.DebugAnswer(curPlayer, "切换皮肤失败查看地图日志")
-        return
-    
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # GM修改
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/TurnFight.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/TurnFight.py
index c062c76..8dfd635 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/TurnFight.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/TurnFight.py
@@ -33,7 +33,7 @@
 #  @remarks 函数详细说明.
 def OnExec(curPlayer, msgList):
     if not msgList:
-        GameWorld.DebugAnswer(curPlayer, "发起战斗: TurnFight mapID [lineID 玩家ID]")
+        GameWorld.DebugAnswer(curPlayer, "发起战斗: TurnFight mapID [lineID 玩家ID V ...]")
         GameWorld.DebugAnswer(curPlayer, "设置属性: TurnFight a 属性ID 值 [阵营 位置] ")
         GameWorld.DebugAnswer(curPlayer, "击杀目标: TurnFight k 阵营 [位置 ...] ")
         GameWorld.DebugAnswer(curPlayer, "添加buff: TurnFight b 阵营  位置 buff归属阵营 位置 技能ID [ID ...]")
@@ -72,6 +72,7 @@
     clientData.FuncLineID = funcLineID
     clientData.TagType = 0 if not tagPlayerID else 1
     clientData.TagID = tagPlayerID
+    clientData.ValueList = msgList[3:]
     index = curPlayer.GetIndex()
     tick = GameWorld.GetGameWorld().GetTick()
     if not TurnAttack.OnTurnFight(index, clientData, tick):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 8257d1d..f6220b2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -216,12 +216,16 @@
                         ("list", "AttrValueList", 0),
                         ),
 
-                "HeroSkin":(
+                "HeroSkinAttr":(
                         ("DWORD", "SkinID", 1),
+                        ("DWORD", "NeedItemID", 0),
+                        ("BYTE", "StarMax", 0),
                         ("list", "WearAttrIDList", 0),
                         ("list", "WearAttrValueList", 0),
-                        ("list", "AllBatAttrIDList", 0),
-                        ("list", "AllBatAttrValueList", 0),
+                        ("list", "WearAttrPerStarAddList", 0),
+                        ("list", "RoleAttrIDList", 0),
+                        ("list", "RoleAttrValueList", 0),
+                        ("list", "RoleAttrPerStarAddList", 0),
                         ),
 
                 "HeroQuality":(
@@ -1994,18 +1998,22 @@
     def GetAttrIDList(self): return self.attrTuple[2] #  属性ID列表 list
     def GetAttrValueList(self): return self.attrTuple[3] #  属性值列表 list
 
-# 皮肤表
-class IPY_HeroSkin():
+# 皮肤时装属性表
+class IPY_HeroSkinAttr():
     
     def __init__(self):
         self.attrTuple = None
         return
         
     def GetSkinID(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
+    def GetNeedItemID(self): return self.attrTuple[1] # 所需道具 DWORD
+    def GetStarMax(self): return self.attrTuple[2] # 最高星级 BYTE
+    def GetWearAttrIDList(self): return self.attrTuple[3] #  穿戴属性ID列表 list
+    def GetWearAttrValueList(self): return self.attrTuple[4] #  穿戴属性值列表 list
+    def GetWearAttrPerStarAddList(self): return self.attrTuple[5] # 穿戴每星加成值列表 list
+    def GetRoleAttrIDList(self): return self.attrTuple[6] #  主公属性ID列表 list
+    def GetRoleAttrValueList(self): return self.attrTuple[7] #  主公属性初始值列表 list
+    def GetRoleAttrPerStarAddList(self): return self.attrTuple[8] # 主公每星加成值列表 list
 
 # 武将品质表
 class IPY_HeroQuality():
@@ -4377,7 +4385,7 @@
         self.__LoadFileData("HeroAwake", onlyCheck)
         self.__LoadFileData("HeroFetter", onlyCheck)
         self.__LoadFileData("HeroLineupHalo", onlyCheck)
-        self.__LoadFileData("HeroSkin", onlyCheck)
+        self.__LoadFileData("HeroSkinAttr", onlyCheck)
         self.__LoadFileData("HeroQuality", onlyCheck)
         self.__LoadFileData("HeroQualityBreak", onlyCheck)
         self.__LoadFileData("HeroQualityAwake", onlyCheck)
@@ -4843,12 +4851,12 @@
         self.CheckLoadData("HeroLineupHalo")
         return self.ipyHeroLineupHaloCache[index]
 
-    def GetHeroSkinCount(self):
-        self.CheckLoadData("HeroSkin")
-        return self.ipyHeroSkinLen
-    def GetHeroSkinByIndex(self, index):
-        self.CheckLoadData("HeroSkin")
-        return self.ipyHeroSkinCache[index]
+    def GetHeroSkinAttrCount(self):
+        self.CheckLoadData("HeroSkinAttr")
+        return self.ipyHeroSkinAttrLen
+    def GetHeroSkinAttrByIndex(self, index):
+        self.CheckLoadData("HeroSkinAttr")
+        return self.ipyHeroSkinAttrCache[index]
 
     def GetHeroQualityCount(self):
         self.CheckLoadData("HeroQuality")
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 e7cd57d..17bd0ea 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -589,7 +589,6 @@
                             ChConfig.Def_Effect_AddFBCnt:"Item_AddFBCnt", # 增加副本可进入次数
                             ChConfig.Def_Effect_EmojiPack:"Item_EmojiPack",
                             ChConfig.Def_Effect_FamilyEmblem:"Item_FamilyEmblem",
-                            ChConfig.Def_Effect_HeroSkin:"Item_HeroSkin",  # 武将皮肤
                             ChConfig.Def_Effect_FamilyTaofaCnt:"Item_FamilyTaofaCnt",  # 增加公会讨伐次数
                             }
     
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
deleted file mode 100644
index cce1865..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_HeroSkin.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/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/PlayerHero.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
index fa1abbe..aa603eb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -229,55 +229,21 @@
     GameWorld.DebugLog("设置武将图鉴激活状态:%s,bookState=%s,updBookState=%s" % (isAct, bookState, updBookState), curPlayer.GetPlayerID())
     return
 
-#def GetHeroBookStarLV(curPlayer, heroID):
-#    ## 武将图鉴星级等级
-#    bookState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID)
-#    return GameWorld.GetValue(bookState, 4, 3)
-#def SetHeroBookStarLV(curPlayer, heroID, starLV):
-#    ## 设置武将图鉴星级等级,支持三位数 0~999 级
-#    bookState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID)
-#    updBookState = GameWorld.SetValue(bookState, 4, 3, starLV)
-#    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroBook % heroID, updBookState)
-#    GameWorld.DebugLog("设置武将图鉴星级等级:%s,bookState=%s,updBookState=%s" % (starLV, bookState, updBookState), curPlayer.GetPlayerID())
-#    return
-
-#def GetHeroBookStarLVH(curPlayer, heroID):
-#    ## 武将图鉴星级历史最高等级
-#    bookStateH = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBookH % heroID)
-#    return GameWorld.GetValue(bookStateH, 4, 3)
-#def SetHeroBookStarLVH(curPlayer, heroID, starLVH):
-#    ## 设置武将图鉴星级历史最高等级,支持三位数 0~999 级
-#    bookStateH = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBookH % heroID)
-#    updBookStateH = GameWorld.SetValue(bookStateH, 4, 3, starLVH)
-#    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroBookH % heroID, updBookStateH)
-#    GameWorld.DebugLog("设置武将图鉴星级历史最高等级:%s,bookStateH=%s,updBookStateH=%s" % (starLVH, bookStateH, updBookStateH), curPlayer.GetPlayerID())
-#    Sync_HeroInfo(curPlayer, [heroID])
-#    return
-
-#def GetHeroBookBreakLV(curPlayer, heroID):
-#    ## 武将图鉴突破等级
-#    bookState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID)
-#    return GameWorld.GetValue(bookState, 7, 3)
-#def SetHeroBookBreakLV(curPlayer, heroID, breakLV):
-#    ## 设置武将图鉴突破等级,支持三位数 0~999 级
-#    bookState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID)
-#    updBookState = GameWorld.SetValue(bookState, 7, 3, breakLV)
-#    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroBook % heroID, updBookState)
-#    GameWorld.DebugLog("设置武将图鉴突破等级:%s,bookState=%s,updBookState=%s" % (breakLV, bookState, updBookState), curPlayer.GetPlayerID())
-#    return
-
-#def GetHeroBookBreakLVH(curPlayer, heroID):
-#    ## 武将图鉴突破历史最高等级
-#    bookStateH = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBookH % heroID)
-#    return GameWorld.GetValue(bookStateH, 7, 3)
-#def SetHeroBookBreakLVH(curPlayer, heroID, breakLVH):
-#    ## 设置武将图鉴突破历史最高等级,支持三位数 0~999 级
-#    bookStateH = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBookH % heroID)
-#    updBookStateH = GameWorld.SetValue(bookStateH, 7, 3, breakLVH)
-#    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroBookH % heroID, updBookStateH)
-#    GameWorld.DebugLog("设置武将图鉴突破历史最高等级:%s,bookStateH=%s,updBookStateH=%s" % (breakLVH, bookStateH, updBookStateH), curPlayer.GetPlayerID())
-#    Sync_HeroInfo(curPlayer, [heroID])
-#    return
+## Def_PDict_HeroSkinInfo 星级*10+是否已激活
+def GetHeroSkinState(curPlayer, skinID):
+    ## 武将时装激活状态
+    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkinInfo % skinID) % 10
+def SetHeroSkinState(curPlayer, skinID, state):
+    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkinInfo % skinID)
+    info = info / 10 * 10 + min(1, state)
+    return PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroSkinInfo % skinID, info)
+def GetHeroSkinStar(curPlayer, skinID):
+    ## 武将时装星级
+    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkinInfo % skinID) / 10
+def SetHeroSkinStar(curPlayer, skinID, star):
+    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkinInfo % skinID)
+    info = star * 10 + info % 10
+    return PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroSkinInfo % skinID, info)
 
 def GetHeroItem(curPlayer, itemIndex):
     curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
@@ -1020,19 +986,38 @@
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 替换洗炼天赋
     return
 
-#// B2 36 武将换肤 #tagCSHeroWearSkin
+#// B2 36 武将皮肤操作 #tagCSHeroSkinOP
 #
-#struct    tagCSHeroWearSkin
+#struct    tagCSHeroSkinOP
 #{
 #    tagHead        Head;
-#    WORD        ItemIndex;    //武将物品所在武将背包位置索引
-#    BYTE        SkinIndex;    //皮肤索引
+#    DWORD        HeroID;        //武将ID
+#    DWORD        SkinID;        //时装ID
+#    BYTE        OPType;        //操作 1-激活;2-佩戴;3-升星
+#    WORD        ItemIndex;    //武将物品所在武将背包位置索引,仅佩戴时有效
 #};
-def OnHeroWearSkin(index, clientData, tick):
+def OnHeroSkinOP(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    heroID = clientData.HeroID
+    skinID = clientData.SkinID
+    opType = clientData.OPType
     itemIndex = clientData.ItemIndex
-    skinIndex = clientData.SkinIndex
-    DoHeroWearSkin(curPlayer, itemIndex, skinIndex)
+    
+    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+    if not heroIpyData:
+        return
+    skinIDList = heroIpyData.GetSkinIDList()
+    if skinID not in skinIDList:
+        GameWorld.DebugLog("不存在该皮肤! heroID=%s,skinID=%s not in %s" % (heroID, skinID, skinIDList))
+        return
+    skinIndex = skinIDList.index(skinID)
+    
+    if opType == 1:
+        ActiveHeroSkin(curPlayer, heroID, skinID)
+    elif opType == 2:
+        DoHeroWearSkin(curPlayer, itemIndex, skinIndex)
+    elif opType == 3:
+        DoHeroSkinStarUP(curPlayer, heroID, skinID)
     return
 
 def DoHeroWearSkin(curPlayer, itemIndex, skinIndex):
@@ -1048,29 +1033,81 @@
         if skinIndex >= len(skinIDList):
             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))
+        skinID = skinIDList[skinIndex]
+        if not GetHeroSkinState(curPlayer, skinID):
+            GameWorld.DebugLog("该武将皮肤未解锁! heroID=%s,skinIndex=%s" % (heroID, skinIndex))
             return
     heroItem.SetUserAttr(ShareDefine.Def_IudetHeroSkin, skinIndex)
     
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 切换皮肤
     return True
 
-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)
+def GMSetHeroSkin(curPlayer, heroID, skinIndex, isActive=1):
+    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+    if not heroIpyData:
+        return
+    skinIDList = heroIpyData.GetSkinIDList()
+    if not skinIDList or len(skinIDList) >= skinIndex:
+        return
+    skinID = skinIDList[skinIndex]
+    __onHeroSkinActive(curPlayer, heroID, skinID, isActive)
+    return
+
+def ActiveHeroSkin(curPlayer, heroID, skinID):
+    skinIpyData = IpyGameDataPY.GetIpyGameData("HeroSkinAttr", skinID)
+    if not skinIpyData:
+        return
+    if GetHeroSkinState(curPlayer, skinID):
+        GameWorld.DebugLog("该武将皮肤已经激活了: heroID=%s,skinID=%s" % (heroID, skinID))
+        return
+    needItemID = skinIpyData.GetNeedItemID()
+    needItemCnt = 1
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, needItemID, needItemCnt)
+    lackCnt = needItemCnt - bindCnt - unBindCnt
+    if lackCnt > 0:
+        GameWorld.DebugLog("激活武将时装物品不足! heroID=%s,needItemID=%s,needItemCnt=%s,lackCnt=%s" % (heroID, needItemID, needItemCnt, lackCnt))
+        return
+    ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, needItemCnt, "HeroSkin")
+    GameWorld.DebugLog("激活武将皮肤: heroID=%s,skinID=%s" % (heroID, skinID), curPlayer.GetPlayerID())
+    __onHeroSkinActive(curPlayer, heroID, skinID, 1)
+    return
+
+def __onHeroSkinActive(curPlayer, heroID, skinID, isActive):
+    SetHeroSkinState(curPlayer, skinID, isActive)
     Sync_HeroInfo(curPlayer, [heroID])
+    RefreshLordAttr(curPlayer) # 时装激活 - 全体属性
+    return
+
+def DoHeroSkinStarUP(curPlayer, heroID, skinID):
+    playerID = curPlayer.GetPlayerID()
+    if not GetHeroSkinState(curPlayer, skinID):
+        GameWorld.DebugLog("该武将时装未激活! heroID=%s,skinID=%s" % (heroID, skinID), playerID)
+        return
+    skinIpyData = IpyGameDataPY.GetIpyGameData("HeroSkinAttr", skinID)
+    if not skinIpyData:
+        return
+    starMax = skinIpyData.GetStarMax()
+    curStar = GetHeroSkinStar(curPlayer, skinID)
+    if curStar >= starMax:
+        GameWorld.DebugLog("武将时装星级已满! heroID=%s,skinID=%s,curStar=%s >= %s" % (heroID, skinID, curStar, starMax), playerID)
+        return
+    needItemID = skinIpyData.GetNeedItemID()
+    needItemCnt = 1
+    if not needItemID or not needItemCnt:
+        return
     
-    #RefreshLordAttr(curPlayer)
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, needItemID, needItemCnt)
+    lackCnt = needItemCnt - bindCnt - unBindCnt
+    if lackCnt > 0:
+        GameWorld.DebugLog("武将时装升星物品不足! heroID=%s,skinID=%s,needItemID=%s,needItemCnt=%s,lackCnt=%s" % (heroID, skinID, needItemID, needItemCnt, lackCnt))
+        return
+    ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, needItemCnt, "Hero")
+    
+    nextStar = curStar + 1
+    GameWorld.DebugLog("武将时装升星! heroID=%s,skinID=%s,nextStar=%s" % (heroID, skinID, nextStar), playerID)
+    SetHeroSkinStar(curPlayer, skinID, nextStar)
+    Sync_HeroInfo(curPlayer, [heroID])
+    RefreshLordAttr(curPlayer) # 时装升星 - 全体属性
     return
 
 #// B2 37 武将图鉴激活升级 #tagCSHeroBookUP
@@ -1136,48 +1173,10 @@
                     
     Sync_HeroInfo(curPlayer, [heroID])
     
-    #RefreshLordAttr(curPlayer) 图鉴属性去除了
-    
     bookCnt = GetHeroBookActCnt(curPlayer)
     PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_HeroBook)
     PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_OSAHeroBook, bookCnt)
     return
-
-#def __doHeroBookStarLVUP(curPlayer, heroID):
-#    ## 图鉴星级升级,废弃
-#    playerID = curPlayer.GetPlayerID()
-#    if not GetHeroBookInitState(curPlayer, heroID):
-#        GameWorld.DebugLog("该武将图鉴未激活! heroID=%s" % heroID, playerID)
-#        return
-#    bookStar = GetHeroBookStarLV(curPlayer, heroID)
-#    bookStarH = GetHeroBookStarLVH(curPlayer, heroID)
-#    if bookStar >= bookStarH:
-#        GameWorld.DebugLog("该武将图鉴星级已达当前英雄最高星级! heroID=%s,bookStar=%s >= %s" % (heroID, bookStar, bookStarH), playerID)
-#        return
-#    GameWorld.DebugLog("武将图鉴星级升级! heroID=%s,bookStar=%s,bookStarH=%s" % (heroID, bookStar, bookStarH), playerID)
-#    SetHeroBookStarLV(curPlayer, heroID, bookStar + 1)
-#    Sync_HeroInfo(curPlayer, [heroID])
-#    
-#    RefreshLordAttr(curPlayer)
-#    return
-
-#def __doHeroBookBreakLVUP(curPlayer, heroID):
-#    ## 图鉴突破升级,废弃
-#    playerID = curPlayer.GetPlayerID()
-#    if not GetHeroBookInitState(curPlayer, heroID):
-#        GameWorld.DebugLog("该武将图鉴未激活! heroID=%s" % heroID, playerID)
-#        return
-#    bookBreakLV = GetHeroBookBreakLV(curPlayer, heroID)
-#    bookBreakLVH = GetHeroBookBreakLVH(curPlayer, heroID)
-#    if bookBreakLV >= bookBreakLVH:
-#        GameWorld.DebugLog("该武将图鉴突破等级已达当前英雄最高突破等级! heroID=%s,bookBreakLV=%s >= %s" % (heroID, bookBreakLV, bookBreakLVH), playerID)
-#        return
-#    GameWorld.DebugLog("武将图鉴突破升级! heroID=%s,bookBreakLV=%s,bookBreakLVH=%s" % (heroID, bookBreakLV, bookBreakLVH), playerID)
-#    SetHeroBookBreakLV(curPlayer, heroID, bookBreakLV + 1)
-#    Sync_HeroInfo(curPlayer, [heroID])
-#    
-#    RefreshLordAttr(curPlayer)
-#    return
 
 #// B2 38 武将锁定 #tagCSHeroLock
 #
@@ -1726,10 +1725,33 @@
 def CalcHeroAddAttr(curPlayer):
     ## 计算武将对主公增加的属性
     
+    skinAttrDict = {}
     fatesAttrDict = {}
     playerID = curPlayer.GetID()
     
     ipyDataMgr = IpyGameDataPY.IPY_Data()
+    
+    # 武将时装
+    for index in range(ipyDataMgr.GetHeroSkinAttrCount()):
+        ipyData = ipyDataMgr.GetHeroSkinAttrByIndex(index)
+        skinID = ipyData.GetSkinID()
+        if not GetHeroSkinState(curPlayer, skinID):
+            continue
+        skinStar = GetHeroSkinStar(curPlayer, skinID)
+        
+        attrIDList = ipyData.GetRoleAttrIDList()
+        attrValueList = ipyData.GetRoleAttrValueList()
+        perStarAddList = ipyData.GetRoleAttrPerStarAddList()
+        for i in range(min(len(attrIDList), len(attrValueList))):
+            attrID = attrIDList[i]
+            attrValuePerStar = perStarAddList[i] if len(perStarAddList) > i else 0
+            attrValue = attrValueList[i] + attrValuePerStar * skinStar
+            skinAttrDict[attrID] = skinAttrDict.get(attrID, 0) + attrValue
+            
+    GameWorld.DebugLog("时装属性: %s" % skinAttrDict, playerID)
+    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_HeroSkin, skinAttrDict)
+    
+    # 宿缘
     for index in range(ipyDataMgr.GetHeroFatesCount()):
         ipyData = ipyDataMgr.GetHeroFatesByIndex(index)
         fatesID = ipyData.GetFatesID()
@@ -1770,18 +1792,21 @@
         heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
         if not heroIpyData:
             continue
-        if heroIDList == None and not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID) \
-            and not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBookH % heroID):
+        if heroIDList == None and not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID):
             continue
+        skinIDList = heroIpyData.GetSkinIDList()
         
         hero = ChPyNetSendPack.tagSCHero()
         hero.HeroID = heroID
-        hero.SkinState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroSkin % heroID)
         hero.BookInitState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroBook % heroID) % 10
-        #hero.BookStarLV = GetHeroBookStarLV(curPlayer, heroID)
-        #hero.BookBreakLV = GetHeroBookBreakLV(curPlayer, heroID)
-        #hero.BookStarLVH = GetHeroBookStarLVH(curPlayer, heroID)
-        #hero.BookBreakLVH = GetHeroBookBreakLVH(curPlayer, heroID)
+        hero.SkinList = []
+        for skinID in skinIDList[1:]: # 第1个默认激活的不同步
+            skin = ChPyNetSendPack.tagSCHeroSkin()
+            skin.SkinID = skinID
+            skin.State = GetHeroSkinState(curPlayer, skinID)
+            skin.Star = GetHeroSkinStar(curPlayer, skinID)
+            hero.SkinList.append(skin)
+        hero.SkinCnt = len(hero.SkinList)
         syncInfoList.append(hero)
         
     if not syncInfoList:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
index fc590a6..ae38c35 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -750,6 +750,7 @@
     countryHeroInfo = {} # 国家武将统计 {country:[heroID, ...], ...}
     fetterHeroInfo = {} # 阵容羁绊武将统计信息 {fetterID:[heroID, ...], ...}
     heroSelfAttrInfo = {} # 武将自身属性 {heroID:{attrID:value, ...}, ...}
+    heroSkinAttrInfo = {} # 武将时装属性 {heroID:{attrID:value, ...}, ...}
     heroLVAttrInfo = {} # 武将等级属性 {heroID:{attrID:value, ...}, ...}
     heroStarTalentInfo = {} # 武将星级天赋属性 {heroID:{attrID:value, ...}, ...}
     heroBreakAttrInfo = {} # 武将突破潜能属性 {heroID:{attrID:value, ...}, ...}
@@ -808,6 +809,21 @@
         for k, v in heroIpyData.GetBatAttrDict().items():
             selfAttrDict[int(k)] = v
         heroSelfAttrInfo[heroID] = selfAttrDict
+        
+        # 时装属性
+        heroSkinAttrDict = {}
+        skinIpyData = IpyGameDataPY.GetIpyGameDataNotLog("HeroSkinAttr", skinID)
+        if skinIpyData:
+            skinStar = PlayerHero.GetHeroSkinStar(curPlayer, skinID)
+            wearAttrIDList = skinIpyData.GetWearAttrIDList()
+            wearAttrValueList = skinIpyData.GetWearAttrValueList()
+            wearAttrPerStarAddList = skinIpyData.GetWearAttrPerStarAddList()
+            for i in range(min(len(wearAttrIDList), len(wearAttrValueList))):
+                attrID = wearAttrIDList[i]
+                attrValuePerStar = wearAttrPerStarAddList[i] if len(wearAttrPerStarAddList) > i else 0
+                attrValue = wearAttrValueList[i] + attrValuePerStar * skinStar
+                heroSkinAttrDict[attrID] = heroSkinAttrDict.get(attrID, 0) + attrValue
+        heroSkinAttrInfo[heroID] = heroSkinAttrDict
         
         # 等级属性
         heroLVAttrDict = {}
@@ -950,6 +966,7 @@
     lvAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_LV)
     equipAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_MainEquip)
     fatesAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HeroFates)
+    skinAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HeroSkin)
     realmAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Realm)
     gubaoAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_Gubao)
     hjgAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HJG)
@@ -962,6 +979,7 @@
     GameWorld.DebugLog("    国家武将统计=%s" % countryHeroInfo, playerID)
     GameWorld.DebugLog("    羁绊武将统计=%s" % fetterHeroInfo, playerID)
     GameWorld.DebugLog("    武将自身属性=%s" % heroSelfAttrInfo, playerID)
+    GameWorld.DebugLog("    穿戴时装属性=%s" % heroSkinAttrInfo, playerID)
     GameWorld.DebugLog("    武将等级属性=%s" % heroLVAttrInfo, playerID)
     GameWorld.DebugLog("    武将吞噬属性=%s" % heroStarTalentInfo, playerID)
     GameWorld.DebugLog("    武将突破潜能=%s" % heroBreakAttrInfo, playerID)
@@ -972,6 +990,7 @@
     GameWorld.DebugLog("    主公等级属性=%s" % lvAttrDict, playerID)
     GameWorld.DebugLog("    主公装备属性=%s" % equipAttrDict, playerID)
     GameWorld.DebugLog("    主公宿缘属性=%s" % fatesAttrDict, playerID)
+    GameWorld.DebugLog("    主公全体时装=%s" % skinAttrDict, playerID)
     GameWorld.DebugLog("    主公官职属性=%s" % realmAttrDict, playerID)
     GameWorld.DebugLog("    主公古宝属性=%s" % gubaoAttrDict, playerID)
     GameWorld.DebugLog("    主幻境阁属性=%s" % hjgAttrDict, playerID)
@@ -1011,6 +1030,7 @@
         lineupHero.heroBatAttrDict = {}
         lineupHero.fightPower = 0
         
+        heroSkinAttrDict = heroSkinAttrInfo.get(heroID, {})
         heroLVAttrDict = heroLVAttrInfo.get(heroID, {})
         starTalentAttrDict = heroStarTalentInfo.get(heroID, {})
         breakAttrDict = heroBreakAttrInfo.get(heroID, {})
@@ -1031,6 +1051,9 @@
                 
             fatesValue = fatesAttrDict.get(attrID, 0)
             fatesPer = fatesAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
+            
+            skinValue = skinAttrDict.get(attrID, 0)
+            skinPer = skinAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
             
             realmValue = realmAttrDict.get(attrID, 0)
             realmPer = realmAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
@@ -1062,6 +1085,7 @@
                 
             lineupHaloValue, lineupHaloPer = lineupHaloAttrInfo.get(attrID, 0), 0
             fetterValue, fetterPer = fetterAttrDict.get(attrID, 0), 0
+            heroSkinValue, heroSkinPer = heroSkinAttrDict.get(attrID, 0), 0
             heroLVValue, heroLVPer = heroLVAttrDict.get(attrID, 0), 0
             starTalentValue, starTalentPer = starTalentAttrDict.get(attrID, 0), 0
             breakLVValue, breakLVPer = breakAttrDict.get(attrID, 0), 0
@@ -1070,6 +1094,7 @@
                 heroSelfPer = selfAttrDict.get(attrPerID, 0) / 10000.0
                 lineupHaloPer = lineupHaloAttrInfo.get(attrPerID, 0) / 10000.0
                 fetterPer = fetterAttrDict.get(attrPerID, 0) / 10000.0
+                heroSkinPer = heroSkinAttrDict.get(attrPerID, 0) / 10000.0
                 heroLVPer = heroLVAttrDict.get(attrPerID, 0) / 10000.0
                 starTalentPer = starTalentAttrDict.get(attrPerID, 0) / 10000.0
                 breakLVPer = breakAttrDict.get(attrPerID, 0) / 10000.0
@@ -1078,9 +1103,10 @@
             # 计算
             attrParamDict = {"lvValue":lvValue, "equipValue":equipValue, "realmValue":realmValue, "realmPer":realmPer, "cardPer":cardPer,
                              "gubaoValue":gubaoValue, "gubaoPer":gubaoPer, "hjgValue":hjgValue, "hjgPer":hjgPer, "horseValue":horseValue, "horsePer":horsePer,
-                             "beautyValue":beautyValue, "beautyPer":beautyPer, "fatesValue":fatesValue, "fatesPer":fatesPer,
+                             "beautyValue":beautyValue, "beautyPer":beautyPer, "fatesValue":fatesValue, "fatesPer":fatesPer, "skinValue":skinValue, "skinPer":skinPer,
                              "dingjungeValue":dingjungeValue, "dingjungePer":dingjungePer, "minggeValue":minggeValue, "minggePer":minggePer,
-                             "heroSelfValue":heroSelfValue, "heroSelfPer":heroSelfPer, "inheritPer":inheritPer, "heroLVValue":heroLVValue, "heroLVPer":heroLVPer,
+                             "heroSelfValue":heroSelfValue, "heroSelfPer":heroSelfPer, "inheritPer":inheritPer, "heroLVValue":heroLVValue, "heroLVPer":heroLVPer, 
+                             "heroSkinValue":heroSkinValue, "heroSkinPer":heroSkinPer,
                              "lineupHaloValue":lineupHaloValue, "lineupHaloPer":lineupHaloPer, "fetterValue":fetterValue, "fetterPer":fetterPer,
                              "starTalentValue":starTalentValue, "starTalentPer":starTalentPer, "breakLVValue":breakLVValue, "breakLVPer":breakLVPer,
                              "awakeTalentValue":awakeTalentValue, "awakeTalentPer":awakeTalentPer,

--
Gitblit v1.8.0