ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHero.py
@@ -42,6 +42,7 @@
    Sync_HeroInfo(curPlayer)
    Sync_PlayerHeroInfo(curPlayer)
    Sync_LineupRecommendInfo(curPlayer)
    Sync_HeroFatesInfo(curPlayer)
    return
def OnPlayerFirstLogin(curPlayer):
@@ -331,12 +332,8 @@
    quality = heroIpyData.GetQuality()
    breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
    heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
    LVMax = GetHeroLVMax(heroItem)
    GameWorld.DebugLog("请求武将升级: itemIndex=%s,heroID=%s,heroLV=%s,quality=%s,breakLV=%s,LVMax=%s"
                       % (itemIndex, heroID, heroLV, quality, breakLV, LVMax), playerID)
    if heroLV >= LVMax:
        GameWorld.DebugLog("该武将已满级!LVMax=%s" % (LVMax), playerID)
        return
    GameWorld.DebugLog("请求武将升级: itemIndex=%s,heroID=%s,heroLV=%s,quality=%s,breakLV=%s"
                       % (itemIndex, heroID, heroLV, quality, breakLV), playerID)
    qualityLVIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityLV", quality, heroLV)
    if not qualityLVIpyData:
        return
@@ -375,12 +372,10 @@
    if not heroIpyData:
        return 0
    quality = heroIpyData.GetQuality()
    breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
    qualityBreakIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, breakLV)
    if not qualityBreakIpyData:
    lvIpyDataList = IpyGameDataPY.GetIpyGameDataByCondition("HeroQualityLV", {"Quality":quality}, True)
    if not lvIpyDataList:
        return 0
    LVMax = qualityBreakIpyData.GetLVMax()
    return LVMax
    return len(lvIpyDataList)
#// B2 31 武将升星 #tagCSHeroStarUP
#
@@ -1268,13 +1263,13 @@
        qualityBreakIpyData = IpyGameDataPY.GetIpyGameData("HeroQualityBreak", quality, retBreakLV)
        if not qualityBreakIpyData:
            continue
        costItemInfo = qualityBreakIpyData.GetUPCostItem()
        if not costItemInfo:
        costItemList = qualityBreakIpyData.GetUPCostItemList()
        if not costItemList:
            continue
        costItemID, costItemCount = costItemInfo
        costItemCount = max(1, int(costItemCount * ratio / 100.0))
        returnItemDict[costItemID] = returnItemDict.get(costItemID, 0) + costItemCount
        returnDict[costItemID] = returnDict.get(costItemID, 0) + costItemCount
        for costItemID, costItemCount in costItemList:
            costItemCount = max(1, int(costItemCount * ratio / 100.0))
            returnItemDict[costItemID] = returnItemDict.get(costItemID, 0) + costItemCount
            returnDict[costItemID] = returnDict.get(costItemID, 0) + costItemCount
    GameWorld.DebugLog("    突破返还: quality=%s,breakLV=%s,ratio=%s,%s,总%s" % (quality, breakLV, ratio, returnDict, returnItemDict))
    return
@@ -1513,43 +1508,196 @@
    Sync_LineupRecommendInfo(curPlayer, [recommendID])
    return
#def RefreshLordAttr(curPlayer):
#    ## 刷新主公属性
#    CalcHeroAddAttr(curPlayer)
#    PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
#    return
def GetHeroFatesState(curPlayer, fatesID): # 宿缘ID状态: 0-未激活;1-已激活
    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroFatesInfo % fatesID)
    return info % 10
def SetHeroFatesState(curPlayer, fatesID, state):
    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroFatesInfo % fatesID)
    info = info / 10 * 10 + min(state, 9)
    info = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroFatesInfo % fatesID, info)
    return info
#def CalcHeroAddAttr(curPlayer):
#    ## 计算武将对主公增加的属性
#
#    heroBookAttrDict = {}
#    playerID = curPlayer.GetID()
#
#    ipyDataMgr = IpyGameDataPY.IPY_Data()
#    for index in range(ipyDataMgr.GetHeroCount()):
#        ipyData = ipyDataMgr.GetHeroByIndex(index)
#        heroID = ipyData.GetHeroID()
#        if not ipyData.GetPlayerCanUse():
#            continue
#        if not GetHeroBookInitState(curPlayer, heroID):
#            # 图鉴未激活
#            continue
#        quality = ipyData.GetQuality()
#        qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
#        if not qualityIpyData:
#            continue
#        #bookInitAddPer = qualityIpyData.GetBookInitAddPer()
#        #bookStarAddPer = qualityIpyData.GetBookStarAddPer()
#        #bookBreakLVAddPer = qualityIpyData.GetBookBreakLVAddPer()
#        bookStar = GetHeroBookStarLV(curPlayer, heroID)
#        bookBreakLV = GetHeroBookBreakLV(curPlayer, heroID)
#        for attrPerID in ChConfig.BaseAttrPerIDList:
#            addPer = bookInitAddPer + bookStar * bookStarAddPer + bookBreakLV * bookBreakLVAddPer
#            heroBookAttrDict[attrPerID] = heroBookAttrDict.get(attrPerID, 0) + addPer
#
#    GameWorld.DebugLog("武将图鉴属性: %s" % heroBookAttrDict, playerID)
#    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_HeroBook, heroBookAttrDict)
#    return
def GetHeroFatesLV(curPlayer, fatesID): # 宿缘ID等级
    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroFatesInfo % fatesID)
    return info / 10
def SetHeroFatesLV(curPlayer, fatesID, lv):
    info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HeroFatesInfo % fatesID)
    info = lv * 10 + info % 10
    info = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HeroFatesInfo % fatesID, info)
    return info
#// B2 41 武将宿缘 #tagCSHeroFates
#
#struct    tagCSHeroFates
#{
#    tagHead         Head;
#    BYTE        FatesID;        // 宿缘ID
#    BYTE        OPType;        // 0-激活领奖;1-升级
#    BYTE        IndexCnt;
#    WORD        ItemIndexList[IndexCnt];    // 升级时消耗的材料卡在武将背包索引列表,升级时才发
#};
def OnHeroFates(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    fatesID = clientData.FatesID
    opType = clientData.OPType
    itemIndexList = clientData.ItemIndexList
    if opType == 1:
        __onHeroFatesLVUP(curPlayer, fatesID, itemIndexList)
    else:
        __onHeroFatesActivite(curPlayer, fatesID)
    return
def __onHeroFatesActivite(curPlayer, fatesID):
    ## 宿缘激活
    if GetHeroFatesState(curPlayer, fatesID):
        GameWorld.DebugLog("宿缘组合已经激活了! fatesID=%s" % fatesID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("HeroFates", fatesID)
    if not ipyData:
        return
    heroIDList = ipyData.GetHeroIDList()
    for heroID in heroIDList:
        if not GetHeroActivite(curPlayer, heroID):
            GameWorld.DebugLog("有武将未获得过,不可激活宿缘! fatesID=%s,heroID=%s,heroIDList=%s" % (fatesID, heroID, heroIDList))
            return
    GameWorld.DebugLog("激活宿缘! fatesID=%s,heroIDList=%s" % (fatesID, heroIDList))
    SetHeroFatesState(curPlayer, fatesID, 1)
    itemList = ipyData.GetAwardItemList()
    ItemControler.GivePlayerItemOrMail(curPlayer, itemList, event=["HeroFates", False, {}])
    Sync_HeroFatesInfo(curPlayer, [fatesID])
    return
def __onHeroFatesLVUP(curPlayer, fatesID, useIndexList):
    if not GetHeroFatesState(curPlayer, fatesID):
        GameWorld.DebugLog("宿缘组合未激活! fatesID=%s" % fatesID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("HeroFates", fatesID)
    if not ipyData:
        return
    fatesQuality = ipyData.GetFatesQuality()
    heroIDList = ipyData.GetHeroIDList()
    fatesNextLV = GetHeroFatesLV(curPlayer, fatesID) + 1
    GameWorld.DebugLog("宿缘升级: fatesID=%s,fatesQuality=%s,fatesNextLV=%s,heroIDList=%s,useIndexList=%s" % (fatesID, fatesQuality, fatesNextLV, heroIDList, useIndexList))
    qualityLVIpyData = IpyGameDataPY.GetIpyGameData("HeroFatesQualityLV", fatesQuality, fatesNextLV)
    if not qualityLVIpyData:
        return
    needStarTotal = qualityLVIpyData.GetNeedStarTotal()
    needHeroCnt = qualityLVIpyData.GetNeedHeroCnt()
    costItemList = []
    heroStarDict = {}
    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for index in range(curPack.GetCount()):
        heroItem = curPack.GetAt(index)
        if not heroItem or heroItem.IsEmpty():
            continue
        heroID = heroItem.GetItemTypeID()
        # 材料卡
        if index in useIndexList:
            if __checkHeroFatesLVUPItem(olPlayer, fatesQuality, index, heroItem, heroID):
                costItemList.append(heroItem)
        if heroID not in heroIDList:
            continue
        if heroID not in heroStarDict:
            heroStarDict[heroID] = 0
        star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
        if star <= heroStarDict[heroID]:
            continue
        heroStarDict[heroID] = star
    nowStarTotal = sum(heroStarDict.values())
    if nowStarTotal < needStarTotal:
        GameWorld.DebugLog("    当前总星级不足: nowStarTotal=%s < %s, heroStarDict=%s" % (nowStarTotal, needStarTotal, heroStarDict))
        return
    GameWorld.DebugLog("    当前总星级: nowStarTotal=%s,needStarTotal=%s,heroStarDict=%s" % (nowStarTotal, needStarTotal, heroStarDict))
    if len(costItemList) < needHeroCnt:
        GameWorld.DebugLog("    可用材料卡不足: %s < %s" % (len(costItemList), needHeroCnt))
        return
    GameWorld.DebugLog("    宿缘升级! needHeroCnt=%s" % needHeroCnt)
    for heroItem in costItemList[:needHeroCnt]:
        ItemCommon.DelItem(curPlayer, heroItem, heroItem.GetCount(), False, "HeroFatesLVUP")
    SetHeroFatesLV(curPlayer, fatesID, fatesNextLV)
    Sync_HeroFatesInfo(curPlayer, [fatesID])
    RefreshLordAttr(curPlayer) # 宿缘
    return
def __checkHeroFatesLVUPItem(olPlayer, fatesQuality, 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))
        return
    #未生效、未上阵、未锁定、未进行过升级、突破、升星、觉醒
    heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
    breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
    starLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
    awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
    if heroLV > 1 or breakLV or starLV or awakeLV:
        GameWorld.DebugLog("    升级突破升星觉醒过的武将无法使用! itemIndex=%s,heroLV=%s,breakLV=%s,starLV=%s,awakeLV=%s" % (itemIndex, heroLV, breakLV, starLV, awakeLV))
        return
    if heroItem.GetIsLocked():
        GameWorld.DebugLog("    锁定的武将无法使用! itemIndex=%s" % (itemIndex))
        return
    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))
        return
    heroID = heroItem.GetItemTypeID()
    _, effItemIndex, _ = olPlayer.GetHeroEffectiveCard(heroID)
    if itemIndex == effItemIndex:
        GameWorld.DebugLog("    生效中的卡牌无法使用! itemIndex=%s,heroID=%s,effItemIndex=%s" % (itemIndex, heroID, effItemIndex))
        return
    return True
def RefreshLordAttr(curPlayer):
    ## 刷新主公属性
    CalcHeroAddAttr(curPlayer)
    PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
    return
def CalcHeroAddAttr(curPlayer):
    ## 计算武将对主公增加的属性
    fatesAttrDict = {}
    playerID = curPlayer.GetID()
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetHeroFatesCount()):
        ipyData = ipyDataMgr.GetHeroFatesByIndex(index)
        fatesID = ipyData.GetFatesID()
        if not GetHeroFatesState(curPlayer, fatesID):
            continue
        fatesLV = GetHeroFatesLV(curPlayer, fatesID)
        if fatesLV <= 0:
            continue
        attrIDList = ipyData.GetAttrIDList()
        lvAttrValueList = ipyData.GetLVAttrValueList()
        for i in range(min(len(attrIDList), len(lvAttrValueList))):
            attrID = attrIDList[i]
            attrValuePerLV = lvAttrValueList[i]
            attrValue = attrValuePerLV * fatesLV
            fatesAttrDict[attrID] = fatesAttrDict.get(attrID, 0) + attrValue
    GameWorld.DebugLog("宿缘属性: %s" % fatesAttrDict, playerID)
    PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_HeroFates, fatesAttrDict)
    return
def Sync_HeroInfo(curPlayer, heroIDList=None):
    if heroIDList != None:
@@ -1663,3 +1811,31 @@
    clientPack.Count = len(clientPack.RecommendList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_HeroFatesInfo(curPlayer, syncIDList=None):
    fatesList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetHeroFatesCount()):
        ipyData = ipyDataMgr.GetHeroFatesByIndex(index)
        fatesID = ipyData.GetFatesID()
        state = GetHeroFatesState(curPlayer, fatesID)
        if syncIDList != None:
            if fatesID not in syncIDList:
                continue
        elif not state:
            continue
        fates = ChPyNetSendPack.tagSCHeroFates()
        fates.FatesID = fatesID
        fates.State = state
        fates.FatesLV = GetHeroFatesLV(curPlayer, fatesID)
        fatesList.append(fates)
    if not fatesList:
        return
    clientPack = ChPyNetSendPack.tagSCHeroFatesInfo()
    clientPack.FatesList = fatesList
    clientPack.Count = len(clientPack.FatesList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return