#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # #------------------------------------------------------------------------------- # ##@package GameWorldBoss # # @todo:ÊÀ½çboss # @author hxp # @date 2014-02-27 # @version 2.2 # # @change: "2014-03-11 19:30" hxp Ôö¼ÓÊÀ½çbossÐÅÏ¢¼Ç¼£¬ÊÇ·ñ´æ»î£¬Éϴλ÷É±Íæ¼ÒµÈ # @change: "2014-03-25 17:00" hxp ÆÁ±Î²¿·ÖLog # @change: "2014-06-03 14:30" hxp BossÖØÉúʱ¼ì²é´´½¨bossÐÅÏ¢¼Ç¼ # @change: "2015-01-07 15:00" hxp ÐÞ¸ÄΪ֧³Ö¿É½ö´æ´¢»÷ɱÕß # @change: "2015-01-10 16:30" hxp Ôö¼Ó½Ç¶·³¡boss»÷ɱ´ÎÊý£¬×´Ì¬ÐÅÏ¢ # @change: "2015-04-29 03:30" hxp bossÖØÉúʱ¼äÐÞ¸ÄΪÿ¸öboss¶ÀÁ¢ # @change: "2015-04-30 14:30" hxp µØÍ¼ÖØÆôʱ֪ͨ»î×ŵÄboss״̬£¬·ÀÖ¹ÖØÆôµØÍ¼ºó²»Ë¢boss # @change: "2016-08-13 14:00" hxp Ôö¼Óboss±»»÷ɱ´ÎÊý¼Ç¼ # @change: "2016-10-13 21:00" hxp Ôö¼Ó¿ª·þÖØÖÃboss±»»÷ɱ´ÎÊý¼Ç¼(Õë¶Ô²»Í¬°æ±¾µÄÐÂÔöÊôÐԳɳ¤bossID) # @change: "2017-01-22 21:00" hxp Ôö¼Ó¼Ç¼µôÂäµÄ×îºÃ×°±¸ÐÅÏ¢ # @change: "2017-05-10 17:50" xdh ÊÀ½çbossË¢ÐÂʱ¼ä¸ù¾ÝÔÚÏßÈËÊý±ä»¯ # @change: "2017-05-24 16:00" hxp ÊÀ½çbossË¢ÐÂʱ¼äÔÚÏßÈËÊýÔö¼Ó¿ç·þ·þÎñÆ÷ÔÚÏßÈËÊýÖ§³Ö # ÏêϸÃèÊö: ÊÀ½çboss # #--------------------------------------------------------------------- #"""Version = 2017-05-24 16:00""" #--------------------------------------------------------------------- import GameWorld import ShareDefine import ChConfig import NetPackCommon import ChPyNetSendPack import PlayerDBGSEvent import PlayerUniversalGameRec import IpyGameDataPY import MergePlayer import PyGameDataStruct import PyDataManager import PlayerControl import CommFunc import PyGameData import PlayerGeTui import time ''' ShareDefine.Def_UniversalGameRecType_BossInfo value1:bossID value2:killedTime value3:killedCnt StrValue3:['ʱ¼ä_Íæ¼ÒÃû',..] ''' g_lastBossRebornTime = 0#boss¸´»îʱ¼ä def CheckResetBossKilledCntOnServerInit(): # ·þÎñÆ÷Æô¶¯ÖØÖÃboss±»»÷ɱ´ÎÊý # ÓÉÓÚ¹«¹²boss±»É±Ê±ÒѾ­ÌáǰÀÛ¼Ó±»É±´ÎÊý, µ±bossÊôÐÔµ÷ÕûΪ°´±»É±´ÎÊý³É³¤Ê±, Ðè½øÐÐÖØÖôÎÊý, È·±£°æ±¾¸üкóbossÊôÐÔ²»»áͻȻ±©Ôö resetVerInfo = [ #[267, 268, 269, 270, 271, 272, 273, 274, 275, 276], # 2016/10/13 ] resetDBKey = "ResetBossKilledCntVer" maxVer = len(resetVerInfo) curVer = PlayerDBGSEvent.GetDBGSTrig_ByKey(resetDBKey) if curVer >= maxVer: GameWorld.DebugLog("ÒѾ­ÖØÖùýboss±»»÷ɱ´ÎÊý!curVer=%s,maxVer=%s" % (curVer, maxVer)) return GameWorld.Log("¿ªÊ¼ÖØÖÃboss±»»÷ɱ´ÎÊý!curVer=%s,maxVer=%s" % (curVer, maxVer)) for resetBossIDList in resetVerInfo[curVer:]: for bossID in resetBossIDList: bossPrizeRec = __GetBossRecDataByID(bossID) killedCnt = __GetKilledCnt(bossPrizeRec) if killedCnt <= 0: continue __SetKilledCnt(bossPrizeRec, 0) GameWorld.Log(" ÖØÖÃboss±»»÷ɱ´ÎÊý: bossID=%s,Òѱ»É±´ÎÊý=%s" % (bossID, killedCnt)) PlayerDBGSEvent.SetDBGSTrig_ByKey(resetDBKey, maxVer) GameWorld.Log(" ÖØÖóɹ¦: maxVer=%s" % (maxVer)) return ## ÊÀ½çboss±»»÷ɱÂß¼­ # @param msgList ÐÅÏ¢Áбí # @param tick ʱ¼ä´Á # @return None def DoGameWorldBossOnKilled(msgList, tick): if len(msgList) <= 0: return bossID = msgList[0] if bossID <= 0: return # ÉèÖò»´æ»î£¬»÷É±Íæ¼ÒÃû killPlayerName = msgList[1] hurtValue = msgList[2] isAddKillCnt = msgList[3] isNotify = msgList[4] if len(msgList) > 4 else True mapID = msgList[5] if len(msgList) > 5 else None isMapNeedShunt = IsMapNeedBossShunt(mapID) isAlive = __GetIsAlive(bossID) GameWorld.DebugLog("»÷ɱÊÀ½çboss DoGameWorldBossOnKilled...bossID=%s,hurtValue=%s,mapID=%s,tick=%s,isMapNeedShunt=%s,isAlive=%s" % (bossID, hurtValue, mapID, tick, isMapNeedShunt, isAlive)) if isMapNeedShunt and not isAlive: GameWorld.DebugLog("ÐèÒª·ÖÁ÷µÄµØÍ¼boss±»»÷ɱ£¬µ«Êǵ±Ç°bossÈ«¾Ö״̬ΪËÀÍö״̬£¬²»ÔÙ¸üÐÂboss»÷ɱÐÅÏ¢£¡") return killedTime = int(time.time()) # ²éÕҼǼ bossPrizeRec = __GetBossRecDataByID(bossID) __SetKillRecord(bossPrizeRec, killedTime, killPlayerName, hurtValue) if isAddKillCnt: befKilledCnt = __GetKilledCnt(bossPrizeRec) __SetKilledCnt(bossPrizeRec, befKilledCnt + 1) GameWorld.DebugLog(" addBossKillCnt: killPlayerName=%s,befKilledCnt=%s" % (killPlayerName, befKilledCnt)) if isNotify: __SetIsAlive(bossID, 0) SetBossRefreshTime(bossID, killedTime) # È«·þ¹ã²¥ÊÀ½çboss±ä¸üÐÅÏ¢ Sync_BossInfo(None, [bossID]) SendMapServerBossKilledCnt(bossID) return def __UpdateBossRefreshList(bossID, killedTime=0, refreshTime=0): for bossInfo in PyGameData.g_sortBOSSRefreshList: if bossID == bossInfo[0]: if killedTime: bossInfo[1] = killedTime if refreshTime: bossInfo[2] = refreshTime break curTime = int(time.time()) PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1]))) GameWorld.DebugLog(' PyGameData.g_sortBOSSRefreshList=%s'%PyGameData.g_sortBOSSRefreshList) return ## ÊÀ½çbossÖØÉú # @param msgList ÐÅÏ¢Áбí # @param tick ʱ¼ä´Á # @return None def DoGameWorldBossOnReborn(msgList, tick): if len(msgList) <= 0: return bossID = msgList[0] isAlive = msgList[1] mapID = msgList[2] if len(msgList) > 2 else None lineID = msgList[3] if len(msgList) > 3 else None GameWorld.DebugLog("ÊÀ½çboss DoGameWorldBossOnReborn...mapID=%s,lineID=%s,bossID=%s,state=%s,tick=%s" % (mapID, lineID, bossID, isAlive, tick)) if bossID <= 0: return isMapNeedShunt = IsMapNeedBossShunt(mapID) if not isAlive: DoRemoveBossShuntPlayerByNPCID(mapID, lineID, bossID) if isMapNeedShunt: __UpdBossLineState(bossID, lineID, isAlive) #__GetBossRecDataByID(bossID) # ¼ì²éÊÇ·ñÓиÃboss¼Ç¼£¬Ã»Óеϰ´´½¨Ð¼Í¼ if isAlive != __GetIsAlive(bossID): __SetIsAlive(bossID, isAlive) # È«·þ¹ã²¥ÊÀ½çboss±ä¸üÐÅÏ¢ Sync_BossInfo(None, [bossID]) return def __UpdBossLineState(bossID, lineID, isAlive): if lineID == None: return bossDeadLineList = PyGameData.g_bossShuntDeadLine.get(bossID, []) if isAlive and lineID in bossDeadLineList: bossDeadLineList.remove(lineID) elif not isAlive and lineID not in bossDeadLineList: bossDeadLineList.append(lineID) else: return PyGameData.g_bossShuntDeadLine[bossID] = bossDeadLineList if not bossDeadLineList: PyGameData.g_bossShuntDeadLine.pop(bossID) if bossID not in PyGameData.g_bossShuntDeadLineChangeBoss: PyGameData.g_bossShuntDeadLineChangeBoss.append(bossID) #GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntDeadLine, PyGameData.g_bossShuntDeadLine) GameWorld.DebugLog(" bossÒÑËÀÍöÏß·±ä¸ü: %s" % PyGameData.g_bossShuntDeadLine) return ## ¸ù¾ÝÊÀ½çbossID»ñÈ¡RecÊý¾Ý # @param bossID: bossID # @return None def __GetBossRecDataByID(bossID): recTypeListData = __GetBossPrizeRecData() # ²éÕÒÊÇ·ñÒÑÓмǼ bossRec = None for index in range(recTypeListData.Count()): universalRecData = recTypeListData.At(index) if universalRecData.GetValue1() == bossID: bossRec = universalRecData #GameWorld.DebugLog("ÊÀ½çboss id=%s ÕÒµ½ÒÑÓмǼ£¡" % (bossID)) break if bossRec == None: GameWorld.DebugLog("ÊÀ½çboss id=%s δÕÒµ½ÒÑÓмǼ£¡Ìí¼ÓмǼ" % (bossID)) #»¹Î´¼Ç¼£¬ÔòÌí¼ÓÒ»¸ö¼Ç¼¶ÔÏó bossRec = recTypeListData.AddRec() bossRec.SetValue1(bossID) return bossRec def __SetKilledCnt(rec, killedCnt): rec.SetValue3(killedCnt) return def __GetKilledCnt(rec): return rec.GetValue3() ## ÉèÖÃÊÀ½çbossÊÇ·ñ»î×Å # @param rec ÐÅÏ¢¼Ç¼ # @param setTick ÉèÖÃʱ¼ä£¬ºÁÃë # @return None def __SetIsAlive(bossID, isAlive): GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_BossIsAlive % bossID, isAlive) return ## »ñÈ¡ÊÀ½çbossÊÇ·ñ»î×Å # @param rec ÐÅÏ¢¼Ç¼ # @return None def __GetIsAlive(bossID): return GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_BossIsAlive % bossID) ## ÉèÖÃÊÀ½çbossÉÏÒ»´Î»÷É±Íæ¼ÒÃû # @param rec ÐÅÏ¢¼Ç¼ # @param setTick ÉèÖÃʱ¼ä£¬ºÁÃë # @return None def __SetKillRecord(rec, killedTime, playerName, hurtValue): killRecord = __GetKillRecord(rec) killRecordList = killRecord.split('|') if killRecord else [] if hurtValue: killRecordList.append('%s_%s_%s' % (killedTime, playerName, hurtValue)) else: killRecordList.append('%s_%s' % (killedTime, playerName)) #¼Ç¼×î½ü5´Î if len(killRecordList) > 5: del killRecordList[0] killRecord = '|'.join(killRecordList) rec.SetStrValue3(killRecord) rec.SetValue2(killedTime) return ## »ñÈ¡ÊÀ½çboss×î½ü5´Î»÷ɱ¼Ç¼ ʱ¼äÍæ¼ÒÃû # @param rec ÐÅÏ¢¼Ç¼ # @return None def __GetKillRecord(rec): return rec.GetStrValue3() ## »ñÈ¡ÊÀ½çboss½±Àø¼Ç¼ÐÅÏ¢ # @param None # @return None def __GetBossPrizeRecData(): recType = ShareDefine.Def_UniversalGameRecType_BossInfo universalRecMgr = GameWorld.GetUniversalRecMgr() recTypeListData = universalRecMgr.GetTypeList(recType) return recTypeListData def SendMapServerBossKilledCnt(bossID=0): return # recTypeListData = __GetBossPrizeRecData() # for index in range(recTypeListData.Count()): # universalRecData = recTypeListData.At(index) # recBossID = universalRecData.GetValue1() # if not recBossID: # continue # # if bossID > 0 and recBossID != bossID: # continue # # killedCnt = __GetKilledCnt(universalRecData) # GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossKilledCnt % recBossID, killedCnt) # if bossID > 0: # break # # return ## ͬ²½bossÏà¹ØÐÅÏ¢ # @param curPlayer: Íæ¼ÒʵÀý£¬Ä¬ÈÏΪNoneʱȫ·þ¹ã²¥ # @return None def Sync_BossInfo(curPlayer=None, syncBOSSIDList=[]): curTime = int(time.time()) bossInfo = ChPyNetSendPack.tagGCGameWorldBossInfo() recTypeListData = __GetBossPrizeRecData() bossInfo.BossInfoList = [] #GameWorld.DebugLog("Sync_BossInfo...count=%s,curTime=%s" % (recTypeListData.Count(), curTime)) for index in range(recTypeListData.Count()): universalRecData = recTypeListData.At(index) bossID = universalRecData.GetValue1() if not bossID: continue if syncBOSSIDList and bossID not in syncBOSSIDList: continue bossInfoObj = ChPyNetSendPack.tagBossInfoObj() bossInfoObj.BossID = bossID bossInfoObj.IsAlive = __GetIsAlive(bossInfoObj.BossID) bossInfoObj.KillRecord = __GetKillRecord(universalRecData) bossInfoObj.RecordLen = len(bossInfoObj.KillRecord) killedTime = universalRecData.GetValue2() refreshTime = __GetBossRefreshTime(bossInfoObj.BossID) bossInfoObj.RefreshSecond = max(0, refreshTime - (curTime - killedTime)) #bossInfoObj.KilledCnt = __GetKilledCnt(universalRecData) bossInfo.BossInfoList.append(bossInfoObj) # GameWorld.DebugLog(" bossID=%s,isAlive=%s,killerName=%s,killedTime=%s,refreshSecond=%s" # % (bossInfoObj.BossID, bossInfoObj.IsAlive, bossInfoObj.KillRecord, # killedTime, bossInfoObj.RefreshSecond)) bossInfo.BossCnt = len(bossInfo.BossInfoList) if not curPlayer: # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò playerManager = GameWorld.GetPlayerManager() for i in range(0, playerManager.GetActivePlayerCount()): curPlayer = playerManager.GetActivePlayerAt(i) if curPlayer == None or not curPlayer.GetInitOK(): continue if PlayerControl.GetIsTJG(curPlayer): continue NetPackCommon.SendFakePack(curPlayer, bossInfo) else: if PlayerControl.GetIsTJG(curPlayer): return NetPackCommon.SendFakePack(curPlayer, bossInfo) return ## Ö´Ðмì²éÊÀ½çbossÖØÉú # @param None # @return None def DoCheckWorldBossReborn(tick): if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossProcessTick, tick): #¼ä¸ôδµ½ return curTime = int(time.time()) DoCheckWorldBossShuntInfo(curTime, tick) BossRebornWorldNotify(curTime) if not PyGameData.g_sortBOSSRefreshList: for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()): ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i) bossID = ipyData.GetNPCID() bossPrizeRec = __GetBossRecDataByID(bossID) killedTime = bossPrizeRec.GetValue2() refreshTime = __GetBossRefreshTime(bossID) PyGameData.g_sortBOSSRefreshList.append([bossID, killedTime, refreshTime]) PyGameData.g_sortBOSSRefreshList.sort(key=lambda asd:max(0, asd[2] - (curTime - asd[1]))) syncBOSSIDList = [] for bossInfo in PyGameData.g_sortBOSSRefreshList: bossID, killedTime, refreshTime = bossInfo isAlive = __GetIsAlive(bossID) if isAlive: #GameWorld.DebugLog(" bossID=%s,δ±»»÷ɱ£¡" % bossID) continue rebornSecond = max(0, refreshTime - (curTime - killedTime)) if rebornSecond > 0: # GameWorld.DebugLog(" bossID=%s,killedTime=%s,ÖØÉúµ¹¼ÆÊ±Ãë(%s)£¡" # % (bossID, killedTime, rebornSecond)) break #´Ë´¦Ö»´¦Àí¸´»îµÄ PlayerGeTui.GeTuiBossReborn(bossID) __SetIsAlive(bossID, 1) syncBOSSIDList.append(bossID) GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 1) GameWorld.DebugLog(" ֪ͨMapServerÖØÉú: bossID=%s,killedTime=%s,rebornSecond=%s" % (bossID, killedTime, rebornSecond)) if syncBOSSIDList: Sync_BossInfo(None, syncBOSSIDList) return #BOSS¸öÍÆÌáǰµ¹¼ÆÊ±Í¨Öª´¦Àí£¬ ¸´»îÓÉDoCheckWorldBossReborn´¦Àí def ProcessBossGeTui(tick): if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossGeTuiTick, tick): #¼ä¸ôδµ½ return curTime = int(time.time()) for bossInfo in PyGameData.g_sortBOSSRefreshList: bossID, killedTime, refreshTime = bossInfo isAlive = __GetIsAlive(bossID) if isAlive: #GameWorld.DebugLog(" bossID=%s,δ±»»÷ɱ£¡" % bossID) continue rebornSecond = max(0, refreshTime - (curTime - killedTime)) if not rebornSecond: #²»´¦Àí¸´»îBOSS continue PlayerGeTui.GeTuiBoss(bossID, rebornSecond) def GetBossIsAliveOrCanReborn(bossID): ##BOSSÊÇ·ñ»î×Å»òÕß¿ÉÖØÉú bossPrizeRec = __GetBossRecDataByID(bossID) killedTime = bossPrizeRec.GetValue2() refreshTime = __GetBossRefreshTime(bossID) curTime = int(time.time()) rebornSecond = max(0, refreshTime - (curTime - killedTime)) isAlive = __GetIsAlive(bossID) return isAlive or rebornSecond == 0 ## ͬ²½µ±Ç°»¹»î×ŵÄboss£¬·ÀÖ¹µØÍ¼ÖØÆôºóÒѾ­Ë¢ÐµÄboss²»Ë¢Ð # @param None # @return None def __SendMapServerAliveBoss(): for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()): ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i) bossID = ipyData.GetNPCID() 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) return ## Íæ¼ÒµÇ¼֪ͨ # @param curPlayer # @return None def OnPlayerLogin(curPlayer): Sync_BossInfo(curPlayer) PyDataManager.GetBossAttentionManager().NotifyBossAttentionInfo(curPlayer) if IsMapNeedBossShunt(0): Sync_BossShuntLineInfo(curPlayer) #BOSS¸´»î»î¶¯Í¨Öª gameWorld = GameWorld.GetGameWorld() state = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_OperationActionState % ShareDefine.OperationActionName_BossReborn) if state: Sync_BossRebornPoint(curPlayer) return ## µØÍ¼Æô¶¯ok֪ͨ # @param None # @return None def OnMapServerInitOK(): SendMapServerBossKilledCnt() __SendMapServerAliveBoss() if IsMapNeedBossShunt(0): GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo) GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntDeadLine, PyGameData.g_bossShuntDeadLine) #֪ͨһ¸ö²ÎÊý bossID = IpyGameDataPY.GetFuncCfg('DogzFBRefreshCfg', 2) onlineCnt = __GetBossOnlineHeroCnt(bossID)[0] GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_BossOnlineHeroCnt % bossID, onlineCnt) return ##-------------------------------------------------------------------------------------------------- def OnKillBossDropGoodItem(msgList, tick): # playerName, mapID, npcID, itemID, userData if len(msgList) != 7: return playerID, killerName, mapID, npcID, itemID, userData, weightValue = msgList GameWorld.DebugLog("»÷ɱBossµôÂäºÃÎïÆ·: mapID=%s,npcID=%s,killerName=%s,itemID=%s, userData=%s, weightValue=%s" % (mapID, npcID, killerName, itemID, userData, weightValue)) maxRecordCnt = IpyGameDataPY.GetFuncCfg('DropRecordNum') if not maxRecordCnt: return recType = ShareDefine.Def_UniversalGameRecType_BossDropGoodItemInfo universalRecMgr = GameWorld.GetUniversalRecMgr() recordList = universalRecMgr.GetTypeList(recType) if maxRecordCnt <= recordList.Count(): curTime = int(time.time()) rangeTime = IpyGameDataPY.GetFuncCfg('DropRecordNum', 2) * 24 * 60 * 60 firstRecData = recordList.At(0) fsaveTime = firstRecData.GetTime() if curTime - fsaveTime > rangeTime: recordList.Delete(0) else: dropRecordList = [] #[Ë÷Òý,Õäϧ¶È,ʱ¼ä] for i in xrange(recordList.Count()): recData = recordList.At(i) saveTime = recData.GetTime() curWeightValue = recData.GetValue5() dropRecordList.append([i, curWeightValue, saveTime]) dropRecordList.append([-1, weightValue, curTime]) #Õäϧ¶ÈÔ½´óÔ½Õä¹ó commonList = sorted(dropRecordList, key=lambda asd:asd[1], reverse=True) commonList = commonList[5:] #³ýÈ¥5¸öÖö¥µÄ ÆäËüµÄÑ¡¸öʱ¼ä×î¾ÉµÄɾÁË commonList.sort(key=lambda asd:asd[2]) if commonList and commonList[0][0] != -1: recordList.Delete(commonList[0][0]) PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, [mapID, npcID, itemID, playerID, weightValue], [killerName, "", userData]) return ## ÊÀ½çbossÔÚÏßÈËÊýͳ¼Æ # @param None: # @return: None def CalcGameWorldBossOnlineCnt(tick): if not GameWorld.SetWorldDictKey(ChConfig.TYPE_WorldBossOnlineCntTick, tick): #¼ä¸ôδµ½ return GameWorld.DebugLog('ÊÀ½çbossÔÚÏßÈËÊýͳ¼Æ') bossRebornDict = {} for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()): ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i) bossID = ipyData.GetNPCID() refreshTimeStr = ipyData.GetRefreshTime() if 'onlineCnt' in refreshTimeStr: bossRebornDict[bossID] = ipyData.GetLVLimit() playerCntDict = {} playerManager = GameWorld.GetPlayerManager() for i in xrange(playerManager.GetActivePlayerCount()): findPlayer = playerManager.GetActivePlayerAt(i) if findPlayer == None or not findPlayer.GetInitOK(): continue if PlayerControl.GetIsTJG(findPlayer): continue findLV = findPlayer.GetLV() for bossid, lvLimit in bossRebornDict.items(): if lvLimit[0] <= findLV <= lvLimit[1]: playerCntDict[bossid] = playerCntDict.get(bossid, 0) + 1 GameWorld.DebugLog(' bossµÈ¼¶ÐÅÏ¢¶ÔÓ¦±¾·þÔÚÏßÈËÊý %s' % playerCntDict) # ´Ë´¦ÐèҪͳ¼ÆÀÛ¼Óµ±Ç°ÔÚ¿ç·þ·þÎñÆ÷µÄÍæ¼Ò mergeServerOnlinePlayerDict = MergePlayer.GetMergeServerOnlinePlayerInfo() for playerInfo in mergeServerOnlinePlayerDict.values(): findLV = playerInfo[MergePlayer.Def_MSOLPlayer_LV] for bossid, lvLimit in bossRebornDict.items(): if lvLimit[0] <= findLV <= lvLimit[1]: playerCntDict[bossid] = playerCntDict.get(bossid, 0) + 1 GameWorld.DebugLog(' bossµÈ¼¶ÐÅÏ¢¶ÔÓ¦±¾·þ¼°¿ç·þÔÚÏßÈËÊý %s' % playerCntDict) for bossid, curOnlineCnt in playerCntDict.items(): SetBossOnlineHeroCnt(bossid, curOnlineCnt) return def SetBossOnlineHeroCnt(bossid, onlieCnt): '''ÉèÖüÆËãbossË¢ÐÂʱ¼äÓõÄÔÚÏßÈËÊý''' ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossid) if not ipyData: return beforeOnlineCnt, unUpdataCnt = __GetBossOnlineHeroCnt(bossid) if not beforeOnlineCnt or abs(onlieCnt - beforeOnlineCnt) * 100 / beforeOnlineCnt < ipyData.GetDiffPer(): newOnlieCnt = onlieCnt unUpdataCnt = 0 else: if unUpdataCnt >= ipyData.GetNoUpdataCnt(): newOnlieCnt = onlieCnt unUpdataCnt = 0 else: newOnlieCnt = beforeOnlineCnt unUpdataCnt += 1 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 def __GetBossOnlineHeroCnt(bossid): '''»ñÈ¡¼ÆËãbossË¢ÐÂʱ¼äÓõÄÔÚÏßÈËÊý''' beforeNum = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_GameWorldBossOnlineCnt % bossid) onlieCnt, unUpdataCnt = beforeNum / 100, beforeNum % 100 return onlieCnt, unUpdataCnt def SetBossRefreshTime(bossid, killedTime): '''ÉèÖÃbossË¢ÐÂʱ¼ä''' ipyData = IpyGameDataPY.GetIpyGameData('BOSSInfo', bossid) if not ipyData: return onlineCnt = __GetBossOnlineHeroCnt(bossid)[0] refreshTime = eval(ipyData.GetRefreshTime()) PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRefreshTime % bossid, refreshTime) __UpdateBossRefreshList(bossid, killedTime, refreshTime) GameWorld.DebugLog(' ÉèÖÃbossË¢ÐÂʱ¼ä BossID=%s,onlineCnt=%s,refreshTime=%s' % (bossid, onlineCnt, refreshTime)) return def __GetBossRefreshTime(bossid): '''»ñÈ¡bossË¢ÐÂʱ¼ä''' return PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRefreshTime % bossid) #// A9 03 ¹Ø×¢BOSSˢР#tagCGAttentionBoss # #struct tagCGAttentionBoss #{ # tagHead Head; # BYTE IsAdd; //0-ĬÈÏδ¹Ø×¢, 1-Ö÷¶¯¹Ø×¢, 2-×Ô¶¯¹Ø×¢, 9-Ö÷¶¯È¡Ïû¹Ø×¢ # DWORD BossID; #}; ## BOSSˢйØ×¢ def OnAttentionBoss(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) bossID = clientData.BossID isAdd = clientData.IsAdd PyDataManager.GetBossAttentionManager().UpdateBossAttention(curPlayer.GetPlayerID(), bossID, isAdd) return # BOSS¹Ø×¢¼Ç¼¹ÜÀí class BossAttentionManager(object): def __init__(self): self.bossAttentionDict = {} # {playerid:record, ...} PyGameDataStruct.tagDBPyBossAttention return def GetBossAttentionDict(self): return self.bossAttentionDict def UpdateBossAttention(self, playerid, bossid, isAdd): if playerid in self.bossAttentionDict: bossAttentionData = self.bossAttentionDict[playerid] recordDict = eval(bossAttentionData.RecordData) if isAdd: recordDict[bossid] = isAdd else: recordDict.pop(bossid, 0) if not recordDict: bossAttentionData.clear() self.bossAttentionDict.pop(playerid) else: bossAttentionData.RecordData = str(recordDict) bossAttentionData.DataLen = len(bossAttentionData.RecordData) else: if not isAdd: return bossAttention = PyGameDataStruct.tagDBPyBossAttention() bossAttention.clear() bossAttention.PlayerID = playerid bossAttention.RecordData = str({bossid:isAdd}) bossAttention.DataLen = len(bossAttention.RecordData) self.bossAttentionDict[playerid] = bossAttention GameWorld.DebugLog("¸üÐÂBOSS¹Ø×¢¼Ç¼ playerid=%s,bossid=%s,isAdd=%s" % (playerid, bossid, isAdd)) return def NotifyBossAttentionInfo(self, curPlayer): #֪ͨboss¹Ø×¢ÐÅÏ¢ if PlayerControl.GetIsTJG(curPlayer): return attentionData = self.bossAttentionDict.get(curPlayer.GetPlayerID()) if not attentionData: return bttentionDict = eval(attentionData.RecordData) packData = ChPyNetSendPack.tagGCBossAttentionInfo() packData.BossList = [] for bossid, addState in bttentionDict.items(): bossInfo = ChPyNetSendPack.tagGCBossAttention() bossInfo.BossID=bossid bossInfo.AddState=addState packData.BossList.append(bossInfo) packData.BossCnt = len(packData.BossList) NetPackCommon.SendFakePack(curPlayer, packData) return # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup def GetSaveData(self): savaData = "" cntData = "" cnt = 0 for attentionData in self.bossAttentionDict.values(): cnt += 1 savaData += attentionData.getBuffer() GameWorld.Log("SaveBossAttention cnt :%s" % cnt) return CommFunc.WriteDWORD(cntData, cnt) + savaData # ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý def LoadPyGameData(self, datas, pos, dataslen): cnt, pos = CommFunc.ReadDWORD(datas, pos) GameWorld.Log("LoadBossAttention cnt :%s" % cnt) self.bossAttentionDict = {} for _ in xrange(cnt): data = PyGameDataStruct.tagDBPyBossAttention() data.clear() pos += data.readData(datas, pos, dataslen) playerID = data.PlayerID if type(eval(data.RecordData)) != list: self.bossAttentionDict[playerID] = data else: data.clear() return pos ##-------------------------------------------------------------------------------------------------- def IsMapNeedBossShunt(mapID): ## Ä¿±êµØÍ¼ÊÇ·ñÐèÒª´¦Àíboss·ÖÁ÷ bossShuntMaxServerDay = IpyGameDataPY.GetFuncCfg("BossShunt", 3) openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1 if openServerDay <= bossShuntMaxServerDay: if not mapID: return True bossShuntMapIDList = IpyGameDataPY.GetFuncEvalCfg("BossShunt") return mapID in bossShuntMapIDList return False def MapServer_WorldBossShuntInfo(msgList, tick): ## µØÍ¼boss·ÖÁ÷ÐÅϢͬ²½×ª·¢ mapID, lineID, shuntPlayerDict = msgList key = (mapID, lineID) PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo) return def OnPlayerTeamChange(curPlayer): if not PyGameData.g_bossShuntPlayerInfo: return updTeamID = curPlayer.GetTeamID() isNeedSyncMap = False for key, shuntPlayerDict in PyGameData.g_bossShuntPlayerInfo.items(): mapID, lineID = key for playerID, shuntInfo in shuntPlayerDict.items(): npcID, teamID, relatedTick = shuntInfo if updTeamID == teamID: continue shuntInfo[1] = updTeamID isNeedSyncMap = True GameWorld.DebugLog("Boss·ÖÁ÷Íæ¼Ò¶ÓÎé±ä¸ü:mapID=%s,lineID=%s,npcID=%s,playerID=%s,teamID=%s,relatedTick=%s,updTeamID=%s" % (mapID, lineID, npcID, playerID, teamID, relatedTick, updTeamID)) if isNeedSyncMap: GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo) return def DoRemoveBossShuntPlayerByNPCID(mapID, lineID, bossID): ## ÒÆ³ý¶ÔÓ¦Ïß·ijֻbossµÄ·ÖÁ÷Ïà¹ØÐÅÏ¢, boss±»»÷ɱʱ´¥·¢Ò»´Î key = (mapID, lineID) if key not in PyGameData.g_bossShuntPlayerInfo: return shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo[key] removePlayerIDList = [] for playerID, shuntInfo in shuntPlayerDict.items(): npcID = shuntInfo[0] if npcID == bossID: shuntPlayerDict.pop(playerID) removePlayerIDList.append(playerID) if not shuntPlayerDict: PyGameData.g_bossShuntPlayerInfo.pop(key) if removePlayerIDList: GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo) GameWorld.DebugLog(" Çå³ýbossÏß··ÖÁ÷Íæ¼Ò: mapID=%s,lineID=%s,bossID=%s,removePlayerIDList=%s, %s" % (mapID, lineID, bossID, removePlayerIDList, PyGameData.g_bossShuntPlayerInfo)) return def DoCheckWorldBossShuntInfo(curTime, tick): ## ¶¨Ê±¼ì²éboss·ÖÁ÷ÐÅÏ¢Êý¾Ý if PyGameData.g_bossShuntDeadLineChangeBoss and curTime % 2 == 0: GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntDeadLine, PyGameData.g_bossShuntDeadLine) Sync_BossShuntLineInfo(None, PyGameData.g_bossShuntDeadLineChangeBoss) PyGameData.g_bossShuntDeadLineChangeBoss = [] if curTime % 10 != 0: return ProceTime = 180000 isNeedSyncMap = False for key, shuntPlayerDict in PyGameData.g_bossShuntPlayerInfo.items(): mapID, lineID = key for playerID, shuntInfo in shuntPlayerDict.items(): npcID, teamID, relatedTick = shuntInfo if not relatedTick or tick - relatedTick <= ProceTime: continue isNeedSyncMap = True shuntPlayerDict.pop(playerID) GameWorld.DebugLog("Boss·ÖÁ÷ÒÆ³ý³¬Ê±Íæ¼Ò:mapID=%s,lineID=%s,npcID=%s,playerID=%s,teamID=%s" % (mapID, lineID, npcID, playerID, teamID)) if not shuntPlayerDict: PyGameData.g_bossShuntPlayerInfo.pop(key) if isNeedSyncMap: GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo) return def OnPlayerChangeMap(curPlayer): ## Íæ¼ÒÇÐͼ if not PyGameData.g_bossShuntPlayerInfo: return teamID = curPlayer.GetTeamID() playerID = curPlayer.GetPlayerID() playerMapID = curPlayer.GetMapID() playerLineID = curPlayer.GetFBID() isNeedSyncMap = False for key, shuntPlayerDict in PyGameData.g_bossShuntPlayerInfo.items(): mapID, lineID = key if playerMapID == mapID and playerLineID == lineID: continue if playerID in shuntPlayerDict: isNeedSyncMap = True shuntPlayerDict.pop(playerID) GameWorld.DebugLog("ÇÐÍ¼ÒÆ³ýÆäËûµØÍ¼Ïß·boss·ÖÁ÷Íæ¼Ò: mapID=%s,lineID=%s,playerID=%s,teamID=%s" % (mapID, lineID, playerID, teamID)) if not shuntPlayerDict: PyGameData.g_bossShuntPlayerInfo.pop(key) if isNeedSyncMap: GameWorld.SendCommMapServerMsg(ShareDefine.Def_Notify_WorldKey_BossShuntPlayer, PyGameData.g_bossShuntPlayerInfo) return def Sync_BossShuntLineInfo(curPlayer=None, syncBOSSIDList=[]): if not syncBOSSIDList: syncBOSSIDList = PyGameData.g_bossShuntDeadLine.keys() bossShuntLineInfo = ChPyNetSendPack.tagGCBossShuntLineStateInfo() bossShuntLineInfo.Clear() bossShuntLineInfo.BossLineStateInfo = [] for bossID in syncBOSSIDList: bossLineState = ChPyNetSendPack.tagGCBossShuntLineState() bossLineState.BossID = bossID bossLineState.DeadLineList = PyGameData.g_bossShuntDeadLine.get(bossID, []) bossLineState.DeadLineCount = len(bossLineState.DeadLineList) bossShuntLineInfo.BossLineStateInfo.append(bossLineState) bossShuntLineInfo.Count = len(bossShuntLineInfo.BossLineStateInfo) 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, bossShuntLineInfo) else: if PlayerControl.GetIsTJG(curPlayer): return NetPackCommon.SendFakePack(curPlayer, bossShuntLineInfo) return def AddBossRebornPoint(addPoint): ## Ôö¼Óboss¸´»îµã global g_lastBossRebornTime gameWorld = GameWorld.GetGameWorld() state = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_OperationActionState % ShareDefine.OperationActionName_BossReborn) if not state: GameWorld.Log(' Ôö¼Óboss¸´»îµã »î¶¯Î´¿ªÆô') return totalPoint = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_BossRebornNeedPoint) if not totalPoint: totalPoint = SetBossRebornNeedPoint() if not totalPoint: GameWorld.Log(' Ôö¼Óboss¸´»îµã ûÓÐ×ܵãÊý£¡£¡£¡£¡') return curPoint = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint) updPoint = (curPoint+addPoint)%totalPoint PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint, updPoint) if curPoint+addPoint >= totalPoint: #ÖØÉúboss killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 1, {}) canRebornBossIDList = [] for bidlist, bkey in killBossCntLimitDict.items(): if bkey not in [0, 1]: continue canRebornBossIDList += list(bidlist) GameWorld.Log('canRebornBossIDList=%s'%canRebornBossIDList) bossIDList = [] for i, bossInfo in enumerate(PyGameData.g_sortBOSSRefreshList): bossID, killedTime, refreshTime = bossInfo if bossID not in canRebornBossIDList: continue isAlive = __GetIsAlive(bossID) if isAlive: continue refreshTime = 0 PyGameData.g_sortBOSSRefreshList[i] = [bossID, killedTime, refreshTime] bossIDList.append(bossID) GameWorld.Log(' boss¸´»î»î¶¯ ÖØÉúboss bossIDList=%s'%bossIDList) g_lastBossRebornTime = int(time.time()) else: #¹ã²¥ needNotifyPointPerList = IpyGameDataPY.GetFuncEvalCfg('BossRebornNotify') for pointPer in needNotifyPointPerList: nPoint = totalPoint * pointPer / 100 if curPoint < nPoint <= updPoint: PlayerControl.WorldNotify(0, 'BossFHPoint1', [updPoint]) break Sync_BossRebornPoint() return def ResetBossRebornPoint(): ## ÖØÖÃboss¸´»îµã PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint, 0) # »î¶¯¿ªÆôʱÉèÖòÎÊý ·þÎñÆ÷ÈËÊý lvLimit = IpyGameDataPY.GetFuncCfg('ServerActivePlayerCnt') yesterdayPlayerCnt = len([1 for lv in PyGameData.g_yesterdayPlayerLVDict.values() if lv >= lvLimit]) #²ÎÊý×òÈÕ»îÔ¾ÈËÊý serverActivePlayerCnt = eval(IpyGameDataPY.GetFuncCompileCfg('ServerActivePlayerCnt', 2)) PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BRServerPlayerCnt, serverActivePlayerCnt) GameWorld.Log(' boss¸´»î»î¶¯¿ªÆôʱÉèÖÃ×òÈÕ»îÔ¾ÈËÊýyesterdayPlayerCnt=%s'%yesterdayPlayerCnt) #ÖØÐ¼ÆËãÐèÒª×ܵãÊý SetBossRebornNeedPoint() Sync_BossRebornPoint() return def SetBossRebornNeedPoint(isSync=False): totalPointList = IpyGameDataPY.GetFuncEvalCfg('BossRebornTotalPoint') playerCntList = IpyGameDataPY.GetFuncEvalCfg('BossRebornTotalPoint', 2) BRServerPlayerCnt = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BRServerPlayerCnt) index = len(playerCntList)-1 for i, cnt in enumerate(playerCntList): preCnt = 0 if i ==0 else playerCntList[i-1] if preCnt <=BRServerPlayerCnt < cnt: index = i break totalPoint = totalPointList[-1] if index >= len(totalPointList) else totalPointList[index] GameWorld.GetGameWorld().SetDict(ChConfig.Def_WorldKey_BossRebornNeedPoint, totalPoint) if isSync: Sync_BossRebornPoint() return totalPoint def BossRebornWorldNotify(curTime): global g_lastBossRebornTime if not g_lastBossRebornTime: return notifySecondList = IpyGameDataPY.GetFuncEvalCfg('BossRebornNotify', 2) if curTime - g_lastBossRebornTime > notifySecondList[-1]: g_lastBossRebornTime = 0 return if (curTime - g_lastBossRebornTime) in notifySecondList: PlayerControl.WorldNotify(0, 'BossFHPoint2') return def Sync_BossRebornPoint(curPlayer=None): ##֪ͨBOSS¸´»îµãÊý packData = ChPyNetSendPack.tagGCBossRebornPoint() packData.Point = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BossRebornPoint) totalPoint = GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_BossRebornNeedPoint) if not totalPoint: totalPoint = SetBossRebornNeedPoint() packData.TotalPoint = totalPoint playerManager = GameWorld.GetPlayerManager() if not curPlayer: 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 Sync_DogzNPCRefreshTime(msgList): #ͬ²½ÉñÊÞ¸±±¾NPCË¢ÐÂʱ¼ä playerID, refreshTimeDict = msgList curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if playerID else None if playerID and not curPlayer: return if not refreshTimeDict: return packData = ChPyNetSendPack.tagGCDogzNPCRefreshTime() packData.InfoList=[] for npcid, rTime in refreshTimeDict.items(): timeInfo = ChPyNetSendPack.tagDogzTimeInfoObj() timeInfo.NPCID = npcid timeInfo.RefreshSecond = rTime packData.InfoList.append(timeInfo) packData.Cnt = len(packData.InfoList) if not playerID: 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