From 2a659639d74889599ed54458863a2f7b31ff4eff Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 29 九月 2023 01:54:33 +0800
Subject: [PATCH] 9946 【BT0.1】【主干】仙盟BOSS修改

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py |  378 ++++++++++++++++++++++--------------------------------
 1 files changed, 154 insertions(+), 224 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py
index 717d12e..fe5a6e2 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyBoss.py
+++ b/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
\ No newline at end of file
+    return state1

--
Gitblit v1.8.0