hxp
2019-10-29 2941a7635bb04ca59afa820b51a23aca9dc70eb9
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py
@@ -39,6 +39,7 @@
import PlayerCompensation
import IpyGameDataPY
import PyGameDataStruct
import CrossRealmPlayer
import PyDataManager
import PlayerControl
import CrossRealmMsg
@@ -46,13 +47,21 @@
import PyGameData
import PlayerGeTui
import IPY_GameServer
import PlayerTeam
import CrossBoss
import PlayerFB
import time
''' boss首杀
ShareDefine.Def_UniversalGameRecType_BossFirstKill
value1:bossID
StrValue2:killedTimeStr
StrValue3:playerName,playerName,...
'''
''' boss击杀信息
ShareDefine.Def_UniversalGameRecType_BossInfo
value1:bossID
value2:killedTime
@@ -103,12 +112,12 @@
    if bossID <= 0:
        return
    
    bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID = msgList
    bossID, killPlayerName, hurtValue, isNotify, mapID, realMapID, copyMapID, killerIDList = msgList
    mapID = PlayerFB.GetRecordMapID(mapID)
    if GameWorld.IsCrossServer():
        CrossBoss.DoCrossBossOnKilled(bossID, killPlayerName, realMapID, dataMapID, copyMapID)
        CrossBoss.DoCrossBossOnKilled(bossID, killPlayerName, mapID, realMapID, copyMapID, killerIDList)
        return
    
    mapID = dataMapID
    isAddKillCnt = False
    
    isMapNeedShunt = IsMapNeedBossShunt(mapID)
@@ -140,6 +149,9 @@
    horsePetRobBossIDList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBossID", 1)
    if bossID in horsePetRobBossIDList:
        OnFamilyKillHorsePetRobBoss(killPlayerName)
    # boss首杀
    OnBossFirstKill(bossID, killerIDList)
    return
def __UpdateBossRefreshList(bossID, killedTime=0, refreshTime=0):
@@ -159,13 +171,14 @@
    ## 世界boss状态变更
    if len(msgList) <= 0:
        return
    bossID, isAlive, dataMapID, realMapID, copyMapID = msgList
    bossID, isAlive, mapID, realMapID, copyMapID = msgList
    mapID = PlayerFB.GetRecordMapID(mapID)
    if GameWorld.IsCrossServer():
        CrossBoss.DoCrossBossStateChange(bossID, isAlive, dataMapID, realMapID, copyMapID)
        CrossBoss.DoCrossBossStateChange(bossID, isAlive, mapID, realMapID, copyMapID)
        return
    
    mapID, lineID = dataMapID, copyMapID
    lineID = copyMapID
    GameWorld.Log("世界boss状态变更: mapID=%s,lineID=%s,bossID=%s,state=%s,tick=%s" % (mapID, lineID, bossID, isAlive, tick))
    
    if bossID <= 0:
@@ -322,7 +335,19 @@
def OnQueryBossInfo(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    bossIDList = clientData.BossIDList
    Sync_BossInfo(curPlayer, bossIDList)
    if not bossIDList:
        Sync_BossInfo(curPlayer)
        CrossBoss.Sync_CrossBossInfo(curPlayer)
        return
    bossID = bossIDList[0]
    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossID)
    if not ipyData:
        return
    mapID = ipyData.GetMapID()
    if mapID in ChConfig.Def_CrossMapIDList:
        CrossBoss.Sync_CrossBossInfo(curPlayer, bossIDList)
    else:
        Sync_BossInfo(curPlayer, bossIDList)
    return
@@ -483,9 +508,8 @@
        isAlive = __GetIsAlive(bossID)
        if not isAlive:
            continue
        mapID = ipyData.GetMapID()
        if mapID != ChConfig.Def_FBMapID_SealDemon:
            GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)
        #if mapID not in ChConfig.WorldBossFBMapIDList:
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1)
    return
## 玩家登录通知
@@ -502,7 +526,6 @@
    state = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_OperationActionState % ShareDefine.OperationActionName_BossReborn)
    if state:
        Sync_BossRebornPoint(curPlayer)
    Sync_DogzNPCRefreshTime(curPlayer)
    return
## 地图启动ok通知
@@ -517,10 +540,6 @@
    if IsMapNeedBossShunt(0):
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo)
        GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntLineState, PyGameData.g_bossShuntLineState)
    #通知一个参数
    bossID = IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2)
    onlineCnt = __GetBossOnlineHeroCnt(bossID)[0]
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossID, onlineCnt)
    
    #仙盟击杀骑宠boss数
    if PyGameData.g_familyKillHorsePetRobBossCntDict:
@@ -541,9 +560,9 @@
def OnKillBossDropGoodItem(msgList, tick):
    # playerName, mapID, npcID, itemID, userData
    if len(msgList) != 8:
    if len(msgList) != 10:
        return
    playerID, killerName, mapID, npcID, itemID, userData, weightValue, serverGroupID = msgList
    playerID, killerName, mapID, lineID, npcID, itemID, userData, weightValue, serverGroupID, playerLV = msgList
    GameWorld.DebugLog("击杀Boss掉落好物品: mapID=%s,npcID=%s,killerName=%s,itemID=%s, userData=%s, weightValue=%s, serverGroupID=%s" 
                       % (mapID, npcID, killerName, itemID, userData, weightValue, serverGroupID))
    maxRecordCnt = IpyGameDataPY.GetFuncCfg('DropRecordNum')
@@ -554,7 +573,11 @@
        # 同步到玩家对应子服
        if not serverGroupID:
            return
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_DropGoodItem, msgList, [serverGroupID])
        zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID)
        if not zoneIpyData:
            return
        serverGroupIDList = zoneIpyData.GetServerGroupIDList()
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_DropGoodItem, msgList, serverGroupIDList)
        return
    
    recType = ShareDefine.Def_UniversalGameRecType_BossDropGoodItemInfo
@@ -584,10 +607,10 @@
            if commonList and commonList[0][0] != -1:
                recordList.Delete(commonList[0][0])
        
    PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, [mapID, npcID, itemID, playerID, weightValue],
                                                      [killerName, "", userData])
    PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, [mapID*100+lineID, npcID, itemID, playerID, weightValue],
                                                      [killerName, '%s|%s'%(serverGroupID, playerLV), userData])
    
    msgList = [killerName, playerID, mapID, npcID, itemID, userData]
    msgList = [killerName, playerID, mapID, npcID, itemID, userData, serverGroupID, playerLV, lineID]
    PlayerControl.WorldNotify(0, 'DropRecord' , msgList)
    return
@@ -655,8 +678,6 @@
    
    newNum = newOnlieCnt * 100 + unUpdataCnt
    PlayerDBGSEvent.SetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_GameWorldBossOnlineCnt % bossid, newNum)
    if bossid == IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2):
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossid, newOnlieCnt)
    GameWorld.DebugLog("设置计算boss刷新时间用的在线人数 Change:bossid=%s, beforeOnlineCnt = %s, newOnlieCnt = %s, unUpdataCnt=%s" % (bossid, beforeOnlineCnt, newOnlieCnt, unUpdataCnt))
    return
@@ -668,7 +689,7 @@
def SetBossRefreshTime(bossid, killedTime):
    '''设置boss刷新时间'''
    ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossid)
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', bossid)
    if not ipyData:
        return
    onlineCnt = __GetBossOnlineHeroCnt(bossid)[0]
@@ -719,6 +740,7 @@
    def GetBossAttentionDict(self):
        return self.bossAttentionDict
    # RecordData改json记录 bossid存为字符串
    def UpdateBossAttention(self, playerid, bossid, isAdd):
        if playerid in self.bossAttentionDict:
            bossAttentionData = self.bossAttentionDict[playerid]
@@ -760,7 +782,7 @@
        packData.BossList = []
        for bossid, addState in bttentionDict.items():
            bossInfo = ChPyNetSendPack.tagGCBossAttention()
            bossInfo.BossID=bossid
            bossInfo.BossID=int(bossid)
            bossInfo.AddState=addState
            packData.BossList.append(bossInfo)
        
@@ -792,10 +814,7 @@
            data.clear()
            pos += data.readData(datas, pos, dataslen)
            playerID = data.PlayerID
            if type(eval(data.RecordData)) != list:
                self.bossAttentionDict[playerID] = data
            else:
                data.clear()
            self.bossAttentionDict[playerID] = data
            
        return pos
@@ -1093,38 +1112,6 @@
        NetPackCommon.SendFakePack(curPlayer, packData)
    return
def Sync_DogzNPCRefreshTime(curPlayer=None):
    #同步神兽副本NPC刷新时间
    refreshTimeDict = PyGameData.g_dogzNPCRefreshTimeDict
    if not refreshTimeDict:
        return
    curTime = int(time.time())
    packData = ChPyNetSendPack.tagGCDogzNPCRefreshTime()
    packData.InfoList=[]
    for npcid, timeinfo in refreshTimeDict.items():
        lastRefreshTime, nextNeedTime = timeinfo
        remainTime = max(0, nextNeedTime - curTime + lastRefreshTime)
        timeInfo = ChPyNetSendPack.tagDogzTimeInfoObj()
        timeInfo.NPCID = npcid
        timeInfo.RefreshSecond = remainTime
        packData.InfoList.append(timeInfo)
    packData.Cnt = len(packData.InfoList)
    if not curPlayer:
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            if PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, packData)
    else:
        if PlayerControl.GetIsTJG(curPlayer):
            return
        NetPackCommon.SendFakePack(curPlayer, packData)
    return
## -----------------------------------------------------------------------------------------------
def OnFamilyKillHorsePetRobBoss(killFamilyName):
@@ -1274,3 +1261,110 @@
    PlayerControl.FamilyNotify(curFamily.GetID(), "FairyGrabBossHelp", [curPlayer.GetName(), npcID])
    return
## -------------------------------------- boss 首杀 ------------------------------------------------
def __GetBossFirstKillRecDataList():
    ## 获取boss首杀记录信息列表
    return GameWorld.GetUniversalRecMgr() .GetTypeList(ShareDefine.Def_UniversalGameRecType_BossFirstKill)
def __GetBossFirstKillRecDataByID(bossID):
    ## 获取boss首杀记录信息数据
    recTypeListData = __GetBossFirstKillRecDataList()
    # 查找是否已有记录
    bossFirstKillRec = None
    for index in xrange(recTypeListData.Count()):
        universalRecData = recTypeListData.At(index)
        if universalRecData.GetValue1() == bossID:
            bossFirstKillRec = universalRecData
            break
    if bossFirstKillRec == None:
        #还未记录,则添加一个记录对象
        bossFirstKillRec = recTypeListData.AddRec()
        bossFirstKillRec.SetValue1(bossID)
    return bossFirstKillRec
def OnBossFirstKill(bossID, killerIDList):
    ## 处理boss首杀逻辑
    maxOSDay = IpyGameDataPY.GetFuncCfg("OSCBossFirstKill", 1)
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
    if openServerDay > maxOSDay:
        GameWorld.DebugLog("超过开服天(%s), 不开放首杀活动!" % maxOSDay)
        return
    if not bossID or not killerIDList:
        return
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", bossID)
    if not ipyData:
        return
    fkRecData = __GetBossFirstKillRecDataByID(bossID)
    if not fkRecData:
        return
    firstKillTimeStr = fkRecData.GetStrValue2()
    if firstKillTimeStr:
        GameWorld.DebugLog("已经首杀过了! bossID=%s, %s" % (bossID, firstKillTimeStr))
        return
    killPlayerList = []
    playerMgr = GameWorld.GetPlayerManager()
    for playerID in killerIDList:
        player = playerMgr.FindPlayerByID(playerID)
        if not player:
            continue
        teamMemLV = PlayerTeam.__GetPlayerTeamLV(player)
        killPlayerList.append([teamMemLV, player.GetName()])
    if not killPlayerList:
        return
    killPlayerList.sort(reverse=True)
    fkPlayerNameList = [nameInfo[1] for nameInfo in killPlayerList]
    fkRecData.SetStrValue2(GameWorld.GetCurrentDataTimeStr())
    fkRecData.SetStrValue3(",".join(fkPlayerNameList))
    # 首杀奖励邮件
    PlayerCompensation.SendMailByKey("BossFirstKillMail", killerIDList, ipyData.GetServerFirstKillPlayerAward(), [bossID])
    ## 主动广播全服玩家
    PlayerUniversalGameRec.SendUniversalGameRecSingle(None, fkRecData)
    return
#// A9 01 获取Boss首杀奖励 #tagCGGetBossFirstKillAward
#
#struct    tagCGGetBossFirstKillAward
#{
#    tagHead    Head;
#    DWORD    NPCID;
#    BYTE    AwardType;    // 0-首杀红包奖励;1-个人首杀奖励
#};
def OnGetBossFirstKillAward(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    bossID = clientData.NPCID
    awardType = clientData.AwardType
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", bossID)
    if not ipyData:
        return
    if awardType == 0:
        fkRecData = __GetBossFirstKillRecDataByID(bossID)
        if not fkRecData:
            return
        firstKillTimeStr = fkRecData.GetStrValue2()
        if not firstKillTimeStr:
            GameWorld.DebugLog("Boss还未首杀,不能领取boss首杀公共红包奖励! bossID=%s" % (bossID), curPlayer.GetPlayerID())
            return
    msgInfo = str([bossID, awardType])
    curPlayer.MapServer_QueryPlayerResult(0, 0, "BossFirstKill", msgInfo, len(msgInfo))
    return
## ------------------------------------------------------------------------------------------------