From 0312684d12e68285b0a0feecb5904c78ecba4731 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 22 七月 2025 20:10:51 +0800
Subject: [PATCH] 121 【武将】武将系统-服务端(Hero命令支持一件上阵;一键满级;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py   |   28 ++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py |   11 +-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py    |  198 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 224 insertions(+), 13 deletions(-)

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 37ad243..95f6e59 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
@@ -19,9 +19,11 @@
 import ShareDefine
 import IpyGameDataPY
 import PlayerControl
+import ItemControler
 import PlayerOnline
 import GameWorld
 import ChConfig
+import random
 
 ## GM命令执行入口
 #  @param curPlayer 当前玩家
@@ -41,12 +43,25 @@
         GameWorld.DebugAnswer(curPlayer, "武将皮肤: Hero sk 武将ID 皮肤索引 是否解锁")
         GameWorld.DebugAnswer(curPlayer, "清空武将: ClearPack 35")
         GameWorld.DebugAnswer(curPlayer, "新增武将: MakeItemCount 英雄ID [个数]")
+        GameWorld.DebugAnswer(curPlayer, "阵容上阵: Hero f 阵容ID [武将ID ...]")
+        GameWorld.DebugAnswer(curPlayer, "阵容武将: Hero h 阵容ID 武将ID 等级 星级 突破等级 觉醒等级 皮肤")
+        GameWorld.DebugAnswer(curPlayer, "阵容满级: Hero h 阵容ID 1")
         return
     
     PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
     
     value = msgList[0]
     value2 = msgList[1] if len(msgList) > 1 else 0
+    
+    # 阵容上阵
+    if value == "f":
+        __oneKeyLineup(curPlayer, msgList)
+        return
+    
+    # 阵容武将
+    if value == "h":
+        __lineupHero(curPlayer, msgList)
+        return
     
     # 图鉴
     if value == "t":
@@ -139,3 +154,186 @@
     
     return
 
+def __oneKeyLineup(curPlayer, msgList):
+    ## 阵容上阵: Hero f 阵容ID [武将ID ...]
+    lineupID = msgList[1] if len(msgList) > 1 else 0
+    heroIDList = list(set(msgList[2:])) # 去重,单阵容武将ID不能重复
+    
+    if lineupID not in ShareDefine.LineupList:
+        GameWorld.DebugAnswer(curPlayer, "不存在该阵容: %s" % lineupID)
+        return
+    
+    if not heroIDList:
+        GameWorld.DebugAnswer(curPlayer, "没有指定阵容武将ID列表!")
+        return
+    
+    for heroID in heroIDList:
+        if not GameWorld.GetGameData().GetItemByTypeID(heroID):
+            GameWorld.DebugAnswer(curPlayer, "不存在该武将: %s" % heroID)
+            return
+        
+    shapeType = 0
+    haveHeroIDList = []
+    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
+    # 直接重置旧阵型
+    syncItemDict = {}
+    for index in range(curPack.GetCount()):
+        heroItem = curPack.GetAt(index)
+        if not heroItem or heroItem.IsEmpty():
+            continue
+        heroID = heroItem.GetItemTypeID()
+        if heroID in heroIDList and heroID not in haveHeroIDList:
+            haveHeroIDList.append(heroID)
+        lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
+        if not lineupCount:
+            continue
+        item = heroItem.GetItem()
+        for lpIndex in range(lineupCount)[::-1]:
+            lineupValue = item.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
+            if PlayerHero.GetLineupValue(lineupValue)[0] != lineupID:
+                continue
+            item.DelUserAttr(ShareDefine.Def_IudetHeroLineup, lineupValue)
+            syncItemDict[index] = heroItem
+            
+    # 给没有的武将
+    for heroID in heroIDList:
+        if heroID in haveHeroIDList:
+            continue
+        if not ItemControler.GivePlayerItem(curPlayer, heroID, 1, False):
+            break
+        
+    # 更新新阵型
+    heroItemDict = {}
+    updHeroIDList = []
+    for index in range(curPack.GetCount()):
+        heroItem = curPack.GetAt(index)
+        if not heroItem or heroItem.IsEmpty():
+            continue
+        heroID = heroItem.GetItemTypeID()
+        if heroID not in heroIDList:
+            continue
+        if heroID in updHeroIDList:
+            # 已经上过该武将了
+            continue
+        updHeroIDList.append(heroID)
+        posNum = heroIDList.index(heroID) + 1
+        item = heroItem.GetItem()
+        lineupValue = PlayerHero.ComLineupValue(lineupID, shapeType, posNum)
+        item.AddUserAttr(ShareDefine.Def_IudetHeroLineup, lineupValue)
+        if index not in syncItemDict:
+            syncItemDict[index] = heroItem
+        heroItemDict[index] = posNum
+        
+    for syncItem in syncItemDict.values():
+        syncItem.Sync_Item()
+        
+    lineup = PlayerOnline.GetOnlinePlayer(curPlayer).GetLineup(lineupID)
+    lineup.UpdLineup(heroItemDict, shapeType)
+    GameWorld.DebugAnswer(curPlayer, "阵容(%s)上阵OK: %s" % (lineupID, heroItemDict))
+    return
+
+def __lineupHero(curPlayer, msgList):
+    #阵容武将: Hero h 阵容ID 武将ID 等级 星级 突破等级 觉醒等级 皮肤
+    #阵容满级: Hero h 阵容ID 1
+    lineupID = msgList[1] if len(msgList) > 1 else 0
+    heroID = msgList[2] if len(msgList) > 2 else 0
+    setLV = msgList[3] if len(msgList) > 3 else None
+    setStar = msgList[4] if len(msgList) > 4 else None
+    setBreakLV = msgList[5] if len(msgList) > 5 else None
+    setAwakeLV = msgList[6] if len(msgList) > 6 else None
+    setSkinID = msgList[7] if len(msgList) > 7 else None
+    
+    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
+    lineup = olPlayer.GetLineup(lineupID)
+    if heroID == 1:
+        setIndexList = lineup.heroItemDict.keys()
+    else:
+        lineupHero = lineup.GetLineupHeroByID(heroID)
+        if not lineupHero:
+            GameWorld.DebugAnswer(curPlayer, "该阵容不存在该武将: %s" % heroID)
+            return
+        setIndexList = [lineupHero.itemIndex]
+        
+    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
+    for itemIndex in setIndexList:
+        if itemIndex < 0 or itemIndex >= curPack.GetCount():
+            continue
+        heroItem = curPack.GetAt(itemIndex)
+        if not heroItem or heroItem.IsEmpty():
+            continue
+        heroID = heroItem.GetItemTypeID()
+        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+        if not heroIpyData:
+            continue
+        quality = heroIpyData.GetQuality()
+        qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
+        if not qualityIpyData:
+            continue
+        singleItem = heroItem.GetItem()
+        
+        # 天赋        
+        if setAwakeLV != None:
+            awakeLV = setAwakeLV
+            if not IpyGameDataPY.GetIpyGameData("HeroQualityAwake", quality, awakeLV):
+                GameWorld.DebugAnswer(curPlayer, "觉醒等级不存在:%s 品质:%s" % (awakeLV, quality))
+                return
+        else:
+            awakeLV = 0
+            for aLV in range(1, 100):
+                if not IpyGameDataPY.GetIpyGameDataNotLog("HeroQualityAwake", quality, aLV):
+                    break
+                awakeLV = aLV
+        PlayerHero.SetHeroAwakeLV(heroItem, awakeLV, False)
+        
+        doCnt = 0
+        awakeRandCnt = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+        while awakeRandCnt and doCnt <= 10:
+            doCnt += 1
+            selectIndex = random.randint(0, awakeRandCnt - 1)
+            PlayerHero.doSelectAwakeTalent(curPlayer, itemIndex, selectIndex, False)
+            awakeRandCnt = singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
+            
+        # 突破
+        if setBreakLV != None:
+            breakLV = setBreakLV
+            if not IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, breakLV):
+                GameWorld.DebugAnswer(curPlayer, "突破等级不存在:%s 品质:%s" % (breakLV, quality))
+                return
+        else:
+            breakLV = 0
+            for bLV in range(1, 100):
+                if not IpyGameDataPY.GetIpyGameDataNotLog("HeroQualityBreak", quality, bLV):
+                    break
+                breakLV = bLV
+        PlayerHero.SetHeroBreakLV(heroItem, breakLV, False)
+        
+        # 星级
+        starMax = PlayerHero.GetHeroStarMax(heroItem)
+        if setStar != None:
+            updStar = min(setStar, starMax)
+        else:
+            updStar = starMax
+        PlayerHero.DoHeroUpdStar(curPlayer, heroItem, updStar, False)
+        
+        # 等级
+        lvMax = PlayerHero.GetHeroLVMax(heroItem)
+        if setLV != None:
+            updHeroLV = min(setLV, lvMax)
+        else:
+            updHeroLV = lvMax
+        singleItem.SetUserAttr(ShareDefine.Def_IudetHeroLV, updHeroLV)
+        
+        # 皮肤
+        skinIDList = heroIpyData.GetSkinIDList()
+        if setSkinID != None:
+            if setSkinID not in skinIDList:
+                GameWorld.DebugAnswer(curPlayer, "皮肤不存在:%s 品质:%s" % (heroID, setSkinID))
+                return
+            skinIndex = skinIDList.index(setSkinID)
+            singleItem.SetUserAttr(ShareDefine.Def_IudetHeroSkin, skinIndex)      
+            
+        heroItem.Sync_Item()
+        PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate([itemIndex])
+        
+    GameWorld.DebugAnswer(curPlayer, "设置阵容武将OK")
+    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
index 6139b88..8165538 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -419,7 +419,7 @@
     starMax = InitStarUpper + addStarUpper
     return starMax
 
-def DoHeroUpdStar(curPlayer, heroItem, updStar):
+def DoHeroUpdStar(curPlayer, heroItem, updStar, isSync=True):
     ## 执行武将星级更新
     curStar = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
     addStar = updStar - curStar
@@ -427,7 +427,8 @@
     item.SetUserAttr(ShareDefine.Def_IudetHeroStar, updStar)
     if addStar > 0:
         __DoHeroStarTalentUp(item, addStar)
-    heroItem.Sync_Item()
+    if isSync:
+        heroItem.Sync_Item()
     
     itemIndex = heroItem.GetItemPlaceIndex()
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate([itemIndex])
@@ -575,9 +576,12 @@
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate([itemIndex])
     return
 
-def SetHeroBreakLV(heroItem, breakLV):
+def SetHeroBreakLV(heroItem, breakLV, isSync=True):
     ## 设置武将突破等级
-    heroItem.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, breakLV)
+    item = heroItem.GetItem()
+    item.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, breakLV)
+    if isSync:
+        heroItem.Sync_Item()
     return
 
 #// B2 33 武将觉醒 #tagCSHeroAwake
@@ -633,12 +637,13 @@
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate([itemIndex])
     return
 
-def SetHeroAwakeLV(heroItem, awakeLV):
+def SetHeroAwakeLV(heroItem, awakeLV, isSync=True):
     ## 设置武将觉醒等级
     item = heroItem.GetItem()
     item.SetUserAttr(ShareDefine.Def_IudetHeroAwakeLV, awakeLV)
     unlockTalentSlotByAwake(item)
-    heroItem.Sync_Item()
+    if isSync:
+        heroItem.Sync_Item()
     return
 
 def unlockTalentSlotByAwake(singleItem):
@@ -712,9 +717,13 @@
 #};
 def OnHeroAwakeSelectTalent(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
-    playerID = curPlayer.GetPlayerID()
     itemIndex = clientData.ItemIndex
     selectIndex = clientData.SelectIndex
+    doSelectAwakeTalent(curPlayer, itemIndex, selectIndex)
+    return
+
+def doSelectAwakeTalent(curPlayer, itemIndex, selectIndex, isSync=True):
+    playerID = curPlayer.GetPlayerID()
     heroItem = GetHeroItem(curPlayer, itemIndex)
     if not heroItem:
         return
@@ -757,10 +766,11 @@
     for index, talentID in enumerate(idList):
         singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentID, talentID)
         singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentIDLV, lvList[index])
-            
+        
     unlockTalentSlotByAwake(singleItem)
     
-    heroItem.Sync_Item()
+    if isSync:
+        heroItem.Sync_Item()
     
     PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate([itemIndex])
     return
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 872e5f6..2a29643 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -97,11 +97,14 @@
         return lineupHero
     
     def GetLineupHeroByID(self, heroID):
+        lineupHero = None
         for posNum in self.lineupHeroDict.keys():
-            lineup = self.GetLineupHero(posNum)
-            if lineup.heroID == heroID:
-                return lineup
-        return
+            lineupHero = self.GetLineupHero(posNum)
+            if lineupHero.heroID == heroID:
+                return lineupHero
+        if False:
+            lineupHero = LineupHero()
+        return lineupHero
     
     def GetLineupInfo(self):
         ## 获取阵容信息,即要用到该阵容了,如战斗或者保存缓存信息等

--
Gitblit v1.8.0