hxp
2026-01-21 3c9851cf6305114c7107136d2acb09f1a033f49a
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -26,6 +26,7 @@
import NetPackCommon
import PlayerControl
import PlayerOnline
import PlayerPreset
import PlayerTask
import GameWorld
import ChConfig
@@ -93,10 +94,10 @@
        return
    GameWorld.DebugLog("初始化新手武将: %s" % defaultHeroInfo, curPlayer.GetPlayerID())
    
    lineupID = ShareDefine.Lineup_Main
    presetID = 1 # 默认预设1
    shapeType = 0
    for heroID, posNum in defaultHeroInfo.items():
        lineupValue = ComLineupValue(lineupID, shapeType, posNum)
        lineupValue = ComLineupValue(presetID, shapeType, posNum)
        setAttrDict = {ShareDefine.Def_IudetHeroLineup:[lineupValue]}
        ItemControler.GivePlayerItem(curPlayer, heroID, 1, False, [ShareDefine.rptHero], setAttrDict=setAttrDict)
        
@@ -289,28 +290,16 @@
        return
    return heroItem
def GetHeroLineupPosNum(heroItem, lineupID=ShareDefine.Lineup_Main):
    ## 获取英雄所在阵型站位
    # @param lineupID: 阵型ID,默认主阵型
    # @return: 0-没有在该阵型;>0-在该阵型中的站位编号
    lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
    if not lineupCount:
        return 0
    for lpIndex in range(lineupCount)[::-1]:
        lineupValue = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
        lpID, _, posNum = GetLineupValue(lineupValue)
        if lpID != lineupID:
            continue
        return posNum
    return 0
def InMainLineup(heroItem):
    ## 是否在主阵容中
    for lpIndex in range(heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)):
        lineupValue = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
        if GetLineupValue(lineupValue)[0] == ShareDefine.Lineup_Main:
            return True
    return False
def GetHeroEffPresetIDList(heroItem):
    ## 获取英雄有生效的预设ID列表
    dataCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroEffPresetID)
    if not dataCount:
        return []
    effPresetIDList = []
    for lpIndex in range(dataCount):
        presetID = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroEffPresetID, lpIndex)
        effPresetIDList.append(presetID)
    return effPresetIDList
#// B2 30 武将升级 #tagCSHeroLVUP
#
@@ -1197,10 +1186,16 @@
#{
#    tagHead        Head;
#    WORD        ItemIndex;    //武将物品所在武将背包位置索引
#    BYTE        LVReset;        //重置等级
#    BYTE        BreakReset;    //重置突破
#    BYTE        AwakeReset;    //重置觉醒
#};
def OnHeroRebirth(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    itemIndex = clientData.ItemIndex
    lvReset =  clientData.LVReset
    breakReset = clientData.BreakReset or lvReset # 突破受等级限制,所以等级重置突破必重置
    awakeReset = clientData.AwakeReset
    heroItem = GetHeroItem(curPlayer, itemIndex)
    if not heroItem:
        return
@@ -1211,7 +1206,7 @@
        GameWorld.DebugLog("该武将未进行过等级突破觉醒培养,不需要重生! itemIndex=%s" % (itemIndex))
        return
    
    if awakeLV:
    if awakeReset and awakeLV:
        rebirthCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt)
        rebirthCntMax = IpyGameDataPY.GetFuncCfg("HeroRebirth", 2)
        if rebirthCntMax and rebirthCnt >= rebirthCntMax:
@@ -1223,38 +1218,55 @@
    if not heroIpyData:
        return
    quality = heroIpyData.GetQuality()
    qualityAwakeIpyData = IpyGameDataPY.GetIpyGameDataNotLog("HeroQualityAwake", quality, awakeLV)
    awakeCostMoney = qualityAwakeIpyData.GetRebirthCostMoney() if qualityAwakeIpyData else 0
    lvCostMoney = 0
    breakCostMoney = 0
    awakeCostMoney = 0
    moneyType = IpyGameDataPY.GetFuncCfg("HeroRebirth", 1)
    lvCostMoney = int(eval(IpyGameDataPY.GetFuncCompileCfg("HeroRebirth", 3)))
    costMoneyTotal = lvCostMoney + awakeCostMoney
    GameWorld.DebugLog("武将重生: itemIndex=%s,heroID=%s,quality=%s,heroLV=%s,breakLV=%s,awakeLV=%s,costMoneyTotal=%s(%s+%s)"
                       % (itemIndex, heroID, quality, heroLV, breakLV, awakeLV, costMoneyTotal, lvCostMoney, awakeCostMoney))
    if awakeReset and awakeLV:
        qualityAwakeIpyData = IpyGameDataPY.GetIpyGameDataNotLog("HeroQualityAwake", quality, awakeLV)
        awakeCostMoney = qualityAwakeIpyData.GetRebirthCostMoney() if qualityAwakeIpyData else 0
    if lvReset:
        lvCostMoney = int(max(0, eval(IpyGameDataPY.GetFuncCompileCfg("HeroRebirth", 3))))
    if breakReset:
        breakCostMoney = int(max(0, eval(IpyGameDataPY.GetFuncCompileCfg("HeroRebirth2", 1))))
    costMoneyTotal = lvCostMoney + awakeCostMoney + breakCostMoney
    GameWorld.DebugLog("武将重生: itemIndex=%s,heroID=%s,quality=%s,heroLV=%s,breakLV=%s,awakeLV=%s,costMoneyTotal=%s(lv:%s+b:%s+a:%s),lvReset=%s,breakReset=%s,awakeReset=%s"
                       % (itemIndex, heroID, quality, heroLV, breakLV, awakeLV, costMoneyTotal, lvCostMoney, breakCostMoney, awakeCostMoney, lvReset, breakReset, awakeReset))
    if moneyType and costMoneyTotal and not PlayerControl.HaveMoney(curPlayer, moneyType, costMoneyTotal):
        return
    
    # 验证通过,可以重生
    ratio = IpyGameDataPY.GetFuncCfg("HeroRebirth", 4)
    returnItemDict = {}
    __calcHeroLVReturnitem(quality, heroLV, returnItemDict, ratio)
    __calcHeroBreakReturnitem(quality, breakLV, returnItemDict, ratio)
    __calcHeroAwakeReturnitem(quality, awakeLV, returnItemDict, ratio)
    if lvReset:
        __calcHeroLVReturnitem(quality, heroLV, returnItemDict, ratio)
    if breakReset:
        __calcHeroBreakReturnitem(quality, breakLV, returnItemDict, ratio)
    if awakeReset:
        __calcHeroAwakeReturnitem(quality, awakeLV, returnItemDict, ratio)
    if moneyType and costMoneyTotal and not PlayerControl.PayMoney(curPlayer, moneyType, costMoneyTotal, "HeroRebirth"):
        return
    
    # 执行重生
    item = heroItem.GetItem()
    item.SetUserAttr(ShareDefine.Def_IudetHeroLV, 1)
    item.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, 0)
    item.SetUserAttr(ShareDefine.Def_IudetHeroAwakeLV, 0)
    if lvReset:
        item.SetUserAttr(ShareDefine.Def_IudetHeroLV, 1)
    if breakReset:
        item.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, 0)
    if awakeReset:
        item.SetUserAttr(ShareDefine.Def_IudetHeroAwakeLV, 0)
    heroItem.Sync_Item()
    
    if returnItemDict:
        returnItemList = [[k, v] for k, v in returnItemDict.items()]
        ItemControler.GivePlayerItemOrMail(curPlayer, returnItemList, event=["HeroRebirth", False, {}])
        
    if awakeLV:
    if awakeReset and awakeLV:
        rebirthCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroAwakeRebirthCnt, rebirthCnt + 1)
        Sync_PlayerHeroInfo(curPlayer)
@@ -1329,7 +1341,6 @@
    ratio = IpyGameDataPY.GetFuncCfg("HeroRebirth", 5)
    dismissItemList = []
    returnItemDict = {}
    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for itemIndex in itemIndexList:
        if itemIndex < 0 or itemIndex >= curPack.GetCount():
@@ -1350,9 +1361,9 @@
            GameWorld.DebugLog("上阵中的武将无法遣散! itemIndex=%s,lineupValueList=%s" % (itemIndex, lineupValueList))
            continue
        heroID = heroItem.GetItemTypeID()
        _, effItemIndex, _ = olPlayer.GetHeroEffectiveCard(heroID)
        if itemIndex == effItemIndex:
            GameWorld.DebugLog("生效中的卡牌无法遣散! itemIndex=%s,heroID=%s,effItemIndex=%s" % (itemIndex, heroID, effItemIndex))
        effPresetIDList = GetHeroEffPresetIDList(heroItem)
        if effPresetIDList:
            GameWorld.DebugLog("生效中的卡牌无法遣散! itemIndex=%s,heroID=%s,effPresetIDList=%s" % (itemIndex, heroID, effPresetIDList))
            continue
        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
        if not heroIpyData:
@@ -1386,26 +1397,25 @@
        
    return
#// B4 12 战斗阵容保存 #tagCSHeroLineupSave
#// B4 12 战斗阵容预设保存 #tagCSHeroPresetSave
#
#struct    tagCSHeroLineupPos
#struct    tagCSHeroPresetPos
#{
#    WORD        ItemIndex;    //武将物品所在武将背包位置索引
#    BYTE        PosNum;        //1~n上阵位置编号  
#};
#
#struct    tagCSHeroLineupSave
#struct    tagCSHeroPresetSave
#{
#    tagHead        Head;
#    BYTE        LineupID;        //阵容ID:1-主阵容;其他待扩展,如某个防守阵容
#    BYTE        ShapeType;    //本阵容阵型,0为默认阵型,可扩展不同的阵型
#    BYTE        PresetID;        //阵容方案预设ID
#    BYTE        PosCnt;
#    tagCSHeroLineupPos    HeroPosList[PosCnt];    // 保存的阵容,只发送最终的阵容武将位置即可
#    tagCSHeroPresetPos    HeroPosList[PosCnt];    // 保存的阵容,只发送最终的阵容武将位置即可
#};
def OnHeroLineupSave(index, clientData, tick):
def OnHeroPresetSave(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    lineupID = clientData.LineupID
    shapeType = clientData.ShapeType
    presetID = clientData.PresetID
    shapeType = 0#clientData.ShapeType
    heroPosList = clientData.HeroPosList
    
    heroPosDict = {}
@@ -1419,11 +1429,11 @@
        indexList.append(itemIndex)
        heroPosDict[posNum] = itemIndex
        
    if lineupID not in ShareDefine.LineupList:
        GameWorld.DebugLog("不存在该阵容,无法保存! lineupID=%s" % lineupID)
    if not PlayerPreset.GetFuncPresetIDState(curPlayer, presetID, ShareDefine.FuncPreset_Hero):
        GameWorld.DebugLog("该武将阵容预设不可用! presetID=%s" % presetID)
        return
    
    GameWorld.DebugLog("保存阵容: lineupID=%s, %s" % (lineupID, heroPosDict), curPlayer.GetPlayerID())
    GameWorld.DebugLog("保存武将预设阵容: presetID=%s, %s" % (presetID, heroPosDict), curPlayer.GetPlayerID())
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    # 直接重置旧阵型
    delCount = 0
@@ -1438,7 +1448,7 @@
        item = heroItem.GetItem()
        for lpIndex in range(lineupCount)[::-1]:
            lineupValue = item.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
            if GetLineupValue(lineupValue)[0] != lineupID:
            if GetLineupValue(lineupValue)[0] != presetID:
                continue
            item.DelUserAttr(ShareDefine.Def_IudetHeroLineup, lineupValue)
            delCount += 1
@@ -1461,26 +1471,17 @@
            continue
        heroIDList.append(itemID)
        item = heroItem.GetItem()
        lineupValue = ComLineupValue(lineupID, shapeType, posNum)
        lineupValue = ComLineupValue(presetID, shapeType, posNum)
        item.AddUserAttr(ShareDefine.Def_IudetHeroLineup, lineupValue)
        if itemIndex not in syncItemDict:
            syncItemDict[itemIndex] = heroItem
        heroItemDict[itemIndex] = posNum
        
    # 主阵容修改时重整背包,约定所有背包由前端自行排序
    #if lineupID == ShareDefine.Lineup_Main:
    #    ResetHeroPack(curPlayer)
    #else:
    # 约定所有背包由前端自行排序
    for syncItem in syncItemDict.values():
        syncItem.Sync_Item()
        
    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
    lineup = olPlayer.GetLineup(lineupID, False)
    lineup.UpdLineup(heroItemDict, shapeType)
    # 主阵容调整,重载生效的卡牌
    if lineupID == ShareDefine.Lineup_Main:
        PlayerOnline.reloadEffHeroCard(curPlayer, olPlayer)
    PlayerOnline.GetOnlinePlayer(curPlayer).UpdHeroItemPreset(presetID, heroItemDict, shapeType)
    return
def ComLineupValue(lineupID, shapeType, posNum): return lineupID * 10000 + shapeType * 100 + posNum
@@ -1607,6 +1608,7 @@
        return
    needStarTotal = qualityLVIpyData.GetNeedStarTotal()
    needHeroCnt = qualityLVIpyData.GetNeedHeroCnt()
    needQuality = qualityLVIpyData.GetNeedQuality()
    
    costItemList = []
    heroStarDict = {}
@@ -1620,7 +1622,7 @@
        
        # 材料卡
        if index in useIndexList:
            if __checkHeroFatesLVUPItem(olPlayer, fatesQuality, index, heroItem, heroID):
            if __checkHeroFatesLVUPItem(olPlayer, needQuality, index, heroItem, heroID):
                costItemList.append(heroItem)
                
        if heroID not in heroIDList:
@@ -1651,15 +1653,15 @@
    RefreshLordAttr(curPlayer) # 宿缘
    return
def __checkHeroFatesLVUPItem(olPlayer, fatesQuality, itemIndex, heroItem, heroID):
def __checkHeroFatesLVUPItem(olPlayer, needQuality, itemIndex, heroItem, heroID):
    ## 检查宿缘材料卡可否使用
    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
    if not heroIpyData:
        return
    
    quality = heroIpyData.GetQuality()
    if quality != fatesQuality:
        GameWorld.DebugLog("    与宿缘品质不同的卡无法使用: itemIndex=%s,heroID=%s,quality=%s != %s" % (itemIndex, heroID, quality, fatesQuality))
    if quality != needQuality:
        GameWorld.DebugLog("    与宿缘所需品质不同的卡无法使用: itemIndex=%s,heroID=%s,quality=%s != %s" % (itemIndex, heroID, quality, needQuality))
        return
    
    #未生效、未上阵、未锁定、未进行过升级、突破、升星、觉醒
@@ -1682,9 +1684,9 @@
        return
    
    heroID = heroItem.GetItemTypeID()
    _, effItemIndex, _ = olPlayer.GetHeroEffectiveCard(heroID)
    if itemIndex == effItemIndex:
        GameWorld.DebugLog("    生效中的卡牌无法使用! itemIndex=%s,heroID=%s,effItemIndex=%s" % (itemIndex, heroID, effItemIndex))
    effPresetIDList = GetHeroEffPresetIDList(heroItem)
    if effPresetIDList:
        GameWorld.DebugLog("    生效中的卡牌无法使用! itemIndex=%s,heroID=%s,effPresetIDList=%s" % (itemIndex, heroID, effPresetIDList))
        return
    
    return True
@@ -1765,39 +1767,39 @@
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_Lineup(curPlayer, lineupID=None):
    if lineupID:
        syncIDList = [lineupID]
    else:
        syncIDList = ShareDefine.LineupList
    lineupList = []
def Sync_HeroPreset(curPlayer, heroPresetID=None):
    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
    for lineupID in syncIDList:
        lineup = olPlayer.GetLineup(lineupID, False)
        if not lineup:
    if heroPresetID:
        syncIDList = [heroPresetID]
    else:
        syncIDList = olPlayer.GetHeroPresetIDList()
    presetList = []
    for heroPresetID in syncIDList:
        heroPreset = olPlayer.GetHeroPreset(heroPresetID)
        if not heroPreset:
            continue
        
        posNumItemIndexDict = {v:k for k, v in lineup.heroItemDict.items()}
        posNumItemIndexDict = {v:k for k, v in heroPreset.heroItemDict.items()}
        heroItemIndexList = [] # 所在武将背包索引+1列表 [站位1物品索引+1, 站位2, ...],站位无武将时为0
        for posNum in range(1, 1 + ShareDefine.LineupObjMax):
            if posNum in posNumItemIndexDict:
                heroItemIndexList.append(posNumItemIndexDict[posNum] + 1)
            else:
                heroItemIndexList.append(0)
        packLineup = ChPyNetSendPack.tagSCLineup()
        packLineup.LineupID = lineup.lineupID
        packLineup.ShapeType = lineup.shapeType
        packLineup.HeroItemIndexList = heroItemIndexList
        packLineup.HeroCnt = len(packLineup.HeroItemIndexList)
        lineupList.append(packLineup)
        preset = ChPyNetSendPack.tagSCHeroPreset()
        preset.PresetID = heroPresetID
        #preset.ShapeType = heroPreset.shapeType
        preset.HeroItemIndexList = heroItemIndexList
        preset.HeroCnt = len(preset.HeroItemIndexList)
        presetList.append(preset)
        
    if not lineupList:
    if not presetList:
        return
    
    clientPack = ChPyNetSendPack.tagSCLineupInfo()
    clientPack.LineupList = lineupList
    clientPack.LineupCnt = len(clientPack.LineupList)
    clientPack = ChPyNetSendPack.tagSCHeroPresetInfo()
    clientPack.PresetList = presetList
    clientPack.PresetCnt = len(clientPack.PresetList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return