| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #  | 
| ##@package E:/GameSVN/U3DGame/ProjectSServer/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py  | 
| # @todo:   | 
| #  | 
| # @author: Alee  | 
| # @date 2017-10-24 ÏÂÎç05:23:55  | 
| # @version 1.0  | 
| #  | 
| # @note:   | 
| #  | 
| #---------------------------------------------------------------------  | 
| #===============================================================================  | 
| # ËµÃ÷ ------------  | 
| # ÔÚC++ÖРIsBattleState µÄº¯Êý  | 
| # bool           Player::IsBattleState()  | 
| # {  | 
| #    //Èç¹ûÓÐNPC¶ÔÕâ¸öÍæ¼ÒÓгðºÞ, ÔòÊÇÕ½¶·×´Ì¬  | 
| #    if(m_AngryNPC.Count() != 0)  | 
| #        return  true;  | 
| #    return      m_IsBattleState;  | 
| # }  | 
| #   | 
| # ½á¹ûΪ ·µ»ØµÄÕæÖµ ²»Ò»¶¨´ú±í m_IsBattleStateÊÇÕæÖµ  | 
| #===============================================================================  | 
| import random  | 
| import GameWorld  | 
| import ChConfig  | 
| import IPY_GameWorld  | 
| import PlayerControl  | 
| import NPCCommon  | 
| #import ItemControler  | 
| import SkillCommon  | 
| import EffGetSet  | 
| import FBLogic  | 
| import EventShell  | 
| import ReadChConfig  | 
| import PetControl  | 
| import GameMap  | 
| import PlayerTruck  | 
| #import PlayerPrestigeSys  | 
| import PlayerFamily  | 
| #import BossHurtMng  | 
| import PassiveBuffEffMng  | 
| import PlayerSuccess  | 
| import GameFuncComm  | 
| import ShareDefine  | 
| import SkillShell  | 
| import PlayerVip  | 
| import FormulaControl  | 
| import IpyGameDataPY  | 
| import PyGameData  | 
| import GameObj  | 
| import BuffSkill  | 
| import PlayerState  | 
| import ChPyNetSendPack  | 
| import NPCHurtManager  | 
| import NetPackCommon  | 
| import FamilyRobBoss  | 
| import FBCommon  | 
| import ChNPC  | 
| import BossHurtMng  | 
| import NPCHurtMgr  | 
| import TurnAttack  | 
|   | 
| import datetime  | 
| import math  | 
| #---------------------------------------------------------------------  | 
|   | 
|   | 
|   | 
| # µ¥´ÎÉËѪÁбí°ü×°£¬NPCѪÁ¿Óг¬¹ý20EµÄÇé¿ö£¬ÓÃÓÚ֪ͨ·â°ü  | 
| # @param hurtList ÊÇg_skillHurtList  | 
| def AddHurt(tagObj, hurtList, hurtType, hurtValue):  | 
|     tagObjType = tagObj.GetGameObjType()  | 
|     hurtList.AddHurt(tagObjType, tagObj.GetID(), hurtType, hurtValue % ShareDefine.Def_PerPointValue,   | 
|                      hurtValue / ShareDefine.Def_PerPointValue, tagObj.GetHP(), tagObj.GetHPEx())  | 
|     return  | 
|   | 
| # ÉËѪÁбíÀÛ»ý¼Ç¼£¬³¬DWORDÌØÊâËõ¼õ´¦Àí  | 
| def AddHurtValue(defender, attackID, attackHurtType, value):  | 
|     defendHurtList = defender.GetPlayerHurtList()  | 
|     defendHurtList.AddHurtValue(attackID, attackHurtType, value % ShareDefine.Def_PerPointValue, value / ShareDefine.Def_PerPointValue)  | 
|     return  | 
|   | 
| def AddTeamPlayerHurtValue(defender, teamID, playerID, value):  | 
|     # Ìí¼Ó¶ÓÎé³ÉÔ±¶ÔNPCÉËѪÀÛ¼Æ  | 
|     if not teamID:  | 
|         return  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         return  | 
|     teamPlayerHurtDict = PyGameData.g_teamPlayerHurtValue  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     key = (lineID, defender.GetID(), defender.GetNPCID())  | 
|     if key not in teamPlayerHurtDict:  | 
|         teamPlayerHurtDict[key] = {}  | 
|     hurtDict = teamPlayerHurtDict[key]  | 
|     hurtKey = (teamID, playerID)  | 
|     hurtDict[hurtKey] = hurtDict.get(hurtKey, 0) + value  | 
|     #GameWorld.DebugLog("AddTeamPlayerHurtValue teamID=%s, playerID=%s, value=%s, key=%s, %s"   | 
|     #                   % (teamID, playerID, value, key, teamPlayerHurtDict))  | 
|     return  | 
|   | 
| def GetTeamPlayerHurtValue(curPlayer, defender):  | 
|     # »ñÈ¡¶ÓÎé³ÉÔ±¶ÔNPCµÄÉËѪÀÛ¼Æ  | 
|     teamPlayerHurtDict = PyGameData.g_teamPlayerHurtValue  | 
|     #GameWorld.DebugLog("GetTeamPlayerHurtValue %s" % (teamPlayerHurtDict))  | 
|     teamID = curPlayer.GetTeamID()  | 
|     if not teamID:  | 
|         return 0  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         return 0  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     key = (lineID, defender.GetID(), defender.GetNPCID())  | 
|     if key not in teamPlayerHurtDict:  | 
|         return 0  | 
|     hurtDict = teamPlayerHurtDict[key]  | 
|     hurtKey = (teamID, curPlayer.GetPlayerID())  | 
|     return hurtDict.get(hurtKey, 0)  | 
|   | 
| def GetTeamPlayerHurtPer(curPlayer, defender):  | 
|     # »ñÈ¡¶ÓÎé³ÉÔ±¶ÔNPCµÄÉËѪÁ¿ÔÚ¶ÓÎé×ÜÉËѪÁ¿µÄÕ¼±È  | 
|     teamPlayerHurtDict = PyGameData.g_teamPlayerHurtValue  | 
|     teamID = curPlayer.GetTeamID()  | 
|     if not teamID:  | 
|         return 0  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         return 0  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     key = (lineID, defender.GetID(), defender.GetNPCID())  | 
|     if key not in teamPlayerHurtDict:  | 
|         return 0  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     playerHurtValue = 0  | 
|     teamHurtValue = 0  | 
|     # ÕâÀïÖ»Ëã±¾¶ÓÎéÄÚ¶ÓÔ±µÄÉ˺¦±ÈÀý£¬¼´ ¶ÓÔ±É˺¦/±¾¶Ó¶ÓÔ±×ÜÉ˺¦  | 
|     hurtDict = teamPlayerHurtDict[key]  | 
|     for key, hurtValue in hurtDict.items():  | 
|         hurtTeamID, hurtPlayerID = key  | 
|         if hurtTeamID != teamID:  | 
|             continue  | 
|           | 
|         teamHurtValue += hurtValue  | 
|         if hurtPlayerID == playerID:  | 
|             playerHurtValue = hurtValue  | 
|       | 
|     if playerHurtValue == 0 or teamHurtValue == 0:  | 
|         hurtPer = 0  | 
|     else:  | 
|         hurtPer = playerHurtValue * 1.0 / teamHurtValue  | 
|     #GameWorld.DebugLog("GetTeamPlayerHurtPer playerHurtValue=%s,teamHurtValue=%s,maxHP=%s,hurtPer=%s"   | 
|     #                   % (playerHurtValue, teamHurtValue, GameObj.GetMaxHP(defender), hurtPer), playerID)  | 
|     return hurtPer  | 
|   | 
| def ClearTeamPlayerHurtValue(defender):  | 
|     # Çå³ýNPC¶ÓÎéÀÛ¼ÆÉËѪ  | 
|     teamPlayerHurtDict = PyGameData.g_teamPlayerHurtValue  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         return  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     key = (lineID, defender.GetID(), defender.GetNPCID())  | 
|     #GameWorld.DebugLog("ClearTeamPlayerHurtValue key=%s, %s" % (key, teamPlayerHurtDict))  | 
|     if key in teamPlayerHurtDict:  | 
|         teamPlayerHurtDict.pop(key)  | 
|     #GameWorld.DebugLog("    teamPlayerHurtDict=%s" % (teamPlayerHurtDict))  | 
|     return  | 
|   | 
| ## »ñµÃÍæ¼ÒPKÊÇ·ñºÏ·¨  | 
| #  @param curPlayer É±ÈËÕß  | 
| #  @param curTagPlayer ±»É±Õß  | 
| #  @return PKÊÇ·ñºÏ·¨  | 
| #  @remarks »ñµÃÍæ¼ÒPKÊÇ·ñºÏ·¨  | 
| def GetIsPKLegality(curPlayer, tagPlayer):  | 
|       | 
|     #Èç¹û²»ÊÇÍæ¼Ò»¥ÏàPK,²»´¦ÀíÂß¼  | 
|     if curPlayer == None or tagPlayer == None:  | 
|         return True  | 
|       | 
|     #Èç¹ûÔÚÌØÊ⸱±¾ÖУ¬ÄÇô¾ÍûÓгͷ£  | 
|     #if not FBLogic.DoFBAttackHasPunish(curPlayer , curTagPlayer):  | 
|     #    return True  | 
|       | 
|     #ºÏ·¨PKÇøÓò  | 
|     legalityAreaList = [IPY_GameWorld.gatFreePK, IPY_GameWorld.gatFamilyPK]  | 
|     if GameMap.GetAreaTypeByMapPos(curPlayer.GetPosX(), curPlayer.GetPosY()) in legalityAreaList \  | 
|         or GameMap.GetAreaTypeByMapPos(tagPlayer.GetPosX(), tagPlayer.GetPosY()) in legalityAreaList:  | 
|         return True  | 
|       | 
|     #¶ñÒâ¹¥»÷×Ô¼ºµÄÍæ¼Ò »ò ÓÐPKÖµµÄ(¶ñÒâɱÈ˲ŻáÓÐPKÖµ)  | 
|     if IsMaliciousAttackPlayer(curPlayer, tagPlayer) or tagPlayer.GetPKValue() > 0:  | 
|         #Ä¿±êÍæ¼ÒºìÃû  | 
|         return True  | 
|       | 
|     #ÆäËû¶¼²»ºÏ·¨£¬·µ»ØFalse  | 
|     return False  | 
|       | 
| ## ¼ì²âÍæ¼ÒPKËÀÍöºóÃû×ֱ仯  | 
| #  @param curPlayer É±ÈËÕß  | 
| #  @param curTagPlayer ±»É±Õß  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def AddPKValue(curPlayer, curTagPlayer, tick):  | 
|       | 
|     #PKºÏ·¨£¬²»³Í·££¬Ìø³ö  | 
|     if GetIsPKLegality(curPlayer, curTagPlayer):  | 
|         #GameWorld.DebugLog("ºÏ·¨»÷É±Íæ¼Ò!tagPlayerID=%s" % curTagPlayer.GetPlayerID(), curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     #Ôö¼ÓPKÖµ  | 
|     PlayerControl.AddPlayerPKValue(curPlayer, tick)  | 
|   | 
|     #֪ͨGameServer, Ìí¼Ó³ðÈË  | 
|     curTagPlayer.GameServer_AddEnemy(curPlayer.GetID(), curPlayer.GetName())  | 
|     return  | 
|   | 
|   | 
| ## µ±Íæ¼ÒɱËÀïÚ³µµÄʱºò´¥·¢  | 
| #  @param curPlayer É±ÈËÕß  | 
| #  @param defender ±»É±Õß  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def OnPlayerKillTruck(curPlayer, curTruck, tick):  | 
|       | 
|     if curPlayer == None or curTruck == None:  | 
|         return  | 
|       | 
|     #ÇøÓò  | 
|     curPlayerAreaType = GameMap.GetAreaTypeByMapPos(curPlayer.GetPosX(), curPlayer.GetPosY())  | 
|     truckAreaType = GameMap.GetAreaTypeByMapPos(curTruck.GetPosX(), curTruck.GetPosY())  | 
|       | 
|     #×ÔÓÉÇøÓò£¬ºÏ·¨£¬·µ»ØTrue  | 
|     if curPlayerAreaType == IPY_GameWorld.gatFreePK or truckAreaType == IPY_GameWorld.gatFreePK:         | 
|         return  | 
|       | 
|     #¼Ò×åÇøÓò£¬PK²»ÊÇͬһ¼Ò×åµÄÍæ¼Ò»òÆä³èÎºÏ·¨£¬·µ»ØTrue  | 
|     if curPlayerAreaType == IPY_GameWorld.gatFamilyPK or truckAreaType == IPY_GameWorld.gatFamilyPK:  | 
|         return  | 
|       | 
|     #ÒѾËÀÍöÁË,²»±äÉ«  | 
|     if GameObj.GetHP(curPlayer) <= 0:  | 
|         return  | 
|       | 
|     curPlayerNameColor = curPlayer.GetPlayerNameColor()  | 
|     #×Ô¼ºÈç¹û²»Êǰ×Ãû¾Í²»±äÉ«  | 
|     if curPlayerNameColor != IPY_GameWorld.pncNormal:  | 
|         return  | 
|       | 
|     curTruckNameColor = PlayerTruck.GetTruckNameColor(curTruck)  | 
|     if curTruckNameColor != IPY_GameWorld.pncNormal:  | 
|         #Ä¿±êÍæ¼Ò²»Êǰ×Ãû¾Í²»±äÉ«  | 
|         return  | 
|       | 
|     #»ÒÃû(9)  | 
|     #SkillCommon.AddBuffBySkillType(curPlayer , ChConfig.Def_SkillID_Gray , tick)  | 
|     return  | 
|   | 
|   | 
| ## µ±Íæ¼ÒɱËÀÍæ¼ÒµÄʱºò´¥·¢  | 
| #  @param curPlayer É±ÈËÕß  | 
| #  @param defender ±»É±Õß  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def OnPlayerKillPlayer(curPlayer, defender, tick):  | 
|       | 
|     PlayerState.SetPKStateTick(curPlayer, tick)  | 
|       | 
|     #´¥·¢»÷É±Íæ¼Òʼþ  | 
|     EventShell.EventResponse_OnKillEnemy(curPlayer, defender)  | 
|       | 
|     #´¥·¢±»É±Ê¼þ  | 
|     EventShell.EventResponse_OnEnemyKill(defender, curPlayer)  | 
|       | 
|     #֪ͨ  | 
|     PlayerControl.NotifyCode(defender, "PK_lhs_318691", [curPlayer.GetName()])  | 
|       | 
|     #¸øÓèɱÈ˽±Àø  | 
|     #if FBLogic.DoFBOnKill_Player_ValuePrize(curPlayer, defender, tick):  | 
|     __GiveKill_Player_ValuePrize(curPlayer, defender, tick)  | 
|       | 
|     NPCCommon.OnPlayerKillNPCPlayer(curPlayer, defender, tick)  | 
|       | 
|     #Ö´Ðи±±¾É±ÈËÂß¼  | 
|     if FBLogic.DoFBOnKill_Player(curPlayer, defender, tick):  | 
|         return  | 
|       | 
|     #¼ÓPKÖµ  | 
|     AddPKValue(curPlayer, defender, tick)  | 
|       | 
|     #»÷É±Íæ¼Ò¹ã²¥Âß¼  | 
|     __DoKillPlayerNotify(curPlayer, defender)  | 
|       | 
|     #´òbossÖв»Ôö¼Ó 2018/7/18¸ÄΪֻҪÔÚÒ°ÍâµØÍ¼±»ÆäËûÍæ¼ÒɱËÀ¶¼Ôö¼ÓÆ£ÀÍ  | 
|     #if not PlayerState.IsInBossState(curPlayer):  | 
|     if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:  | 
|         PlayerControl.NomalDictSetProperty(defender, ChConfig.Def_PDict_IsAddReviveTired, 1)  | 
|     return  | 
|   | 
|   | 
| ## »÷É±Íæ¼ÒÏà¹ØÌáʾ  | 
| #  @param attacker É±ÈËÕß  | 
| #  @param defender ±»É±Õß  | 
| #  @return None  | 
| def __DoKillPlayerNotify(attacker, defender):  | 
|       | 
|     defFamilyID = defender.GetFamilyID()  | 
|     if defFamilyID <= 0:  | 
|         return  | 
|               | 
|     defFamilyMemberLv = defender.GetFamilyMemberLV()  | 
|     defName = defender.GetName()  | 
|     atkName = attacker.GetName()  | 
|       | 
|     defMapID = defender.GetMapID()  | 
|     defPosX = defender.GetPosX()  | 
|     defPosY = defender.GetPosY()   | 
|     if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  | 
|         return  | 
|       | 
|     crossNotifyList = []  | 
|     isCrossServer = GameWorld.IsCrossServer()  | 
|     atkServerGroupID = PlayerControl.GetPlayerServerGroupID(attacker)  | 
|     defServerGroupID = PlayerControl.GetPlayerServerGroupID(defender)  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     # É±ÈËÍæ¼ÒÓаï»á  | 
|     if attacker.GetFamilyID() > 0:  | 
|         atkFamilyName = attacker.GetFamilyName()  | 
|         atkFamilyMemberLv = attacker.GetFamilyMemberLV()  | 
|           | 
|         notifyCode = 'PK_pan_671654'   | 
|         paramList = [defFamilyMemberLv, defName, defMapID, atkFamilyName, atkFamilyMemberLv, atkName, defPosX, defPosY, lineID]  | 
|           | 
|     else:  | 
|         # É±ÈËÍæ¼ÒÎÞ°ï»á  | 
|         notifyCode = 'PK_pan_318691'  | 
|         paramList = [defFamilyMemberLv, defName, defMapID, atkName,defPosX, defPosY, lineID]  | 
|       | 
|     if isCrossServer:  | 
|         crossNotifyList.append(PlayerControl.GetCrossFamilyNotifyInfo(defFamilyID, notifyCode, paramList))  | 
|     else:  | 
|         PlayerControl.FamilyNotify(defFamilyID, notifyCode, paramList)  | 
|       | 
|     # ÓÐְλ±»É±£¬È«·þ¹ã²¥  | 
|     if defFamilyMemberLv > 0:  | 
|         defFamilyName = defender.GetFamilyName()  | 
|       | 
|         killCnt = attacker.GetDictByKey(ChConfig.Def_PlayerKey_KillPlayerCnt % defender.GetPlayerID()) + 1  | 
|         attacker.SetDict(ChConfig.Def_PlayerKey_KillPlayerCnt % defender.GetPlayerID(), killCnt)  | 
|         #±»É±ÖØÖû÷ɱÊý  | 
|         defender.SetDict(ChConfig.Def_PlayerKey_KillPlayerCnt % attacker.GetPlayerID(), 0)  | 
|           | 
|         killPlayerNotifyDict = IpyGameDataPY.GetFuncEvalCfg('FamilyKilledNotify')  | 
|           | 
|         killKeys = sorted(killPlayerNotifyDict.keys())  | 
|         notifyKey = 0   | 
|         for killCntKey in killKeys:  | 
|             if killCnt < killCntKey:  | 
|                 break  | 
|             notifyKey = killCntKey  | 
|         if notifyKey in killPlayerNotifyDict:  | 
|             notifyMark = killPlayerNotifyDict[notifyKey]  | 
|             msgParamList = [atkName, defMapID, defFamilyName, defFamilyMemberLv, defName]  | 
|             if isCrossServer:  | 
|                 crossNotifyList.append(PlayerControl.GetCrossWorldNotifyInfo(0, notifyMark, msgParamList))  | 
|                 if atkServerGroupID != defServerGroupID:  | 
|                     PlayerControl.NotifyCode(attacker, notifyMark, msgParamList)  | 
|             else:  | 
|                 PlayerControl.WorldNotify(0, notifyMark, msgParamList)  | 
|                   | 
|     if crossNotifyList:  | 
|         PlayerControl.CrossNotify([defServerGroupID], crossNotifyList)  | 
|           | 
|     return  | 
|   | 
| def OnNPCHitPlayer(curNPC, defender, tick):  | 
|     if ChConfig.IsGameBoss(curNPC):  | 
|         PlayerState.SetBossStateTick(defender, tick)  | 
|     return  | 
|   | 
| ## µ±Íæ¼Ò¹¥»÷Íæ¼ÒµÄʱºò´¥·¢  | 
| #  @param curPlayer ¹¥»÷Obj  | 
| #  @param defender ·ÀÓùObj  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def OnPlayerHitPlayer(attacker, defender, tick):  | 
|     #´¦Àí¸±±¾¹¥»÷Íæ¼Òʼþ  | 
|     if attacker.GetID() == defender.GetID():  | 
|         #GameWorld.DebugLog("×Ô¼º²»´¦Àí: %s" % attacker.GetID())  | 
|         return  | 
|       | 
|     #if FBLogic.DoFBOnHit_Player(attacker, defender, tick):  | 
|     #    return  | 
|       | 
|     #¶ñÒâ¹¥»÷  | 
|     if not GetIsPKLegality(attacker, defender):  | 
|         AddMaliciousAttackPlayer(attacker, defender, tick)  | 
|         #»ÒÃû(9)  | 
|         #SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_Gray, tick)  | 
|     else:  | 
|         UpdMaliciousAttackTick(attacker, defender, tick)  | 
|           | 
|     #Ìí¼ÓÉËѪ¼Ç¼  | 
|     AddPlayerHitPlayerHurt(attacker, defender, tick)  | 
|       | 
|     #Ö»ÒªÒ»·½·¢Æð¹¥»÷£¬Ë«·½¾ù½øÈëPK״̬  | 
|     PlayerState.SetPKStateTick(attacker, tick)  | 
|     PlayerState.SetPKStateTick(defender, tick)  | 
|     return  | 
|   | 
| ## Ìí¼ÓÉËѪ¼Ç¼  | 
| #  @param curPlayer ¹¥»÷Obj  | 
| #  @param defender ·ÀÓùObj  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def AddPlayerHitPlayerHurt(attacker, defender, tick):  | 
|     #Ìí¼ÓÉËѪ¼Ç¼  | 
|     defPlayerHurtList = defender.GetPlayerHurtList()  | 
|       | 
|     #³¬¹ýÉÏÏÞÁË, ²»Ìí¼Ó  | 
|     if defPlayerHurtList.GetHurtCount() >= ChConfig.Def_PlayerHurtListCount:  | 
|         return  | 
|       | 
|     AddHurtValue(defender, attacker.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1)  | 
|     return  | 
|   | 
| ## ±»¹¥»÷Õß±»¶¯buff´¥·¢  | 
| #  @param curTagPlayer ±»¹¥»÷Õß  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @param isSuperHit ±©»÷  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def DefenderSpringBuff(curTagPlayer, tick, isSuperHit=False):  | 
|     return  | 
|      | 
| #---------------------------------------------------------------------  | 
|   | 
| def GetBattleRelationType(attacker, defender):  | 
|     if not defender:  | 
|         return ChConfig.Def_BattleRelationType_Comm  | 
|       | 
|     #0ͨÓà 1 PVPÀàÐÍ  2PVEÀàÐÍ    | 
|     attackPlayer, attackNPC = GetAttackPlayer(attacker)  | 
|     defenderPlayer, defenderNPC = GetAttackPlayer(defender)  | 
|       | 
|     if attackPlayer and defenderPlayer:  | 
|         return ChConfig.Def_BattleRelationType_PVP  | 
|       | 
|     return ChConfig.Def_BattleRelationType_PVE  | 
|   | 
| # ÅжÏPK¹ØÏµÊÇ·ñ¿É¹¥»÷ Def_BattleRelationType_CommNoBossÒ²¿É¹¥»÷ Ö»Êǹ¥»÷ÎÞЧ¹û  | 
| def CheckBattleRelationType(attacker, defender, curSkill, battleRelationType):  | 
|     skillBattleType = SkillCommon.GetSkillBattleType(curSkill)  | 
|     if skillBattleType in [ChConfig.Def_BattleRelationType_Comm, ChConfig.Def_BattleRelationType_CommNoBoss]:  | 
|         return True  | 
|       | 
|     #if battleRelationType in [ChConfig.Def_BattleRelationType_Comm, ChConfig.Def_BattleRelationType_CommNoBoss]:  | 
|     #    return True  | 
|       | 
|     # µ±·ÇPVP¹ØÏµÊ±£¬ÌØÊâPVP¼¼ÄÜ  | 
|     if battleRelationType != ChConfig.Def_BattleRelationType_PVP:  | 
|         if curSkill.GetSkillType() in [ChConfig.Def_SkillType_Atk, ChConfig.Def_SkillType_Passive] \  | 
|             and SkillCommon.GetSkillBattleType(curSkill) == ChConfig.Def_BattleRelationType_PVP:  | 
|             if attacker.GetGameObjType() == IPY_GameWorld.gotPlayer and IsPVPNPC(defender):  | 
|                 #GameWorld.DebugLog("---ÌØÊâPVP¹ØÏµ atkID=%s vs defID=%s, skillID=%s" % (attacker.GetID(), defender.GetID(), curSkill.GetSkillID()))  | 
|                 return True  | 
|               | 
|     if skillBattleType != battleRelationType:  | 
|         # PKģʽµÄÅж¨  | 
|         return False  | 
|     return True  | 
|   | 
| def IsPVPNPC(obj):  | 
|     if not obj:  | 
|         return False  | 
|     return obj.GetGameObjType() == IPY_GameWorld.gotNPC and obj.GetType() in ChConfig.PVPNPCTypeList  | 
|   | 
| ## »ñÈ¡¹¥»÷ÀàÐÍ  | 
| #  @param attack ¹¥»÷·½¶ÔÏó  | 
| #  @param attackUseSkill ¹¥»÷·½Ê¹Óõļ¼ÄÜ  | 
| #  @return ¹¥»÷ÀàÐÍ Èç IPY_GameWorld.ghtPhy  | 
| #  @remarks »ñÈ¡¹¥»÷ÀàÐÍ  | 
| def GetBattleType(attack, attackUseSkill):  | 
|     # GetHurtTypeÓ÷¨¸Ä³É pvp pve±êʶ  | 
|     return SkillCommon.GetBattleType(attackUseSkill)  | 
|     #return IPY_GameWorld.ghtPhy  | 
| #    #---¼¼Äܹ¥»÷, ¶Á±í»ñÈ¡¹¥»÷ÀàÐÍ---  | 
| #    if attackUseSkill != None:  | 
| #        return attackUseSkill.GetHurtType()  | 
| #  | 
| #    #---ÆÕͨ¹¥»÷---  | 
| #  | 
| #    #Íæ¼ÒËãÆÕͨ¹¥»÷  | 
| #    if attack.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
| #        return IPY_GameWorld.ghtPhy  | 
| #  | 
| #    #NPC¶Á±íÈ¡  | 
| #    return attack.GetHurtType()  | 
|   | 
| ## ÊäÈë»ù´¡ÊýÖµ,·µ»ØÔöÇ¿ºóµÄÖµ - ¼¼ÄܼÓÇ¿  | 
| #  @param value »ù´¡Öµ  | 
| #  @param skill ¼¼ÄÜ  | 
| #  @return ÔöÇ¿ºóµÄÖµ  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetEnhanceValue(value, skill):  | 
|     per = skill.GetEffect(0).GetEffectValue(0)  | 
|     eff = skill.GetEffect(0).GetEffectValue(1)  | 
|     #GameWorld.Log("±»¶¯ -> ×ÔÉíÊôÐÔ,¼¼ÄÜID = %s,¼¼ÄÜÔöÇ¿ = %s,¸½¼Ó = %s , »ù´¡Öµ = %s"%(skill.GetSkillName(),per,eff,value))  | 
|     return max(value * per / ChConfig.Def_MaxRateValue + eff , 1)  | 
|   | 
| ## ÊäÈë»ù´¡ÊýÖµ,·µ»ØÔöÇ¿ºóµÄÖµ (LV)- Ð§¹û¼ÓÇ¿  | 
| #  @param value »ù´¡Öµ  | 
| #  @param eff Ð§¹û  | 
| #  @return ÔöÇ¿ºóµÄÖµ  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetEnhanceValue_Eff(value, eff):  | 
|     per = eff.GetEffectValue(0)  | 
|     eff = eff.GetEffectValue(1)  | 
|     #GameWorld.Log("value = %s,per = %s,erf = %s"%(value,per,eff))  | 
|     return max(value * per / ChConfig.Def_MaxRateValue + eff , 1)  | 
|   | 
| ## ÊäÈë»ù´¡Ð§¹ûÖµ,(Íæ¼ÒË÷Òý) -> ¼¼ÄÜÔöÇ¿  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curEffect µ±Ç°Ð§¹û  | 
| #  @return ÔöÇ¿ºóµÄÖµ  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetEnhanceIndexValue_Eff(curPlayer, curEffect):  | 
|     index = curEffect.GetEffectValue(0)  | 
|     skillPer = curEffect.GetEffectValue(1)  | 
|     effect = curEffect.GetEffectValue(2)  | 
|     maxValue = EffGetSet.GetValueByEffIndex(curPlayer, index)  | 
|     #GameWorld.Log("-----%s,%s,%s,%s"%(index,skillPer,effect,maxValue))  | 
|       | 
|     if maxValue == None:  | 
|         return 0  | 
|       | 
|     return max(maxValue * skillPer / ChConfig.Def_MaxRateValue + effect , 1)  | 
| #--------------------------------------------------------------------------  | 
| ## ÉèÖÃÍæ¼Ò½øÈëÕ½¶·×´Ì¬  | 
| #  @param defender µ±Ç°Íæ¼Ò£¨±»¹¥»÷ÁË£©  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def SetPlayerBattleState(defender, tick):  | 
|     #ÉèÖÃÍæ¼Ò¿ªÊ¼Õ½¶·Ê±¼ä  | 
|     defender.SetLastBattleTick(tick)  | 
|       | 
|     #·ÇÕ½¶·ÖÐ,½øÈëÕ½¶·×´Ì¬  | 
|     defender.SetBattleState(True)  | 
|       | 
|     return  | 
| #--------------------------------------------------------------------------  | 
|   | 
| ## ¸øµ±Ç°Íæ¼ÒµÄËùÓÐÕÙ»½ÊÞÌí¼Ó³ðºÞ   | 
| #  @param curObj ³ðºÞ¶ÔÏó  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param angryValue ³ðºÞÖµ  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def SummonAddAngryByOwner(curObj, curPlayer, angryValue):  | 
|     #Íæ¼ÒµÄÕÙ»½ÊÞ,Èç¹ûÖ÷È˹¥»÷ģʽ²»¿É¹¥»÷µ±Ç°Ä¿±ê,È«²¿²»Ìí¼Ó  | 
|     if curObj.GetGameObjType() == IPY_GameWorld.gotPlayer and not CheckPlayerAttackMode_Player(curPlayer, curObj):  | 
|         return  | 
|       | 
|     #Èç¹û¹¥»÷·½ÊÇNPC²¢ÇÒÊÇÏÝÚåÔò²»Ìí¼Ó³ðºÞ  | 
|     if curObj.GetGameObjType() == IPY_GameWorld.gotNPC and \  | 
|     curObj.GetType() == IPY_GameWorld.ntFairy:  | 
|         return  | 
|           | 
|     #¸øÕâ¸öÍæ¼ÒµÄÕÙ»½ÊÞÌí¼Ó³ðºÞ  | 
|     for i in range(0, curPlayer.GetSummonCount()):  | 
|         curTagSummon = curPlayer.GetSummonNPCAt(i)  | 
|         #²»¾ß±¸¹¥»÷ÄÜÁ¦µÄÕÙ»½ÊÞ,²»Ìí¼Ó  | 
|         if not GetNPC_Has_Attack(curTagSummon):  | 
|             continue  | 
|           | 
|         #¹Ì¶¨µÄÕÙ»½ÊÞ³¬¹ý¹¥»÷¾àÀë,²»Ìí¼Ó  | 
|         if not curTagSummon.GetOrgSpeed() and not CheckNPCAttackDist(curTagSummon, curObj, None):  | 
|             continue  | 
|           | 
|         summonControl = NPCCommon.NPCControl(curTagSummon)  | 
|         summonControl.AddObjToAngryList(curObj, angryValue, True, False)  | 
|       | 
|     #---Èç¹ûÕâ¸öÍæ¼ÒÓгèÎï³öÕ½£¬ÔòÌí¼Ó³ðºÞ---  | 
|     petMgr = curPlayer.GetPetMgr()  | 
|     fightPetObj = petMgr.GetFightPet()  # ³öÕ½µÄ³èÎï¶ÔÏó  | 
|     if fightPetObj != None:  | 
|         petControl = NPCCommon.NPCControl(fightPetObj)  | 
|         petControl.AddObjToAngryList(curObj, angryValue)  | 
|           | 
|     return  | 
|   | 
| ## ¼ì²éNPCÊÇ·ñÓй¥»÷Á¦  | 
| #  @param curNPC µ±Ç°NPC  | 
| #  @return npcµÄ¹¥»÷Á¦  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetNPC_Has_Attack(curNPC):  | 
|     #×îСÎï¹¥, ×î´óÎï¹¥  | 
|     return (curNPC.GetMinAtk() or curNPC.GetMaxAtk())  | 
|   | 
| #--------------------------------------------------------------------------  | 
|   | 
| ## Íæ¼Ò¹¥»÷ʧ°ÜϵͳÌáʾ  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param message ÌáʾÐÅÏ¢ ÈçChConfig.Def_PASysMessage_None  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def PlayerAttackFailSysMessanage(curPlayer , message):  | 
|       | 
|     #ÎÞÌáʾ£¬Ö±½ÓÌø³ö  | 
|     if message == ChConfig.Def_PASysMessage_None:  | 
|         return  | 
|       | 
|     #ÌáʾÔÒò¼°¶ÔÓ¦µÄÌáʾmark×é³ÉµÄ×Öµä  | 
|     messageDic = ChConfig.Def_MessageDic  | 
|       | 
|     #ÕÒ²»µ½´«ÈëµÄÔÒò¶ÔÓ¦µÄÌáʾmark£¬Ìø³ö  | 
|     if message not in messageDic.keys():  | 
|         GameWorld.ErrLog('Íæ¼Ò¹¥»÷ʧ°ÜϵͳÌáʾÕÒ²»µ½¶ÔÓ¦µÄÌáʾmark,´«ÈëµÄÔÒò£º%s' % message, curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     PlayerControl.NotifyCode(curPlayer, messageDic[message])  | 
|       | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## Íæ¼Ò¹¥»÷ģʽÅжϠ  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curTagPlayer Ä¿±êÍæ¼Ò   | 
| #  @return True or False ÊÇ·ñ¿ÉÒÔ¹¥»÷Ä¿±ê  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayerAttackMode_Player(curPlayer, curTagPlayer) :  | 
|       | 
|     #´Ë²»×öÅж¨£¬Í³Ò»ÔÚGetPlayersRelation(curPlayer, curTagPlayer)º¯ÊýÖÐ×öÅж¨  | 
|     #·µ»Ø¿É¹¥»÷  | 
|     return True  | 
|       | 
|       | 
| #===============================================================================  | 
| #---------------------------------------------------------------------  | 
| #2010-5-26 chenxuewei ½£Ê¥ÏîÄ¿ÐÂÊÖ×î´óµÈ¼¶Îª30¼¶£¨Ìáµ½ChConfig£©  | 
| ## »ñµÃÊÇ·ñÊÇÐÂÊÖ  | 
| #  @param curPlayer Íæ¼Ò¶ÔÏó  | 
| #  @return True or False  | 
| #  @remarks »ñµÃcurPlayerÊÇ·ñÊÇÐÂÊÖ  | 
| def GetIsNewGuy(curPlayer):  | 
|       | 
|     if curPlayer.GetLV() < IpyGameDataPY.GetFuncCfg("PKConfig", 5):  | 
|         return True  | 
|       | 
|     return False  | 
|   | 
| #---------------------------------------------------------------------  | 
| #¹ØÏµÓÐ3²ã£¬ÎÞ-ÓѺÃ-µÐÈË  | 
| ## ÅжÏÊÇ·ñÎÞ¹ØÏµ£¬¼´ÊÇ·ñ¿ÉÊÍ·Å(Ôö/¼õ)¼¼ÄÜ»òÆÕ¹¥  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curTagPlayer Ä¿±êÍæ¼Ò   | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayersRelationInFB_IsNone(curPlayer , curTagPlayer):  | 
|     mapType = GameWorld.GetMap().GetMapFBType()  | 
|     #²»ÔÚ¸±±¾ÖÐ  | 
|     if mapType == IPY_GameWorld.fbtNull:  | 
|         return False  | 
|       | 
|     return FBLogic.CheckPlayersRelationInFB_IsNone(curPlayer , curTagPlayer)  | 
|   | 
| #¹ØÏµÓÐ3²ã£¬ÎÞ-ÓѺÃ-µÐÈË  | 
| ##ÅжÏÊÇ·ñÓѺùØÏµ£¬¸Ã²ãÅж¨ÎªÓѺÃÂß¼ÖеÄ×îºóÅÐ¶Ï  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param curTagPlayer Ä¿±êÍæ¼ÒʵÀý  | 
| # @return ²¼¶ûÖµ  | 
| def CheckPlayersRelationInFB_IsFriend(curPlayer, curTagPlayer):  | 
|     # hxp - ²»×öµØÍ¼ÀàÐÍÅжϣ¬ÔÚÄÚ²ãÅжϣ¬ÊÊÓ¦ËùÓеØÍ¼£¬Õ½ÃËÌìÌÃÐèÇó  | 
| #    mapType = GameWorld.GetMap().GetMapFBType()  | 
| #    #²»ÔÚ¸±±¾ÖÐ  | 
| #    if mapType == IPY_GameWorld.fbtNull:  | 
| #        return False  | 
|       | 
|     return FBLogic.CheckPlayersRelationInFB_IsFriend(curPlayer , curTagPlayer)  | 
|   | 
|   | 
| ## Íæ¼ÒÔÚ¸±±¾ÖÐ,¿É·ñ¹¥»÷¶ÔÔ±  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curTagPlayer Ä¿±êÍæ¼Ò   | 
| #  @return True or False  | 
| #  @remarks Íæ¼ÒÔÚ¸±±¾ÖÐ,¿É·ñ¹¥»÷¶ÔÔ±  | 
| def PlayerCanAttackTeamerInFB(curPlayer , curTagPlayer):  | 
|     # hxp - ²»×öµØÍ¼ÀàÐÍÅжϣ¬ÔÚÄÚ²ãÅжϣ¬ÊÊÓ¦ËùÓеØÍ¼£¬Õ½ÃËÌìÌÃÐèÇó  | 
| #    mapType = GameWorld.GetMap().GetMapFBType()  | 
| #    #²»ÔÚ¸±±¾ÖÐ  | 
| #    if mapType == IPY_GameWorld.fbtNull:  | 
| #        return False  | 
|       | 
|     return FBLogic.DoCanAttackTeamer(curPlayer , curTagPlayer)  | 
|   | 
| #--------------------------------------------------------------------------  | 
|   | 
| ## Ìí¼Ó¶ÔÏóµ½NPCÉËѪÁÐ±í   | 
| #  @param curObj ¹¥»÷·½  | 
| #  @param curTagNPC ·ÀÊØ·½(NPC)  | 
| #  @param curTaglNPCHPBefore ·ÀÊØ·½±»¹¥»÷ǰѪÁ¿  | 
| #  @param hurtHP ¹¥»÷ÉËѪֵ  | 
| #  @return None or True  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def NPCAddObjInHurtList(curObj, curTagObj, curTaglNPCHPBefore, hurtHP, isBounce=False):  | 
|     if curObj == None:  | 
|         GameWorld.ErrLog("NPCAddObjInHurtList NoFindObj")  | 
|         return  | 
|       | 
|     #if curTaglNPCHPBefore < hurtHP:  | 
|     #    hurtHP = curTaglNPCHPBefore  | 
|           | 
|     curObjType = curObj.GetGameObjType()  | 
|     if curObjType == IPY_GameWorld.gotPlayer:  | 
|         #BossHurtMng.BossAddPlayerInHurtList(curObj, curTagObj, hurtHP)  | 
|         FamilyRobBoss.OnPlayerHurtFamilyOwnerBoss(curObj, curTagObj, hurtHP)  | 
|         if curTagObj.GetGameObjType() == IPY_GameWorld.gotNPC:  | 
|             FBLogic.DoFB_Player_HurtNPC(curObj, curTagObj, hurtHP)  | 
|         if GameObj.GetHP(curTagObj) == 0:  | 
|             curTagObj.SetDict(ChConfig.Def_PlayerKey_LastHurt, curObj.GetPlayerID())  | 
|               | 
|         if NPCHurtManager.AddHurtValue(curObj, curTagObj, hurtHP, isBounce):  | 
|             return  | 
|           | 
|         if NPCHurtMgr.AddHurtValue(curObj, curTagObj, hurtHP, isBounce):  | 
|             return  | 
|           | 
|         curTeam = curObj.GetTeam()  | 
|           | 
|         #2012-04-23 jiang ¹¥»÷ïÚ³µÖ»Ëã¸öÈËÉ˺¦  | 
|         if curTagObj.GetGameObjType() == IPY_GameWorld.gotNPC and \  | 
|            curTagObj.GetGameNPCObjType() == IPY_GameWorld.gnotTruck or curTeam == None:  | 
|             #ÎÞ¶ÓÎé,Ìí¼Ó¸öÈËÉ˺¦  | 
|             AddHurtValue(curTagObj, curObj.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, hurtHP)  | 
|             return True  | 
|                   | 
|         #Ìí¼Ó¶ÓÎéÉ˺¦  | 
|         AddHurtValue(curTagObj, curTeam.GetTeamID(), ChConfig.Def_NPCHurtTypeTeam, hurtHP)  | 
|         #Ìí¼Ó¶ÓÎé³ÉÔ±É˺¦£¬ÓÃÓÚ¹¦ÄÜͳ¼Æ¶ÓÔ±É˺¦  | 
|         AddTeamPlayerHurtValue(curTagObj, curTeam.GetTeamID(), curObj.GetPlayerID(), hurtHP)  | 
|           | 
|     elif curObjType == IPY_GameWorld.gotNPC:  | 
|         AddHurtValue(curTagObj, curObj.GetID(), ChConfig.Def_NPCHurtTypeNPC, hurtHP)  | 
|           | 
|     else:  | 
|         GameWorld.ErrLog('NPCAddObjInHurtList UnKnow ObjType = %s' % (curObjType))  | 
|   | 
|     return True  | 
|   | 
| ## PVPÉ˺¦  | 
| #  @remarks Íæ¼Ò½ÇÉ«¼°³èÎï¡¢ÕÙ»½ÊÞÖ®¼ä²úÉúµÄÉ˺¦¶¼ËãPVPÉ˺¦;   | 
| #           Áí·´É˼°³ÖÐøµôѪbuffÒ²Ëã, µ«·´É˼°buff½ö¼ÆËãÍæ¼ÒÖ®¼ä  | 
| def OnPVPDamage(curPlayer, damageValue, tagPlayer, damageMsg):  | 
|     FBLogic.OnPVPDamage(curPlayer, damageValue, tagPlayer)  | 
|     return  | 
|   | 
| #--------------------------------------------------------------------------  | 
|   | 
| def CheckSightLevel(attacker, defender):  | 
|     ## ÅжÏÊÇ·ñ¿ÉÊÓÊÓÒ°²ã¼¶  | 
|     # @return ÊÇ·ñÔÚ¿ÉÊÓÊÓÒ°²ã  | 
|     if not attacker.GetVisible() or not defender.GetVisible():  | 
|         return False  | 
|     if defender.GetSightLevel() == ChConfig.SightLevel_Public or attacker.GetSightLevel() == ChConfig.SightLevel_Public:  | 
|         return True  | 
|     return attacker.GetSightLevel() == defender.GetSightLevel()  | 
|   | 
| #--------¹¥»÷¶ÔÏóÅжÏ,¸øÄÚ²ãµ÷Óà  | 
|   | 
| ## ¹¥»÷¶ÔÏó,ͨÓÃÅжϠ  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckCanAttackTag(attacker, defender):  | 
|       | 
|     if not CheckIsAvailableTag(attacker, defender):  | 
|         return False  | 
|       | 
|     if not defender.GetCanAttack():  | 
|         #Õâ¸ö¶ÔÏ󲻿ɹ¥»÷  | 
|         #GameWorld.Log("defender = %s->%s Õâ¸ö¶ÔÏ󲻿ɹ¥»÷"%(defender.GetName(),defender.GetID()))  | 
|         return False  | 
|       | 
|     if not CheckSightLevel(attacker, defender):  | 
|         return False  | 
|       | 
|     atkObjType = attacker.GetGameObjType()  | 
|     defObjType = defender.GetGameObjType()  | 
|     # Èç¹ûÊÇÍæ¼Ò ´ò NPC  | 
|     if atkObjType == IPY_GameWorld.gotPlayer and defObjType == IPY_GameWorld.gotNPC:  | 
|         ##¹¥»÷´ÎÊýÅÐ¶Ï  | 
|         #if not CheckAttackNPCByCnt(attacker, defender):  | 
|         #    return False  | 
|           | 
|         #»÷ɱ´ÎÊýÅÐ¶Ï  | 
|         if not NPCHurtManager.IsAssistPlayer(attacker.GetPlayerID(), defender) and not CheckKillNPCByCnt(attacker, defender):  | 
|             return False  | 
|           | 
|         #ÏÉÃ˹éÊôNPCÅÐ¶Ï  | 
|         if not CheckCanAttackFamilyOwnerNPC(attacker, defender):  | 
|             return False  | 
|           | 
|     # NPC´òÍæ¼Ò£¬·´¹ýÀ´ÅÐ¶Ï  | 
|     elif atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer:  | 
|         ##¹¥»÷´ÎÊýÅÐ¶Ï  | 
|         #if not CheckAttackNPCByCnt(defender, attacker, False):  | 
|         #    return False  | 
|           | 
|         #»÷ɱ´ÎÊýÅÐ¶Ï  | 
|         if not CheckKillNPCByCnt(defender, attacker, False) and not NPCHurtManager.IsAssistPlayer(defender.GetPlayerID(), attacker):  | 
|             return False  | 
|           | 
|         #ÏÉÃ˹éÊôNPCÅÐ¶Ï  | 
|         if not CheckCanAttackFamilyOwnerNPC(defender, attacker, False):  | 
|             return False  | 
|           | 
|     # NPC´òNPC  | 
|     elif atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotNPC:  | 
|         if PetControl.IsPet(attacker) or attacker.GetGameNPCObjType()== IPY_GameWorld.gnotSummon:  | 
|             #»÷ɱ´ÎÊýÅÐ¶Ï  | 
|             if not CheckKillNPCByCnt(attacker, defender, False):  | 
|                 ownerPlayer = GetAttackPlayer(attacker)[0]  | 
|                 if ownerPlayer and not NPCHurtManager.IsAssistPlayer(ownerPlayer.GetPlayerID(), defender):  | 
|                     return False  | 
|                   | 
|             #ÏÉÃ˹éÊôNPCÅÐ¶Ï  | 
|             if not CheckCanAttackFamilyOwnerNPC(attacker, defender, False):  | 
|                 return False  | 
|               | 
|     #¹¥»÷NPCµÈ¼¶ÏÞÖÆ  | 
|     #if not CheckCanAttackNPCByLV(attacker, defender):  | 
|     #    return False  | 
|       | 
|     isWoodPile = True if (defObjType == IPY_GameWorld.gotNPC and defender.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]) \  | 
|         or (atkObjType == IPY_GameWorld.gotNPC and attacker.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]) else False  | 
|     #²»¿É¹¥»÷ÇøÓò  | 
|     if not isWoodPile and not CheckCanAtkByArea(attacker, defender):  | 
|         return False  | 
|   | 
|     #ÑéÖ¤FBÖÐÊÇ·ñ¿É¹¥»÷, ¹¥»÷ºÍ³ðºÞÅжϻáµ÷Óøú¯Êý£¬Åж¨²»¿É¹¥»÷µÄÇé¿ö  | 
|     if not FBLogic.CheckCanAttackTagObjInFB(attacker, defender):  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| def CheckCanAttackNPCByLV(attacker, defender):  | 
|     ''' Åжϵ±Ç°µÈ¼¶¿É·ñ¹¥»÷¸ÃNPC '''  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         #GameWorld.DebugLog("Ö»Åжϱ»¹¥»÷µÄÊÇNPCµÄÇé¿ö")  | 
|         return True  | 
|       | 
|     npcID = defender.GetNPCID()  | 
|     attackLVLimitDict = ReadChConfig.GetEvalChConfig("AttackNPCLVLimit")  | 
|     if npcID not in attackLVLimitDict:  | 
|         #GameWorld.DebugLog("ÎÞ¹¥»÷µÈ¼¶ÏÞÖÆµÄNPC, npcID=%s" % npcID)  | 
|         return True  | 
|       | 
|     minLV, maxLV = attackLVLimitDict[npcID]  | 
|     atkPlayer, npcObjType = GetAttackPlayer(attacker)  | 
|     # ¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ  | 
|     if not atkPlayer:  | 
|         #GameWorld.DebugLog("¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ")  | 
|         return True  | 
|       | 
|     judgeMaxLV = maxLV if maxLV > 0 else 99999  | 
|     if minLV <= atkPlayer.GetLV() <= judgeMaxLV:  | 
|         #GameWorld.DebugLog("Íæ¼Ò¹¥»÷NPCµÈ¼¶Ìõ¼þÂú×ã!")  | 
|         return True  | 
|       | 
|     # Êµ¼Ê¹¥»÷ÕßÀàÐÍNoneÔòÐèÒªÌáÊ¾Íæ¼Ò  | 
|     if npcObjType is None:  | 
|         if minLV > 0 and maxLV > 0:  | 
|             PlayerControl.NotifyCode(atkPlayer, "GeRen_liubo_689354", [minLV, maxLV])  | 
|         elif minLV > 0:  | 
|             PlayerControl.NotifyCode(atkPlayer, "GeRen_liubo_198823", [minLV - 1])  | 
|         elif maxLV > 0:  | 
|             PlayerControl.NotifyCode(atkPlayer, "GeRen_liubo_437659", [maxLV + 1])  | 
|     #else:  | 
|     #    GameWorld.DebugLog("³èÎï/ÕÙ»½ÊÞ¹¥»÷NPCµÈ¼¶ÊÜÏÞ!ÎÞ·¨Ôì³ÉÉ˺¦!")  | 
|                 | 
|     return False  | 
|   | 
| def CheckCanAttackFamilyOwnerNPC(attacker, defender, isNotify=True):  | 
|     ''' ÅжϿɷñ¹¥»÷ÏÉÃ˹éÊôµÄNPC '''  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         #GameWorld.DebugLog("Ö»Åжϱ»¹¥»÷µÄÊÇNPCµÄÇé¿ö")  | 
|         return True  | 
|       | 
|     if NPCCommon.GetDropOwnerType(defender) != ChConfig.DropOwnerType_Family:  | 
|         return True  | 
|       | 
|     atkPlayer, npcObjType = GetAttackPlayer(attacker)  | 
|     # ¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ  | 
|     if not atkPlayer:  | 
|         #GameWorld.DebugLog("¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ")  | 
|         return True  | 
|       | 
|     atkLimitNotifyMark = ""  | 
|     if GetIsNewGuy(atkPlayer):  | 
|         atkLimitNotifyMark = "FairyGrabBossNotAtk"  | 
|     elif not atkPlayer.GetFamilyID():  | 
|         atkLimitNotifyMark = "FairyGrabBossNoFairy"  | 
|           | 
|     if atkLimitNotifyMark:  | 
|         if npcObjType is None and isNotify:  | 
|             PlayerControl.NotifyCode(atkPlayer, atkLimitNotifyMark)  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| def CheckKillNPCByCnt(attacker, defender, isNotify=True):  | 
|     ''' Åжϵ±ÈÕ»÷ɱ¸ÃNPC´ÎÊýÊÇ·ñÒÑÂú '''  | 
|     # º¯ÊýÃüÃûÎÊÌ⣬ʵ¼ÊÉϴ˺¯ÊýΪ¼ì²é¿É·ñ¹¥»÷boss  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         #GameWorld.DebugLog("Ö»Åжϱ»¹¥»÷µÄÊÇNPCµÄÇé¿ö")  | 
|         return True  | 
|     if not ChConfig.IsGameBoss(defender):  | 
|         return True  | 
|     npcID = defender.GetNPCID()  | 
|     killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit')   | 
|     index = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)  | 
|     if index == None:  | 
|         return True  | 
|       | 
|     atkPlayer, npcObjType = GetAttackPlayer(attacker)  | 
|     # ¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ  | 
|     if not atkPlayer:  | 
|         #GameWorld.DebugLog("¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ")  | 
|         return True  | 
|     funcInfoDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 5, {})  | 
|     if index in funcInfoDict:  | 
|         #¶ÔÓ¦¹¦ÄÜ먦Æô£¬²»Äܹ¥»÷  | 
|         funcID, funcSysMark = funcInfoDict[index]  | 
|         if not GameFuncComm.GetFuncCanUse(atkPlayer, funcID):  | 
|             PlayerControl.NotifyCode(atkPlayer, funcSysMark)  | 
|             return  | 
|     canKillCnt = BossHurtMng.GetCanKillBossCnt(atkPlayer, index)[0]  | 
|       | 
|     if canKillCnt <= 0:  | 
|         #if BossHurtMng.GetPlayerBossHurt(atkPlayer, defender):  | 
|         #    GameWorld.DebugLog("¹¥»÷¹ý¸Ãboss¿É¼ÌÐø¹¥»÷")  | 
|         #    return True  | 
|         #´ÎÊý²»×ã  | 
|         # Êµ¼Ê¹¥»÷ÕßÀàÐÍNoneÔòÐèÒªÌáÊ¾Íæ¼Ò  | 
|         if npcObjType is None:  | 
|             if isNotify:  | 
|                 sysMark = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit', 3, {}).get(index, '')  | 
|                 PlayerControl.NotifyCode(atkPlayer, sysMark)  | 
|         return False  | 
|       | 
|     npcDataEx = NPCCommon.GetNPCDataEx(npcID)  | 
|     if npcDataEx and npcDataEx.GetFightPowerLackAtkLimit():  | 
|         if npcDataEx.GetSuppressFightPower() > PlayerControl.GetFightPower(atkPlayer):  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(atkPlayer, "BossFightPowerHint")   | 
|             #GameWorld.DebugLog("Õ½Á¦²»×㣬ÎÞ·¨¹¥»÷boss! npcID=%s,SuppressFightPower=%s > playerFightPower=%s"   | 
|             #                   % (npcID, npcDataEx.GetSuppressFightPower(), PlayerControl.GetFightPower(atkPlayer)))                 | 
|             return False  | 
|           | 
|     return True  | 
|   | 
|   | 
| def CheckAttackNPCByCnt(attacker, defender, isNotify=True):  | 
|     ''' Åжϵ±ÈÕ¹¥»÷¸ÃNPC´ÎÊýÊÇ·ñÒÑÂú '''  | 
|     if defender.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         #GameWorld.DebugLog("Ö»Åжϱ»¹¥»÷µÄÊÇNPCµÄÇé¿ö")  | 
|         return True  | 
|     if not ChConfig.IsGameBoss(defender):  | 
|         return True  | 
|       | 
|     limitBossIDList, limitCnt = ReadChConfig.GetEvalChConfig("AttackBossCntLimit")  | 
|     npcID = defender.GetNPCID()  | 
|     if npcID not in limitBossIDList:  | 
|         return True  | 
|       | 
|     atkPlayer, npcObjType = GetAttackPlayer(attacker)  | 
|     # ¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ  | 
|     if not atkPlayer:  | 
|         #GameWorld.DebugLog("¹¥»÷Õß·ÇÍæ¼Ò²»ÏÞÖÆ")  | 
|         return True  | 
|       | 
|     hasAttackCnt = atkPlayer.NomalDictGetProperty(ChConfig.Def_PDict_WorldBoss_HurtCnt, 0)  | 
|       | 
|     if hasAttackCnt >= limitCnt:  | 
|         #if BossHurtMng.GetPlayerBossHurt(atkPlayer, defender):  | 
|         #    GameWorld.DebugLog("¹¥»÷¹ý¸Ãboss¿É¼ÌÐø¹¥»÷")  | 
|         #    return True  | 
|         #´ÎÊý²»×ã  | 
|         # Êµ¼Ê¹¥»÷ÕßÀàÐÍNoneÔòÐèÒªÌáÊ¾Íæ¼Ò  | 
|         if npcObjType is None:  | 
|             if isNotify:  | 
|                 PlayerControl.NotifyCode(atkPlayer, "GeRen_liubo_759061")  | 
|         return False  | 
|     return True  | 
|   | 
| def GetAttackPlayer(atkObj):  | 
|     ''' »ñÈ¡¹¥»÷ÕßËùÊôÍæ¼ÒʵÀý  | 
|     @return:  | 
|              µ±Êµ¼Ê¹¥»÷ÕßÎªÍæ¼Òʱ£¬·µ»Ø [curPlayer, None]   | 
|              µ±Êµ¼Ê¹¥»÷ÕßÊÇÆÕͨNPCʱ£¬·µ»Ø [None, None]  | 
|              µ±Êµ¼Ê¹¥»÷ÕßÊdzèÎï»òÕÙ»½ÊÞʱ£¬·µ»Ø [Ö÷ÈËcurPlayer, npcObjType]  | 
|     '''  | 
|       | 
|     atkObjType = atkObj.GetGameObjType()  | 
|     # Èç¹ûÊÇÍæ¼Ò  | 
|     if atkObjType == IPY_GameWorld.gotPlayer:  | 
|         return atkObj, None  | 
|       | 
|     npcObjType = atkObj.GetGameNPCObjType()  | 
|     # ÅжÏÕÙ»½ÊÞÖ÷ÈË  | 
|     if npcObjType == IPY_GameWorld.gnotSummon:  | 
|         curNPCDetail = GameWorld.GetObjDetail(atkObj)  | 
|         if curNPCDetail:  | 
|             curNPCOwner = curNPCDetail.GetOwner()  | 
|             if curNPCOwner:  | 
|                 summonOwner = GameWorld.GetObjDetail(curNPCOwner)  | 
|                 # ÕÙ»½ÊÞÖ÷ÈËÎªÍæ¼Ò  | 
|                 if summonOwner and summonOwner.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|                     return summonOwner, npcObjType  | 
|               | 
|     # ÅжϳèÎïÖ÷ÈË  | 
|     elif npcObjType == IPY_GameWorld.gnotPet:  | 
|         ownerPlayer = PetControl.GetPetOwner(atkObj)  | 
|         if ownerPlayer != None:  | 
|             return ownerPlayer, npcObjType  | 
|           | 
|     return None, None  | 
|   | 
| ##¼ì²é¶ÔÏóÊÇ·ñÔÚ°²È«ÇøÖУ¬Ä¿Ç°Ö»´¦ÀíÍæ¼Ò  | 
| # @param None  | 
| # @return None  | 
| def CheckCanAtkByArea(curObj, tagObj):  | 
|     areaType = GameMap.GetAreaTypeByMapPos(curObj.GetPosX(), curObj.GetPosY())  | 
|     tagAreaType = GameMap.GetAreaTypeByMapPos(tagObj.GetPosX(), tagObj.GetPosY())  | 
|       | 
|     #×ÔÓÉÇøÓò£¬ºÏ·¨£¬·µ»ØTrue  | 
|     if areaType == IPY_GameWorld.gatSafe or tagAreaType == IPY_GameWorld.gatSafe:         | 
|         return False  | 
|       | 
|     #²»Í¬ÇøÓò  | 
|     #if areaType != tagAreaType:  | 
|     #    return False  | 
|       | 
|     return True  | 
|   | 
|   | 
| ## ¹¥»÷¶ÔÏó, ÓÐЧĿ±ê  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckIsAvailableTag(attacker, defender):  | 
|     if defender == None or defender.GetID() == 0:  | 
|         return False  | 
|     if GameObj.GetHP(attacker) <= 0 or GameObj.GetHP(defender) <= 0:  | 
|         #¶ÔÏóÒѾËÀÍö  | 
|         return False  | 
|       | 
|     #Ìí¼Ó£¨ÏµÍ³£©ÒþÉíÕß²»¿É¹¥»÷£¬Ö¤Ã÷¼Ò×åÕ½·ÇÒþÉí  | 
|     if not attacker.GetVisible():  | 
|         return False  | 
|       | 
|     if not defender.GetVisible():  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| #---------------------------------------------------------------------  | 
| ##¼ì²é¶ÔÏóÊÇ·ñ¿ÉÒÔ¹¥»÷(Obj¸¸Àà·½·¨)  | 
| # @param curObj ¼ì²é¶ÔÏó  | 
| # @return ²¼¶ûÖµ  | 
| # @remarks ¼ì²é¶ÔÏóÊÇ·ñ¿ÉÒÔ¹¥»÷(Obj¸¸Àà·½·¨)  | 
| def CheckObjCanDoLogic(curObj):  | 
|     #Ò쳣״̬  | 
|     if curObj == None or curObj.GetID() == 0:  | 
|         return False  | 
|       | 
|     #ËÀÍö״̬  | 
|     if GameObj.GetHP(curObj) <= 0:  | 
|         return False  | 
|       | 
|     #·ÇÕý³£×´Ì¬(ÒþÐÎ)  | 
|     if not curObj.GetVisible():  | 
|         return False  | 
|       | 
|     return True  | 
| #---------------------------------------------------------------------  | 
| ## Íæ¼Ò¹¥»÷¶ÔÏó,ͨÓÃÅжϠ  | 
| #  @param attacker µ±Ç°Íæ¼Ò  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayerCanAttackTag(curPlayer, defender):  | 
|     if not CheckCanAttackTag(curPlayer, defender):  | 
|         curPlayer.Notify_AttackFail(  | 
|                                      defender.GetID() ,  | 
|                                      defender.GetGameObjType() ,  | 
|                                      defender.GetPosX() ,  | 
|                                      defender.GetPosY() ,  | 
|                                      IPY_GameWorld.afrNull  | 
|                                      )  | 
|         return False  | 
|       | 
| #===============================================================================  | 
| #    #»ñµÃµ±Ç°µØÍ¼  | 
| #    curMap = GameWorld.GetMap()  | 
| #    #ÅжÁ¹¥»÷ÊÇ·ñ¿ÉÒÔµ½´ï  | 
| #    if not curMap.CanJumpTo( curPlayer.GetPosX(), curPlayer.GetPosY(),  | 
| #                         defender.GetPosX(), defender.GetPosY(),  | 
| #                         ChConfig.Def_PlayerCanAttackBalk ):  | 
| #        curPlayer.Notify_AttackFail(IPY_GameWorld.afrHaveObs)  | 
| #        return False  | 
| #===============================================================================  | 
|     if curPlayer.GetPlayerAction() not in ChConfig.Def_PlayerCanAttackState:  | 
|         return False  | 
|       | 
|     #ÊÇ·ñÆï³Ë  | 
|     #===========================================================================  | 
|     # if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvNull:  | 
|     #    return False  | 
|     #===========================================================================  | 
|       | 
| #===============================================================================  | 
| #    if not ItemControler.CheckAttackConsumeArrow(curPlayer, True):  | 
| #        #Èç¹ûÓùåó,ÊÇ·ñÓÐ×Óµ¯  | 
| #        return False  | 
| #===============================================================================  | 
|     return True  | 
|   | 
| ## ¼ì²éÍæ¼Ò¹¥»÷¾àÀë   | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curTag µ±Ç°¶ÔÏó  | 
| #  @param useSkill Ê¹Óõļ¼ÄÜ(ÎÞ->´«ÈëNone)  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayerAttackDist(curPlayer, curTag, useSkill):  | 
|     #¹¥»÷ÆðµãÈ¡»º´æµÄ×ø±ê  | 
|     atkStartPosX = curPlayer.GetAttackTargetPosX()  | 
|     atkStartPosY = curPlayer.GetAttackTargetPosY()  | 
|       | 
|     #ÅжϾàÀë, µ±Çл»µØÍ¼Íæ¼Òδ¹¥»÷±»¶¯Êͷż¼ÄÜʱ£¬¾àÀë²»¶ÔÎÞ·¨¹¥»÷  | 
|     dist = min(GameWorld.GetDist(atkStartPosX, atkStartPosY, curTag.GetPosX(), curTag.GetPosY()),  | 
|                GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), curTag.GetPosX(), curTag.GetPosY()))  | 
|   | 
|     #ÆÕͨ¹¥»÷Óü¼ÄÜʵÏÖ  | 
|     if not useSkill:  | 
|         return True  | 
|       | 
|     #¼¼Äܹ¥»÷( ÓÐÈÝ´í¾àÀë )  | 
|     skillDist = useSkill.GetAtkDist()  | 
|     if skillDist == 0:  | 
|         return True  | 
|       | 
|     skillDist += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(curPlayer, curTag, useSkill, ChConfig.TriggerType_SkillDist)  | 
|     if dist > skillDist + ChConfig.Def_PlayerAttackDistZoom:  | 
|         #PlayerControl.NotifyCode(curPlayer, "XW_SF_DistanceFarness")  | 
|         #GameWorld.GodLog(curPlayer, '¼¼ÄܾàÀ볬Զ = %s, ¼¼Äܹ¥»÷¾àÀë = %s'%( dist, skillDist ))  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
|   | 
| ## NPC¹¥»÷¶ÔÏó,ͨÓÃÅÐ¶Ï  | 
| #  @param curNPC µ±Ç°NPC  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @param skill Ê¹Óõļ¼ÄÜ(ÎÞ->´«ÈëNone)  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckNPCCanAttackTag(curNPC, defender, skill):  | 
|     if not CheckCanAttackTag(curNPC, defender):  | 
|         #GameWorld.Log("NPC¹¥»÷²»Âú×ãͨÓÃÌõ¼þ")  | 
|         return False  | 
|       | 
|     if not CheckNPCAttackDist(curNPC, defender, skill):  | 
|         return False  | 
|       | 
|     #NPC¹¥»÷ÅжÏ:ÎÞ·¨¹¥»÷×Ô¼º,°üÀ¨¶Ô×Ô¼ºÊ¹Óü¼ÄÜ»òBuff  | 
|     if GameWorld.IsSameObj(curNPC, defender):  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| ## ¼ì²éNPC¹¥»÷¾àÀë(µ±Ç°NPC,µ±Ç°¶ÔÏó,ʹÓõļ¼ÄÜ(ÎÞ->´«ÈëNone))  | 
| #  @param curNPC µ±Ç°NPC  | 
| #  @param curTag µ±Ç°¶ÔÏó  | 
| #  @param skill Ê¹Óõļ¼ÄÜ(ÎÞ->´«ÈëNone)  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckNPCAttackDist(curNPC, curTag, skill):  | 
|     #»ñÈ¡¾àÀë  | 
|     dist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),  | 
|                              curTag.GetPosX(), curTag.GetPosY())  | 
|     #ÆÕͨ¹¥»÷  | 
|     if skill == None:  | 
|         if dist > curNPC.GetAtkDist():  | 
|             return  | 
|     #¼¼Äܹ¥»÷  | 
|     elif dist > skill.GetAtkDist():  | 
|         return  | 
|       | 
|     return True  | 
|   | 
| ## ¼ì²é±»¹¥»÷ºó,ÌØÊâBuffÏûʧ  | 
| #  @param curTagPlayer ±»¹¥»÷·½  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def SuperAttackedBuff(curTagPlayer):  | 
|     return  | 
| #--------------------------------------------------------------------------  | 
|   | 
| #-----------ÌØÊâÀàÐͼ¼ÄÜÅÐ¶Ï  | 
| ## ¸´»î¼¼ÄÜÅжϠ  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curTag µ±Ç°¶ÔÏó  | 
| #  @param skill ¼¼ÄÜ  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckSkill_ReBorn(curPlayer, curTag, skill):  | 
|     if curTag == None or curTag.GetID() == 0:  | 
|         #¶ÔÏóÒÑÏûʧ  | 
|         return False  | 
|       | 
|     if curTag.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         #GameWorld.Log("ÎÞ·¨¶Ô·ÇÍæ¼Ò¶ÔÏóʹÓø´»î¼¼ÄÜ")  | 
|         return False  | 
|       | 
|     if not GameWorld.IsSameCountry(curPlayer, curTag):  | 
|         #GameWorld.Log("ÎÞ·¨¶Ô·Ç±¾¹úÍæ¼ÒʹÓø´»î¼¼ÄÜ")  | 
|         return False  | 
|       | 
|     if GameObj.GetHP(curTag) > 0:  | 
|         #GameWorld.Log("ÎÞ·¨¶ÔÉúÃü!=0µÄÍæ¼ÒʹÓø´»î¼¼ÄÜ")  | 
|         return False  | 
|       | 
|     if not CheckPlayerAttackDist(curPlayer, curTag, skill):  | 
|         #¹¥»÷̫Զ  | 
|         return False  | 
|       | 
|     if CheckPlayerAttackMode_Player(curPlayer, curTag):  | 
|         #GameWorld.Log("ÎÞ·¨¸´»îµÐ¶ÔÍæ¼Ò")  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
|   | 
| ## ÏÉÁÆÊõ (->Ö»ÄܶÔ×Ô¼ºµÄ¶ÓԱʹÓÃ)   | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param curTag µ±Ç°¶ÔÏó  | 
| #  @param skill ¼¼ÄÜ  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckSkill_Team(curPlayer, curTag, skill):  | 
|     if curTag == None or curTag.GetID() == 0:  | 
|         #¶ÔÏóÒÑÏûʧ  | 
|         return False  | 
|       | 
|     #¿ÉÒÔ¶Ô×Ô¼ºÊ¹Óà  | 
|     if GameWorld.IsSameObj(curPlayer, curTag) :  | 
|         return True  | 
|       | 
|     if curTag.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         return False  | 
|       | 
|     if GameObj.GetHP(curTag) == 0:  | 
|         return False  | 
|       | 
|     if not CheckPlayerAttackDist(curPlayer, curTag, skill):  | 
|         #¹¥»÷̫Զ  | 
|         return False  | 
|       | 
|     if CheckPlayerAttackMode_Player(curPlayer, curTag):  | 
|         #GameWorld.Log("¿ÉÒÔ¹¥»÷,ÎÞ·¨Ê¹ÓÃÖÎÁÆ")  | 
|         return False  | 
|       | 
|     curTagTeam = curTag.GetTeam()  | 
|     curPlayerTeam = curPlayer.GetTeam()  | 
|     if curPlayerTeam == None or curTagTeam == None :  | 
|         return False  | 
|       | 
|     return curTagTeam.GetTeamID() == curPlayerTeam.GetTeamID()  | 
|   | 
| #===============================================================================  | 
| # #------------------  | 
| # ## É˺¦½á¹¹Ìå  | 
| # (  | 
| # Def_HurtType_Normal,   | 
| # Def_HurtType_SuperHit,   | 
| # Def_HurtType_Miss,   | 
| # ) = range(0, 3)  | 
| # #ÀàÐÍ: 0-ÆÕͨ 1-±©»÷ 2-¶ãÉÁ  | 
| #===============================================================================  | 
|   | 
| ## É˺¦½á¹¹ÌåÀà  | 
| #  | 
| #  PyClassÀàµÄÏêϸ˵Ã÷.  | 
| class HurtType:  | 
|     HurtHP = 0  | 
|     HurtType = 0  | 
|     ## ³õʼ»¯º¯Êý  | 
|     #  @param hurtHP ÉËѪֵ  | 
|     #  @param hurtType ÉËѪÀàÐÍ  | 
|     #  @return None  | 
|     #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
|     def __init__(self):  | 
|         self.HurtHP = 0    #NPCÈ¡É˺¦Öµ£¬Íæ¼ÒÈ¡µôѪֵ£¬ÔÂß¼²»ÐÞ¸Ä  | 
|         self.HurtType = 0  | 
|         self.LostHP = 0     #µôѪֵ  | 
|         self.RealHurtHP = 0 #É˺¦Öµ  | 
|           | 
| #####################################  | 
|   | 
| ##Åж¨ÊÇ·ñ´¥·¢¼¼Äܱط¢Éú״̬  | 
| # @param happenState ¼¼ÄÜ·¢Éú̬  | 
| # @param cmpType ×´Ì¬¶Ô±ÈÖµ  | 
| # @return ±È½Ï½á¹û  | 
| def IsHappenStateByType(happenState, cmpType):  | 
|     return happenState & cmpType  | 
|   | 
|   | 
| # ±íÏÖÐÎʽ ÖÂÃüÒ»»÷>(ÖØ»÷>±©»÷)>»áÐÄ>¸ñµ²>¾³½çÑ¹ÖÆ  | 
| # ÖØ»÷¶¨Ò壺µ±´¥·¢ÖØ»÷ʱ£¬ÔòÔö¼ÓË«±¶±©»÷¹Ì¶¨ÖµÉ˺¦£¨ÖØ»÷Ó뱩»÷»¥³â£¬ÓÅÏÈÅжÏÖØ»÷£¬µ±ÖØ»÷´¥·¢Ê±£¬±©»÷²»´¥·¢£©  | 
| def CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState, curSkill):  | 
|     ''' »ñÈ¡É˺¦ÀàÐͽá¹û   | 
|     Ö§³Ö¶àÖÖÉ˺¦ÀàÐÍͬʱ´¥·¢, Æ®×Ö±íÏÖÒÔ×îÖÕ±íÏÖÉ˺¦ÀàÐÍΪÖ÷  | 
|     @return: ×îÖÕ±íÏÖÉ˺¦ÀàÐÍ, {É˺¦ÀàÐÍ:[ÊÇ·ñ´¥·¢, É˺¦¼ÆËãÖµ, ´¥·¢Ê±·ÀÊØ·½µÄÉ˺¦¼õÃâÖµ], ...}  | 
|     '''  | 
|     hurtType = ChConfig.Def_HurtType_Normal  | 
|     # É˺¦ÀàÐͽá¹ûÐÅÏ¢, Ä¬ÈÏÖµ{É˺¦ÀàÐÍ:[ÊÇ·ñ´¥·¢, É˺¦¼ÆËãÖµ, ´¥·¢Ê±·ÀÊØ·½µÄÉ˺¦¼õÃâÖµ], ...}  | 
|     hurtTypeResultDict = {  | 
|                           ChConfig.Def_HurtType_LuckyHit:[False, 0, 0],  | 
|                           ChConfig.Def_HurtType_SuperHit:[False, 0, 0],  | 
|                           ChConfig.Def_HurtType_Parry:[False, 0, 0],  | 
|                           ChConfig.Def_HurtType_Zhuxian:[False, 0, 0],  | 
|                           ChConfig.Def_HurtType_DeadlyHit:[False, 0, 0],  | 
|                           ChConfig.Def_HurtType_ThumpHit:[False, 0, 0],  | 
|                           }  | 
|       | 
|     calcTypeList =  []  | 
|     if atkObjType == IPY_GameWorld.gotPlayer:  | 
|         calcTypeList += [ChConfig.Def_HurtType_LuckyHit, ChConfig.Def_HurtType_SuperHit,   | 
|                          ChConfig.Def_HurtType_Zhuxian, ChConfig.Def_HurtType_DeadlyHit,  | 
|                          ChConfig.Def_HurtType_ThumpHit]  | 
|     elif atkObjType == IPY_GameWorld.gotNPC:  | 
|         if PetControl.IsPetNPC(atkObj):  | 
|             calcTypeList += [ChConfig.Def_HurtType_SuperHit]  | 
|         else:  | 
|             calcTypeList += [ChConfig.Def_HurtType_SuperHit, ChConfig.Def_HurtType_DeadlyHit]  | 
|               | 
|     if defObjType == IPY_GameWorld.gotPlayer:  | 
|         calcTypeList += [ChConfig.Def_HurtType_Parry]  | 
|           | 
|     if not calcTypeList:  | 
|         return hurtType, hurtTypeResultDict  | 
|       | 
|     # ÓÅÏȼ¶Áбí, »¥³âÁÐ±í  | 
|     priorityList, mutexList = ReadChConfig.GetEvalChConfig("CalcHurtTypeInfo")  | 
|     happenFunc = {  | 
|                   ChConfig.Def_HurtType_LuckyHit:__HurtTypeHappen_LuckyHit,  | 
|                   ChConfig.Def_HurtType_SuperHit:__HurtTypeHappen_SuperHit,  | 
|                   ChConfig.Def_HurtType_Parry:__HurtTypeHappen_Parry,  | 
|                   #ChConfig.Def_HurtType_Zhuxian:__HurtTypeHappen_Zhuxian,  | 
|                   ChConfig.Def_HurtType_DeadlyHit:__HurtTypeHappen_Deadly,  | 
|                   ChConfig.Def_HurtType_ThumpHit:__HurtTypeHappen_ThumpHit,  | 
|                   }  | 
|       | 
|     hadCheckList = [] # ÒѾ´¦Àí¹ýµÄÉ˺¦ÀàÐÍÁÐ±í  | 
|     # ÏȼÆË㻥³â±íÀï  | 
|     for mutexHurtTypeList in mutexList:  | 
|         curMHHappen = False # µ±Ç°»¥³âÁбíÊÇ·ñÓд¥·¢µÄ  | 
|         for hType in mutexHurtTypeList:  | 
|             if hType not in calcTypeList or hType not in happenFunc:  | 
|                 continue  | 
|             if hType in hadCheckList:  | 
|                 continue  | 
|               | 
|             hadCheckList.append(hType)  | 
|             if curMHHappen:  | 
|                 # Ö»ÒªÆäÖÐÒ»¸öÒÑ´¥·¢µÄÔòºóÃæµÄ¾ùΪĬÈϲ»´¥·¢  | 
|                 continue  | 
|             result = happenFunc[hType](atkObj, defObj, happenState, curSkill)  | 
|             if result: # Èç¹û´¥·¢£¬¸üÐÂÏà¹ØÊýÖµ  | 
|                 hurtTypeResultDict[hType] = result  | 
|                 curMHHappen = True  | 
|               | 
|     # ÔÙËãÓÅÏȼ¶ÁбíÀï  | 
|     for hType in priorityList:  | 
|         if hType not in calcTypeList or hType not in happenFunc:  | 
|             continue  | 
|         if hType not in hadCheckList:  | 
|             hadCheckList.append(hType)  | 
|             result = happenFunc[hType](atkObj, defObj, happenState, curSkill)  | 
|             if result: # Èç¹û´¥·¢£¬¸üÐÂÏà¹ØÊýÖµ  | 
|                 hurtTypeResultDict[hType] = result  | 
|                   | 
|         # ×îÖÕÉ˺¦ÀàÐÍΪ°´ÓÅÏȼ¶È¡µÚÒ»¸ö´¥·¢µÄ  | 
|         if hurtTypeResultDict[hType][0] and hurtType == ChConfig.Def_HurtType_Normal:  | 
|             hurtType = hType  | 
|               | 
|     return hurtType, hurtTypeResultDict  | 
|   | 
|   | 
| def __HurtTypeHappen_LuckyHit(atkObj, defObj, happenState, curSkill):  | 
|     ''' ÅжÏÉ˺¦ÀàÐÍÊÇ·ñ·¢Éú - »áÐÄÒ»»÷  | 
|     @return: ÊÇ·ñ´¥·¢, ´¥·¢Ê±É˺¦¼ÆËã¹Ì¶¨Öµ, ´¥·¢Ê±·ÀÊØ·½µÄÉ˺¦¼õÃâ¹Ì¶¨Öµ  | 
|     '''  | 
|     if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_LuckyHit):  | 
|         return True, atkObj.GetLuckyHitVal(), PlayerControl.GetLuckyHitReduce(defObj)  | 
|       | 
|     aLuckyHitRate = atkObj.GetLuckyHitRate()  | 
|     dLuckyHitRateReduce = PlayerControl.GetLuckyHitRateReduce(defObj)  | 
|       | 
|   | 
|     atkLuckyHitRate = eval(ReadChConfig.GetChConfig("CalcLuckyHitRate"))  | 
|     if atkLuckyHitRate <= 0:  | 
|         return  | 
|     if GameWorld.CanHappen(atkLuckyHitRate):  | 
|         return True, atkObj.GetLuckyHitVal(), PlayerControl.GetLuckyHitReduce(defObj)  | 
|     return  | 
|   | 
| def __HurtTypeHappen_SuperHit(atkObj, defObj, happenState, curSkill):  | 
|     ''' ÅжÏÉ˺¦ÀàÐÍÊÇ·ñ·¢Éú - ±©»÷  | 
|     @return: ÊÇ·ñ´¥·¢, ´¥·¢Ê±É˺¦¼ÆËã¹Ì¶¨Öµ, ´¥·¢Ê±·ÀÊØ·½µÄÉ˺¦¼õÃâ¹Ì¶¨Öµ  | 
|     '''  | 
|       | 
|     if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_SuperHit):  | 
|         return True, atkObj.GetSuperHit(), GameObj.GetSuperHitReduce(defObj)  | 
|       | 
|     aSuperHitRate = atkObj.GetSuperHitRate()  | 
|     dSuperHitRateReduce = GameObj.GetSuperHitRateReduce(defObj)  | 
|     superHitRate = eval(ReadChConfig.GetChConfig("CalcSuperHitRate"))  | 
|     superHitRate += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill,   | 
|                                                                        ChConfig.TriggerType_Buff_AddSuperHitRate)  | 
|     superHitRate += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill,   | 
|                                                                        ChConfig.TriggerType_Buff_AddSuperHitRate)  | 
|     if superHitRate <= 0:  | 
|         return  | 
|     if GameWorld.CanHappen(superHitRate):  | 
|         return True, atkObj.GetSuperHit(), GameObj.GetSuperHitReduce(defObj)  | 
|     return  | 
|   | 
| def __HurtTypeHappen_Parry(atkObj, defObj, happenState, curSkill):  | 
|     ''' ÅжÏÉ˺¦ÀàÐÍÊÇ·ñ·¢Éú - ·ÀÊØ·½µÖÓù  | 
|     @return: ÊÇ·ñ´¥·¢, ´¥·¢Ê±É˺¦¼ÆËãÖµ, ´¥·¢Ê±·ÀÊØ·½µÄÉ˺¦¼õÃâÖµ  | 
|     '''  | 
|     chanceDefPer = PlayerControl.GetDamChanceDef(defObj)  | 
|     if not chanceDefPer:  | 
|         return  | 
|     if GameWorld.CanHappen(ChConfig.Def_ChanceDefRate):  | 
|         return True, 0, chanceDefPer  | 
|     return  | 
|   | 
| #def __HurtTypeHappen_Zhuxian(atkObj, defObj, happenState, curSkill):  | 
| #    """ÖïÏÉÒ»»÷"""  | 
| #    rate = PlayerControl.GetZhuXianRate(atkObj)  | 
| #    if not rate:  | 
| #        return  | 
| #      | 
| #    if GameWorld.CanHappen(rate):  | 
| #        return True, PlayerControl.GetZhuXianHurtPer(atkObj), 0  | 
| #    return  | 
|   | 
| # ÖÂÃüÒ»»÷  | 
| def __HurtTypeHappen_Deadly(atkObj, defObj, happenState, curSkill):  | 
|     deadlyHitValue = PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, None, ChConfig.TriggerType_IsDealy)  | 
|     if deadlyHitValue:  | 
|         return True, deadlyHitValue, 0  | 
|     return  | 
|   | 
| #ÖØ»÷¶¨Ò壺µ±´¥·¢ÖØ»÷ʱ£¬ÔòÔö¼ÓË«±¶±©»÷¹Ì¶¨ÖµÉ˺¦£¨ÖØ»÷Ó뱩»÷»¥³â£¬ÓÅÏÈÅжÏÖØ»÷£¬µ±ÖØ»÷´¥·¢Ê±£¬±©»÷²»´¥·¢£©  | 
| def __HurtTypeHappen_ThumpHit(atkObj, defObj, happenState, curSkill):  | 
|       | 
|     if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_ThumpHit):  | 
|         return True, int(atkObj.GetSuperHit()*1.5), GameObj.GetSuperHitReduce(defObj)  | 
|       | 
|     thumpHitRate = 0    | 
|     thumpHitRate += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill,   | 
|                                                                        ChConfig.TriggerType_AddThumpHitRate)  | 
|     thumpHitRate += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill,   | 
|                                                                        ChConfig.TriggerType_AddThumpHitRate)  | 
|     if thumpHitRate <= 0:  | 
|         return  | 
|     if GameWorld.CanHappen(thumpHitRate):  | 
|         return True, atkObj.GetSuperHit()*2, GameObj.GetSuperHitReduce(defObj)  | 
|     return  | 
|   | 
|   | 
| def ChangeSkillHurtPer(atkObj, defObj, curSkill, skillPer):  | 
|     ## ¸Ä±ä¼¼ÄÜÉ˺¦°Ù·Ö±È  | 
|       | 
|     if not curSkill:  | 
|         return skillPer  | 
|       | 
|     if atkObj.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         return skillPer  | 
|       | 
|     skillTypeID = curSkill.GetSkillTypeID()  | 
|       | 
|     addPer = 0  | 
|     reducePer = 0  | 
|     addPer += SkillCommon.GetSkillAddPerByID(atkObj, skillTypeID)  | 
|       | 
|     if defObj.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|         reducePer = SkillCommon.GetSkillReducePerByID(defObj, skillTypeID)  | 
|           | 
|         #¸ù¾Ý·ÀÊØ·½Ö°Òµ ¼ÆËã¹¥»÷·½É˺¦¼Ó³É  | 
|         if defObj.GetJob() in [ShareDefine.PlayerJob_Warrior, ShareDefine.PlayerJob_Knight]:  | 
|             addPer += PlayerControl.GetJobAHurtAddPer(atkObj)  | 
|         elif defObj.GetJob() in [ShareDefine.PlayerJob_Wizard, ShareDefine.PlayerJob_ForceUser]:  | 
|             addPer += PlayerControl.GetJobBHurtAddPer(atkObj)  | 
|         elif defObj.GetJob() in [ShareDefine.PlayerJob_Assassin, ShareDefine.PlayerJob_BowMaster]:  | 
|             addPer += PlayerControl.GetJobCHurtAddPer(atkObj)  | 
|           | 
|         #¸ù¾Ý¹¥»÷·½Ö°Òµ ¼ÆËã·ÀÊØ·½É˺¦¼õÃâ  | 
|         if atkObj.GetJob() in [ShareDefine.PlayerJob_Warrior, ShareDefine.PlayerJob_Knight]:  | 
|             reducePer += PlayerControl.GetJobAAtkReducePer(defObj)  | 
|         elif atkObj.GetJob() in [ShareDefine.PlayerJob_Wizard, ShareDefine.PlayerJob_ForceUser]:  | 
|             reducePer += PlayerControl.GetJobBAtkReducePer(defObj)  | 
|         elif atkObj.GetJob() in [ShareDefine.PlayerJob_Assassin, ShareDefine.PlayerJob_BowMaster]:  | 
|             reducePer += PlayerControl.GetJobCAtkReducePer(defObj)  | 
|           | 
|     if addPer or reducePer:  | 
|         addSkillPer = addPer - reducePer  | 
|         skillPer = max(0, skillPer + addSkillPer)  | 
|           | 
|     return skillPer  | 
|   | 
| # ¸Ä±ä¼¼ÄÜÉ˺¦£¨Ð§¹ûID1010£©, Ò°ÍâС¹Ö1009Ìæ»»1010É˺¦(2018-03-07Ôö¼Ó¾«Ó¢¹Ö)  | 
| def ChangeSkillHurt(curPlayer, defObj, curSkill, skillPer, skillValue):  | 
|       | 
|     changeInfo = GetCanChangeSkillHurtEffect(curPlayer, defObj, curSkill, skillPer, skillValue)  | 
|     if changeInfo:  | 
|         skillPer, skillValue = changeInfo  | 
|     return skillPer, skillValue  | 
|   | 
| # ¶ÔNPCÉ˺¦µÄÌØÊâ´¦Àí£¬ÎªÖ¸¶¨É˺¦Ìæ»» ·Ç¶îÍâ¼ÓÉ˺¦  | 
| # 1. ¶Ô·ÇBOSS¹ÖµÄÌØÊâÉ˺¦ 2.¶ÔXXϵ¹ÖÎïµÄÌØÊâÉ˺¦  | 
| def GetCanChangeSkillHurtEffect(attacker, defObj, curSkill, skillPer, skillValue):  | 
|     if not curSkill:  | 
|         return  | 
|       | 
|     if not attacker.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline):  | 
|         if defObj.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|             return  | 
|           | 
|         if attacker.GetGameObjType() == IPY_GameWorld.gotNPC and attacker.GetType() == IPY_GameWorld.ntMonster:  | 
|             # ÆÕͨ¹ÖÎÞ´ËЧ¹û  | 
|             return  | 
|           | 
|         if defObj.GetIsBoss() > ChConfig.Def_NPCType_Ogre_Super:  | 
|             return  | 
|           | 
|         if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull and \  | 
|         GameWorld.GetMap().GetMapID() not in IpyGameDataPY.GetFuncEvalCfg('SkillXPAddByFB', 1):  | 
|             return  | 
|       | 
|     effectIDList = [ChConfig.Def_Skill_Effect_AttackReplace, ChConfig.Def_Skill_Effect_AttackReplaceByNPCSeries,   | 
|                     ChConfig.Def_Skill_Effect_AttackReplaceByTagHP, ChConfig.Def_Skill_Effect_AttackReplaceByTagState]  | 
|     findEffect, effectID = GetSkillEffectByEffectIDs(curSkill, effectIDList)  | 
|     if not findEffect:  | 
|         return  | 
|       | 
|     if effectID == ChConfig.Def_Skill_Effect_AttackReplace:  | 
|         # ¶ÔС¹ÖºÍ¾«Ó¢¹ÖµÄÉ˺¦  | 
|         if defObj.GetIsBoss() > ChConfig.Def_NPCType_Ogre_Super:  | 
|             return  | 
|           | 
|         if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull and \  | 
|         GameWorld.GetMap().GetMapID() not in IpyGameDataPY.GetFuncEvalCfg('SkillXPAddByFB', 1):  | 
|             return  | 
|           | 
|         return findEffect.GetEffectValue(0), findEffect.GetEffectValue(1)  | 
|       | 
|     elif effectID == ChConfig.Def_Skill_Effect_AttackReplaceByNPCSeries:  | 
|         # ¶ÔÖ¸¶¨ÏµÔì³ÉÖ¸¶¨É˺¦  | 
|         if findEffect.GetEffectValue(2)&NPCCommon.GetNPCSeries(defObj) == 0:  | 
|             return  | 
|           | 
|         return findEffect.GetEffectValue(0), findEffect.GetEffectValue(1)  | 
|       | 
|     elif effectID == ChConfig.Def_Skill_Effect_AttackReplaceByTagHP:  | 
|         # Ä¿±êѪÁ¿ÅÐ¶Ï  | 
|         hpPer = findEffect.GetEffectValue(1)  | 
|         calcType = findEffect.GetEffectValue(2) #¼ÆË㷽ʽ£º 0-СÓÚ£»1-´óÓÚ£»Ä¬Èϰüº¬ÁÙ½çÖµ  | 
|         tagHPPer = GameObj.GetHP(defObj) * float(ChConfig.Def_MaxRateValue) / GameObj.GetMaxHP(defObj)  | 
|         if calcType == 1:  | 
|             if tagHPPer < hpPer:  | 
|                 return  | 
|         else:  | 
|             if tagHPPer > hpPer:  | 
|                 return  | 
|         changeSkillPer = findEffect.GetEffectValue(0)  | 
|         GameWorld.DebugLog("        Ä¿±êѪÁ¿±ä¸ü¼¼ÄÜÉ˺¦! atkID=%s,defID=%s,tagHPPer=%s,hpPer=%s,changeSkillPer=%s,skillPer=%s"   | 
|                           % (attacker.GetID(), defObj.GetID(), tagHPPer, hpPer, changeSkillPer, skillPer))  | 
|         return changeSkillPer, skillValue  | 
|       | 
|     elif effectID == ChConfig.Def_Skill_Effect_AttackReplaceByTagState:  | 
|         # Ä¿±ê״̬ÅÐ¶Ï  | 
|         tagState = findEffect.GetEffectValue(1)  | 
|         if not GameObj.GetPyPlayerState(defObj, tagState):  | 
|             return  | 
|         changeSkillPer = findEffect.GetEffectValue(0)  | 
|         GameWorld.DebugLog("        Ä¿±ê״̬±ä¸ü¼¼ÄÜÉ˺¦! atkID=%s,defID=%s,tagState=%s,changeSkillPer=%s,skillPer=%s"   | 
|                            % (attacker.GetID(), defObj.GetID(), tagState, changeSkillPer, skillPer))  | 
|         return changeSkillPer, skillValue  | 
|       | 
|     return  | 
|       | 
|       | 
| # ´ÓЧ¹ûIDÁбíÖÐÕÒµ½ÆäÖÐÒ»¸öЧ¹û  | 
| def GetSkillEffectByEffectIDs(curSkill, effectIDList):  | 
|     for i in range(0, curSkill.GetEffectCount()):  | 
|         curEffect = curSkill.GetEffect(i)  | 
|         curEffectID = curEffect.GetEffectID()  | 
|           | 
|         if not curEffectID:  | 
|             #²ß»®ÓпÉÄÜÖÐ;ɾ³ý£¬²»ÓÃreturn  | 
|             continue  | 
|           | 
|         #²»ÊÇÐèÒªµÄЧ¹û  | 
|         if curEffectID not in effectIDList:  | 
|             continue  | 
|           | 
|         #ÕÒµ½ÁË  | 
|         return curEffect, curEffectID  | 
|       | 
|     return None, 0  | 
|   | 
|       | 
|       | 
| # ElfÁéÎªÌæÉí¹¥»÷£¬ÒªÈ¡Íæ¼ÒµÄÊôÐÔ£¬NPCΪÖ÷ÈËÔò»¹ÊÇÈ¡Áé  | 
| def ElfChangeAttacker(attacker):  | 
|     if not attacker:  | 
|         return attacker  | 
|     if attacker.GetGameObjType() != IPY_GameWorld.gotNPC:  | 
|         # --Íæ¼Ò  | 
|         return attacker  | 
|       | 
|     npcType = attacker.GetType()  | 
|     if npcType == IPY_GameWorld.ntElf:  | 
|         # ntElf ¶¨ÒåΪÈËÎïʹÓöԵسÖÐøÐÔ¼¼ÄÜ£¬²¢ÇÒÈËÎï¿ÉÒÔÒÆ¶¯£¬ÔòÐèÒªntElf×öÒÀÍÐÎïµÄÇé¿ö  | 
|         # ÄÇôntElfÖ´ÐÐÈËÎïµÄÉ˺¦¼ÆËãºÍ±»¶¯´¥·¢Ð§¹û  | 
|         # 2018-11-16 Elf Ö§³ÖÖ÷ÈËΪNPC  | 
|         # owner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, attacker)  | 
|           | 
|         owner = NPCCommon.GetSummonOwnerDetel(attacker)  | 
|         return attacker if not owner else owner  | 
|       | 
|     return attacker  | 
|      | 
| # ¼ì²é¶ÔÏóÊÇ·ñÊôÓÚÍæ¼Ò£¬±ÈÈçÓÃÓÚ´¿PVPÑéÖ¤  | 
| def CheckIsPlayerOnwer(gameObj):  | 
|     if not gameObj:  | 
|         return False  | 
|       | 
|     objType = gameObj.GetGameObjType()  | 
|       | 
|     if objType == IPY_GameWorld.gotPlayer:  | 
|         return True  | 
|       | 
|     objNPCType = gameObj.GetGameNPCObjType()  | 
|     if objNPCType == IPY_GameWorld.gnotNormal:  | 
|         return False  | 
|       | 
|     if objNPCType == IPY_GameWorld.gnotSummon:  | 
|         owner = NPCCommon.GetSummonOwnerDetel(gameObj)  | 
|         if not owner:  | 
|             return False  | 
|         if owner.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|             return False  | 
|               | 
|     return True  | 
|       | 
| # ¹¥»÷ʱ·ÀÊØ·½Éñ±ø»¤¶ÜµÄ´¦Àí  | 
| def CalcAtkProDef(atkObj, defObj, hurtValue, curSkill, tick):  | 
|     if defObj.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         return hurtValue  | 
|       | 
|     if not CheckIsPlayerOnwer(atkObj):  | 
|         return hurtValue  | 
|   | 
|     curProDef = PlayerControl.GetProDef(defObj)  | 
|     if not curProDef:  | 
|         return hurtValue  | 
|       | 
|     absortValue = min(PlayerControl.GetProDefAbsorb(defObj)*hurtValue/ChConfig.Def_MaxRateValue, curProDef)  | 
|       | 
|     PlayerControl.SetProDef(defObj, curProDef - absortValue)  | 
|       | 
|     # ±»¶¯¼¼ÄÜ´¥·¢  | 
|     defObj.SetDict(ChConfig.Def_PlayerKey_GodWeaponBeforeProDef, curProDef)  | 
|     PassiveBuffEffMng.OnPassiveSkillTrigger(defObj, atkObj, None, ChConfig.TriggerType_ProDefValue, tick)  | 
|     return hurtValue - absortValue  | 
|   | 
|   | 
| # ÉèÖÃÍæ¼ÒÒ»´ÎÖ÷¶¯Ð͹¥»÷ÖеĵÚÒ»¸ö·ÀÓùÕß  | 
| def SetFirstDefender(attacker, defObj, curSkill):  | 
|     if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         return  | 
|       | 
|     if curSkill and curSkill.GetFuncType() not in [ChConfig.Def_SkillFuncType_FbSkill,  | 
|                                           ChConfig.Def_SkillFuncType_NormalAttack]:  | 
|         return  | 
|       | 
|     if attacker.GetDictByKey(ChConfig.Def_PlayerKey_FirstDefender):  | 
|         return   | 
|       | 
|     attacker.SetDict(ChConfig.Def_PlayerKey_FirstDefender, defObj.GetID())  | 
|     return  | 
|   | 
| # Çå³ýµÚһĿ±ê  | 
| def ClearFirstDefender(attacker):  | 
|     if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         return  | 
|     attacker.SetDict(ChConfig.Def_PlayerKey_FirstDefender, 0)  | 
|       | 
|     return  | 
|   | 
| def GetFirstDefenderID(attacker):  | 
|     return attacker.GetDictByKey(ChConfig.Def_PlayerKey_FirstDefender)  | 
|   | 
|   | 
|   | 
| ## ¼ÆËãÉËѪֵ  | 
| #  @param atkObj ¹¥»÷Õß  | 
| #  @param defObj ·ÀÓùÕß  | 
| #  @param atkType ¹¥»÷ÀàÐÍ(ÆÕͨ¹¥»÷ ½£Æø¹¥»÷)  | 
| #  @param atkSkillValue ¹¥»÷Õß¼¼ÄÜÔöÇ¿  | 
| #  @param atkSkillPer ¹¥»÷Õß¼¼ÄÜÔöÇ¿°Ù·Ö±È  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @param happenState ¼¼ÄÜ·¢Éú״̬  | 
| #  @param finalHurtPer ¶Ô×îÖÕ¼ÆËã³öÀ´µÄÉ˺¦Ó°ÏìЧ¹û(ÓÐÕý¸º£¬Ä¬ÈÏ10000)  | 
| #  @return None or HurtType É˺¦½á¹¹ÌåÀà   | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetHurtHP(attacker, defObj, curSkill, atkSkillValue, atkSkillPer, tick):  | 
|     atkObj = ElfChangeAttacker(attacker)  # ElfÁéÎªÌæÉí¹¥»÷£¬ÒªÈ¡Íæ¼ÒµÄÊôÐÔ  | 
|       | 
|     #ÉèÖõÚÒ»¸ö·ÀÓùÕß  | 
|     SetFirstDefender(atkObj, defObj, curSkill)  | 
|       | 
|     resultHurtType = HurtType()  | 
|     defObjType = defObj.GetGameObjType()  | 
|     dHP = GameObj.GetHP(defObj)                # ·ÀÊØ·½µ±Ç°ÑªÁ¿  | 
|     dMaxHP = GameObj.GetMaxHP(defObj)          # ·ÀÊØ·½×î´óѪÁ¿  | 
|       | 
|     # ÖÕ¼«Õ¶É±ÐÂЧ¹û£¬±ØÐëºÍնɱÑϸñÇø·Ö£¬»áÉæ¼°µ½CD¸ÅÂÊ£¬ÒѾ´¥·¢ÆäËû¼¼ÄܵÈÎÊÌâ  | 
|     if PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_ZhongjiZhansha):  | 
|         # Õ¶É±  | 
|         hurtType = ChConfig.Def_HurtType_ZhognjiZhansha  | 
|         hurtValue = GameObj.GetHP(defObj)  | 
|         #É˺¦½á¹¹Ìå  | 
|         resultHurtType.HurtHP = hurtValue  | 
|         resultHurtType.HurtType = hurtType  | 
|         resultHurtType.RealHurtHP = hurtValue  | 
|           | 
|         remainHP = 0 # Ê£ÓàѪÁ¿  | 
|   | 
|     # Õ¶É±£¬±ôËÀµÈÇé¿öµÄ´¦Àí  | 
|     elif PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackKill):  | 
|         # Õ¶É±  | 
|         hurtType = ChConfig.Def_HurtType_Zhansha  | 
|         hurtValue = GameObj.GetHP(defObj)  | 
|         #É˺¦½á¹¹Ìå  | 
|         resultHurtType.HurtHP = hurtValue  | 
|         resultHurtType.HurtType = hurtType  | 
|         resultHurtType.RealHurtHP = hurtValue  | 
|           | 
|         remainHP = 0 # Ê£ÓàѪÁ¿  | 
|   | 
|     else:  | 
|         # µ±¼¼ÄܱíµÄ¼¼ÄÜÉ˺¦°Ù·Ö±ÈΪ0£¬¼¼ÄÜÉ˺¦Ôö¼ÓÖµ¶¨ÒåΪֱ½ÓÉ˺¦Öµ£¬²»¾¹ý¼ÆËã  | 
|         if atkSkillPer == 0:  | 
|             hurtValue, hurtType = int(atkSkillValue), ChConfig.Def_HurtType_Normal  | 
|             hurtValue += atkObj.GetDictByKey(ChConfig.Def_PlayerKey_MoreHurtValue)  | 
|               | 
|         elif SkillShell.IsPlayerUseSkill(atkObj, curSkill) and SkillShell.isClientHurtValue(defObj.GetID(), defObjType):  | 
|             clientValue, hurtType = SkillShell.GetClientHurtByObj(defObj.GetID(), defObjType)  | 
|             hurtValue = min(clientValue, atkObj.GetMaxAtk()*200)    # ·ÀÏÂÉ˺¦¿ÉÄÜÉÏÏÞ  | 
|         else:  | 
|             hurtValue, hurtType = CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick, orgAtkObj=attacker)  | 
|           | 
|         WriteHurtLog(attacker, defObj, curSkill, hurtValue, hurtType, "¹«Ê½²ã")  | 
|           | 
|         # ¸÷ÖÖ¼õÉË ÎüÊÕ¶Ü´¦Àí  | 
|         hurtValue = CalcHurtHPWithBuff(atkObj, defObj, hurtValue, curSkill, tick)  | 
|           | 
|         #É˺¦½á¹¹Ìå  | 
|         resultHurtType.HurtHP = hurtValue  | 
|         resultHurtType.HurtType = hurtType  | 
|         resultHurtType.RealHurtHP = hurtValue  | 
|           | 
|         remainHP = min(dMaxHP, max(0, dHP - hurtValue)) # Ê£ÓàѪÁ¿  | 
|       | 
|     remainHP = int(remainHP)    #·À·¶  | 
|     if defObjType == IPY_GameWorld.gotPlayer:  | 
|         curHP = GameObj.GetHP(defObj)  | 
|         GameObj.SetHP(defObj, remainHP, False)  | 
|           | 
|         lockHPPer = PassiveBuffEffMng.OnObjsPassiveSkillLockHP(defObj, atkObj, curSkill, ChConfig.TriggerType_LockHP, tick)  | 
|         if lockHPPer:  | 
|             # ËøÑªÇé¿ö  | 
|             lockHP = GameObj.GetMaxHP(defObj)*lockHPPer/ChConfig.Def_MaxRateValue  | 
|             if lockHP < curHP and remainHP < lockHP:  | 
|                 remainHP = lockHP  | 
|             elif lockHP >= curHP:  | 
|                 remainHP = curHP  | 
|               | 
|             #ËøÑª¾ÀÕýѪÁ¿  | 
|             GameObj.SetHP(defObj, remainHP, False)  | 
|               | 
|     elif defObjType == IPY_GameWorld.gotNPC:  | 
|         if defObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  | 
|             #ÉèÖóèÎïÊ£ÓàѪÁ¿  | 
|             PetControl.SetPetHP(defObj, remainHP)  | 
|               | 
|         elif defObj.GetGameNPCObjType() == IPY_GameWorld.gnotTruck:  | 
|             remainHP = max(PlayerTruck.GetTruckDestroyMinHP(defObj), remainHP)  | 
|             GameObj.SetHP(defObj, remainHP)  | 
|           | 
|         elif defObj.GetType() == ChConfig.ntHelpBattleRobot:  | 
|             remainHP = min(dHP, max(GameObj.GetMaxHP(defObj)/2, remainHP)) # ÖúÕ½»úÆ÷ÈËÊ£ÓàѪÁ¿²»ÄÜÉÙÓÚÒ»°ë  | 
|             GameObj.SetHP(defObj, remainHP)  | 
|               | 
|         else:  | 
|             #·ÀÊØ·½ÊǹÖÎïNPC£¬Ö»¿ÛÆäѪ  | 
|             npcID = defObj.GetNPCID()  | 
|             timeLostHPIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCTimeLostHP", npcID)  | 
|             if timeLostHPIpyData:  | 
|                 UpdateTimeMonsterHP(defObj, timeLostHPIpyData, tick)  | 
|             else:  | 
|                 GameObj.SetHP(defObj, remainHP)  | 
|     else:  | 
|         GameWorld.ErrLog('¼ÆËãÉËѪֵʱ,·ÀÊØ·½ÀàÐÍ´íÎó£ºdefObjType = %s' % (defObjType))  | 
|         return resultHurtType  | 
|   | 
|     if GameObj.GetHP(defObj) > 0:  | 
|         # ±»¹¥»÷Õß½«²¿·ÖÉ˺¦×ª»¯ÎªÑªÁ¿, ·µ»Ø×ª»¯µÄ°Ù·Ö±È(СÊýµã)  | 
|         changePer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_ChangeHurtToHP)  | 
|         if changePer:  | 
|             SkillCommon.SkillAddHP(defObj, 0, int(changePer*hurtValue))  | 
|       | 
|     lostValue = dHP - GameObj.GetHP(defObj) # Êµ¼ÊµôѪÁ¿  | 
|     resultHurtType.LostHP = lostValue  | 
|     if defObjType == IPY_GameWorld.gotPlayer:  | 
|         FBLogic.OnFBLostHP(defObj, lostValue)  | 
|       | 
|     WriteHurtLog(attacker, defObj, curSkill, resultHurtType.LostHP, resultHurtType.HurtType, "×îÖÕ¿ÛѪ")  | 
|       | 
|     AttackEventTrigger(atkObj, defObj, curSkill, resultHurtType, tick)  | 
|       | 
|     return resultHurtType  | 
|   | 
| def UpdateTimeMonsterHP(curNPC, ipyData, tick):  | 
|     '''  | 
|     NPC×ÜѪÁ¿ = µ¥ÈËÿÃëµôѪÁ¿*ÀíÂÛ»÷ɱËùÐèʱ¼ä  | 
|          µôѪֵ = µ¥ÈËÿÃëµôѪÁ¿+min(µ±Ç°ÈËÊý, ×î´óÈËÊý)*¸½¼ÓµôѪÁ¿+(ÓÐЧսÁ¦-±ê×¼Õ½Á¦)/xÕ½Á¦*xÕ½Á¦¸½¼ÓµôѪ  | 
|     '''  | 
|       | 
|     lastLostHPTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPTick)  | 
|     curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPTick, tick)  | 
|     if not lastLostHPTick or tick - lastLostHPTick >= 2000:  | 
|         passTick = 1000  | 
|     else:  | 
|         passTick = tick - lastLostHPTick  | 
|       | 
|     if passTick <= 0:  | 
|         return  | 
|           | 
|     lostHPPerSecond = ipyData.GetLostHPPerSecond()  | 
|     maxPlayerCount = ipyData.GetMaxPlayerCount()  | 
|     lostHPPerSecondEx = ipyData.GetLostHPPerSecondEx()  | 
|     fightPowerMinByLV = ipyData.GetFightPowerMinByLV()  | 
|     fightPowerMin = ipyData.GetFightPowerMin()  | 
|     fightPowerMax = ipyData.GetFightPowerMax()  | 
|     everyFightPower = ipyData.GetEveryFightPower()  | 
|     everyFightPowerLostHPEx = ipyData.GetEveryFightPowerLostHPEx()  | 
|     if fightPowerMinByLV and fightPowerMin:  | 
|         npcLV = NPCCommon.GetNPCLV(curNPC)  | 
|         playerCurLVIpyData = PlayerControl.GetPlayerLVIpyData(npcLV)  | 
|         if not playerCurLVIpyData:  | 
|             return  | 
|         ReFightPower = playerCurLVIpyData.GetReFightPower() # Õ½¶·Á¦  | 
|         reRate = ReFightPower / float(fightPowerMin)  | 
|         #GameWorld.DebugLog("±ê×¼Õ½Á¦ÐèҪȡµÈ¼¶±í: fightPowerMin=%s,fightPowerMax=%s,everyFightPower=%s,npcLV=%s,ReFightPower=%s,reRate=%s"   | 
|         #                   % (fightPowerMin, fightPowerMax, everyFightPower, npcLV, ReFightPower, reRate))  | 
|         fightPowerMin = ReFightPower  | 
|         fightPowerMax = int(fightPowerMax * reRate)  | 
|         everyFightPower = int(everyFightPower * reRate)  | 
|         #GameWorld.DebugLog("°´±ÈÀý¸üÐÂÕ½Á¦ÖµÐÅÏ¢: fightPowerMin=%s,fightPowerMax=%s,everyFightPower=%s"   | 
|         #                   % (fightPowerMin, fightPowerMax, everyFightPower))  | 
|           | 
|     effFightPower = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPFightPower) \  | 
|                     + curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPFightPowerEx) * ChConfig.Def_PerPointValue  | 
|     effPlayerCount = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCount)  | 
|     refreshPlayerCountTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCountTick)  | 
|     if not refreshPlayerCountTick or tick - refreshPlayerCountTick >= 3000:  | 
|         curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCountTick, tick)  | 
|         fightPowerTotal = 0  | 
|         effPlayerCount = 0  | 
|         for i in xrange(curNPC.GetInSightObjCount()):  | 
|             seeObj = curNPC.GetInSightObjByIndex(i)  | 
|             if seeObj == None :  | 
|                 continue  | 
|             if not seeObj.GetVisible():  | 
|                 continue  | 
|             seeObjType = seeObj.GetGameObjType()  | 
|             if seeObjType != IPY_GameWorld.gotPlayer:  | 
|                 continue  | 
|             effPlayerCount += 1  | 
|             if fightPowerMin:            | 
|                 seePlayer = GameWorld.GetObj(seeObj.GetID(), seeObjType)  | 
|                 fightPowerTotal += (0 if not seePlayer else PlayerControl.GetFightPower(seePlayer))  | 
|           | 
|         effPlayerCount = max(effPlayerCount, 1)  | 
|           | 
|         effFightPower = int(fightPowerTotal / effPlayerCount)  | 
|         if fightPowerMax and effFightPower > fightPowerMax:  | 
|             effFightPower = fightPowerMax  | 
|               | 
|         if maxPlayerCount and effPlayerCount > maxPlayerCount:  | 
|             effPlayerCount = maxPlayerCount  | 
|               | 
|         curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPFightPower, effFightPower % ChConfig.Def_PerPointValue)  | 
|         curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPFightPowerEx, effFightPower / ChConfig.Def_PerPointValue)  | 
|         curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCount, effPlayerCount)  | 
|         #GameWorld.DebugLog("Ë¢ÐÂÓ°ÏìÈËÊý: effPlayerCount=%s,effFightPower=%s" % (effPlayerCount, effFightPower))  | 
|           | 
|     hurtValuePerSecond = lostHPPerSecond  | 
|     #ÈËÊý¸½¼ÓÉ˺¦  | 
|     if effPlayerCount > 1:  | 
|         playerCountHurtEx = (effPlayerCount - 1) * lostHPPerSecondEx  | 
|         hurtValuePerSecond += playerCountHurtEx  | 
|         #GameWorld.DebugLog("playerCountHurtEx=%s,hurtValuePerSecond=%s" % (playerCountHurtEx, hurtValuePerSecond))  | 
|           | 
|     #Õ½Á¦¸½¼ÓÉ˺¦  | 
|     if fightPowerMin and effFightPower and everyFightPower and everyFightPowerLostHPEx:  | 
|         fightPowerHurtEx = (effFightPower - fightPowerMin) / float(everyFightPower) * everyFightPowerLostHPEx # ¿ÉÄÜΪ¸ºÖµ  | 
|         hurtValuePerSecond += fightPowerHurtEx  | 
|         #GameWorld.DebugLog("fightPowerHurtEx=%s,hurtValuePerSecond=%s" % (fightPowerHurtEx, hurtValuePerSecond))  | 
|           | 
|     lostHPTotal = max(1, int(hurtValuePerSecond * passTick / 1000.0))  | 
|       | 
|     remainHP = min(GameObj.GetMaxHP(curNPC), max(0, GameObj.GetHP(curNPC) - lostHPTotal))  | 
|     GameObj.SetHP(curNPC, remainHP, isByTime=True)  | 
|     #GameWorld.DebugLog("¹ÖÎﰴʱ¼äµôѪ: npcID=%s,effPlayerCount=%s,effFightPower=%s,hurtValuePerSecond=%s,passTick=%s,lostHPTotal=%s"   | 
|     #                   % (curNPC.GetNPCID(), effPlayerCount, effFightPower, hurtValuePerSecond, passTick, lostHPTotal))  | 
|     return  | 
|   | 
| # ¼ÆËãÉ˺¦ºó£¬Òò¸÷ÖÖbuffºÍ״̬µÄÓ°Ïì´¦Àí  | 
| def CalcHurtHPWithBuff(atkObj, defObj, hurtValue, curSkill, tick):  | 
|     # ÓÅÏÈ´¦ÀíÉñ±ø»¤¶Ü  | 
|     hurtValue = CalcAtkProDef(atkObj, defObj, hurtValue, curSkill, tick)  | 
|   | 
|     # É˺¦ÎüÊÕ¶Ü»ØÑªÐÍ  | 
|     buffManager = defObj.GetBuffState()  | 
|       | 
|     curEffect, plusValue, skillID = BuffSkill.FindBuffEffectPlusByEffectID(buffManager, ChConfig.Def_Skill_Effect_AbsorbShield)  | 
|     if skillID:  | 
|         absortValue = int(hurtValue*curEffect.GetEffectValue(0)/ShareDefine.Def_MaxRateValue)  | 
|         if absortValue:  | 
|             hurtValue -= absortValue  | 
|             findBuff = SkillCommon.FindBuffByID(defObj, skillID)[0]  | 
|             if findBuff:  | 
|                 # ÓÃÓÚ±¬Õ¨  | 
|                 findBuff.SetValue1(min(findBuff.GetValue1() + absortValue, findBuff.GetValue()))  | 
|                 if findBuff.GetValue() == findBuff.GetValue1():  | 
|                     # ÂúÖµÔò֪ͨ±¬Õ¨  | 
|                     findBuff.SetRemainTime(1)  | 
|       | 
|           | 
|     # Ìì¤·¨£¬½«ÆÚ¼äÊܵ½µÄÉ˺¦×ÜÖµÓÃÓÚ»ØÑª£¬²»¸Ä±äÉ˺¦,ÔÝÇÒ²»Óà  | 
|     #===========================================================================  | 
|     # curEffect, plusValue, skillID2 = BuffSkill.FindBuffEffectPlusByEffectID(buffManager, ChConfig.Def_Skill_Effect_StoreBlood)  | 
|     # if skillID2:  | 
|     #    absortValue = hurtValue*curEffect.GetEffectValue(0)/ShareDefine.Def_MaxRateValue  | 
|     #    if absortValue:  | 
|     #        findBuff = SkillCommon.FindBuffByID(defObj, skillID2)[0]  | 
|     #        if findBuff:  | 
|     #            # ÓÃÓÚ»ØÑª  | 
|     #            findBuff.SetValue(int(findBuff.GetValue() + absortValue))  | 
|     #===========================================================================  | 
|       | 
|     curEffect, plusValue, skillID = BuffSkill.FindBuffEffectPlusByEffectID(buffManager, ChConfig.Def_Skill_Effect_AbsorbShieldXMZJ)  | 
|     if skillID:  | 
|         absortValue = hurtValue*curEffect.GetEffectValue(0)/ShareDefine.Def_MaxRateValue  | 
|         if absortValue:  | 
|             hurtValue -= absortValue  | 
|             findBuff = SkillCommon.FindBuffByID(defObj, skillID)[0]  | 
|             if findBuff:  | 
|                 # ÓÃÓÚ»ØÑª  | 
|                 findBuff.SetValue(min(int(findBuff.GetValue() + absortValue), ChConfig.Def_UpperLimit_DWord))  | 
|       | 
|     hurtValue = max(int(hurtValue), 0)  | 
|     # buff¼õÉÙÉ˺¦°Ù·Ö±È  | 
|     reducePer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, None, ChConfig.TriggerType_ReduceHurtHPPer)  | 
|       | 
|     # ±»¹¥»÷±»¶¯¼¼ÄÜÌØÊâ¼õÃâ Êܵ½µ¥´ÎÉ˺¦³¬¹ýÉúÃüÉÏÏÞ10%ʱºò£¬¼õÃâ50%É˺¦£¬CD10Ãë  | 
|     defObj.SetDict(ChConfig.Def_PlayerKey_curHurtValue, hurtValue % ShareDefine.Def_PerPointValue)  | 
|     defObj.SetDict(ChConfig.Def_PlayerKey_curHurtValueEx, hurtValue / ShareDefine.Def_PerPointValue)  | 
|     reducePer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_ReduceHurtHPPer)  | 
|     hurtValue = int(hurtValue*(max(ChConfig.Def_MaxRateValue - reducePer, 0))*1.0/ChConfig.Def_MaxRateValue)  | 
|       | 
|     hurtValue = CalcBloodShield(atkObj, defObj, hurtValue)  | 
|       | 
|     # ÊÜÉËÉÏÏÞ´¦Àí£¬±ØÐë·Åµ½×îºó  | 
|     beHurtMax = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, None, ChConfig.TriggerType_BeHurtMax)  | 
|     if beHurtMax > 0:  | 
|         GameWorld.DebugLog("        ×î¸ßÊÜÉËÖµÏÞÖÆ: defID=%s,beHurtMax=%s,hurtValue=%s" % (defObj.GetID(), beHurtMax, hurtValue))  | 
|         hurtValue = min(hurtValue, beHurtMax)  | 
|           | 
|     return hurtValue  | 
|   | 
|   | 
|   | 
| # GM ÃüÁî  HurtLog ²é¿´Õ½¶·É˺¦ÈÕÖ¾  | 
| def WriteHurtLog(attacker, defObj, curSkill, hurtValue, hurtType, msg):  | 
|     logLevel = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_HurtLog)  | 
|     if not logLevel:  | 
|         return  | 
|       | 
|     if logLevel == 1:  | 
|         # Ö»¿´Íæ¼ÒÉ˺¦  | 
|         if not attacker:  | 
|             return  | 
|           | 
|         if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|             return  | 
|         msg = "Íæ¼Ò" + msg  | 
|       | 
|     attackerID = attacker.GetID() if attacker else 0  | 
|     defenderID = defObj.GetID() if defObj else 0  | 
|     skillID = curSkill.GetSkillID() if curSkill else 0  | 
|     skillName = curSkill.GetSkillName()  if curSkill else ""  | 
|     attackerName = attacker.GetName() if attacker else ""  | 
|     defenderName = defObj.GetName() if defObj else ""  | 
|       | 
|     if attacker and attacker.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|         attackerName = attackerName.decode("utf8").encode('gbk')  | 
|           | 
|     if defObj and defObj.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|         defenderName = defenderName.decode("utf8").encode('gbk')  | 
|           | 
|     GameWorld.DebugLog("¹¥»÷É˺¦-%s£º(%s %s)¹¥»÷(%s %s), ¼¼ÄÜID:(%s %s), É˺¦Öµ:%s, É˺¦ÀàÐÍ:%s "%(  | 
|                         msg, attackerID, attackerName, defenderID, defenderName,  | 
|                         skillID, skillName, hurtValue, hurtType))  | 
|   | 
| # Ñª¶ÜÖ§³Ö¶à¸öͬʱ´æÔÚ£¬ ·´µ¯Ò²»á±»ÎüÊÕ  | 
| def CalcBloodShield(atkObj, defObj, hurtValue):  | 
|     # É˺¦ÖµÓÃÓÚѪ¶ÜµÖÏû  | 
|     GameObj.SetBloodShiledHurt(defObj, hurtValue)  | 
|       | 
|     PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, None, ChConfig.TriggerType_BloodShield)  | 
|       | 
|     return GameObj.GetBloodShiledHurt(defObj)  | 
|   | 
|   | 
| # ¼ÆËã¹¥»÷É˺¦  | 
| # maxHurt²ÎÊýÓÃÓÚÄ£Äâ¼ÆËã×î´óÉ˺¦£¬·À·¶¿Í»§¶Ë¹¥»÷É˺¦¹ý¸ß  | 
| def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick, happenState=None, **atkwargs):  | 
|     # ·¹öÉÁ±ÜÌØÊâ´¦Àí  | 
|     if tick - defObj.GetDictByKey(ChConfig.Def_PlayerKey_SomersaultTime) < 500:  | 
|         return 0, ChConfig.Def_HurtType_Miss  | 
|       | 
|     multiValue = 0 # É˺¦±¶Öµ  | 
|     atkPer = ChConfig.Def_MaxRateValue    # Ìá¸ß»ù´¡¹¥»÷Á¦  | 
|     summonAtkObj = atkwargs.get('orgAtkObj', None) if atkwargs.get('orgAtkObj', None) else atkObj  | 
|     if summonAtkObj.GetGameObjType() == IPY_GameWorld.gotNPC and summonAtkObj.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:  | 
|         summonAtkPerValue = summonAtkObj.GetDictByKey(ChConfig.Def_GameObjKey_InheritOwner)  | 
|         if summonAtkPerValue > 0:  | 
|             # ±©·çÑ©ÀàÕÙ»½ÊÞת»¯ÎªÖ÷È˼ÆËãÉ˺¦  | 
|             ownerAtkObj = NPCCommon.GetSummonOwnerDetel(summonAtkObj)  | 
|             if not ownerAtkObj:  | 
|                 return 0, ChConfig.Def_HurtType_Miss  | 
|               | 
|             atkPer = summonAtkPerValue  | 
|             #GameWorld.DebugLog("ÕÙ»½ÊÞÈ¡Ö÷ÈË---------%s-%s-%s-%s"%(ownerAtkObj.GetID(), atkSkillPer, atkSkillValue, summonAtkPerValue))  | 
|           | 
|     atkObjType = atkObj.GetGameObjType()  | 
|     defObjType = defObj.GetGameObjType()  | 
|   | 
|     aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType) # »ñÈ¡¾³½ç  | 
|     if defObjType == IPY_GameWorld.gotNPC and ChConfig.IsGameBoss(defObj) and dRealmLV > aRealmLV:  | 
|         aRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", aRealmLV)  | 
|         dRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", dRealmLV)  | 
|         aRealmLVLarge = aRealmIpyData.GetLvLarge() if aRealmIpyData else 0  | 
|         dRealmLVLarge = dRealmIpyData.GetLvLarge() if dRealmIpyData else 0  | 
|         if dRealmLVLarge > aRealmLVLarge:  | 
|             if atkObjType == IPY_GameWorld.gotPlayer:  | 
|                 GameWorld.DebugLog("BossRealmHint%s-%s"%(dRealmLV, aRealmLV))  | 
|                 PlayerControl.NotifyCode(atkObj, 'BossRealmHint', [dRealmLVLarge])  | 
|                   | 
|             # ¹¥»÷¸ß¾³½çµÄBOSS É˺¦¹Ì¶¨Îª1  | 
|             return 1, ChConfig.Def_HurtType_Normal  | 
|           | 
|     atkType = GetBattleType(atkObj, curSkill)  | 
|     happenState = happenState if happenState else SkillShell.GetHappenState(curSkill)  | 
|     happenState += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_HappenState)  | 
|   | 
|     aLV = atkObj.GetLV()                # ¹¥»÷·½µÈ¼¶  | 
|     dLV = defObj.GetLV()                # ·ÀÊØ·½µÈ¼¶  | 
|   | 
|     aHit = GameObj.GetMissDefRate(atkObj)#atkObj.GetHit()  | 
|     if curSkill and atkObjType == IPY_GameWorld.gotPlayer and curSkill.GetFuncType() != ChConfig.Def_SkillFuncType_NormalAttack:  | 
|         aHit = aHit*IpyGameDataPY.GetFuncCfg("FightHappenRate", 2)  | 
|           | 
|     #aHitSuccessRate = PlayerControl.GetHitSucessRate(atkObj) if atkObjType == IPY_GameWorld.gotPlayer else ChConfig.Def_MaxRateValue  | 
|     #aHitSuccessRate += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_HitSuccess)  | 
|     dMiss = GameObj.GetMissRate(defObj)#defObj.GetMiss()  | 
|     dMiss += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_MissPer)  | 
|     #dMissSuccessRate = PlayerControl.GetMissSucessRate(defObj) if defObjType == IPY_GameWorld.gotPlayer else 0  | 
|     #dMissSuccessRate += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_MissSuccessPer)  | 
|     skillID = curSkill.GetSkillID() if curSkill else 0  | 
|       | 
|       | 
|     atkIsBoss = 0 # ¹¥»÷·½ÊÇ·ñboss  | 
|     suppressValueLV = 0 # µÈ¼¶×îÖÕÑ¹ÖÆÖµ, ÓÉÑ¹ÖÆ¹æÔò¼°Ïà¹Ø²ÎÊý¼ÆËãµÃ³ö£¬¿É×÷ΪÉ˺¦¹«Ê½¼ÆËã²ÎÊýʹÓà  | 
|     suppressValueFP = 0 # Õ½Á¦×îÖÕÑ¹ÖÆÖµ, ÓÉÑ¹ÖÆ¹æÔò¼°Ïà¹Ø²ÎÊý¼ÆËãµÃ³ö£¬¿É×÷ΪÉ˺¦¹«Ê½¼ÆËã²ÎÊýʹÓà  | 
|     suppressLV, suppressFightPower = 0, 0 # Ñ¹ÖƵȼ¶²î¡¢Õ½Á¦²î  | 
|     suppressReMaxHP = 0 # NPCÑ¹ÖÆµÈ¼¶ÉúÃüÖµ, µÈ¼¶±íÖÐNPCµÈ¼¶¶ÔÓ¦µÄÊý¾Ý, Ñ¹ÖƵȼ¶²î´óÓÚ0ʱ²ÅÓÐÖµ  | 
|     suppressNPCFightPower = 0 # Ñ¹ÖÆNPCÕ½Á¦  | 
|     fbFightPower, fbBaseHurt = 0, 0 # ¸±±¾Õ½Á¦, ¸±±¾±£µ×É˺¦  | 
|     #µ±¹¥»÷·½ÎªNPC£¬·ÀÊØ·½ÎªÍæ¼Òʱ£¬¼ÆËãÑ¹ÖÆµÈ¼¶ ¼° Ñ¹ÖÆÕ½Á¦  | 
|     if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer:  | 
|           | 
|         if curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_RealmSuppress:  | 
|             # ¾³½çÑ¹ÖÆ¼¼Äܲ»¶Ô¸ßµÈ¼¶¾³½çÍæ¼Ò²úÉú¹¥»÷  | 
|             aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType)  | 
|             if aRealmLV <= dRealmLV:  | 
|                 return 0, ChConfig.Def_HurtType_Immune   # ÃâÒß  | 
|               | 
|         atkIsBoss = 1 if ChConfig.IsGameBoss(atkObj) else 0  | 
|         if NPCCommon.GetIsLVSuppress(atkObj):  | 
|             suppressLV = max(0, aLV - dLV)  | 
|             if suppressLV:  | 
|                 suppressLVIpyData = PlayerControl.GetPlayerLVIpyData(aLV)  | 
|                 suppressReMaxHP = 0 if not suppressLVIpyData else suppressLVIpyData.GetReMaxHP()  | 
|         suppressNPCFightPower = NPCCommon.GetSuppressFightPower(atkObj)  | 
|         if suppressNPCFightPower:  | 
|             suppressFightPower = max(0, suppressNPCFightPower - PlayerControl.GetFightPower(defObj))  | 
|               | 
|     turnFightTimeline = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)  | 
|     mustHit = False  | 
|     petNPCOwner = None  | 
|     helpBattleFormatKey = ""  | 
|     if atkObjType == IPY_GameWorld.gotNPC and atkObj.GetType() == ChConfig.ntHelpBattleRobot:  | 
|         mustHit = True  | 
|         suppressNPCFightPower = NPCCommon.GetSuppressFightPower(atkObj)  | 
|         fbFightPower = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBFightPower)  | 
|         fbBaseHurt = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBBaseHurt)  | 
|         helpBattleFormatKey = "HelpRobot_Atk"  | 
|     if defObjType == IPY_GameWorld.gotNPC and defObj.GetType() == ChConfig.ntHelpBattleRobot:  | 
|         mustHit = True  | 
|         suppressNPCFightPower = NPCCommon.GetSuppressFightPower(defObj)  | 
|         fbFightPower = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBFightPower)  | 
|         fbBaseHurt = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBBaseHurt)  | 
|         helpBattleFormatKey = "HelpRobot_Def"  | 
|     if atkObjType == IPY_GameWorld.gotNPC and PetControl.IsPetNPC(atkObj):  | 
|         mustHit = True  | 
|         GameWorld.DebugLog("        Áé³è±ØÃüÖÐ")  | 
|         petNPCOwner = PetControl.GetPetNPCOwner(atkObj)  | 
|     #È¥³ý·´»÷±ØÃüÖÐÉ趨  | 
|     #if turnFightTimeline:  | 
|     #    if atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnBattleType) == ChConfig.TurnBattleType_AtkBack:  | 
|     #        mustHit = True  | 
|     #        GameWorld.DebugLog("        ·´»÷±ØÃüÖÐ: atkID=%s,defID=%s" % (atkObj.GetID(), defObj.GetID()))  | 
|     if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_HitOn):  | 
|         mustHit = True  | 
|         GameWorld.DebugLog("        ¼¼ÄܱØÃüÖÐ: skillID=%s" % skillID)  | 
|           | 
|     #ÃüÖй«Ê½ ¹¥»÷·½ÀàÐͲ»Í¬£¬¹«Ê½²»Í¬  | 
|     missRateFormula = ReadChConfig.GetChConfig('CalcCanHit')  | 
|     if not mustHit and not PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill,   | 
|                            ChConfig.TriggerType_Buff_MustBeHit):  | 
|         # ¼¼ÄܶÔÖ¸¶¨BOSSÎÞЧ¹ûµÄ·µ»ØMISS  | 
|         if defObjType == IPY_GameWorld.gotNPC and defObj.GetIsBoss() not in ChConfig.Def_SkillAttack_NPCIsBoss \  | 
|         and SkillCommon.GetSkillBattleType(curSkill) == ChConfig.Def_BattleRelationType_CommNoBoss and SkillShell.IsNPCSkillResist(defObj):  | 
|             return 0, ChConfig.Def_HurtType_Miss  | 
|           | 
|         #¹¥»÷·½´¦ÓÚ³°·í£¬·ÀÊØ·½´¦ÓÚÃâÒß³°·íÕß¹¥»÷Ôòmiss  | 
|         if GameObj.GetPyPlayerState(atkObj, ChConfig.Def_PlayerState_Sneer) and \  | 
|         GameObj.GetPyPlayerState(defObj, ChConfig.Def_PlayerState_MissSneerAtk):  | 
|             return 0, ChConfig.Def_HurtType_Miss  | 
|           | 
|         missRate = eval(missRateFormula)  | 
|         if GameWorld.CanHappen(missRate):  | 
|             return 0, ChConfig.Def_HurtType_Miss  | 
|           | 
|     hurtValueExPer = 0 # ×îÖÕµÄÉ˺¦Öµ¸½¼Ó¶îÍâÉ˺¦°Ù·Ö±È  | 
|     hurtType, hurtTypeResultDict = CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState, curSkill)  | 
|     #GameWorld.DebugLog("GetHurtHP hurtType=%s, hurtTypeResultDict=%s" % (hurtType, hurtTypeResultDict))  | 
|     isLuckyHit, aLuckyHit, dLuckyHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_LuckyHit] # ÐÒÔËÒ»»÷  | 
|       | 
|     # ÖØ»÷ºÍ±©»÷»¥³â£¬²¢ÇÒʹÓÃͬһ¸ö²ÎÊý  | 
|     isSuperHit, aSuperHit, dSuperHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_ThumpHit]   | 
|     aSuperHitHurtPer = GameObj.GetSuperHitHurtPer(atkObj)  | 
|     dSuperHitHurtDefPer = GameObj.GetSuperHitHurtPer(defObj)  | 
|     if not isSuperHit:  | 
|         isSuperHit, aSuperHit, dSuperHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_SuperHit]   | 
|           | 
|         # ±©»÷¼Ó³É  | 
|         superHitPer = 0  | 
|         superHitPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitPer)  | 
|         superHitPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitPer)  | 
|         aSuperHit = aSuperHit*(superHitPer + ChConfig.Def_MaxRateValue)/ChConfig.Def_MaxRateValue  | 
|           | 
|         if isSuperHit:  | 
|             hurtValueExPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_BeSuperHitHurtExPer)  | 
|     else:  | 
|         # ÖØ»÷¼Ó³É  | 
|         thumpPer = 0  | 
|         thumpPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddThumpHitPer)  | 
|         thumpPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddThumpHitPer)  | 
|         aSuperHit = aSuperHit*(thumpPer + ChConfig.Def_MaxRateValue)/ChConfig.Def_MaxRateValue  | 
|           | 
|     dDamChanceDef = hurtTypeResultDict[ChConfig.Def_HurtType_Parry][2] # µÖÓù, ´óÓÚ0´ú±í´¥·¢µÖÓùЧ¹û  | 
|     isZhuxianHit, aZhuxianHurtPer, dZhuxianReducePer = hurtTypeResultDict[ChConfig.Def_HurtType_Zhuxian] # ÖïÏÉÒ»»÷  | 
|     isDeadlyHit, deadlyHitMultiValue, _ = hurtTypeResultDict[ChConfig.Def_HurtType_DeadlyHit] # ÖÂÃüÒ»»÷  | 
|   | 
|     if PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_OneDamage):  | 
|         return 1, hurtType  | 
|       | 
|     wReFightPower = 0  | 
|     worldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)  | 
|     if worldLV:  | 
|         wLVIpyData = PlayerControl.GetPlayerLVIpyData(worldLV)  | 
|         wReFightPower = 0 if not wLVIpyData else wLVIpyData.GetReFightPower() # µ±Ç°ÊÀ½çµÈ¼¶²Î¿¼Õ½Á¦  | 
|       | 
|     # ¸Ä±ä¼¼ÄÜÉ˺¦  | 
|     atkSkillPer, atkSkillValue = ChangeSkillHurt(atkObj, defObj, curSkill, atkSkillPer, atkSkillValue)  | 
|     atkSkillPer = ChangeSkillHurtPer(atkObj, defObj, curSkill, atkSkillPer)  | 
|       | 
|     # --- ÐÂÔöÆÕͨ¹¥»÷µÄÊýÖµºÍ¼¼Äܹ¥»÷µÄÊýÖµ£¬¸ù¾ÝÀàÐ͸÷×Ô¼ÆËã  | 
|     if atkObjType == IPY_GameWorld.gotPlayer:  | 
|         if not curSkill or curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:  | 
|             atkSkillPer += PlayerControl.GetNormalHurtPer(atkObj)  | 
|             atkSkillValue += PlayerControl.GetNormalHurt(atkObj)  | 
|         elif curSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_FbSkill, ChConfig.Def_SkillFuncType_FbPassiveSkill]:  | 
|             atkSkillPer += PlayerControl.GetFabaoHurtPer(atkObj)  | 
|             atkSkillValue += PlayerControl.GetFabaoHurt(atkObj)  | 
|             | 
|     atkSkillValue += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SkillValue)  | 
|     atkSkillValue += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SkillValue)  | 
|       | 
|     #  atkSkillPer °üº¬ÆÕ¹¥£¬ËùÒÔ²»ÊÇÓü¼ÄÜÔöÇ¿´¦Àí  | 
|     atkSkillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddSkillPer)  | 
|     atkSkillPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddSkillPer)  | 
|     atkSkillPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_BeAttackAddSkillPer)  | 
|     # Ó¡¼ÇÔö¼ÓµÄ¼¼ÄÜÉ˺¦£¬ÓÃÓÚÆ®×Ö  | 
|     atkSkillPerYinji = PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddSkillPerYinji)  | 
|     atkSkillPer += atkSkillPerYinji  | 
|     if curSkill and curSkill.GetXP():  | 
|         atkSkillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_XPAttackAddSkillPer)  | 
|           | 
|     if hurtType == ChConfig.Def_HurtType_SuperHit:  | 
|         # ±©»÷Ôö¼Ó¼¼ÄÜÉ˺¦  | 
|         atkSkillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSkillPer)  | 
|         atkSkillPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSkillPer)  | 
|           | 
|         # buffÖб©»÷¼õ²ã£¬ÎÞ´¥·¢¼¼ÄÜ  | 
|         PassiveBuffEffMng.OnPassiveBuffTrigger(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSubLayer, tick)  | 
|     elif hurtType == ChConfig.Def_HurtType_ThumpHit:  | 
|         atkSkillValue += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_ThumpSkillValue)  | 
|   | 
|     if isLuckyHit:  | 
|         # »áÐÄÒ»»÷ʱÔö¼Ó»áÐÄÉ˺¦¹Ì¶¨Öµ   | 
|         aLuckyHit += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_LuckyHit)  | 
|         aLuckyHit -= PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_BeLuckyHitSubPer)  | 
|         aLuckyHit = max(aLuckyHit, 0)  | 
|           | 
|     #²ÎÓëÔËËãµÄÊýÖµ  | 
|     rand = random.random()                #ÖÖ×ÓÊý 0~1  | 
|       | 
|     #------- ¹¥»÷·½  | 
|     aMinAtk = atkObj.GetMinAtk()        # ¹¥»÷·½×îС¹¥»÷  | 
|     aMaxAtk = atkObj.GetMaxAtk()       # ¹¥»÷·½×î´ó¹¥»÷  | 
|     if petNPCOwner:  | 
|         petNPCOwner.SetDict("useSkillPetID", atkObj.GetID())  | 
|         #Ö÷È˹¥»÷Á¦¿ÉÄÜ»á±ä»¯£¬ËùÒÔÔÚÕâÀïÓõ½Ê±Ö±½ÓÈ¡  | 
|         aMinAtk = petNPCOwner.GetMinAtk()        # ¹¥»÷·½×îС¹¥»÷  | 
|         aMaxAtk = petNPCOwner.GetMaxAtk()       # ¹¥»÷·½×î´ó¹¥»÷  | 
|         #GameWorld.DebugLog("Áé³è¹¥»÷£¬Ö±½ÓÈ¡Ö÷È˹¥»÷Á¦: %s ~ %s,  ×Ô¼º: %s ~ %s" % (aMinAtk, aMaxAtk, atkObj.GetMinAtk(), atkObj.GetMaxAtk()))  | 
|           | 
|         hurtValueExPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(petNPCOwner, defObj, curSkill, ChConfig.TriggerType_PetAtkHurtExPer)  | 
|     else:  | 
|         atkPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddAtkPer)          | 
|           | 
|     if atkPer != ChConfig.Def_MaxRateValue:  | 
|         aMinAtk = aMinAtk * float(atkPer)/ChConfig.Def_MaxRateValue  | 
|         aMaxAtk = aMaxAtk * float(atkPer)/ChConfig.Def_MaxRateValue  | 
|           | 
|     enemyObj = None  | 
|     aPetStrengthenPer, dPetWeakenPer = 0, 0 # Ç¿»¯ÁéÊÞ, Èõ»¯ÁéÊÞ  | 
|     if turnFightTimeline:  | 
|         if petNPCOwner:  | 
|             aPetStrengthenPer = GameObj.GetPetStrengthenPer(petNPCOwner)  | 
|                           | 
|             enemyObj = TurnAttack.GetEnemyObj(petNPCOwner)  | 
|             if enemyObj:  | 
|                 dPetWeakenPer = GameObj.GetPetWeakenPer(enemyObj)  | 
|                   | 
|     aIceAtk = atkObj.GetIceAtk()        # ±ù¹¥, ÔªËØÕæÉË, Íæ¼Ò¼°NPCͨÓà  | 
|     aIceAtk += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddIceAtk)  | 
|     #------- ·ÀÊØ·½  | 
|     dMinAtk = defObj.GetMinAtk()        # ·ÀÊØ·½×îС¹¥»÷  | 
|     dMaxAtk = defObj.GetMaxAtk()        # ·ÀÊØ·½×î´ó¹¥»÷  | 
|     dDef = defObj.GetDef()              # ·ÀÊØ·½·ÀÓùÁ¦  | 
|     dHP = GameObj.GetHP(defObj)                # ·ÀÊØ·½µ±Ç°ÑªÁ¿  | 
|     dMaxHP = GameObj.GetMaxHP(defObj)          # ·ÀÊØ·½×î´óѪÁ¿  | 
|     dIceDef = defObj.GetIceDef()        # ±ù·À, ÔªËØÕæ·À, Íæ¼Ò¼°NPCͨÓà     | 
|       | 
|     # ¹¥»÷·½  | 
|     aFinalHurtPer = GameObj.GetFinalHurtPer(atkObj) # ×îÍâ²ãÉ˺¦¼Ó³É, ¿ÉÄÜΪ¸ºÖµ  | 
|     aFinalHurtPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddFinalPer)  | 
|     if atkObjType == IPY_GameWorld.gotPlayer:  | 
|         aIgnoreDefRate = atkObj.GetIgnoreDefRate()  # ÎÞÊÓ·ÀÓù±ÈÂÊ  | 
|         aSkillAtkRate = atkObj.GetSkillAtkRate()    # ¼¼Äܹ¥»÷Á¦¼Ó³É  | 
|         aDamagePVP = PlayerControl.GetDamagePVP(atkObj)     # PVP¹Ì¶¨É˺¦  | 
|         aDamagePVE = PlayerControl.GetDamagePVE(atkObj)     # PVE¹Ì¶¨É˺¦  | 
|           | 
|         aNPCHurtAddPer = PlayerControl.GetNPCHurtAddPer(atkObj)     # PVEÉ˺¦¼Ó³É  | 
|         aDamagePerPVP = PlayerControl.GetDamagePerPVP(atkObj)     # Íâ²ãPVPÉ˺¦¼Ó³É  | 
|         aDamagePerPVP += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddPVPDamagePer)  | 
|           | 
|         aFinalHurt = PlayerControl.GetFinalHurt(atkObj)     # ×îÖչ̶¨É˺¦  | 
|         # ±»¶¯Ôö¼Ó×îÖÕÉ˺¦  | 
|         aFinalHurt += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddFinalValue)  | 
|         aFinalHurt += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddFinalValue)  | 
|           | 
|         aOnlyFinalHurt = PlayerControl.GetOnlyFinalHurt(atkObj) # ¶îÍâ¹Ì¶¨É˺¦  | 
|         aFightPower = PlayerControl.GetFightPower(atkObj)  | 
|     else:  | 
|         aIgnoreDefRate = 0  # ÎÞÊÓ·ÀÓù±ÈÂÊ  | 
|         aSkillAtkRate = NPCCommon.GetSkillAtkRate(atkObj)   # ¼¼Äܹ¥»÷Á¦¼Ó³É  | 
|         if atkObjType == IPY_GameWorld.gotNPC and atkObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  | 
|             aSkillAtkRate += atkObj.GetSkillAtkRate()  | 
|               | 
|         aNPCHurtAddPer = 0  # PVEÉ˺¦¼Ó³É  | 
|         aDamagePerPVP = 0   # Íâ²ãPVPÉ˺¦¼Ó³É  | 
|         aDamagePVP = 0      # PVP¹Ì¶¨É˺¦  | 
|         aDamagePVE = 0      # PVE¹Ì¶¨É˺¦  | 
|         aFinalHurt = NPCCommon.GetFinalHurt(atkObj) # ×îÖչ̶¨É˺¦  | 
|         aOnlyFinalHurt = 0 # ¶îÍâ¹Ì¶¨É˺¦  | 
|         aFightPower = NPCCommon.GetSuppressFightPower(atkObj)  | 
|           | 
|           | 
|     #·ÀÊØ·½µÄÀàÐÍ  | 
|     dFinalHurtReducePer = GameObj.GetFinalHurtReducePer(defObj)  | 
|     dFinalHurtReducePer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_dFinalHurtReducePer)  | 
|     if defObjType == IPY_GameWorld.gotPlayer:  | 
|         dIgnoreDefRateReduce = PlayerControl.GetIgnoreDefRateReduce(defObj)  # ÎÞÊÓ·ÀÓù±ÈÂÊ¿¹ÐÔ  | 
|         dSkillAtkRateReduce = PlayerControl.GetSkillAtkRateReduce(defObj) # ¼¼Äܹ¥»÷Á¦¼õÉÙ  | 
|         dDamagePVPReduce = PlayerControl.GetDamagePVPReduce(defObj) # PVP¹Ì¶¨¼õÉË  | 
|         #dDamReduce += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_DamageReduce)  | 
|         dDamagePerPVPReduce = PlayerControl.GetDamagePerPVPReduce(defObj) # Íâ²ãPVP¼õÉË  | 
|         dDamagePerPVPReduce += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_DamageReducePVP)  | 
|         dFinalHurtReduce = PlayerControl.GetFinalHurtReduce(defObj) # ×îÖչ̶¨É˺¦¼õÉÙ  | 
|         dBeHurtPer = PlayerControl.GetBeHurtPer(defObj)      # ¼ÓÉîÊܵ½É˺¦°Ù·Ö±È  | 
|         dFightPower = PlayerControl.GetFightPower(defObj)  | 
|     else:  | 
|         dIgnoreDefRateReduce = 0    # ÎÞÊÓ·ÀÓù±ÈÂÊ¿¹ÐÔ  | 
|         dSkillAtkRateReduce = 0     # ¼¼Äܹ¥»÷Á¦¼õÉÙ  | 
|         dDamagePVPReduce = 0        # PVP¹Ì¶¨¼õÉË  | 
|         dDamagePerPVPReduce = 0     # Íâ²ãPVP¼õÉË  | 
|         dFinalHurtReduce = 0        # ×îÖչ̶¨É˺¦¼õÉÙ  | 
|         dBeHurtPer = 0  | 
|         dFightPower = NPCCommon.GetSuppressFightPower(defObj)  | 
|           | 
|     #¹¥»÷×Öµä { ¹¥»÷ÀàÐÍ : '¹«Ê½' }  | 
|     mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())  | 
|     hurtDist = ReadChConfig.GetEvalChConfig('CalcAttackValue')  | 
|   | 
|     if suppressLV:  | 
|         suppressFormulaKeyLV = "SuppressValueLV_%s" % (atkIsBoss)  | 
|         if suppressFormulaKeyLV in hurtDist:  | 
|             suppressLVFormula = hurtDist[suppressFormulaKeyLV]  | 
|             suppressValueLV = eval(FormulaControl.GetCompileFormula(suppressFormulaKeyLV, suppressLVFormula))  | 
|               | 
|     if suppressFightPower:  | 
|         suppressFormulaKeyFP = "SuppressValueFP_%s" % (atkIsBoss)  | 
|         if suppressFormulaKeyFP in hurtDist:  | 
|             suppressFPFormula = hurtDist[suppressFormulaKeyFP]  | 
|             suppressValueFP = eval(FormulaControl.GetCompileFormula(suppressFormulaKeyFP, suppressFPFormula))  | 
|       | 
|     # ¾³½çÑ¹ÖÆ¹æÔò  | 
|     # 1. ÆäÖÐÒ»·½ÎÞ¾³½çµÈ¼¶ÔòÎÞЧ£¬ ÈçÆÕͨNPC  | 
|     # 2. ³èÎïºÍÕÙ»½ÊÞ£¨ÈçË®ÔªËØ£©ÓÐЧ£¬ È¡Ö÷ÈË  | 
|     # 3. Íæ¼ÒµØ¾³½çµÍÓÚBOSSÔòÉ˺¦¹Ì¶¨Îª1 £¨ÔÚº¯ÊýÈë¿Ú´¦ÒÑ´¦Àí£©  | 
|     # 4. ÆäËûÇé¿öͳһ¾³½çÑ¹ÖÆ ¾³½ç²î*2%  | 
|     if aRealmLV == 0 or dRealmLV == 0:  | 
|         SuppressValueRealmRate = 10000  | 
|     else:  | 
|         suppressRealmRateMapKey = "SuppressValueRealm_%s" % mapID  | 
|         if suppressRealmRateMapKey not in hurtDist:  | 
|             suppressRealmRateMapKey = "SuppressValueRealm"  | 
|         SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula(suppressRealmRateMapKey, hurtDist[suppressRealmRateMapKey])))  | 
|           | 
|     # Æï³èÕù¶á×îÖÕÉ˺¦Ë¥¼õ  | 
|     if defObjType == IPY_GameWorld.gotNPC and FamilyRobBoss.IsHorsePetRobBoss(defObj.GetNPCID()):  | 
|         ownerPlayer, npcObjType = GetAttackPlayer(atkObj)  | 
|               | 
|         if ownerPlayer:  | 
|             findBuff = SkillCommon.FindBuffByID(ownerPlayer, ChConfig.Def_SkillID_HorsePetRobBossKillCntBuff)[0]  | 
|             if findBuff:  | 
|                 reduceFinalHurtPer = findBuff.GetSkill().GetEffect(0).GetEffectValue(0)  | 
|                 aFinalHurtPer -= reduceFinalHurtPer  | 
|       | 
|     # ÏÉÃËboss×îÖÕÉ˺¦¼Ó³É  | 
|     if atkObjType == IPY_GameWorld.gotPlayer and mapID == ChConfig.Def_FBMapID_FamilyBossMap:  | 
|         aFinalHurtPer += PlayerControl.GetFamilyBossHurtPer(atkObj)  | 
|           | 
|     atkStateMark = GetObjAtkStateMark(atkObj)  | 
|     defStateMark = GetObjAtkStateMark(defObj)  | 
|     hurtFormulaKey = "%sV%s_%s" % (atkStateMark, defStateMark, atkType)  | 
|       | 
|     suppressLVGroup = 0 # NPCÑ¹ÖÆµÈ¼¶×é±àºÅ  | 
|     mapHurtKey = "%s_%s" % (hurtFormulaKey, mapID)  | 
|     if mapHurtKey in hurtDist:  | 
|         hurtFormulaKey = mapHurtKey  | 
|     elif atkStateMark == "E" and defStateMark == "P":  | 
|         suppressLVGroup = NPCCommon.GetIsLVSuppress(atkObj)  | 
|     elif atkStateMark == "P" and defStateMark == "E":  | 
|         suppressLVGroup = NPCCommon.GetIsLVSuppress(defObj)  | 
|           | 
|     if suppressLVGroup:  | 
|         suppressLVHurtKey = "%s_%s" % (hurtFormulaKey, suppressLVGroup)  | 
|         if suppressLVHurtKey in hurtDist:  | 
|             hurtFormulaKey = suppressLVHurtKey  | 
|       | 
|     # ÖúÕ½»úÆ÷ÈËÌØÊâÉËѪkey  | 
|     if helpBattleFormatKey:  | 
|         hurtFormulaKey = helpBattleFormatKey  | 
|           | 
|     # »ØºÏÕ½¶·  | 
|     if turnFightTimeline:  | 
|         hurtFormulaKey = "TurnFight_%sV%s_%s" % (atkStateMark, defStateMark, atkType)  | 
|           | 
|     if hurtFormulaKey not in hurtDist:  | 
|         GameWorld.ErrLog("CalcAttackValue.txt É˺¦¹«Ê½Î´ÅäÖÃ, key=%s, skillID=%s" % (hurtFormulaKey, skillID))  | 
|         return 0, ChConfig.Def_HurtType_Miss  | 
|       | 
|     if atkwargs.get('hurtFormulaKey', None):  | 
|         # Ö¸¶¨¹«Ê½  | 
|         aBurnValue = atkwargs.get('burnValue', 0)  | 
|         aBurnPer = atkwargs.get('burnPer', 0)  | 
|         hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)  | 
|   | 
|     hurtFormula = hurtDist[hurtFormulaKey]  | 
|       | 
|     hurtValue = int(eval(FormulaControl.GetCompileFormula(hurtFormulaKey, hurtFormula)))  | 
|     if isDeadlyHit and deadlyHitMultiValue != 1:  | 
|         multiValue += deadlyHitMultiValue  | 
|           | 
|     if atkObjType == IPY_GameWorld.gotPlayer and defObjType == IPY_GameWorld.gotNPC and mapID == ChConfig.Def_FBMapID_CrossBattlefield:  | 
|         fbMultiValue = FBLogic.GetFBPlayerHurtNPCMultiValue(atkObj, defObj)  | 
|         if fbMultiValue != 1:  | 
|             multiValue += fbMultiValue  | 
|               | 
|     if multiValue:  | 
|         GameWorld.DebugLog("        ¶à±¶É˺¦: atkID=%s,defID=%s,skillID=%s,hurtValue=%s,multiValue=%s"   | 
|                            % (atkObj.GetID(), defObj.GetID(), skillID, hurtValue, multiValue))  | 
|         hurtValue = int(hurtValue * multiValue)  | 
|           | 
|     # ¸½¼Ó¶îÍâµÄÉ˺¦°Ù·Ö±È - ÔÚ×îÖÕµÄÉ˺¦¼ÆËãÍêºóÔÙ¶îÍ⸽¼ÓµÄÉ˺¦°Ù·Ö±È  | 
|     if hurtValueExPer > 0:  | 
|         GameWorld.DebugLog("        ¶îÍ⸽¼ÓÉ˺¦: atkID=%s,defID=%s,skillID=%s,hurtValue=%s,hurtValueExPer=%s"   | 
|                            % (atkObj.GetID(), defObj.GetID(), skillID, hurtValue, hurtValueExPer))  | 
|         hurtValue += int(hurtValue * hurtValueExPer / float(ChConfig.Def_MaxRateValue))  | 
|           | 
|     #hurtValue = min(max(hurtValue, 0), ChConfig.Def_UpperLimit_DWord)  | 
|       | 
|     if hurtType == ChConfig.Def_HurtType_Normal and atkSkillPerYinji > 0:  | 
|         return hurtValue, ChConfig.Def_HurtType_Yinji  | 
|     elif hurtType == ChConfig.Def_HurtType_Normal and SuppressValueRealmRate > 10000:  | 
|         # ´æÔÚÑ¹ÖÆ  | 
|         return hurtValue, ChConfig.Def_HurtType_RealmSupress  | 
|       | 
|     return hurtValue, hurtType  | 
|   | 
| # »ñÈ¡EVPºÍPVEÉ˺¦°Ù·Ö±È²î£¬PVEÎÞ¾³½çÑ¹ÖÆ, ¾³½çµÈ¼¶¶ÔÓ¦ÁбíµÄindex£¬Ô½½çÈ¡×î¸ß  | 
| def GetRealmHurtPer(aRealmLV, dRealmLV, gridIndex):  | 
|     suppressRealmHurtPer = 0  | 
|     suppressRealmDict = IpyGameDataPY.GetFuncEvalCfg("RealmGroup", gridIndex)  | 
|       | 
|     plus_minus = 1  # ¸ºÊýΪ·´Ñ¹ÖÆ  | 
|     if aRealmLV >= dRealmLV:  | 
|         suppressList = range(dRealmLV+1, aRealmLV+1)  | 
|     else:  | 
|         suppressList = range(aRealmLV+1, dRealmLV+1)  | 
|         plus_minus = -1  | 
|       | 
|       | 
|     for realmLV in suppressList:  | 
|         suppressRealmHurtPer += suppressRealmDict.get(realmLV, 0)  | 
|           | 
|     return suppressRealmHurtPer*plus_minus  | 
|   | 
|   | 
| # »ñȡ˫·½¾³½çÖµ  | 
| def GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType):  | 
|     if atkObjType == IPY_GameWorld.gotNPC:  | 
|         ownerPlayer, npcObjType = GetAttackPlayer(atkObj)  | 
|         if ownerPlayer:  | 
|             # ÕÙ»½Ê޺ͳèÎïÈ¡Ö÷È˾³½ç£¬¿ÉÒÔÊǹ¥»÷·½ÐèÌáÈ¡  | 
|             aRealmLV = ownerPlayer.GetOfficialRank()   | 
|         else:  | 
|             aRealmLV = NPCCommon.GetRealmLV(atkObj)  | 
|             if aRealmLV == 0:  | 
|                 # 0´ú±í²»ÒªÑ¹ÖÆ  | 
|                 return 0, 0  | 
|     else:  | 
|         aRealmLV = atkObj.GetOfficialRank()  | 
|           | 
|     if defObjType == IPY_GameWorld.gotNPC:  | 
|         # ÕÙ»½Ê޺ͳèÎïÈ¡Ö÷È˾³½ç£¬µ«ÊdzèÎïºÍÈËÎïÕÙ»½ÊÞ²»¿É±»¹¥»÷£¬¹Ê²»ÐèÒª  | 
|         dRealmLV = NPCCommon.GetRealmLV(defObj)  | 
|         if dRealmLV == 0:  | 
|             # 0´ú±í²»ÒªÑ¹ÖÆ  | 
|             return 0, 0  | 
|     else:  | 
|         dRealmLV = defObj.GetOfficialRank()  | 
|           | 
|     return aRealmLV, dRealmLV  | 
|   | 
|   | 
| ## ¹¥»÷ʱʼþ´¦Àí£¬·´µ¯ÎüѪ»òÕß¶îÍâ´¥·¢¼¼ÄÜµÈ  | 
| #  @param resultHurtType É˺¦½á¹¹Ìå  | 
| #  @return   | 
| def AttackEventTrigger(atkObj, defObj, curSkill, resultHurtType, tick):  | 
|       | 
|     #·´µ¯É˺¦  | 
|     CalcBounceHP(atkObj, defObj, resultHurtType.LostHP, resultHurtType.HurtType, curSkill)  | 
|     #ÎüѪ  | 
|     CalcSuckBlood(atkObj, defObj, curSkill, resultHurtType, tick)  | 
|       | 
|     turnFightTimeline = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)  | 
|     if atkObj.GetGameObjType() == IPY_GameWorld.gotPlayer or turnFightTimeline:  | 
|         # ¼Ç¼×îºóÒ»´ÎÉ˺¦Öµ  | 
|         GameObj.SetLastHurtValue(atkObj, resultHurtType.RealHurtHP)  | 
|         GameObj.SetLastBeHurtValue(defObj, resultHurtType.RealHurtHP)  | 
|         if defObj.GetGameObjType() == IPY_GameWorld.gotNPC:  | 
|             atkObj.SetDict(ChConfig.Def_PlayerKey_LastHurtNPCObjID, defObj.GetID())  | 
|         else:  | 
|             defObj.SetDict(ChConfig.Def_PlayerKey_LastAttackerObjID, atkObj.GetID())  | 
|               | 
|     TurnAttack.AddTurnObjHurtValue(atkObj, defObj, resultHurtType.HurtType, resultHurtType.RealHurtHP, resultHurtType.LostHP, curSkill)  | 
|       | 
|     if resultHurtType.RealHurtHP:  | 
|         PassiveBuffEffMng.OnPassiveSkillTrigger(defObj, atkObj, None, ChConfig.TriggerType_BeHurt, tick)  | 
|           | 
|     return  | 
|   | 
|   | 
|   | 
| def GetObjAtkStateMark(obj):  | 
|     objType = obj.GetGameObjType()  | 
|     if objType == IPY_GameWorld.gotPlayer:  | 
|         return "P"  | 
|       | 
|     if objType == IPY_GameWorld.gotNPC:  | 
|         if obj.GetType() == ChConfig.ntRobot:  | 
|             return "Robot"  | 
|         if obj.GetType() == ChConfig.ntHelpBattleRobot:  | 
|             return "HelpRobot"  | 
|         if obj.GetType() in ChConfig.PVPNPCTypeList:  | 
|             return "P"  | 
|         if obj.GetType() == IPY_GameWorld.ntPet:  | 
|             return "Pet"  | 
|           | 
|     objType = obj.GetGameNPCObjType()  | 
|     if objType == IPY_GameWorld.gnotPet:  | 
|         return "Pet"  | 
|               | 
|     return "E"  | 
|   | 
| ## »ñÈ¡PVE,PVP¹¥»÷ÐÎʽ  | 
| # @param None  | 
| # @return ¹¥»÷ÐÎʽ×Ö·û´®  | 
| def GetAtkState(atkObj, defObj):  | 
|     isPet = PetControl.IsPetNPC(atkObj)  | 
|     if IsPVENPCObj(atkObj) or IsPVENPCObj(defObj):  | 
|         return 'PVE_%s' if not isPet else 'PetVE_%s'  | 
|       | 
|     return 'PVP_%s' if not isPet else 'PetVP_%s'  | 
|       | 
|   | 
| ## ÊÇ·ñ·ÇÍæ¼ÒÏà¹ØµÄNPC  | 
| #  @param obj  | 
| #  @return bool  | 
| def IsPVENPCObj(obj):  | 
|     objType = obj.GetGameObjType()  | 
|     if objType == IPY_GameWorld.gotPlayer:  | 
|         return False  | 
|       | 
|     objType = obj.GetGameNPCObjType()  | 
|     if objType == IPY_GameWorld.gnotPet:  | 
|         return False  | 
|       | 
|     if objType == IPY_GameWorld.gnotSummon:  | 
|         npcOwner_Player = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, obj)  | 
|         if npcOwner_Player != None:  | 
|             return False  | 
|           | 
|     return True  | 
|       | 
| ##´¦Àí¹¥»÷ÕßµÄÉ˺¦·´µ¯ºÍÎüѪ£¬GetHurtHPÖÐÖ±½Ó´¦Àí£¬Íâ²ãÎÞ·¨Õýȷ֪ͨ·´µ¯ºÍÎüѪƮ×Ö  | 
| ##·´µ¯É˺¦Âß¼  | 
| # @param atkObj ¹¥»÷Õß  | 
| # @param defObj ·ÀÊØÕß  | 
| # @param hurtValue É˺¦Öµ     | 
| # @return None  | 
| def CalcBounceHP(atkObj, defObj, hurtValue, hurtType, curSkill):  | 
|     if not atkObj.GetCanAttack():  | 
|         return  | 
|       | 
|     if GameObj.GetHP(atkObj) <= 1:  | 
|         return  | 
|       | 
|     #Ö»ÓÐÍæ¼Ò»á·´µ¯  | 
|     defObjType = defObj.GetGameObjType()  | 
|     if defObjType == IPY_GameWorld.gotPlayer:  | 
|         #boss¾³½çÑ¹ÖÆ²»·´µ¯  | 
|         atkObjType = atkObj.GetGameObjType()  | 
|         aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType) # »ñÈ¡¾³½ç  | 
|         if atkObjType == IPY_GameWorld.gotNPC and ChConfig.IsGameBoss(atkObj) and aRealmLV > dRealmLV:  | 
|             aRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", aRealmLV)  | 
|             dRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", dRealmLV)  | 
|             aRealmLVLarge = aRealmIpyData.GetLvLarge() if aRealmIpyData else 0  | 
|             dRealmLVLarge = dRealmIpyData.GetLvLarge() if dRealmIpyData else 0  | 
|             if aRealmLVLarge > dRealmLVLarge:  | 
|                 #GameWorld.DebugLog("boss´ó¾³½çÑ¹ÖÆÍæ¼Ò£¬²»·´µ¯: aRealmLV=%s,dRealmLV=%s,aRealmLVLarge=%s,dRealmLVLarge=%s" % (aRealmLV, dRealmLV, aRealmLVLarge, dRealmLVLarge))  | 
|                 return  | 
|           | 
|         ##Ãþ¹Ö´ÎÊýÅÐ¶Ï  | 
|         #if not CheckAttackNPCByCnt(defObj, atkObj, False):  | 
|         #    GameWorld.DebugLog("²»Äܹ¥»÷£¬²»·´µ¯")  | 
|         #    return  | 
|         #ɱ¹Ö´ÎÊýÅÐ¶Ï  | 
|         if not CheckKillNPCByCnt(defObj, atkObj, False) and not NPCHurtManager.IsAssistPlayer(defObj.GetPlayerID(), atkObj):  | 
|             #GameWorld.DebugLog("²»Äܹ¥»÷£¬²»·´µ¯")  | 
|             return  | 
|       | 
|     #ûÓз´µ¯Í˳ö  | 
|     defObj_DamageBackRate = GameObj.GetDamageBackRate(defObj)  | 
|     defObj_DamageBackRate += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, None, None, ChConfig.TriggerType_BounceHPPer)  | 
|     defObj_DamageBackRate += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_BounceHPPerByAttacker)  | 
|       | 
|     bounceHP = hurtValue * defObj_DamageBackRate / float(ChConfig.Def_MaxRateValue)  | 
|     bounceHP  = int(bounceHP + PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, None, None, ChConfig.TriggerType_BounceHP))  | 
|     bounceHP  = int(bounceHP + PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, None, None, ChConfig.TriggerType_BounceHP))  | 
|     if bounceHP <= 0:  | 
|         return  | 
|     skillID = curSkill.GetSkillID() if curSkill else 0  | 
|     GameWorld.DebugLog("        ·´µ¯: defID=%s,atkID=%s,skillID=%s,hurtValue=%s,defObj_DamageBackRate=%s,bounceHP=%s"   | 
|                        % (defObj.GetID(), atkObj.GetID(), skillID, hurtValue, defObj_DamageBackRate, bounceHP))  | 
|       | 
|     bounceHP = bounceHP if bounceHP < GameObj.GetHP(atkObj) else GameObj.GetHP(atkObj) - 1  | 
|       | 
|     # Ñª¶Ü   | 
|     realSubHP = CalcBloodShield(atkObj, defObj, bounceHP)  | 
|     remainHP = max(GameObj.GetHP(atkObj) - realSubHP, 1)  | 
|       | 
|     #curObjType = atkObj.GetGameObjType()  | 
|     #---NPC´¦Àí---  | 
|     atkObjType = atkObj.GetGameObjType()  | 
|     if atkObjType == IPY_GameWorld.gotNPC:  | 
|         #³èÎï»ØÑª  | 
|         if atkObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  | 
|             PetControl.SetPetHP(atkObj, remainHP)  | 
|         #ÆÕͨNPC»ØÑª  | 
|         else:  | 
|             GameObj.SetHP(atkObj, remainHP)  | 
|             #¹ã²¥ÑªÁ¿  | 
|             #atkObj.Notify_HP()  | 
|       | 
|     elif atkObjType == IPY_GameWorld.gotPlayer:  | 
|         GameObj.SetHP(atkObj, remainHP, False)  | 
|           | 
|         # Ë«·½¶¼ÊÇÍæ¼Ò  | 
|         if defObjType == IPY_GameWorld.gotPlayer:  | 
|             OnPVPDamage(defObj, bounceHP, atkObj, "Player bounce Player")   | 
|           | 
|     ChangeHPView(atkObj, defObj, skillID, bounceHP, ChConfig.Def_HurtType_BounceHurt)  | 
|     return  | 
|   | 
|   | 
| ## ¹¥»÷Õß»ØÑªÂß¼  | 
| #  @param atkObj ¹¥»÷Õß  | 
| #  @param defObj ·ÀÊØÕß  | 
| #  @return None  | 
| def CalcSuckBlood(atkObj, defObj, curSkill, resultHurtType, tick):  | 
|       | 
|     hurtValue, hurtType = resultHurtType.RealHurtHP, resultHurtType.HurtType,   | 
|     if not hurtValue:  | 
|         return  | 
|       | 
|     if curSkill and SkillCommon.isPassiveSkill(curSkill):  | 
|         #GameWorld.DebugLog("        ±»¶¯¼¼Äܲ»ÎüѪ: skillID=%s" % curSkill.GetSkillID())  | 
|         return  | 
|       | 
|     if atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline):  | 
|         pass  | 
|     else:  | 
|         tick = GameWorld.GetGameWorld().GetTick()  | 
|         if tick - atkObj.GetTickByType(ChConfig.TYPE_Player_Tick_SuckBlood) \  | 
|             < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_SuckBlood]:  | 
|             return  | 
|         atkObj.SetTickByType(ChConfig.TYPE_Player_Tick_SuckBlood, tick)  | 
|           | 
|     atkObjType = atkObj.GetGameObjType()  | 
|     defObjType = defObj.GetGameObjType()  | 
|       | 
|     suckHP = GameObj.GetAtkBackHP(atkObj) # ¹¥»÷»ØÑª¹Ì¶¨Öµ  | 
|     if atkObjType == IPY_GameWorld.gotPlayer:  | 
|         # É±¹Ö»ØÑª  | 
|         if defObjType == IPY_GameWorld.gotNPC and GameObj.GetHP(defObj) <= 0:  | 
|             suckHP += atkObj.GetKillBackHP()  | 
|               | 
|         #PVP¹¥»÷»ØÑª  | 
|         if defObjType == IPY_GameWorld.gotPlayer:  | 
|             suckHP += PlayerControl.GetPVPAtkBackHP(atkObj)  | 
|     else:  | 
|         pass  | 
|       | 
|     # °Ù·Ö±ÈÎüѪ  | 
|     suckHPPer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_Buff_SuckBloodPer)  | 
|     suckHPPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_Buff_SuckBloodPer)  | 
|     if hurtType == ChConfig.Def_HurtType_SuperHit:  | 
|         suckHPPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSuckBloodPer)  | 
|     elif hurtType == ChConfig.Def_HurtType_ThumpHit:      | 
|         suckHPPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_ThumpHitSuckBloodPer)  | 
|           | 
|     suckHPPer += GameObj.GetSuckHPPer(atkObj)  | 
|     suckHPDefPer = GameObj.GetSuckHPDefPer(defObj)  | 
|       | 
|     suckHPPerFinal = max(0, suckHPPer - suckHPDefPer)  | 
|     suckHPByPer = int(hurtValue * suckHPPerFinal*1.0 / ChConfig.Def_MaxRateValue)  | 
|       | 
|     suckHPTotal = suckHPByPer + suckHP  | 
|     if suckHPTotal <= 0:  | 
|         return  | 
|     skillID = curSkill.GetSkillID() if curSkill else 0  | 
|     GameObj.SetHP(atkObj, min(GameObj.GetMaxHP(atkObj), GameObj.GetHP(atkObj) + suckHPTotal), False)      | 
|       | 
|     ChangeHPView(atkObj, None, skillID, suckHPTotal, ChConfig.Def_HurtTYpe_Recovery)  | 
|     GameWorld.DebugLog("        ÎüѪ: atkID=%s,defID=%s,×îÖÕ±ÈÀý=%s(%s-%s),ÉËѪ=%s,×ÜÎüѪ=%s(%s+%s),HP=%s,skillID=%s"   | 
|                        % (atkObj.GetID(), defObj.GetID(), suckHPPerFinal, suckHPPer, suckHPDefPer, hurtValue, suckHPTotal, suckHPByPer, suckHP, GameObj.GetHP(atkObj), skillID))  | 
|     return  | 
|   | 
| ## ¹¥»÷Õß»ØÀ¶Âß¼  | 
| #  @param atkObj ¹¥»÷Õß  | 
| #  @param defObj ·ÀÊØÕß  | 
| #  @return None  | 
| def CalcSuckMagic(atkObj, defObj, hurtValue):  | 
|   | 
|     if atkObj.GetGameObjType() != IPY_GameWorld.gotPlayer:  | 
|         return  | 
|       | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     if tick - atkObj.GetTickByType(ChConfig.TYPE_Player_Tick_SuckMagic) \  | 
|         < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_SuckMagic]:  | 
|         return  | 
|       | 
|     atkObj.SetTickByType(ChConfig.TYPE_Player_Tick_SuckMagic, tick)  | 
|       | 
|     suckMP = 0  | 
|       | 
|     # É±¹Ö»ØÀ¶  | 
|     if defObj.GetGameObjType() == IPY_GameWorld.gotNPC and GameObj.GetHP(defObj) <= 0:  | 
|         suckMP += atkObj.GetKillBackMP()  | 
|       | 
|     # ¹¥»÷ÎüÀ¶  | 
|     atkBackMPPer = PlayerControl.GetAtkBackMPPer(atkObj)  | 
|     if atkBackMPPer > 0:  | 
|         suckMP += int(hurtValue * atkBackMPPer / float(ChConfig.Def_MaxRateValue))  | 
|       | 
|     if suckMP <= 0:  | 
|         return  | 
|       | 
|     atkObj.SetMP(min(atkObj.GetMaxMP(), atkObj.GetMP() + suckMP))  | 
|     return  | 
|   | 
| #---------------------------------------------------------------------  | 
| ## »ñµÃÄ¿±êÊÇ·ñËÀÍö  | 
| #  @param taget Ä¿±êObj  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def GetIsDead(taget):  | 
|     if not taget:  | 
|         return True  | 
|       | 
|     tagetType = taget.GetGameObjType()  | 
|       | 
|     if tagetType == IPY_GameWorld.gotPlayer:  | 
|         return (taget.GetPlayerAction() == IPY_GameWorld.paDie)  | 
|       | 
|     elif tagetType == IPY_GameWorld.gotNPC:  | 
|         if taget.GetGameNPCObjType() == IPY_GameWorld.gnotTruck:  | 
|             #ïÚ³µÅж¨ÊÇ·ñ¿ÉÒÔ¹¥»÷( Ë𻵵ÄïÚ³µÊÇÎ޵еĠGetCanAttack = 0 )  | 
|             return (not taget.GetCanAttack())  | 
|           | 
|         return (taget.GetCurAction() == IPY_GameWorld.laNPCDie)  | 
|       | 
|     GameWorld.Log('###GetIsDead = %s ' % (tagetType))  | 
|     return False  | 
|   | 
| def IsMaliciousAttackPlayer(curPlayer, tagPlayer):  | 
|     # ÅжÏÄ¿±êÍæ¼ÒÊÇ·ñÊǶñÒâ¹¥»÷×Ô¼ºµÄÍæ¼Ò  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_maliciousAttackDict:  | 
|         return False  | 
|     return tagPlayer.GetPlayerID() in PyGameData.g_maliciousAttackDict[playerID].keys()  | 
|   | 
| def AddMaliciousAttackPlayer(atkPlayer, defPlayer, tick):  | 
|     # Ìí¼Ó¶ñÒâ¹¥»÷Íæ¼Ò  | 
|     atkPlayerID = atkPlayer.GetPlayerID()  | 
|     defPlayerID = defPlayer.GetPlayerID()  | 
|     defMaliciousAttackPlayerDict = {}  | 
|     if defPlayerID in PyGameData.g_maliciousAttackDict:  | 
|         defMaliciousAttackPlayerDict = PyGameData.g_maliciousAttackDict[defPlayerID]  | 
|           | 
|     if atkPlayerID not in defMaliciousAttackPlayerDict:  | 
|         # Í¨ÖªÍæ¼Ò±»¶ñÒâ¹¥»÷  | 
|         addAtkPlayerPack = ChPyNetSendPack.tagMCAddMaliciousAtkPlayer()  | 
|         addAtkPlayerPack.AtkPlayerID = atkPlayerID  | 
|         NetPackCommon.SendFakePack(defPlayer, addAtkPlayerPack)  | 
|           | 
|     defMaliciousAttackPlayerDict[atkPlayerID] = tick  | 
|     PyGameData.g_maliciousAttackDict[defPlayerID] = defMaliciousAttackPlayerDict  | 
|     #GameWorld.DebugLog("¶ñÒâ¹¥»÷Íæ¼Ò: atkPlayerID=%s,defPlayerID=%s,tick=%s, g_maliciousAttackDict=%s"   | 
|     #                   % (atkPlayerID, defPlayerID, tick, PyGameData.g_maliciousAttackDict), defPlayerID)  | 
|     return  | 
|   | 
| def UpdMaliciousAttackTick(atkPlayer, defPlayer, tick):  | 
|     # ¹¥»÷¶ñÒâ¹¥»÷×Ô¼ºµÄÍæ¼Òʱ£¬¸üжñÒâ¹¥»÷tick  | 
|     atkPlayerID = atkPlayer.GetPlayerID()  | 
|     if atkPlayerID not in PyGameData.g_maliciousAttackDict:  | 
|         return  | 
|     maliciousAtkPlayerDict = PyGameData.g_maliciousAttackDict[atkPlayerID]  | 
|     defPlayerID = defPlayer.GetPlayerID()  | 
|     if defPlayerID not in maliciousAtkPlayerDict:  | 
|         return  | 
|     maliciousAtkPlayerDict[defPlayerID] = tick  | 
|     #GameWorld.DebugLog("·´»÷¸üжñÒâ¹¥»÷Íæ¼Ò: atkPlayerID=%s,defPlayerID=%s,tick=%s, g_maliciousAttackDict=%s"   | 
|     #                   % (atkPlayerID, defPlayerID, tick, PyGameData.g_maliciousAttackDict), atkPlayerID)  | 
|     return  | 
|   | 
| def ProcessMaliciousAttackPlayer(curPlayer, tick):  | 
|     ## Ë¢Ð¶ñÒâ¹¥»÷Íæ¼ÒÕýµ±·ÀÎÀʱ¼ä  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if playerID not in PyGameData.g_maliciousAttackDict:  | 
|         return  | 
|     defendTime = IpyGameDataPY.GetFuncCfg("PKConfig", 3) * 1000 # Õýµ±·ÀÎÀʱ³¤  | 
|     defMaliciousAttackPlayerDict = PyGameData.g_maliciousAttackDict[playerID]  | 
|     for atkPlayerID, atkTick in defMaliciousAttackPlayerDict.items():  | 
|         if tick - atkTick < defendTime:  | 
|             continue  | 
|           | 
|         defMaliciousAttackPlayerDict.pop(atkPlayerID)  | 
|           | 
|         delAtkPlayerPack = ChPyNetSendPack.tagMCDelMaliciousAtkPlayer()  | 
|         delAtkPlayerPack.AtkPlayerID = atkPlayerID  | 
|         NetPackCommon.SendFakePack(curPlayer, delAtkPlayerPack)  | 
|         #GameWorld.DebugLog("ɾ³ý¶ñÒâ¹¥»÷Íæ¼Ò: atkPlayerID=%s,defPlayerID=%s, g_maliciousAttackDict=%s"   | 
|         #                   % (atkPlayerID, playerID, PyGameData.g_maliciousAttackDict), playerID)  | 
|           | 
|     if not defMaliciousAttackPlayerDict:  | 
|         PyGameData.g_maliciousAttackDict.pop(playerID)  | 
|         #GameWorld.DebugLog("    Çå¿ÕÍæ¼ÒÊܵ½µÄ¶ñÒâ¹¥»÷ÐÅÏ¢: g_maliciousAttackDict=%s" % PyGameData.g_maliciousAttackDict, playerID)  | 
|     return  | 
|   | 
|   | 
| ## »ñµÃÁ½¸öÍæ¼ÒµÄ¹ØÏµ  | 
| #  @param curPlayer ¹¥»÷·½Obj  | 
| #  @param tagPlayer Ä¿±êObj  | 
| #  @return ¹¥»÷·½ÓëÄ¿±êµÄ¹ØÏµ  | 
| #  @remarks »ñµÃÁ½¸öÍæ¼ÒµÄ¹ØÏµ  | 
| def GetPlayersRelation(curPlayer, tagPlayer):  | 
|     '''  | 
|     PKģʽ  | 
|         0    ºÍƽģʽ    IPY_GameWorld.amPeace            ¶ÔËùÓÐÍæ¼Ò¶¼ÊÇÓѺ㬶ñÒâ¹¥»÷×Ô¼ºµÄÍæ¼Ò³ýÍâ  | 
|         1    È«Ìåģʽ    IPY_GameWorld.amAll              ¶ÔËùÓÐÍæ¼Ò¶¼Êǵжԣ¬¼Ò×åÇøÓòͬÃËÍæ¼Ò³ýÍâ    | 
|         2    ·ÀÎÀģʽ    IPY_GameWorld.amCountry          ±¾·þÍæ¼ÒÓѺã¬Ëû·þÍæ¼Ò¶¼ÊÇµÐ¶Ô  | 
|         5    Ç¿ÖÆÄ£Ê½    IPY_GameWorld.amFamily           ¶ÓÓÑ¡¢ÏÉÃ˳ÉÔ±¡¢Í¬ÕóÓªÓѺã¬ÆäËûÍæ¼ÒµÐ¶Ô  | 
|         7    Ëø¶¨µ¥Ò»Ä¿±êģʽ IPY_GameWorld.amContest       Ö»¶ÔÑ¡ÖÐÄ¿±êÓÐÉ˺¦, Ä¿Ç°Ö»ÓÃÓÚ²¿·ÖBOSSÕù¶áµØÍ¼  | 
|           | 
|     ³¡¾°ÇøÓò  | 
|         ÆÕÍ¨ÇøÓò    IPY_GameWorld.gatNormal    ¿É¸ù¾Ý²»Í¬PKģʽPK£¬»÷É±Íæ¼ÒÓгͷ£  | 
|         °²È«ÇøÓò    IPY_GameWorld.gatSafe      ²»ÄÜPK  | 
|         ×ÔÓÉÇøÓò    IPY_GameWorld.gatFreePK    ¿É¸ù¾Ý²»Í¬PKģʽPK£¬»÷É±Íæ¼ÒÎ޳ͷ£  | 
|           | 
|     ¼ò»¯¹ØÏµÅжÏÂß¼£º ¿É·ñ¹¥»÷È«Óɹ¥»÷ģʽ¾ö¶¨£¬²ß»®Í¨¹ýµØÍ¼Ä¬ÈÏģʽ¼°¿ÉÇл»Ä£Ê½¿ØÖÆPK¹ØÏµ  | 
|       | 
|     Ç±¹æÔò:  | 
|         °²È«ÇøÓò²»¿É¹¥»÷  | 
|         ÆÕÍ¨ÇøÓòÖÐPKÖµ´ïµ½ÉÏÏÞ²»Äܹ¥»÷±ðÈË  | 
|         Ë«·½²»Í¬ÔÚÍ¬Ò»ÇøÓò²»¿É¹¥»÷  | 
|         ²»¿É¹¥»÷´ò×øÖеÄÍæ¼Ò  | 
|         ¶ñÒâ¹¥»÷×Ô¼ºµÄÍæ¼ÒÎÞÂÛʲôÇé¿ö϶¼¿É·´»÷£¬²»ÓÃÇл»Ä£Ê½  | 
|     '''  | 
|     #¹ØÏµÓÐ3²ã£¬ÎÞ-ÓѺÃ-µÐÈË  | 
|     #ÅжÏÊÇ·ñ¿ÉÊÍ·Å(Ôö/¼õ)¼¼ÄÜ»òÆÕ¹¥  | 
|     if CheckPlayersRelationInFB_IsNone(curPlayer, tagPlayer):  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None  | 
|       | 
|     curPlayerAreaType = GameMap.GetAreaTypeByMapPos(curPlayer.GetPosX(), curPlayer.GetPosY())  # µ±Ç°Íæ¼ÒËùÔÚÇøÓò  | 
|     tagPlayerAreaType = GameMap.GetAreaTypeByMapPos(tagPlayer.GetPosX(), tagPlayer.GetPosY())  # Ä¿±êÍæ¼ÒËùÔÚÇøÓò  | 
|       | 
|     #ÔÚ°²È«Çø£¬²»¿ÉPK£¬¿É¼ÓÔöÒæbuff  | 
|     if curPlayerAreaType == IPY_GameWorld.gatSafe or tagPlayerAreaType == IPY_GameWorld.gatSafe:  | 
|         return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_IsSafeArea  | 
|       | 
|     #¹¥ÊØË«·½²»ÔÚÍ¬Ò»ÇøÓò£¬²»¿ÉPK£¬²»¿É¼ÓÔöÒæbuff  | 
|     if curPlayerAreaType != tagPlayerAreaType:  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_CurAreaNotPK  | 
|       | 
|     #·ÀÊØ·½ÊÇÔÚ´ò×ø£¬²»¿ÉPK£¬²»¿É¼ÓÔöÒæbuff  | 
|     if tagPlayer.GetPlayerAction() == IPY_GameWorld.paSit:  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_SitNotPK  | 
|       | 
|     if GetIsNewGuy(curPlayer):  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_NewGuy  | 
|       | 
|     if GetIsNewGuy(tagPlayer):  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_NotAttackNewGuy  | 
|       | 
|     #ºÍƽ¹â»·  | 
|     if GetPeaceBuff(curPlayer) or GetPeaceBuff(tagPlayer):  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None  | 
|       | 
|     #¶ñÒâ¹¥»÷µÄÍæ¼ÒĬÈ϶¼ÊǵÐÈË, ÎÞÂÛʲôģʽ  | 
|     if IsMaliciousAttackPlayer(curPlayer, tagPlayer):  | 
|         return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None  | 
|       | 
|     #»ñµÃÍæ¼Ò¹¥»÷ģʽ  | 
|     curPlayerAttackMode = curPlayer.GetAttackMode()  | 
|     if curPlayerAttackMode == IPY_GameWorld.amPeace:  | 
|         return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_AttackMode  | 
|       | 
|     # Ç¿ÖÆÄ£Ê½(²»¿É¹¥»÷ͬ¶ÓÎ顢ͬÏÉÃË¡¢Í¬ÕóÓªÍæ¼Ò)  | 
|     elif curPlayerAttackMode == IPY_GameWorld.amFamily:  | 
|         if CanAlikeTeam(curPlayer, tagPlayer):  | 
|             return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_NotAttackTeam  | 
|         if CanAlikeFamily(curPlayer, tagPlayer):  | 
|             return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_NotAttackFamily  | 
|         if CanAlikeFaction(curPlayer, tagPlayer):  | 
|             return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_NotAttackFaction  | 
|           | 
|     # ·ÀÎÀģʽ(²»¿É¹¥»÷ͬ·þÍæ¼Ò)  | 
|     elif curPlayerAttackMode == IPY_GameWorld.amCountry:  | 
|         if IsSameServer(curPlayer, tagPlayer):  | 
|             return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_NotAttackServer  | 
|           | 
|     # Ëø¶¨Ä£Ê½(²»¿É¹¥»÷¶ÓÓÑ)  | 
|     elif curPlayerAttackMode == IPY_GameWorld.amContest:  | 
|         if CanAlikeTeam(curPlayer, tagPlayer):  | 
|             return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_NotAttackTeam  | 
|           | 
|         selectObjType = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SelectObjType)  | 
|         selectObjID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SelectObjID)  | 
|         if selectObjType != IPY_GameWorld.gotPlayer or selectObjID != tagPlayer.GetPlayerID():  | 
|             #GameWorld.DebugLog("·ÀÎÀģʽ²»¿É¹¥»÷·ÇÑ¡ÖÐÄ¿±ê! selectObjType=%s,selectObjID=%s" % (selectObjType, selectObjID))  | 
|             return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None  | 
|           | 
|     # È«Ìåģʽ  | 
|     elif curPlayerAttackMode == IPY_GameWorld.amAll:  | 
|         pass  | 
|       | 
|     # ÐÖú¹ØÏµ²»¿É¹¥»÷  | 
|     if NPCHurtManager.IsAssistRelation(curPlayer, tagPlayer):  | 
|         return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_NotAttackTeam  | 
|           | 
|     # ÒÔÏÂΪËùÊôÇøÓòµÄÒ»Ð©ÌØÊâ´¦Àí  | 
|     #ÆÕÍ¨Çø  | 
|     if curPlayerAreaType == IPY_GameWorld.gatNormal:  | 
|         # ¹¥»÷·½PKÖµ´óÓÚ×î´óPKÖµ£¬²»¿ÉPK£¬¿É¼ÓÔöÒæbuff  | 
|         if curPlayer.GetPKValue() >= PlayerControl.GetMaxPKValue():  | 
|             return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackNotPK  | 
|           | 
|         # Ä¿±êÎÞPKÖµµÄÏíÊÜPK±£»¤Ê±¼ä  | 
|         if not tagPlayer.GetPKValue() and IsPKProtectTime():  | 
|             return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_PKProtectTime  | 
|           | 
|     if CheckPlayersRelationInFB_IsFriend(curPlayer, tagPlayer):  | 
|         return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None  | 
|       | 
|     #µÐÈ˹ØÏµ£¬¿ÉPK£¬¿É¼Ó¼õÒæbuff  | 
|     return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None  | 
|   | 
| def GetPeaceBuff(curPlayer):  | 
|     return SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_Peace)[0]  | 
|   | 
| ## »ñÈ¡Íæ¼ÒºÍïÚ³µµÄ¹ØÏµ  | 
| #  @param curPlayer: ¹¥»÷·½ÊµÀý  | 
| #  @param curTagTruck: ïÚ³µÊµÀý  | 
| #  @return: ¿É·ñ¹¥»÷  | 
| def GetPlayerAndTruckRelation(curPlayer, curTagTruck):  | 
|       | 
|     if curPlayer == None or curTagTruck == None:  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None  | 
|       | 
|     #¹¥»÷·½Íæ¼ÒÇøÓò  | 
|     curPlayerAreaType = GameMap.GetAreaTypeByMapPos(curPlayer.GetPosX(), curPlayer.GetPosY())  | 
|       | 
|     #ïÚ³µËùÔÚÇøÓò  | 
|     truckAreaType = GameMap.GetAreaTypeByMapPos(curTagTruck.GetPosX(), curTagTruck.GetPosY())  | 
|       | 
|     #¹¥»÷·½»òïÚ³µÔÚ°²È«Çø  | 
|     if curPlayerAreaType == IPY_GameWorld.gatSafe or truckAreaType == IPY_GameWorld.gatSafe:  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_IsSafeArea  | 
|       | 
|     #¹¥ÊØË«·½²»ÔÚÍ¬Ò»ÇøÓò£¬²»¿ÉPK£¬²»¿É¼ÓÔöÒæbuff  | 
|     if curPlayerAreaType != truckAreaType:  | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_CurAreaNotPK  | 
|       | 
|     curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagTruck)  | 
|     if curTagPlayer:  | 
|         if curPlayer.GetID() == curTagPlayer.GetID():  | 
|             #²»Äܹ¥»÷×Ô¼ºµÄïÚ³µ  | 
|             return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None  | 
|   | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Truck):  | 
|         #Truck_hgg_31379:¹¦ÄÜ먦Æô,²»Äܹ¥»÷ïÚ³µ  | 
|         PlayerControl.NotifyCode(curPlayer, "Truck_hgg_31379", [GameFuncComm.GetFuncLimitLV(ShareDefine.GameFuncID_Truck)])     | 
|         return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None  | 
|           | 
|     curTruckOTeamID = PlayerTruck.GetTruckTeamID(curTagTruck)  | 
|     curTruckFamilyID = PlayerTruck.GetTruckFamilyID(curTagTruck)  | 
|     curTruckNameColor = PlayerTruck.GetTruckNameColor(curTagTruck)  | 
|       | 
|     #ÆÕÍ¨ÇøÓò  | 
|     if curPlayerAreaType == IPY_GameWorld.gatNormal:  | 
|         #ºÍƽģʽ  | 
|         if curPlayer.GetAttackMode() == IPY_GameWorld.amPeace :  | 
|             #ÈçïÚ³µÖ÷È˲»ÊǺìÃûÒ²²»ÊÇ»ÆÃû£¬Ôò¸øÏµÍ³Ìáʾ£º²»¿É¹¥»÷  | 
|             if curTruckNameColor not in [IPY_GameWorld.pncGray, IPY_GameWorld.pncRed]:  | 
|                 return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_CurAreaNotPK  | 
|               | 
|     curPlayerTeamID = curPlayer.GetTeamID()  # ¹¥»÷·½¶ÓÎéID  | 
|     curPlayerFamilyID = curPlayer.GetFamilyID()  # ¹¥»÷·½¼Ò×åID  | 
|     if curPlayerTeamID and curTruckOTeamID and curTruckOTeamID == curPlayerTeamID:  | 
|         #¹¥»÷·½ºÍïÚ³µÖ÷ÈËͬ¶ÓÎé  | 
|         return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_NotAttackTeam  | 
|       | 
|     if curTruckFamilyID and curPlayerFamilyID and curTruckFamilyID == curPlayerFamilyID:  | 
|         #¹¥»÷·½ºÍïÚ³µÖ÷ÈËͬ¼Ò×å  | 
|         return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_NotAttackFamily  | 
|       | 
|     return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None  | 
|   | 
| def IsPKProtectTime():  | 
|     ## ÊÇ·ñÊÇPK±£»¤Ê±¼ä¶Î  | 
|     pkProtecTimeList = IpyGameDataPY.GetFuncEvalCfg("PKConfig", 1)  | 
|     if not pkProtecTimeList:  | 
|         return False  | 
|       | 
|     startTime, endTime = pkProtecTimeList  | 
|     startHour, startMinute = startTime  | 
|     endHour, endMinute = endTime  | 
|       | 
|     curTime = GameWorld.GetCurrentTime()  | 
|     curYear, curMonth, curDay = curTime.year, curTime.month, curTime.day  | 
|       | 
|     startDateTime = datetime.datetime(curYear, curMonth, curDay, startHour, startMinute, 0)  | 
|     endDateTime = datetime.datetime(curYear, curMonth, curDay, endHour, endMinute, 0)  | 
|       | 
|     if curTime >= startDateTime or curTime <= endDateTime:  | 
|         return True  | 
|     return False  | 
|   | 
| def IsSameServer(curPlayer, curTagPlayer):  | 
|     # ÊÇ·ñͬ·þÍæ¼Ò  | 
|     # ÔÝʱֱ½Ó·µ»ØTrue£¬×ö¿ç·þʱÔÙ´¦Àí  | 
|     return True  | 
|   | 
| ## ÊÇ·ñͬÕóÓª  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param curTagPlayer: Ä¿±êÍæ¼ÒʵÀý  | 
| #  @return: ÊÇ·ñͬÕóÓª  | 
| def CanAlikeFaction(curPlayer, curTagPlayer):  | 
|     curFaction = curPlayer.GetFaction()  # ÕóÓª  | 
|     tagFaction = curTagPlayer.GetFaction()  # ÕóÓª  | 
|     return curFaction and tagFaction and curFaction == tagFaction  | 
|   | 
| ## ÊÇ·ñͬ¼Ò×å  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param curTagPlayer: Ä¿±êÍæ¼ÒʵÀý  | 
| #  @return: ÊÇ·ñͬ¼Ò×å  | 
| def CanAlikeFamily(curPlayer, curTagPlayer):  | 
|     curFamilyID = curPlayer.GetFamilyID()  # ¼Ò×å  | 
|     tagFamilyID = curTagPlayer.GetFamilyID()  # ¼Ò×å  | 
|     return curFamilyID and tagFamilyID and curFamilyID == tagFamilyID  | 
|   | 
| ## ÊÇ·ñͬ¶ÓÎé  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param curTagPlayer: Ä¿±êÍæ¼ÒʵÀý  | 
| #  @return: ÊÇ·ñͬ¶ÓÎé  | 
| def CanAlikeTeam(curPlayer, curTagPlayer):  | 
|     curPlayerTeamID = curPlayer.GetTeamID()  | 
|     curTagTeamID = curTagPlayer.GetTeamID()  | 
|     return curPlayerTeamID and curTagTeamID and curPlayerTeamID == curTagTeamID  | 
| #---------------------------------------------------------------------  | 
| ##´¦Àí¶ÔÏóËÀÍöÂß¼  | 
| # @param curObjDetel ¶ÔÏóʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Àí¶ÔÏóËÀÍöÂß¼  | 
| def DoLogic_ObjDead(atkObj, curObjDetel, curSkill, tick):  | 
|     if GameObj.GetHP(curObjDetel) > 0:  | 
|         return  | 
|       | 
|     if TurnAttack.SetKilled(curObjDetel):  | 
|         return  | 
|           | 
|     #---Íæ¼Ò´¦Àí---  | 
|     if curObjDetel.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|         playerControl = PlayerControl.PlayerControl(curObjDetel)  | 
|         playerControl.SetDead()  | 
|         return  | 
|       | 
|     #---NPC´¦Àí---  | 
|     if not ChNPC.OnCheckCanDie(atkObj, curObjDetel, curSkill, tick):  | 
|         return  | 
|       | 
|     npcControl = NPCCommon.NPCControl(curObjDetel)  | 
|     npcControl.SetKilled()  | 
|     return  | 
|   | 
|   | 
| ## ¸øÓèÍæ¼Ò»÷É±Íæ¼Ò½±Àø  | 
| #  @param curPlayer: ¹¥»÷·½  | 
| #  @param defender: ·ÀÊØ·½  | 
| #  @param tick: Ê±¼ä´Á  | 
| #  @return: None  | 
| def __GiveKill_Player_ValuePrize(curPlayer, defender, tick):  | 
|     mapType = GameWorld.GetMap().GetMapFBType()  | 
|       | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|      | 
|           | 
|     # ·Ç¸±±¾µØÍ¼²Å¸ø½±Àø  | 
|     if mapType != IPY_GameWorld.fbtNull:  | 
|         GameWorld.DebugLog("    __GiveKill_Player_ValuePrize ¸±±¾µØÍ¼É±È˲»¸ø½±Àø£¡£¡£¡")  | 
|         return  | 
|   | 
|     attackLV = curPlayer.GetLV()    # ¹¥»÷Õߵȼ¶  | 
|     attackPrestige = PlayerControl.GetPrestige(curPlayer)    # ¹¥»÷ÕßÍþÍû  | 
|     attackNotoriety = curPlayer.GetInfamyValue()    # ¹¥»÷Õß¶ñÃûÖµ  | 
|     attackPkValue = curPlayer.GetPKValue()  # ¹¥»÷ÕßpkÖµ  | 
|     attackFightPower = PlayerControl.GetFightPower(curPlayer) # ¹¥»÷ÕßÕ½¶·Á¦  | 
|       | 
|     defendLV = defender.GetLV()    # ·ÀÊØÕߵȼ¶  | 
|     defendPrestige = PlayerControl.GetPrestige(defender)    # ·ÀÊØÕßÍþÍû  | 
|     defendNotoriety = defender.GetInfamyValue()    # ·ÀÊØÕß¶ñÃûÖµ  | 
|     defendPkValue = defender.GetPKValue()  # ·ÀÊØÕßpkÖµ  | 
|     defendFightPower = PlayerControl.GetFightPower(defender) # ·ÀÊØÕßÕ½¶·Á¦  | 
|       | 
| #    #½ñÈÕɱÈË»ñµÃÍþÍûÖµ  | 
| #    prestigeByDay = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_KillPlayerAddPrestige)  | 
| #      | 
| #    addPrestige = int(eval(ReadChConfig.GetChConfig("KillPlayerPrestige")))  | 
| #    if addPrestige > 0:  | 
| #        maxPrestigeByDay = ReadChConfig.GetEvalChConfig("KillPlayerMaxPrestigeByDay")  | 
| #        if prestigeByDay < maxPrestigeByDay:  | 
| #            #û³¬¹ýÿÈÕɱÈË»ñµÃÍþÍû×î´óÖµ, ¸øÓèÍþÍû  | 
| #            addPrestige = min(addPrestige, maxPrestigeByDay - prestigeByDay)  | 
| #            PlayerPrestigeSys.AddPrestigeOffcialLV(curPlayer, addPrestige, ChConfig.Def_AddPrestige_Kill)  | 
| #            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_KillPlayerAddPrestige, prestigeByDay + addPrestige)  | 
| #        else:  | 
| #            #GeRen_wll_0:½ñÈÕ»ñµÃÍþÍûÒÑ´ïÉÏÏÞ  | 
| #            PlayerControl.NotifyCode(curPlayer, "PK_liubo_372238")  | 
| #              | 
| #    elif addPrestige < 0:  | 
| #        GameWorld.ErrLog("KillPlayerPrestige¼ÆËã½á¹û£º%s" % addPrestige)  | 
|       | 
|     #¶ñÃûÖµ      | 
|     curPlayer.SetInfamyValue(min(attackNotoriety + ChConfig.Def_KillValue_Notoriety,  | 
|                              ChConfig.Def_UpperLimit_DWord))  | 
|       | 
|     #»îÔ¾¶È  | 
| #    activeByDay = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_KillPlayerAddActive)  | 
| #    addActiveValue = int(eval(ReadChConfig.GetChConfig("KillPlayerFamilyAvtive")))  | 
| #    if addActiveValue > 0 and curPlayer.GetFamilyID() != 0:  | 
| #        maxAvtiveByDay = ReadChConfig.GetEvalChConfig("KillPlayerMaxAvtiveByDay")  | 
| #        if activeByDay < maxAvtiveByDay:  | 
| #            addActiveValue = min(addActiveValue, maxAvtiveByDay - activeByDay)  | 
| #            PlayerFamily.AddPlayerFamilyActiveValue(curPlayer, addActiveValue, True, \  | 
| #                                                    PlayerFamily.Def_AddFAVReason_KillPlayer)  | 
| #            PlayerControl.NotifyCode(curPlayer, "GeRen_admin_425673", [addActiveValue])  | 
| #            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_KillPlayerAddActive, activeByDay + addActiveValue)  | 
| #        else:  | 
| #            PlayerControl.NotifyCode(curPlayer, "PK_liubo_161795")              | 
| #  | 
| #    elif addActiveValue < 0:  | 
| #        GameWorld.ErrLog("KillPlayerFamilyAvtive¼ÆËã½á¹û£º%s" % addActiveValue)  | 
|   | 
|     #---·ÀÊØÕß  | 
|     #ÍþÍûÖµ  | 
| #    lostPrestige = int(eval(ReadChConfig.GetChConfig("BeKilledPlayerPrestige")))  | 
| #    if lostPrestige > 0:  | 
| #        PlayerPrestigeSys.SubPrestigeOffcialLV(defender, lostPrestige, ChConfig.Def_SubPrestige_BeKilled)  | 
| #    elif lostPrestige < 0:  | 
| #        GameWorld.ErrLog("BeKilledPlayerPrestige¼ÆËã½á¹û£º%s" % lostPrestige)  | 
|           | 
|     #¶ñÃûÖµ  | 
|     defender.SetInfamyValue(max(defendNotoriety - ChConfig.Def_BeKilledValue_Notoriety, 0))  | 
|     return  | 
|   | 
|   | 
| ## Åж¨Ë«·½Ö®¼äÓÐÕϰµãÊÇ·ñ¿É¹¥»÷£¬Ö»ÓÐBOSS ¿É¹¥»÷  | 
| #  @param None  | 
| #  @return bool  | 
| def CanAttackByPath(attacker, defender):  | 
|     #boss ²»ÑéÖ¤Õϰµã  | 
|     if attacker.GetGameObjType() == IPY_GameWorld.gotNPC:  | 
|         if attacker.GetIsBoss() >= ChConfig.Def_NPCType_Boss_Blue:  | 
|             return True  | 
|           | 
|     #Íæ¼ÒºÍС¹ÖÖ®¼äÓÐÕϰµã²»¿É¹¥»÷  | 
|     canLineTo = GameWorld.GetMap().CanLineTo(attacker.GetPosX(), attacker.GetPosY(),  | 
|                                  defender.GetPosX(), defender.GetPosY())  | 
|       | 
|     if attacker.GetGameObjType() == IPY_GameWorld.gotPlayer and not canLineTo:  | 
|         PlayerControl.NotifyCode(attacker, "PK_liubo_827276")  | 
|           | 
|     return canLineTo  | 
|   | 
|   | 
| # ÑªÁ¿±ä»¯Æ®ÑªÍ¨Öª  | 
| def ChangeHPView(curObj, srcObj, skillID, changeHP, changType):  | 
|     srcID, srcType = 0, 0  | 
|     if srcObj:  | 
|         srcID, srcType = srcObj.GetID(), srcObj.GetGameObjType()  | 
|     curObj.ChangeHPView(skillID, changeHP % ShareDefine.Def_PerPointValue, changeHP / ShareDefine.Def_PerPointValue,   | 
|                         changType, srcID, srcType, curObj.GetHP(), curObj.GetHPEx())  | 
|     return |