| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package NPCHurtMgr  | 
| #  | 
| # @todo:NPCÉËѪ¹ÜÀí  | 
| # @author hxp  | 
| # @date 2020Äê03ÔÂ16ÈÕ  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: NPCÉËѪ¹ÜÀí  | 
| #  | 
| # ÓÉÓÚ NPCHurtManager Ä£¿é֮ǰÕë¶ÔÐÖú×öµÄ£¬²âÊԱȽÏÂé·³£¬ÎªÁ˲»È¥¶¯µ½ÔÀ´µÄÄ£¿éÂß¼£¬¹ÊÐÂдһ¸öÉËѪģ¿é¹ÜÀí  | 
| # ÐÂÄ£¿éÉËѪÁбíͨÓÃÂß¼Óɸ¸Àà´¦Àí£¬ÇÒº¯ÊýÃüÃûÓëc++½Ó¿ÚÌṩµÄº¯ÊýÃûÒ»Ö£¬²»Í¬ÐèÇóÀàÐ͵ÄÉËѪÁбí¶îÍâÂß¼Ôò¿ÉÀ©Õ¹×ÓÀà½øÐд¦Àí  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2020Äê03ÔÂ16ÈÕ 18:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import PyGameData  | 
| import IPY_GameWorld  | 
| import IpyGameDataPY  | 
| import PlayerBossReborn  | 
| import PlayerActHorsePetFeast  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import ShareDefine  | 
| import PlayerTeam  | 
| import NPCCommon  | 
| import ChConfig  | 
| import GameObj  | 
|   | 
|   | 
| class HurtValueObj():  | 
|     ''' ÉËѪ¶ÔÏ󣬿ÉÄÜÊÇÍæ¼Ò¡¢¶ÓÎéµÈ  | 
|     '''  | 
|       | 
|     def __init__(self):  | 
|         self.__hurtID = 0  | 
|         self.__hurtType = ChConfig.Def_NPCHurtTypePlayer # ¾ùĬÈÏÊÇÍæ¼Ò  | 
|         self.__hurtName = ""  | 
|         self.__hurtValue = 0  | 
|         return  | 
|       | 
|     def GetValueID(self): return self.__hurtID  | 
|     def SetValueID(self, hurtID): self.__hurtID = hurtID  | 
|     def GetValueType(self): return self.__hurtType  | 
|     def SetValueType(self, hurtType): self.__hurtType = hurtType  | 
|     def GetHurtName(self): return self.__hurtName  | 
|     def SetHurtName(self, hurtName): self.__hurtName = hurtName  | 
|     def GetHurtValue(self): return self.__hurtValue  | 
|     def SetHurtValue(self, hurtValue): self.__hurtValue = hurtValue  | 
|       | 
| class HurtValueObjList(object):  | 
|     ''' ÉËѪÁÐ±í¸¸À࣬ÀàËÆ IPY_GameObj.IPY_PlayerHurtList  | 
|                     Ö»×ö»ù´¡µÄÉËѪÀÛ¼Ó¡¢ÅÅÐòµÈ¹«¹²Âß¼  | 
|                       | 
|             ×¢Ò⣺  | 
|                 ÔÐÖúÉ˺¦ÒòΪÊÇ×îÏÈ×öµÄÂß¼£¬²âÊԱȽÏÂé·³£¬Ôݲ»Ð޸ļ̳иÃÀ࣬»¹ÊDZ£ÁôÔÀ´µÄµ¥¶À´¦Àí  | 
|                 ºóÐøÐèÒªÔö¼ÓµÄ²»Í¬ÉËѪ¹æÔòÂß¼¿ÉÖ±½Ó¼Ì³Ð¸ÃÀà½øÐÐÀ©Õ¹´¦Àí  | 
|                   | 
|     '''  | 
|       | 
|     def __init__(self, lineID, objID, npcID):  | 
|         GameWorld.DebugLog("¼ÓÔØNPCÉËѪÁбí!", npcID, lineID)  | 
|         self.lineID = lineID  | 
|         self.objID = objID  | 
|         self.npcID = npcID  | 
|         self.curNPC = GameWorld.FindNPCByID(objID)  | 
|           | 
|         self.__hurtPlayerDict = {} # ËùÓÐÉËÑªÍæ¼Ò¸öÌåʵÀý×Öµä {playerID:HurtValueObj, ...}  | 
|           | 
|         self.__hurtSortList = []  | 
|         self.__hurtDict = {} # ÉËѪÁбíʵÀý×ֵ䣬ʵ¼ÊµÄNPCÉËѪÁбíʵÀý£¬¿ÉÄܲ»ÊÇÍæ¼Ò{(hurtID, hurtType):HurtValueObj, ...}  | 
|           | 
|         self.checkHurtValidFunc = None # ¼ì²éÉËѪÓÐЧÐÔº¯Êý£¬ÎÞЧÉËѪÇå³ý£¬¿É²»ÉèÖã¬Ôò²»¼ì²é  | 
|         self.getHurtObjPlayerIDListFunc = None # »ñÈ¡ÉËѪÍÅÌåʵÀý°üº¬µÄÍæ¼ÒIDÁÐ±í£¬¿É²»ÉèÖã¬Ôò°´ÉËѪÀàÐÍÈ¡¶ÔӦĬÈÏIDÁÐ±í  | 
|         self.onKilledFunc = None # npc±»»÷ɱºóÐø´¦Àíº¯Êý£¬¿É²»ÉèÖà  | 
|         return  | 
|       | 
|     def Clear(self):  | 
|         GameWorld.DebugLog("Çå³ýNPCÉËѪÁбí!", self.npcID, self.lineID)  | 
|           | 
|         self.__hurtSortList = []  | 
|         self.__hurtDict = {}  | 
|         # ÖØÖÃËùÓÐÍæ¼ÒÉËѪֵ  | 
|         for hurtObj in self.__hurtPlayerDict.values():  | 
|             hurtObj.SetHurtValue(0)  | 
|         return  | 
|       | 
|     def OnDelete(self):  | 
|         return  | 
|       | 
|     def __GetHurtObj(self, hurtID, hurtType, hurtName=""):  | 
|         ## »ñÈ¡ÉËѪÁбíÉËѪÀàÐÍʵÀý£¬¿ÉÄÜÊǸöÈË¡¢¶ÓÎé¡¢¼Ò×å¡¢ÕóÓªµÈ  | 
|         hurtObj = None  | 
|         hurtKey = (hurtID, hurtType)  | 
|         if hurtKey not in self.__hurtDict:  | 
|             GameWorld.DebugLog("Ìí¼ÓÉËѪÁбí¶ÔÏó: hurtID=%s,hurtType=%s" % (hurtID, hurtType), self.npcID, self.lineID)  | 
|             hurtObj = HurtValueObj()  | 
|             hurtObj.SetValueID(hurtID)  | 
|             hurtObj.SetValueType(hurtType)  | 
|             hurtObj.SetHurtName(hurtName)  | 
|             self.__hurtDict[hurtKey] = hurtObj  | 
|         hurtObj = self.__hurtDict[hurtKey]  | 
|         return hurtObj  | 
|       | 
|     def __GetHurtPlayer(self, playerID, playerName=""):  | 
|         ## »ñÈ¡ÉËÑªÍæ¼ÒʵÀý, Ã¿¸öÍæ¼Ò¶ÀÁ¢, ÇÒÉËѪ¶ÀÁ¢Í³¼Æ  | 
|         hurtPlayer = None  | 
|         if playerID not in self.__hurtPlayerDict:  | 
|             GameWorld.DebugLog("Ìí¼ÓÉËÑªÍæ¼Ò: playerID=%s,playerName=%s" % (playerID, playerName), self.npcID, self.lineID)  | 
|             hurtPlayer = HurtValueObj()  | 
|             hurtPlayer.SetValueID(playerID)  | 
|             #hurtPlayer.SetHurtName(playerName)  | 
|             self.__hurtPlayerDict[playerID] = hurtPlayer  | 
|         hurtPlayer = self.__hurtPlayerDict[playerID]  | 
|         # ÒòΪÉËÑªÍæ¼Ò¿ÉÄÜÔÚijЩÇé¿öÏ´´½¨ÁËûÓÐÃû×ÖµÄʵÀý£¬ËùÒÔÕâÀïÔÚÓд«ÈëÃû×Öʱ½øÐÐÇ¿ÖÆ¸üР | 
|         if playerName:  | 
|             hurtPlayer.SetHurtName(playerName)  | 
|         return hurtPlayer  | 
|       | 
|     def AddHurtValue(self, playerID, playerName, addValue, hurtType, hurtID, hurtName):  | 
|         ''' Ìí¼ÓÉËѪ  | 
|         @param playerID: ¹±Ï×É˺¦µÄÍæ¼ÒID  | 
|         @param playerName: ¹±Ï×É˺¦µÄÍæ¼ÒÃû  | 
|         @param addValue: ¹±Ï×É˺¦Öµ  | 
|         @param hurtType: ÉËѪÍÅÌåʵÀýÀàÐÍ£¬¿ÉÄÜÊÇÍæ¼Ò¸öÈË¡¢¶ÓÎé¡¢¼Ò×å¡¢ÕóÓªµÈ  | 
|         @param hurtID: ÉËѪÍÅÌåʵÀýID  | 
|         @param hurtName: ÉËѪÍÅÌåʵÀýÃû  | 
|         '''  | 
|           | 
|         hurtObj = self.__GetHurtObj(hurtID, hurtType, hurtName)  | 
|           | 
|         # ÉËѪÁбíÉËѪÀÛ¼Ó£¬Ä³¸öÍÅÌåµÄÀÛ¼ÆÉ˺¦  | 
|         befValue = hurtObj.GetHurtValue()  | 
|         updValue = befValue + addValue  | 
|         hurtObj.SetHurtValue(updValue)  | 
|         isNewHurt = befValue == 0 and updValue > 0  | 
|           | 
|         hurtPlayer = self.__GetHurtPlayer(playerID, playerName)  | 
|         # ÉËÑªÍæ¼ÒÉËѪÀÛ¼Ó£¬Õâ¸ö½öÉËÑªÍæ¼Ò×Ô¼ºµÄ¸öÈËÊä³ö£¬·ÇÉËѪÁбíÖеĻã×ÜÊä³ö  | 
|         updHurtPlayerValue = hurtPlayer.GetHurtValue() + addValue  | 
|         hurtPlayer.SetHurtValue(updHurtPlayerValue)  | 
|           | 
|         #GameWorld.DebugLog("    hurtID=%s,hurtType=%s,updValue=%s (%s + %s), playerID=%s,updHurtPlayerValue=%s"   | 
|         #                   % (hurtID, hurtType, updValue, befValue, addValue, playerID, updHurtPlayerValue), self.npcID, self.lineID)  | 
|         if isNewHurt:  | 
|             self.__Sort()  | 
|               | 
|         return isNewHurt  | 
|       | 
|     def __CmpHurtValue(self, hurtObjA, hurtObjB):  | 
|         ## É˺¦ÅÅÐò±È½Ïº¯Êý  | 
|         if hurtObjA.GetHurtValue() > hurtObjB.GetHurtValue():  | 
|             return 1  | 
|         if hurtObjA.GetHurtValue() == hurtObjB.GetHurtValue():  | 
|             return 0  | 
|         return -1  | 
|       | 
|     def __Sort(self):  | 
|         ## ÉËѪÅÅÐò  | 
|         self.__hurtSortList = sorted(self.__hurtDict.values(), cmp=self.__CmpHurtValue, reverse=True)  | 
|         return  | 
|       | 
|     def __SyncHurtList(self):  | 
|         ## Í¬²½Ç°¶ËÉËѪÁÐ±í  | 
|           | 
|         syncPlayerIDList = []  | 
|         # Ôݶ¨ÅÅÐòºóĬÈÏͬ²½ÉËѪÁÐ±í¸øËùÓÐÏà¹ØÍæ¼Ò£¬ÉËѪΪ0µÄ²»Í¬²½Ç°¶Ë£¬½öÓÃÓÚºó¶ËÂß¼Óà  | 
|         hurtValueList = []  | 
|         for hurtObj in self.__hurtSortList:  | 
|             hurtValue = hurtObj.GetHurtValue()  | 
|             if not hurtValue:  | 
|                 continue  | 
|             syncPlayerIDList += self.__GetHurtObjAllPlayerID(hurtObj)  | 
|               | 
|             hurtValueObj = ChPyNetSendPack.tagMCBossHurtValue()  | 
|             hurtValueObj.HurtID = hurtObj.GetValueID()  | 
|             hurtValueObj.HurtType = hurtObj.GetValueType()  | 
|             hurtValueObj.HurtName = hurtObj.GetHurtName()  | 
|             hurtValueObj.HurtValue = hurtValue % ShareDefine.Def_PerPointValue  | 
|             hurtValueObj.HurtValueEx = hurtValue / ShareDefine.Def_PerPointValue  | 
|             hurtValueList.append(hurtValueObj)  | 
|               | 
|         if not syncPlayerIDList:  | 
|             return  | 
|           | 
|         bossHurtInfoPack = ChPyNetSendPack.tagMCBossHurtValueRankInfo()  | 
|         bossHurtInfoPack.ObjID = self.objID  | 
|         bossHurtInfoPack.HurtValueList = hurtValueList  | 
|         bossHurtInfoPack.HurtCount = len(hurtValueList)  | 
|           | 
|         curNPC = self.curNPC  | 
|         copyPlayerManager = GameWorld.GetMapCopyPlayerManager()  | 
|         for playerID in syncPlayerIDList:  | 
|             player = copyPlayerManager.FindPlayerByID(playerID)  | 
|             if not player:  | 
|                 continue  | 
|             if not player.CanSeeOther(curNPC):  | 
|                 continue  | 
|             NetPackCommon.SendFakePack(player, bossHurtInfoPack)  | 
|               | 
|         return  | 
|       | 
|     def RefreshHurtList(self, tick, refreshInterval=3000, isKilled=False):  | 
|         '''Ë¢ÐÂÉËѪÁÐ±í  | 
|         @return: atkPlayer, hurtID, hurtType  | 
|         '''  | 
|           | 
|         curNPC = self.curNPC  | 
|           | 
|         if not isKilled:  | 
|             if refreshInterval and tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < refreshInterval:  | 
|                 return self.__GetAtkObj(isKilled)  | 
|               | 
|         curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick)  | 
|           | 
|         # 1. ¼ì²éÇå³ýÎÞЧÉËѪ  | 
|         if self.checkHurtValidFunc:  | 
|             self.checkHurtValidFunc()  | 
|               | 
|         # 2. ÅÅÐò  | 
|         self.__Sort()  | 
|           | 
|         # 3. Í¬²½Ç°¶Ë  | 
|         self.__SyncHurtList()  | 
|           | 
|         # 4. »÷ɱ¸½¼ÓÂß¼  | 
|         if isKilled:  | 
|             if self.onKilledFunc:  | 
|                 self.onKilledFunc()  | 
|                   | 
|         return self.__GetAtkObj(isKilled)  | 
|       | 
|     def __GetAtkObj(self, isKilled):  | 
|         '''µÚÒ»¸ö¿É¹¥»÷µÄ×î´óÉËѪ¶ÔÏó  | 
|         @return: atkPlayer, hurtType, hurtID  | 
|         '''  | 
|         import AttackCommon  | 
|         atkPlayer, atkHurtType, atkHurtID = None, 0, 0  | 
|         curNPC = self.curNPC  | 
|         refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  | 
|         for rank, hurtObj in enumerate(self.__hurtSortList, 1):  | 
|               | 
|             hurtID = hurtObj.GetValueID()  | 
|             hurtType = hurtObj.GetValueType()  | 
|               | 
|             playerIDList = self.__GetHurtObjAllPlayerID(hurtObj)  | 
|               | 
|             playerDisableReason = {}  | 
|             maxHurtValue = 0  | 
|             for playerID in playerIDList:  | 
|                   | 
|                 player = GameWorld.GetObj(playerID, IPY_GameWorld.gotPlayer)  | 
|                 if player == None:  | 
|                     continue  | 
|                   | 
|                 if GameObj.GetHP(player) <= 0 or player.GetPlayerAction() == IPY_GameWorld.paDie:  | 
|                     playerDisableReason[playerID] = "dead"  | 
|                     continue  | 
|                   | 
|                 if not player.GetVisible() or not AttackCommon.CheckSightLevel(player, curNPC):  | 
|                     playerDisableReason[playerID] = "no visible or sightLevel different"  | 
|                     continue  | 
|                   | 
|                 if not self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):  | 
|                     playerDisableReason[playerID] = "not in boss area"  | 
|                     continue  | 
|                   | 
|                 if playerID not in self.__hurtPlayerDict:  | 
|                     playerDisableReason[playerID] = "no hurt"  | 
|                     continue  | 
|                 hurtPlayer = self.__hurtPlayerDict[playerID]  | 
|                 hurtValue = hurtPlayer.GetHurtValue()                  | 
|                 if hurtValue > maxHurtValue:  | 
|                     maxHurtValue = hurtValue  | 
|                     atkPlayer, atkHurtType, atkHurtID = player, hurtType, hurtID  | 
|                       | 
|             if maxHurtValue:  | 
|                 return atkPlayer, atkHurtType, atkHurtID  | 
|               | 
|             if rank == 1 and isKilled:  | 
|                 pass  | 
|                 #GameWorld.Log("bossËÀÍöʱ£¬µÚÒ»ÃûÍŶÓûÓйéÊôȨ! playerDisableReason=%s" % playerDisableReason)  | 
|                   | 
|         return atkPlayer, atkHurtType, atkHurtID  | 
|       | 
|     def __GetHurtObjAllPlayerID(self, hurtObj):  | 
|         ## »ñÈ¡ÉËѪʵÀýÍÅÌåËùÓеÄÍæ¼ÒID  | 
|           | 
|         hurtID = hurtObj.GetValueID()  | 
|         hurtType = hurtObj.GetValueType()  | 
|         if self.getHurtObjPlayerIDListFunc:  | 
|             return self.getHurtObjPlayerIDListFunc(hurtObj)  | 
|           | 
|         if hurtType == ChConfig.Def_NPCHurtTypePlayer:  | 
|             return [hurtID]  | 
|           | 
|         if hurtType == ChConfig.Def_NPCHurtTypeTeam:  | 
|             teamID = hurtID  | 
|             return PlayerTeam.GetMapTeamPlayerIDList(teamID)  | 
|           | 
|         return []  | 
|       | 
|     def GetIsInRefreshPoint(self, curPosX, curPosY, refreshPoint):  | 
|         if not refreshPoint:  | 
|             return False  | 
|           | 
|         if (curPosX >= refreshPoint.GetPosX() - refreshPoint.GetMoveDist() and  | 
|                 curPosX <= refreshPoint.GetPosX() + refreshPoint.GetMoveDist() and  | 
|                 curPosY >= refreshPoint.GetPosY() - refreshPoint.GetMoveDist() and  | 
|                 curPosY <= refreshPoint.GetPosY() + refreshPoint.GetMoveDist()):  | 
|             return True  | 
|           | 
|         return False  | 
|       | 
|     def GetHurtCount(self): return len(self.__hurtSortList)  | 
|     def GetHurtAt(self, index): return self.__hurtSortList[index]  | 
|       | 
|     def GetMaxHurtValue(self): return None if not self.__hurtSortList else self.__hurtSortList[0]  | 
|     def GetLastTimeHurtValue(self):  | 
|         return  | 
|       | 
| class PlayerRankHurtList(HurtValueObjList):  | 
|     ''' ÅÅÐÐÉËѪÁбí×ÓÀà, ÀàËÆ IPY_GameObj.IPY_PlayerHurtList  | 
|                     ÉËѪÁÐ±í¹æÔò:  | 
|                             Í³¼Æ¹éÊôÀàÐÍΪ ChConfig.DropOwnerType_RankHurtPlayer  | 
|                             ²»Ö§³ÖÐÖú£¬½öͳ¼Æ¸öÈËÉ˺¦£¬²»ÇåÉËѪ£¬¸ù¾ÝÍæ¼ÒÅÅÃû·¢·ÅÓʼþ½±Àø  | 
|     '''  | 
|       | 
|     def __init__(self, lineID, objID, npcID):  | 
|         super(PlayerRankHurtList, self).__init__(lineID, objID, npcID)  | 
|           | 
|         self.onKilledFunc = self.__DoNPCOnKilledLogic  | 
|         return  | 
|       | 
|     def Clear(self):  | 
|         ## ¸ÃÁÐ±í²»ÇåÉËѪ£¬ÖØÐ´Clearº¯Êý  | 
|         GameWorld.DebugLog("²»ÇåNPCÉËѪÁбí!", self.npcID, self.lineID)  | 
|           | 
|         return  | 
|       | 
|     def AddHurtValue(self, atkPlayer, addValue):  | 
|         ## Ìí¼ÓÍæ¼ÒÅÅÐÐÉËѪ  | 
|         playerID = atkPlayer.GetPlayerID()  | 
|         playerName = atkPlayer.GetPlayerName()  | 
|         hurtType = ChConfig.Def_NPCHurtTypePlayer # ¸ÃÁбíֻĬÈÏÍæ¼Ò  | 
|         super(PlayerRankHurtList, self).AddHurtValue(playerID, playerName, addValue, hurtType, playerID, playerName)  | 
|         return  | 
|       | 
|     def __DoNPCOnKilledLogic(self):  | 
|         ## Ö´ÐÐNPC»÷ɱºóÐø´¦ÀíÂß¼  | 
|           | 
|         if self.npcID == IpyGameDataPY.GetFuncCfg("BossRebornServerBoss", 3):  | 
|             PlayerBossReborn.DoBossRebornActionBossOnKilledLogic(self)  | 
|               | 
|         PlayerActHorsePetFeast.DoActBossOnKilledLogic(self)  | 
|           | 
|         ## Í¬Ñù°ñµ¥Âß¼µÄ²»Í¬¹¦Äܽ±Àø´¦Àí ...  | 
|           | 
|         return  | 
|   | 
| def __GetBossLineID(npcID):  | 
|     return GameWorld.GetGameWorld().GetLineID()  | 
|   | 
| def ClearPlayerHurtList(curNPC):  | 
|     ## Çå¿ÕÉËѪÁбí - ÖØÖÃNPC״̬ʱµ÷Óà  | 
|       | 
|     objID = curNPC.GetID()  | 
|     npcID = curNPC.GetNPCID()  | 
|     lineID = __GetBossLineID(npcID)  | 
|     key = (lineID, objID, npcID)  | 
|       | 
|     if key in PyGameData.g_npcHurtListDict:  | 
|         hurtList = PyGameData.g_npcHurtListDict[key]  | 
|         hurtList.Clear()  | 
|           | 
|     return  | 
|   | 
| def DeletePlayerHurtList(curNPC):  | 
|     ## É¾³ýÉËѪÁбí - NPCËÀÍöʱµ÷Óà  | 
|       | 
|     objID = curNPC.GetID()  | 
|     npcID = curNPC.GetNPCID()  | 
|     lineID = __GetBossLineID(npcID)  | 
|     key = (lineID, objID, npcID)  | 
|       | 
|     if key in PyGameData.g_npcHurtListDict:  | 
|         hurtList = PyGameData.g_npcHurtListDict.pop(key)  | 
|         hurtList.OnDelete()  | 
|           | 
|     return  | 
|   | 
| def RefreshHurtList(curNPC, tick, refreshInterval=3000, isKilled=False):  | 
|     ## Ë¢ÐÂÉËѪÁÐ±í  | 
|     # @return: atkPlayer, ownerType, ownerID  | 
|       | 
|     objID = curNPC.GetID()  | 
|     npcID = curNPC.GetNPCID()  | 
|     lineID = __GetBossLineID(npcID)  | 
|     key = (lineID, objID, npcID)  | 
|       | 
|     if key not in PyGameData.g_npcHurtListDict:  | 
|         return  | 
|     hurtList = PyGameData.g_npcHurtListDict[key]  | 
|     return hurtList.RefreshHurtList(tick, refreshInterval, isKilled)  | 
|   | 
| def AddHurtValue(atkPlayer, defNPC, value, isBounce):  | 
|     '''Ìí¼ÓÉËѪ  | 
|     @param isBounce: ÊÇ·ñ·´µ¯É˺¦£¬·´µ¯É˺¦²»¼ÆÈë·ÇÖ÷¶¯¹¥»÷µÄÍæ¼ÒÉËѪ£¬ÒòΪ¹æ¶¨Íæ¼Ò¹¥»÷ÁíÒ»¸öbossÔòÒªÇå³ýͬµØÍ¼ÉÏÒ»¸öbossµÄ¸ÃÍæ¼ÒÉ˺¦  | 
|                                                         ·ÀÖ¹ËÀÍö»Ø¸´»îµãÅÜͼÖб»Ö÷¶¯ÐÍboss¹¥»÷¼ÆÈëÉËѪµ¼ÖÂÇå³ýͬµØÍ¼ÉÏÒ»¸öÖ÷¶¯¹¥»÷µÄbossÉËѪ  | 
|     '''  | 
|       | 
|     if not ChConfig.IsGameBoss(defNPC):  | 
|         return  | 
|       | 
|     ## ¸ù¾Ý¸öÈËÉËѪÅÅÐÐÖ±½Ó¸ø½±ÀøµÄ  | 
|     if NPCCommon.GetDropOwnerType(defNPC) == ChConfig.DropOwnerType_RankHurtPlayer:  | 
|         hurtList = __AddNewHurtList(defNPC, PlayerRankHurtList)  | 
|           | 
|     ## ÆäËûÉËѪÁбí×ÓÀà¹ÜÀí ...  | 
|       | 
|     else:  | 
|         return  | 
|       | 
|     return hurtList.AddHurtValue(atkPlayer, value)  | 
|   | 
| def __AddNewHurtList(curNPC, className):  | 
|     objID = curNPC.GetID()  | 
|     npcID = curNPC.GetNPCID()  | 
|     lineID = __GetBossLineID(npcID)  | 
|     key = (lineID, objID, npcID)  | 
|     if key not in PyGameData.g_npcHurtListDict:  | 
|         hurtList = className(lineID, objID, npcID)  | 
|         PyGameData.g_npcHurtListDict[key] = hurtList  | 
|     hurtList = PyGameData.g_npcHurtListDict[key]  | 
|     return hurtList  | 
|   | 
| def GetPlayerHurtList(curNPC):  | 
|     ''' »ñÈ¡ÉËѪÁÐ±í£¬¿ÉÄÜΪNone  | 
|     '''  | 
|       | 
|     if not ChConfig.IsGameBoss(curNPC):  | 
|         return  | 
|       | 
|     objID = curNPC.GetID()  | 
|     npcID = curNPC.GetNPCID()  | 
|     lineID = __GetBossLineID(npcID)  | 
|     key = (lineID, objID, npcID)  | 
|     if key not in PyGameData.g_npcHurtListDict:  | 
|         return  | 
|       | 
|     return PyGameData.g_npcHurtListDict[key]  | 
|   |