ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -29,9 +29,15 @@
import random
    
def PlayerOnDay(curPlayer):
    if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt):
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroAwakeRebirthCnt, 0)
        Sync_PlayerHeroInfo(curPlayer)
    return
    
def OnPlayerLogin(curPlayer):
    Sync_HeroInfo(curPlayer)
    Sync_PlayerHeroInfo(curPlayer)
    return
def OnPlayerFirstLogin(curPlayer):
@@ -548,11 +554,16 @@
    if not heroIpyData:
        return
    quality = heroIpyData.GetQuality()
    heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
    breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
    GameWorld.DebugLog("请求武将突破: itemIndex=%s,heroID=%s,quality=%s,breakLV=%s"
                       % (itemIndex, heroID, quality, breakLV), playerID)
    GameWorld.DebugLog("请求武将突破: itemIndex=%s,heroID=%s,quality=%s,heroLV=%s,breakLV=%s"
                       % (itemIndex, heroID, quality, heroLV, breakLV), playerID)
    ipyData = IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, breakLV)
    if not ipyData:
        return
    LVMax = ipyData.GetLVMax()
    if heroLV < LVMax:
        GameWorld.DebugLog("未满级,无法突破: heroLV=%s < %s" % (heroLV, LVMax), playerID)
        return
    nextBreakLV = breakLV + 1
    if not IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, nextBreakLV):
@@ -1079,6 +1090,191 @@
    heroItem.SetIsLocked(1 if isLock else 0)
    return
#// B2 39 武将重生 #tagCSHeroRebirth
#
#struct    tagCSHeroRebirth
#{
#    tagHead        Head;
#    WORD        ItemIndex;    //武将物品所在武将背包位置索引
#};
def OnHeroRebirth(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    itemIndex = clientData.ItemIndex
    heroItem = GetHeroItem(curPlayer, itemIndex)
    if not heroItem:
        return
    heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
    breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
    awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
    if heroLV <= 1 and not breakLV and not awakeLV:
        GameWorld.DebugLog("该武将未进行过等级突破觉醒培养,不需要重生! itemIndex=%s" % (itemIndex))
        return
    if awakeLV:
        rebirthCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt)
        rebirthCntMax = IpyGameDataPY.GetFuncCfg("HeroRebirth", 2)
        if rebirthCntMax and rebirthCnt >= rebirthCntMax:
            GameWorld.DebugLog("今日觉醒过的武将重生次数已达上限! rebirthCnt=%s >= %s" % (rebirthCnt, rebirthCntMax))
            return
    heroID = heroItem.GetItemTypeID()
    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
    if not heroIpyData:
        return
    quality = heroIpyData.GetQuality()
    ipyData = IpyGameDataPY.GetIpyGameData("HeroQualityAwake", quality, awakeLV)
    if not ipyData:
        return
    costMoney = ipyData.GetRebirthCostMoney()
    moneyType = IpyGameDataPY.GetFuncCfg("HeroRebirth", 1)
    if moneyType and costMoney and not PlayerControl.HaveMoney(curPlayer, moneyType, costMoney):
        return
    # 验证通过,可以重生
    GameWorld.DebugLog("武将重生: itemIndex=%s,heroID=%s,quality=%s,heroLV=%s,breakLV=%s,awakeLV=%s"
                       % (itemIndex, heroID, quality, heroLV, breakLV, awakeLV))
    returnItemDict = {}
    __calcHeroLVReturnitem(quality, heroLV, returnItemDict)
    __calcHeroBreakReturnitem(quality, breakLV, returnItemDict)
    __calcHeroAwakeReturnitem(quality, awakeLV, returnItemDict)
    if moneyType and costMoney and not PlayerControl.PayMoney(curPlayer, moneyType, costMoney, "HeroRebirth"):
        return
    # 执行重生
    item = heroItem.GetItem()
    item.SetUserAttr(ShareDefine.Def_IudetHeroLV, 1)
    item.SetUserAttr(ShareDefine.Def_IudetHeroBreakLV, 0)
    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:
        rebirthCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroAwakeRebirthCnt, rebirthCnt + 1)
        Sync_PlayerHeroInfo(curPlayer)
    return
def __calcHeroLVReturnitem(quality, heroLV, returnItemDict):
    ## 计算武将等级返还
    returnDict = {}
    for retLV in range(1, heroLV):
        qualityLVIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityLV", quality, retLV)
        if not qualityLVIpyData:
            continue
        costItemInfo = qualityLVIpyData.GetUPCostItem()
        if not costItemInfo:
            continue
        costItemID, costItemCount = costItemInfo
        returnItemDict[costItemID] = returnItemDict.get(costItemID, 0) + costItemCount
        returnDict[costItemID] = returnDict.get(costItemID, 0) + costItemCount
    GameWorld.DebugLog("    等级返还: quality=%s,heroLV=%s,%s,总%s" % (quality, heroLV, returnDict, returnItemDict))
    return
def __calcHeroBreakReturnitem(quality, breakLV, returnItemDict):
    # 计算武将突破返还
    returnDict = {}
    for retBreakLV in range(0, breakLV):
        qualityBreakIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, retBreakLV)
        if not qualityBreakIpyData:
            continue
        costItemInfo = qualityBreakIpyData.GetUPCostItem()
        if not costItemInfo:
            continue
        costItemID, costItemCount = costItemInfo
        returnItemDict[costItemID] = returnItemDict.get(costItemID, 0) + costItemCount
        returnDict[costItemID] = returnDict.get(costItemID, 0) + costItemCount
    GameWorld.DebugLog("    突破返还: quality=%s,breakLV=%s,%s,总%s" % (quality, breakLV, returnDict, returnItemDict))
    return
def __calcHeroAwakeReturnitem(quality, awakeLV, returnItemDict):
    # 计算武将觉醒返还
    returnDict = {}
    for retAwakeLV in range(0, awakeLV):
        qualityAwakeIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityAwake", quality, retAwakeLV)
        if not qualityAwakeIpyData:
            continue
        costItemInfo = qualityAwakeIpyData.GetUPCostItem()
        if not costItemInfo:
            continue
        costItemID, costItemCount = costItemInfo
        returnItemDict[costItemID] = returnItemDict.get(costItemID, 0) + costItemCount
        returnDict[costItemID] = returnDict.get(costItemID, 0) + costItemCount
    GameWorld.DebugLog("    觉醒返还: quality=%s,awakeLV=%s,%s,总%s" % (quality, awakeLV, returnDict, returnItemDict))
    return
#// B2 40 武将遣散 #tagCSHeroDismiss
#
#struct    tagCSHeroDismiss
#{
#    tagHead         Head;
#    WORD        Count;
#    WORD        ItemIndexList[Count];    // 武将物品所在武将背包位置索引列表
#};
def OnHeroDismiss(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    itemIndexList = clientData.ItemIndexList
    GameWorld.DebugLog("武将遣散: itemIndexList=%s" % itemIndexList)
    dismissItemList = []
    returnItemDict = {}
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for itemIndex in itemIndexList:
        if itemIndex < 0 or itemIndex >= curPack.GetCount():
            continue
        heroItem = curPack.GetAt(itemIndex)
        if not heroItem or heroItem.IsEmpty():
            continue
        awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
        if awakeLV:
            GameWorld.DebugLog("觉醒过的武将需先重生后才可遣散! itemIndex=%s,awakeLV=%s" % (itemIndex, awakeLV))
            continue
        if heroItem.GetIsLocked():
            GameWorld.DebugLog("锁定的武将无法遣散! itemIndex=%s" % (itemIndex))
            continue
        lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
        if lineupCount:
            lineupValueList = [heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex) for lpIndex in range(lineupCount)]
            GameWorld.DebugLog("上阵中的武将无法遣散! itemIndex=%s,lineupValueList=%s" % (itemIndex, lineupValueList))
            continue
        heroID = heroItem.GetItemTypeID()
        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
        if not heroIpyData:
            continue
        quality = heroIpyData.GetQuality()
        heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
        breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
        heroStar = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
        qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
        if not qualityIpyData:
            continue
        GameWorld.DebugLog("Dzɢ: itemIndex=%s,heroID=%s,quality=%s,heroLV=%s,breakLV=%s,heroStar=%s" % (itemIndex, heroID, quality, heroLV, breakLV, heroStar))
        dismissReturnItems = qualityIpyData.GetDismissReturnItems()
        for itemID, itemCount in dismissReturnItems:
            starRetCnt = (heroStar + 1) * itemCount
            returnItemDict[itemID] = returnItemDict.get(itemID, 0) + starRetCnt
        GameWorld.DebugLog("    星级返还: quality=%s,heroStar=%s,%s,总%s" % (quality, heroStar, dismissReturnItems, returnItemDict))
        __calcHeroLVReturnitem(quality, heroLV, returnItemDict)
        __calcHeroBreakReturnitem(quality, breakLV, returnItemDict)
        dismissItemList.append([itemIndex, heroItem])
    if not dismissItemList:
        return
    for itemIndex, heroItem in dismissItemList:
        ItemCommon.DelItem(curPlayer, heroItem, heroItem.GetCount(), False, "HeroDismiss")
    if returnItemDict:
        returnItemList = [[k, v] for k, v in returnItemDict.items()]
        ItemControler.GivePlayerItemOrMail(curPlayer, returnItemList, event=["HeroDismiss", False, {}])
    return
#// B4 12 战斗阵容保存 #tagCSHeroLineupSave
#
#struct    tagCSHeroLineupPos
@@ -1220,15 +1416,6 @@
    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_HeroBook, heroBookAttrDict)
    return
def RefreshLineupHeroAttr(curPlayer):
    ## 刷新阵容武将属性
    # 计算阵容总战力 = 角色总战力为主阵容战力,需同步计算不同阵容战力
    return
def CaclHeroCardAttr():
    return
def Sync_HeroInfo(curPlayer, heroIDList=None):
    if heroIDList != None:
        syncHeroIDList = heroIDList
@@ -1266,3 +1453,46 @@
    clientPack.HeroCnt = len(clientPack.HeroInfoList)    
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_Lineup(curPlayer, lineupID=None):
    if lineupID:
        syncIDList = [lineupID]
    else:
        syncIDList = ShareDefine.LineupList
    lineupList = []
    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
    for lineupID in syncIDList:
        lineup = olPlayer.GetLineup(lineupID)
        if not lineup:
            continue
        posNumItemIndexDict = {v:k for k, v in lineup.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)
    if not lineupList:
        return
    clientPack = ChPyNetSendPack.tagSCLineupInfo()
    clientPack.LineupList = lineupList
    clientPack.LineupCnt = len(clientPack.LineupList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_PlayerHeroInfo(curPlayer):
    ## 武将公共信息
    clientPack = ChPyNetSendPack.tagSCPlayerHeroInfo()
    clientPack.AwakeRebirthCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroAwakeRebirthCnt)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return