hxp
2023-09-29 2a659639d74889599ed54458863a2f7b31ff4eff
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py
@@ -19,7 +19,7 @@
import PlayerFamilyAction
import GameWorld
import PlayerFamily
import PlayerCompensation
import ChPyNetSendPack
import NetPackCommon
import ShareDefine
@@ -29,251 +29,181 @@
import ChConfig
import time
#value1:已开启次数 value2:是否开启中(0未开启,time值-开启中,2-退出计时中)
def GetFamilyBossOpenCnt(fActionData): return fActionData.GetValue1()
def SetFamilyBossOpenCnt(fActionData, cnt): return fActionData.SetValue1(cnt)
def GetFamilyBossIsOpen(fActionData): return fActionData.GetValue2()
def SetFamilyBossIsOpen(fActionData, isOpen): return fActionData.SetValue2(isOpen)
def GetFamilyBossLimitCnt(family):
    '''仙盟BOSS每周次数限制'''
    return PlayerFamily.GetFamilySetting(family, ChConfig.Def_FamilySetting_BossFBCnt)#IpyGameDataPY.GetFuncCfg('FamilyBossOpen', 4)
def GetFamilyBossCostFood():
    '''仙盟BOSS开启消耗兽粮'''
    return IpyGameDataPY.GetFuncCfg('FamilyBossOpen', 2)
def ChekcFamilyBossOpenTime():
    '''是否在可开启活动的时间内'''
    beginTime, endTime = IpyGameDataPY.GetFuncEvalCfg('FamilyBossOpen', 3)
    curTime = GameWorld.GetServerTime()
    isAtCPing = '%02d:00:00' % endTime > str(curTime)[11:19] > '%02d:00:00' % beginTime
    return isAtCPing
## 检查家族boss副本是否开启
#  @param familyID 家族id
#  @param mapID 地图id
#  @return True-是
def CheckIsFamilyBossFBOpen(familyID, mapID):
    if familyID <= 0:
        return False
    familyBossFBOpenData = __GetFamilyBossFBActionData(familyID)
    if not familyBossFBOpenData:
        return False
    return GetFamilyBossIsOpen(familyBossFBOpenData)
## 家族boss副本OnWeek
#  @param familyID 家族id
#  @return None
def FamilyBossFBOnWeek(familyID):
    PlayerFamilyAction.ClearFamilyAction(familyID, ShareDefine.Def_ActionType_FamilyBossFB)
    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not curFamily:
        GameWorld.ErrLog("FamilyBossFBOnWeek can not find family! familyID=%s" % (familyID))
        return
    __Notify_FamilyAllMemberBossFBInfo(curFamily)
def FamilyBossFBOnWeek(curFamily):
    return
def FamilyBossFBOnDay(curFamily):
    __FamilyBossFBHurtOnDay(curFamily)
    return
## 玩家登录,通知家族副本信息
#  @param curPlayer 玩家实例
#  @return None
def OnLogin(curPlayer):
    NotifyFamilyBossFBInfo(curPlayer)
    SyncFamilyBosFBInfo(curPlayer.GetFamilyID(), None, curPlayer)
    NotifyAllFamilyBossState(curPlayer)
    return
## 开启家族boss副本
#  @param curPlayer 玩家实例
#  @param mapID 副本地图id
#  @param tick 时间
#  @return None
def OpenFamilyBossFB(curPlayer, tick):
    GameWorld.DebugLog("OpenFamilyBossFB", curPlayer.GetPlayerID())
    curFamily = curPlayer.GetFamily()
    if curFamily == None:
        GameWorld.ErrLog("    player not family!", curPlayer.GetPlayerID())
        return
    if not ChekcFamilyBossOpenTime():
        GameWorld.DebugLog("    不在活动时间内")
        return
    familyId = curFamily.GetID()
    familyBossFBData = __GetFamilyBossFBActionData(familyId)
    if not familyBossFBData:
        GameWorld.ErrLog("    can find Def_ActionType_FamilyBossFB familyId=%s"
                                                                % (familyId))
        return
    if GetFamilyBossIsOpen(familyBossFBData):
        GameWorld.DebugLog('    仙盟BOSS已开启,不能再次开启')
        return
    curWeekOpenCnt = GetFamilyBossOpenCnt(familyBossFBData)
    # 次数判断
    maxOpenCnt = GetFamilyBossLimitCnt(curFamily)
    if curWeekOpenCnt >= maxOpenCnt:
        GameWorld.Log("    本周开启次数=%s >= 最大开启次数=%s" % (curWeekOpenCnt, maxOpenCnt))
        return
    foodCost = GetFamilyBossCostFood()
    if not foodCost:
        GameWorld.ErrLog("    无法找到开启家族boss副本消耗信息 familyId=%s, foodCost=%s" % (familyId, foodCost))
        return
    # 处理消耗逻辑等
    if not __DoOpenCostLogic(curFamily, curPlayer, foodCost):
        return
    SetFamilyBossOpenCnt(familyBossFBData, curWeekOpenCnt + 1) # 增加开启次数
    SetFamilyBossIsOpen(familyBossFBData, 1)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_FamilyBossOpenCount, [familyId, curWeekOpenCnt + 1])
    # 广播给在线家族成员家族boss副本信息
    __Notify_FamilyAllMemberBossFBInfo(curFamily)
    GameWorld.Log("OpenFamilyBossFB ok familyId=%s,curWeekOpenCnt=%s!" % (familyId, curWeekOpenCnt + 1))
def OnPlayerJionFamily(curFamily, curPlayer):
    SyncFamilyBosFBInfo(curPlayer.GetFamilyID(), None, curPlayer)
    return
## 开启家族boss副本消耗逻辑
#  @param curFamily 家族实例
#  @param curPlayer 玩家实例
#  @param costInfoList 消耗信息列表
#  @param openIndex 开启次数索引
#  @return True-扣除消耗成功
def __DoOpenCostLogic(curFamily, curPlayer, foodCost):
    # 成员家族等级需求判断
    curMember = curFamily.FindMember(curPlayer.GetPlayerID())
def __FamilyBossFBHurtOnDay(curFamily):
    familyID = curFamily.GetID()
    
    if not curMember:
        GameWorld.ErrLog("家族成员查找异常 = %s" % (curPlayer.GetPlayerID()))
        return False
    if not PlayerFamily.GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanOpenBoss):
        GameWorld.DebugLog("开启仙盟BOSS->你没有权限" )
        return False
    # 家族兽粮消耗
    familyBossFood = PlayerFamily.GetFamilyBossFood(curFamily)
    if familyBossFood < foodCost:
        GameWorld.Log("    __DoOpenCostLogic 需求家族兽粮=%s,当前家族兽粮=%s"
                      % (foodCost, familyBossFood))
        return False
    # 扣除兽粮
    PlayerFamily.SetFamilyBossFood(curFamily, max(0, familyBossFood - foodCost))
    #通知客户端刷新
    curFamily.Broadcast_FamilyChange()
    #通知地图服务器刷新
    PlayerFamily.SendPack_MapServer_PlayerFamilyRefresh(curFamily)
    GameWorld.Log("    __DoOpenCostLogic 扣除家族兽粮=%s OK!, familyID=%s,playerFamilyLV=%s"
                  % (foodCost, curPlayer.GetFamilyID(), curMember.GetFamilyLV()), curPlayer.GetPlayerID())
    return True
## 获取家族boss副本开启信息
#  @param familyID 家族id
#  @param mapID 地图id
#  @return ActionData
def __GetFamilyBossFBActionData(familyID):
    #补发仙盟伤血奖励
    hurtValueTotal = 0
    memberHurtAwardStateDict = {}
    fActionType = ShareDefine.Def_ActionType_FamilyBossFB
    familyBossFBAction = GameWorld.GetFamilyActionManager().GetFamilyAction(familyID, fActionType)
    if familyBossFBAction.Count() <= 0:
        # 没有的话添加数据
        tick = GameWorld.GetGameWorld().GetTick()
        if not PlayerFamilyAction.AddFamilyActionNote("", familyID, fActionType, [], tick):
            return
    return familyBossFBAction.At(0)
def NotifyFamilyBossFBInfo(curPlayer):
    '''通知玩家仙盟BOSS副本信息'''
    familyID = curPlayer.GetFamilyID()
    if familyID:
        familyBossFBInfoPack = __GetFamilyBossFBInfoPack(familyID)
        NetPackCommon.SendFakePack(curPlayer, familyBossFBInfoPack)
    return
## 通知家族所有成员boss相关信息
#  @param curFamily 家族对象
#  @return None
def __Notify_FamilyAllMemberBossFBInfo(curFamily):
    familyID = curFamily.GetID()
    familyBossFBInfoPack = __GetFamilyBossFBInfoPack(familyID)
    for i in range(0, curFamily.GetCount()):
        notifyMember = curFamily.GetAt(i)
    for index in range(familyBossFBAction.Count()):
        actionData = familyBossFBAction.At(index)
        playerID = actionData.GetValue1()
        if playerID == 1:
            hurtValueTotal = GetFamilyBossPlayerHurtValue(actionData)
        else:
            hurtAwardStateFamily = actionData.GetValue2()
            memberHurtAwardStateDict[playerID] = hurtAwardStateFamily
            
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(notifyMember.GetPlayerID())
        if curPlayer == None:
    #GameWorld.DebugLog("__FamilyBossFBHurtOnDay hurtValueTotal=%s,memberHurtAwardStateDict=%s" % (hurtValueTotal, memberHurtAwardStateDict), familyID)
    awardIpyDataList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for ipyIndex in range(ipyDataMgr.GetFamilyBossHurtAwardCount()):
        ipyData = ipyDataMgr.GetFamilyBossHurtAwardByIndex(ipyIndex)
        if ipyData.GetAwardType() != 2:
            continue
        needHurtTotal = ipyData.GetNeedHurtTotal()
        if hurtValueTotal < needHurtTotal:
            #GameWorld.DebugLog("    仙盟伤血不足,不补发该奖励! needHurtTotal=%s" % needHurtTotal, familyID)
            continue
        awardIpyDataList.append(ipyData)
    offLineHourMax = 48
    for index in xrange(curFamily.GetCount()):
        member = curFamily.GetAt(index)
        playerID = member.GetPlayerID()
        offLineHour = GameWorld.GetPastHour(GameWorld.ChangeTimeNumToStr(member.GetExattr2())) if member.GetExattr2() > 1 else 0
        if offLineHour >= offLineHourMax:
            #GameWorld.DebugLog("    离线过久,不补发. playerID=%s,offLineHour=%s" % (playerID, offLineHour), familyID)
            continue
        
        # 发送副本开启信息
        NetPackCommon.SendFakePack(curPlayer, familyBossFBInfoPack)
        hurtAwardStateFamily = memberHurtAwardStateDict.get(playerID, 0)
        for ipyData in awardIpyDataList:
            recordIndex = ipyData.GetRecordIndex()
            if hurtAwardStateFamily & pow(2, recordIndex):
                #GameWorld.DebugLog("    已经领取过,不补发. playerID=%s,recordIndex=%s,%s" % (playerID, recordIndex, hurtAwardStateFamily), familyID)
                continue
            needHurtTotal = ipyData.GetNeedHurtTotal()
            paramList = [needHurtTotal]
            awardItemList = ipyData.GetAwardItemList()
            PlayerCompensation.SendMailByKey("FamilyBossHurtAwardFamily", [playerID], awardItemList, paramList)
            #GameWorld.DebugLog("    邮件补发伤血奖励. playerID=%s,recordIndex=%s" % (playerID, recordIndex), familyID)
            
    # 最后清除action
    PlayerFamilyAction.ClearFamilyAction(familyID, fActionType)
    SyncFamilyBosFBInfo(familyID, curFamily)
    return
## 获取家族副本boss相关信息包
#  @param familyID 家族id
#  @return tagGCFamilyBossFBInfo实例
def __GetFamilyBossFBInfoPack(familyID):
    familyBossFBInfo = ChPyNetSendPack.tagGCFamilyBossFBInfo()
    familyBossFBInfo.Clear()
    familyBossFBOpenData = __GetFamilyBossFBActionData(familyID)
    familyBossFBInfo.IsOpen = GetFamilyBossIsOpen(familyBossFBOpenData) if familyBossFBOpenData else 0
    familyBossFBInfo.OpenCnt = GetFamilyBossOpenCnt(familyBossFBOpenData) if familyBossFBOpenData else 0
    return familyBossFBInfo
## 家族boss开始、被击杀
#  @param msgList 信息列表
#  @param tick 时间
#  @return None
def FamilyBossOnKilled(msgList, tick):
    familyID, isOpen = msgList
    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
    GameWorld.Log("FamilyBossOnKilled familyID=%s" % (familyID))
def GetFamilyBossFBActionData(familyID, playerID=1):
    ## 获取仙盟boss伤血action
    # playerID  1-特殊类型,记录仙盟总伤害信息;>1-玩家仙盟伤血奖励领奖记录
    
    if not curFamily:
        GameWorld.ErrLog("OnFamilyBossKilled can not find family! familyID=%s" % (familyID))
        return
    familyBossFBData = __GetFamilyBossFBActionData(familyID)
    if not familyBossFBData:
        return
    if not GetFamilyBossIsOpen(familyBossFBData):
        GameWorld.ErrLog("    boss已经被击杀,重复击杀!不处理! familyId=%s"  % (familyID))
        return
    if isOpen == 1:
        SetFamilyBossIsOpen(familyBossFBData, int(time.time()))
    else:
        #设置FB结束
        SetFamilyBossIsOpen(familyBossFBData, isOpen)
    findActionData = None
    fActionType = ShareDefine.Def_ActionType_FamilyBossFB
    familyBossFBAction = GameWorld.GetFamilyActionManager().GetFamilyAction(familyID, fActionType)
    for index in range(familyBossFBAction.Count()):
        actionData = familyBossFBAction.At(index)
        if playerID == actionData.GetValue1():
            findActionData = actionData
            break
    if not findActionData:
        findActionData = familyBossFBAction.AddAction()
        findActionData.SetFamilyId(familyID)
        findActionData.SetActionType(fActionType)
        findActionData.SetValue1(playerID)
        
    # 广播给在线家族成员家族boss副本信息
    __Notify_FamilyAllMemberBossFBInfo(curFamily)
    return findActionData
def GetFamilyBossPlayerHurtValue(actionData):
    return actionData.GetValue3() * ChConfig.Def_PerPointValue + actionData.GetValue2()
def SetFamilyBossPlayerHurtValue(actionData, hurtValue):
    actionData.SetValue2(hurtValue % ChConfig.Def_PerPointValue)
    actionData.SetValue3(hurtValue / ChConfig.Def_PerPointValue)
    return
def MapServer_FamilyBoss(msgList, tick):
    msgType, msgData = msgList
    # 同步伤血
    if msgType == "FBMemberHurt":
        __addFBMemberHurtInfo(msgData)
        return
    # 仙盟伤血领奖  - 请求
    if msgType == "FamilyHurtAwardReq":
        familyID = msgData[0]
        actionData = GetFamilyBossFBActionData(familyID)
        hurtValueTotal = GetFamilyBossPlayerHurtValue(actionData) if actionData else 0
        return msgList + [hurtValueTotal]
    # 仙盟伤血领奖记录同步 - 用于加入仙盟时,同步到GameServer,方便统一处理补发奖励
    if msgType == "FamilyHurtAwardStateFamily":
        familyID, playerID, hurtAwardStateFamily = msgData
        actionData = GetFamilyBossFBActionData(familyID, playerID)
        actionData.SetValue2(hurtAwardStateFamily)
        return
    return
def __addFBMemberHurtInfo(msgData):
    ## 增加仙盟boss仙盟总伤血
    statsType, familyID, fightMemCount, addFamilyHurt = msgData
    curFamily = GameWorld.GetFamilyManager().FindFamily(familyID)
    if not curFamily:
        return
    actionData = GetFamilyBossFBActionData(familyID)
    if not actionData:
        return
    actionData.SetValue4(fightMemCount)
    hurtValueTotal = GetFamilyBossPlayerHurtValue(actionData) + addFamilyHurt
    SetFamilyBossPlayerHurtValue(actionData, hurtValueTotal)
    #GameWorld.DebugLog("FamilyBossFBMemberHurt statsType=%s,familyID=%s,fightMemCount=%s,addFamilyHurt=%s,hurtValueTotal=%s"
    #                   % (statsType, familyID, fightMemCount, addFamilyHurt, hurtValueTotal))
    if statsType:
        SyncFamilyBosFBInfo(familyID, curFamily)
    return
def SyncFamilyBosFBInfo(familyID, curFamily=None, curPlayer=None):
    if not familyID:
        return
    if not curFamily and not curPlayer:
        return
    actionData = GetFamilyBossFBActionData(familyID)
    if not actionData:
        return
    clientPack = ChPyNetSendPack.tagGCFamilyBosFBInfo()
    clientPack.Clear()
    clientPack.HurtTotal = actionData.GetValue2()
    clientPack.HurtTotalPoint = actionData.GetValue3()
    clientPack.FightMemCount = actionData.GetValue4()
    if curFamily:
        for i in range(0, curFamily.GetCount()):
            notifyMember = curFamily.GetAt(i)
            curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(notifyMember.GetPlayerID())
            if curPlayer == None:
                continue
            NetPackCommon.SendFakePack(curPlayer, clientPack)
        return
    if curPlayer:
        NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
#############################多仙盟BOSS#############################
@@ -321,4 +251,4 @@
#是否在仙盟BOSS活动中
def IsInAllFamilyBoss(lineID=-1):
    state1 = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyBoss1)
    return state1
    return state1