hxp
2026-03-12 5c8b87ef0812652af80655923ac5ca277b346f61
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -22,16 +22,20 @@
import ItemControler
import PlayerSuccess
import ChPyNetSendPack
import OpenServerActivity
import PlayerActivity
import NetPackCommon
import PlayerControl
import PlayerOnline
import PlayerPreset
import PlayerBeauty
import PlayerTask
import PlayerHJG
import GameWorld
import ChConfig
import random
import math
    
def PlayerOnDay(curPlayer):
    if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt):
@@ -114,6 +118,8 @@
        singleItem.SetUserAttr(ShareDefine.Def_IudetHeroAwakeLV, 0)
    if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin):
        singleItem.SetUserAttr(ShareDefine.Def_IudetHeroSkin, 0)
    if singleItem.GetUserAttr(ShareDefine.Def_IudetHeroSkinAttr):
        singleItem.SetUserAttr(ShareDefine.Def_IudetHeroSkinAttr, 0)
        
    if singleItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID):
        singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
@@ -188,6 +194,7 @@
        #首次获得图鉴额外逻辑 ...
        Sync_HeroInfo(curPlayer, [heroID])
        PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 首次获得
        OpenServerActivity.UpdOSA_HeroTrainBillboard(curPlayer) # 首次获得
        
    return
@@ -319,6 +326,7 @@
    PlayerActivity.AddDailyTaskValue(curPlayer, ChConfig.DailyTask_HeroLVUP, 1)
    PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_HeroLVUP)
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_OSAHeroLVUP, 1)
    OpenServerActivity.UpdOSA_HeroTrainBillboard(curPlayer) # 升级
    return
def GetHeroLVMax(heroItem):
@@ -384,7 +392,7 @@
    quality = heroIpyData.GetQuality()
    star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
    awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
    starMax = GetHeroStarMax(heroItem)
    starMax = GetHeroStarMax(heroID, 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)
@@ -398,11 +406,31 @@
    DoHeroUpdStar(curPlayer, heroItem, updStar)
    
    PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 升星
    # 固定返还一个遣散本体材料
    qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
    if qualityIpyData:
        ratio = IpyGameDataPY.GetFuncCfg("HeroRebirth", 5)
        returnItemList = []
        dismissReturnItems = qualityIpyData.GetDismissReturnItems()
        for itemID, itemCount in dismissReturnItems:
            returnCnt = max(1, int(itemCount * ratio / 100.0))
            returnItemList.append([itemID, returnCnt])
        returnItemExDict = {}
        __calcHeroQualityReturnItemEx(curPlayer, qualityIpyData, returnItemExDict)
        for key, itemCount in returnItemExDict.items():
            itemID, isBind = key
            returnItemList.append([itemID, itemCount, isBind])
        GameWorld.DebugLog("吞噬额外总返还: %s" % returnItemList)
        ItemControler.GivePlayerItemOrMail(curPlayer, returnItemList, event=["HeroStarUPReturn", False, {}])
    OpenServerActivity.UpdOSA_HeroTrainBillboard(curPlayer) # 升星
    return
def GetHeroStarMax(heroItem):
    ## 获取武将当前最大星级
    heroID = heroItem.GetItemTypeID()
def GetHeroStarMax(heroID, heroItem=None):
    ## 获取武将卡物品当前最大星级
    # @param heroItem: 传入武将物品时,则取本物品当前觉醒对应的最大星级
    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
    if not heroIpyData:
        return 0
@@ -412,8 +440,10 @@
        return 0
    InitStarUpper = qualityIpyData.GetInitStarUpper()
    
    awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
    if not awakeLV:
    awakeLV = 99999
    if heroItem:
        awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
    if awakeLV <= 0:
        return InitStarUpper
    
    addStarUpper = 0
@@ -430,7 +460,11 @@
def DoHeroUpdStar(curPlayer, heroItem, updStar, isSync=True):
    ## 执行武将星级更新
    #heroID = heroItem.GetItemTypeID()
    heroID = heroItem.GetItemTypeID()
    versionStarMax = GetHeroStarMax(heroID) # 版本理论最大星级
    if updStar > versionStarMax:
        updStar = versionStarMax
        GameWorld.DebugLog("不超过版本最大武将星级: heroID=%s,versionStarMax=%s" % (heroID, versionStarMax))
    curStar = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
    addStar = updStar - curStar
    item = heroItem.GetItem()
@@ -563,8 +597,8 @@
        singleItem.AddUserAttr(ShareDefine.Def_IudetHeroTalentIDLV, lvList[index])
    return
def GetHeroItemStarMax(curPlayer, heroID):
    ## 获取某个武将ID当前最大星级
def GetHeroIDStar(curPlayer, heroID):
    ## 获取某个武将ID当前星级,同时存在多张卡时取最大的星级
    starMax = 0
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for index in range(curPack.GetCount()):
@@ -646,6 +680,7 @@
    SetHeroBreakLV(curPlayer, heroItem, nextBreakLV)
    
    PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 突破
    OpenServerActivity.UpdOSA_HeroTrainBillboard(curPlayer) # 突破
    return
def SetHeroBreakLV(curPlayer, heroItem, breakLV, isSync=True):
@@ -712,6 +747,7 @@
    SetHeroAwakeLV(heroItem, nextAwakeLV)
    
    PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 觉醒
    OpenServerActivity.UpdOSA_HeroTrainBillboard(curPlayer) # 觉醒
    return
def SetHeroAwakeLV(heroItem, awakeLV, isSync=True):
@@ -823,21 +859,51 @@
        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
    commTalentSlot = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 1) # 常规天赋槽个数
    talentMaxLV = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 2) # 每个天赋最大等级
    idCount = len(idList)
    GameWorld.DebugLog("选择天赋: heroID=%s,selectTalentID=%s,idList=%s,lvList=%s" % (heroID, selectTalentID, idList, lvList))
    
    if idCount < commTalentSlot:
        idList += [0] * (commTalentSlot - idCount)
        lvList += [0] * (commTalentSlot - idCount)
        selectTalentLV = 1
        GameWorld.DebugLog("常规槽位未全部解锁,觉醒槽位默认1级天赋")
    else:
        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
        if not heroIpyData:
            return
        quality = heroIpyData.GetQuality()
        qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
        if not qualityIpyData:
            return
        InitStarUpper = qualityIpyData.GetInitStarUpper()
        heroAwakeIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("HeroAwake", heroID)
        if not heroAwakeIpyDataList:
            return
        preSlotStarMax = 0 # 上一档槽位最大星级
        preSlotStarMax += InitStarUpper
        for ipyData in heroAwakeIpyDataList:
            if idCount < ipyData.GetUnlockTalentSlot():
                break
            preSlotStarMax += ipyData.GetAddStarUpper()
        curStar = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
        GameWorld.DebugLog("常规槽位已全部解锁, idCount=%s,preSlotStarMax=%s,curStar=%s" % (idCount, preSlotStarMax, curStar))
        overflowStar = curStar - preSlotStarMax # 溢出星级 = 当前星级 - 上一档槽位最大星级
        selectTalentLV = max(1, min(overflowStar + 1, talentMaxLV)) # 保底1级 + 溢出星级
    idList.append(selectTalentID)
    lvList.append(1)
    lvList.append(selectTalentLV)
    singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDAwakeRand)
    
    GameWorld.DebugLog("更新选择天赋: selectTalentID=%s,idList=%s,lvList=%s" % (selectTalentID, idList, lvList))
    GameWorld.DebugLog("selectTalentID=%s,selectTalentLV=%s,idList=%s,lvList=%s" % (selectTalentID, selectTalentLV, idList, lvList))
    singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentID)
    singleItem.ClearUserAttr(ShareDefine.Def_IudetHeroTalentIDLV)
    for index, talentID in enumerate(idList):
@@ -959,6 +1025,8 @@
    heroItem.Sync_Item()
    GameWorld.DebugLog("武将洗炼结果! itemIndex=%s,heroID=%s,washIDList=%s,lockTalentIndexs=%s" 
                       % (itemIndex, heroID, washIDList, lockTalentIndexs))
    OpenServerActivity.AddOSAValue(curPlayer, ShareDefine.Def_BT_OSA_HeroTrain, washCostItemCount)
    OpenServerActivity.UpdOSA_HeroTrainBillboard(curPlayer) # 洗炼
    return
def HeroTalentWashReplace(curPlayer, itemIndex, heroItem):
@@ -993,7 +1061,7 @@
#    tagHead        Head;
#    DWORD        HeroID;        //武将ID
#    DWORD        SkinID;        //ʱװID
#    BYTE        OPType;        //操作 1-激活;2-佩戴;3-升星
#    BYTE        OPType;        //操作 1-激活;2-选择形象;3-升星;4-选择属性
#    WORD        ItemIndex;    //武将物品所在武将背包位置索引,仅佩戴时有效
#};
def OnHeroSkinOP(index, clientData, tick):
@@ -1015,12 +1083,15 @@
    if opType == 1:
        ActiveHeroSkin(curPlayer, heroID, skinID)
    elif opType == 2:
        DoHeroWearSkin(curPlayer, itemIndex, skinIndex)
        DoHeroWearSkin(curPlayer, itemIndex, skinIndex, False)
    elif opType == 3:
        DoHeroSkinStarUP(curPlayer, heroID, skinID)
    elif opType == 4:
        DoHeroWearSkin(curPlayer, itemIndex, skinIndex, True)
    return
def DoHeroWearSkin(curPlayer, itemIndex, skinIndex):
def DoHeroWearSkin(curPlayer, itemIndex, skinIndex, isSkinAttr):
    # @param isSkinAttr: 是否是选择属性的,反之则为选择皮肤形象
    heroItem = GetHeroItem(curPlayer, itemIndex)
    if not heroItem:
        return
@@ -1037,9 +1108,17 @@
        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) # 切换皮肤
    GameWorld.DebugLog("切换武将皮肤! heroID=%s,skinIndex=%s,isSkinAttr=%s" % (heroID, skinIndex, isSkinAttr))
    item = heroItem.GetItem()
    if not isSkinAttr:
        item.SetUserAttr(ShareDefine.Def_IudetHeroSkin, skinIndex)
    else:
        # 选属性同步修改形象
        item.SetUserAttr(ShareDefine.Def_IudetHeroSkin, skinIndex)
        item.SetUserAttr(ShareDefine.Def_IudetHeroSkinAttr, skinIndex)
        PlayerOnline.GetOnlinePlayer(curPlayer).OnHeroItemUpate(heroItem) # 切换皮肤属性
    heroItem.Sync_Item()
    return True
def GMSetHeroSkin(curPlayer, heroID, skinIndex, isActive=1):
@@ -1357,6 +1436,7 @@
    ratio = IpyGameDataPY.GetFuncCfg("HeroRebirth", 5)
    dismissItemList = []
    returnItemDict = {}
    returnItemExDict = {}
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for itemIndex in itemIndexList:
        if itemIndex < 0 or itemIndex >= curPack.GetCount():
@@ -1399,6 +1479,7 @@
        GameWorld.DebugLog("    星级返还: quality=%s,heroStar=%s,ratio=%s,%s,总%s" % (quality, heroStar, ratio, dismissReturnItems, returnItemDict))
        __calcHeroLVReturnitem(quality, heroLV, returnItemDict, ratio)
        __calcHeroBreakReturnitem(quality, breakLV, returnItemDict, ratio)
        __calcHeroQualityReturnItemEx(curPlayer, qualityIpyData, returnItemExDict)
        dismissItemList.append([itemIndex, heroItem])
    
    if not dismissItemList:
@@ -1409,10 +1490,45 @@
        
    if returnItemDict:
        returnItemList = [[k, v] for k, v in returnItemDict.items()]
        for key, itemCount in returnItemExDict.items():
            itemID, isBind = key
            returnItemList.append([itemID, itemCount, isBind])
        GameWorld.DebugLog("遣散总返还: %s" % returnItemList)
        ItemControler.GivePlayerItemOrMail(curPlayer, returnItemList, event=["HeroDismiss", False, {}])
        
    return
def __calcHeroQualityReturnItemEx(curPlayer, qualityIpyData, returnItemExDict):
    ## 其他功能额外返还
    # 红颜特殊效果: 遣散/吞噬额外返还百分比
    beautyReturnItems = qualityIpyData.GetBeautyReturnItems()
    if beautyReturnItems:
        isBind = ItemControler.GetIsBindValue(srcSign=ChConfig.ItemSrcSign_BeautyEff)
        retPer = PlayerBeauty.GetBeautyEffInfo(curPlayer, PlayerBeauty.EffType_HeroItemExPer)[0]
        for itemID, itemCount in beautyReturnItems:
            if not retPer:
                break
            key = (itemID, isBind)
            retCnt = max(1, int(math.ceil(itemCount * retPer / 100.0)))
            returnItemExDict[key] = returnItemExDict.get(key, 0) + retCnt
        GameWorld.DebugLog("    红颜返还: retPer=%s,%s,总%s" % (retPer, beautyReturnItems, returnItemExDict))
    # 称号特殊效果: 遣散/吞噬额外返还百分比
    titleReturnItems = qualityIpyData.GetTitleReturnItems()
    if titleReturnItems:
        isBind = ItemControler.GetIsBindValue(srcSign=ChConfig.ItemSrcSign_TitleEff)
        retPer = PlayerHJG.GetTitleEffInfo(curPlayer, PlayerHJG.TitleEff_HeroItemExPer)[0]
        for itemID, itemCount in titleReturnItems:
            if not retPer:
                break
            key = (itemID, isBind)
            retCnt = max(1, int(math.ceil(itemCount * retPer / 100.0)))
            returnItemExDict[key] = returnItemExDict.get(key, 0) + retCnt
        GameWorld.DebugLog("    称号返还: retPer=%s,%s,总%s" % (retPer, titleReturnItems, returnItemExDict))
    return
#// B4 12 战斗阵容预设保存 #tagCSHeroPresetSave
#
#struct    tagCSHeroPresetPos