#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#---------------------------------------------------------------------  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
##@package NPCCommon  
 | 
#npcͨÓÃÄ£¿é  
 | 
#  
 | 
# @author Alee  
 | 
# @date 2010-02-20 16:30  
 | 
# @version 1.1  
 | 
#  
 | 
# @change: "2018-07-09 15:30" hxp ×°±¸µôÂäÑÕÉ«¶ÔÓ¦¼þÊýÉÏÏÞÓÉÔÀ´µÄÖ»ÏÞÖÆ¶ÀÁ¢¸ÅÂʸÄΪ¹«¹²ÏÞÖÆÌõ¼þ  
 | 
#  
 | 
#------------------------------------------------------------------------------   
 | 
#"""Version = 2018-07-09 15:30"""  
 | 
#---------------------------------------------------------------------  
 | 
import IPY_GameWorld  
 | 
import GameWorld  
 | 
import PlayerControl  
 | 
import GameMap  
 | 
import ChConfig  
 | 
import EventShell  
 | 
import SkillShell  
 | 
import BuffSkill  
 | 
import BaseAttack  
 | 
import ChNetSendPack  
 | 
import SkillCommon  
 | 
import AttackCommon  
 | 
import ItemControler  
 | 
import ItemCommon  
 | 
import FBLogic  
 | 
import ReadChConfig  
 | 
import PetControl  
 | 
import NPCAI  
 | 
import OperControlManager  
 | 
import ShareDefine  
 | 
import ChItem  
 | 
#import AICommon  
 | 
import ChPyNetSendPack  
 | 
import DataRecordPack  
 | 
import NetPackCommon  
 | 
import FBCommon  
 | 
import PlayerActivity  
 | 
import PlayerSuccess  
 | 
import BossHurtMng  
 | 
import GY_Query_BossFirstKill  
 | 
import GameLogic_FamilyInvade  
 | 
import GameLogic_GatherSoul  
 | 
import FormulaControl  
 | 
import PlayerBossReborn  
 | 
import PlayerFairyCeremony  
 | 
import PlayerActCollectWords  
 | 
import PlayerNewFairyCeremony  
 | 
import GameLogic_CrossGrassland  
 | 
import PlayerFeastWish  
 | 
import PlayerFeastTravel  
 | 
import PlayerGoldInvest  
 | 
import PlayerWeekParty  
 | 
import NPCHurtManager  
 | 
import PlayerActLogin  
 | 
import FamilyRobBoss  
 | 
import IpyGameDataPY  
 | 
import PlayerState  
 | 
import PyGameData  
 | 
import PlayerTeam  
 | 
import NPCHurtMgr  
 | 
import PlayerVip  
 | 
import GameObj  
 | 
import ChNPC  
 | 
  
 | 
import random  
 | 
import math  
 | 
import time  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
OnNPCDie = None  
 | 
  
 | 
# NPCÊôÐԳɳ¤ÅäÖÃÏà¹ØË÷Òý  
 | 
(  
 | 
NPCAttr_ParamDict, # ¹ý³Ì²ÎÊý¹«Ê½  
 | 
NPCAttr_AttrStrengthenList, # µÈ¼¶³É³¤ÊôÐÔ¹«Ê½  
 | 
NPCAttr_PlayerCntCoefficient, # µØÍ¼ÈËÊý¶ÔÓ¦ÊôÐÔ¶îÍâ³É³¤ÏµÊý {mapID:{"ÊôÐÔÃû":{×é¶Ó½øÈëÈËÊý:ϵÊý, ...}, ...}, ...}  
 | 
NPCAttr_NPCPlayerCntCoefficient, # NPCÌØÊâ³É³¤ÈËÊý¶ÔÓ¦ÊôÐÔ¶îÍâ³É³¤ÏµÊý {npcID:{"ÊôÐÔÃû":{ÈËÊý:ϵÊý, ...}, ...}, ...}, ÓÅÏȼ¶´óÓÚµØÍ¼ÈËÊýϵÊý  
 | 
NPCAttr_DynNPCLVMap, # ¶¯Ì¬µÈ¼¶µÄµØÍ¼IDÁÐ±í£¬Ä¬ÈÏÒÑˢгöÀ´µÄNPCµÈ¼¶²»»áÔÙ±ä¸ü£¬Ï´ÎË¢³öÀ´µÄ¹ÖÎïµÈ¼¶±ä¸ü [µØÍ¼ID, ...]  
 | 
NPCAttr_DynPCCoefficientMap, # ¶¯Ì¬ÈËÊýϵÊýµÄµØÍ¼ID {µØÍ¼ID:ÊÇ·ñÂíÉÏË¢ÐÂÊôÐÔ, ...}  
 | 
) = range(6)  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##NPC³õʼ»¯->³öÉúµ÷Óà  
 | 
# @param curNPC NPCʵÀý  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks NPC³õʼ»¯->³öÉúµ÷Óà  
 | 
def InitNPC(curNPC):  
 | 
    callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s" % (curNPC.GetAIType(), "DoInit"))  
 | 
    if callFunc == None:  
 | 
        #NPCAI²»¿ÉʹÓà  
 | 
        #ĬÈÏÉ趨³ðºÞ¶È×î´ó¸öÊý  
 | 
        curNPC.GetNPCAngry().Init(ChConfig.Def_Default_NPC_Angry_Count)  
 | 
    else:  
 | 
        callFunc(curNPC)  
 | 
          
 | 
    #³õʼ»¯´¦Àí¼ä¸ô  
 | 
    curNPC.SetIsNeedProcess(False)  
 | 
    #³õʼ»¯Õâ¸öNPCµÄʱÖÓ  
 | 
    curNPC.SetTickTypeCount(ChConfig.TYPE_NPC_Tick_Count)  
 | 
    return  
 | 
  
 | 
def GetNPCLV(curNPC):  
 | 
    # NPCµÈ¼¶  
 | 
    if hasattr(curNPC, "GetCurLV"):  
 | 
        return max(curNPC.GetCurLV(), curNPC.GetLV())  
 | 
    return curNPC.GetLV()  
 | 
  
 | 
def GetRealmLV(curNPC): return curNPC.GetMAtkMin()      # NPC±íÖдË×ֶκ¬Òå¸Ä³É¾³½çµÈ¼¶  
 | 
def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV)      # NPC±íÖдË×ֶκ¬Òå¸Ä³É¾³½çµÈ¼¶  
 | 
def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # ·ç·À´ú±íÊÇ·ñµÈ¼¶Ñ¹ÖÆ  
 | 
def GetSuppressFightPower(curNPC): return curNPC.GetThunderDef() # À×·À´ú±íÑ¹ÖÆÕ½Á¦  
 | 
def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(value)  
 | 
def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # »ð·À´ú±íÍÆ¼öÕ½Á¦  
 | 
def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # À×¹¥´ú±íµôÂä¹éÊôÀàÐÍ  
 | 
def GetFaction(curNPC): return curNPC.GetCountry()  
 | 
def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # ¶¾¹¥´ú±íNPC¼¼ÄÜÉ˺¦¼Ó³ÉÍò·ÖÂÊ  
 | 
def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # »ð¹¥´ú±íNPC×îÖչ̶¨É˺¦¼Ó³É, ÆÕ¹¥Ò²ÓÐЧ¹û  
 | 
def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # »ð¹¥´ú±íNPC×îÖչ̶¨É˺¦¼Ó³É, ÆÕ¹¥Ò²ÓÐЧ¹û  
 | 
def GetSkillEnhance(curNPC): return curNPC.GetWindAtk() # ·ç¹¥´ú±íNPC ¡¶ÆÕ¹¥¡· µÄ¼¼Äܸ½¼ÓÉ˺¦¹Ì¶¨Öµ  
 | 
def GetNPCSeries(curNPC): return curNPC.GetPoisionDef() # ¶¾·À×ֶδú±íNPCϵ£¬°´¶þ½øÖÆÎ»Çø·Ö  
 | 
  
 | 
def DoNPCAttrStrengthen(curNPC, isReborn, isDyn=False):  
 | 
    '''NPCÊôÐÔÔöÇ¿, NPCÊôÐԳɳ¤ÓÉÁ½¸öÒòËØ¾ö¶¨  
 | 
    1.NPC³É³¤µÈ¼¶£¬³É³¤µÈ¼¶¾ö¶¨³É³¤ÊôÐÔ£¬Óë³É³¤±í½áºÏʹÓà  
 | 
            ¿ÉÉèÖõØÍ¼NPCµÈ¼¶¶¯Ì¬³É³¤£¬µ«ÊÇÒѾˢгöÀ´µÄNPCµÈ¼¶²»±ä£¬¶¯Ì¬µÈ¼¶±ä¸üºóˢеÄNPCµÈ¼¶²Å»áʹÓÃ×îеȼ¶  
 | 
              
 | 
    2.Íæ¼ÒÈËÊýÒòËØ£¬¾ö¶¨NPCÊôÐԵĶîÍâ³É³¤ÏµÊý£¬¿Éµ¥¶ÀʹÓ㬻òÕߺÍ1Ò»ÆðʹÓà  
 | 
            ¿ÉÉèÖÃÂíÉÏË¢ÐÂNPCÊôÐÔ  
 | 
            ³ýѪÁ¿Í⣬ÆäËûÊôÐÔ»á¸ù¾Ý¶¯Ì¬ÒòËØÖ±½Ó±ä¸ü  
 | 
            ÑªÁ¿»á¸ù¾ÝѪÁ¿°Ù·Ö±È¶¯Ì¬±ä¸üÖÁÏàÓ¦µÄ°Ù·Ö±È  
 | 
    '''  
 | 
    npcID = curNPC.GetNPCID()  
 | 
    strengthenIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCStrengthen", npcID)  
 | 
    if not strengthenIpyData:  
 | 
        #GameWorld.DebugLog("¸ÃNPCÊôÐÔ²»³É³¤£¡npcID=%s" % npcID)  
 | 
        return  
 | 
      
 | 
    strengthenLV = 0  
 | 
    strengthenPlayerCnt = 0  
 | 
      
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
      
 | 
    if strengthenIpyData.GetIsStrengthenByPlayerCount():  
 | 
        if FamilyRobBoss.IsHorsePetRobBoss(npcID):  
 | 
            strengthenPlayerCnt = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_HorsePetRobBossPlayerCount)  
 | 
        else:  
 | 
            strengthenPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt)  
 | 
            if not strengthenPlayerCnt:  
 | 
                GameWorld.ErrLog("NPCÅäÖÃÁ˰´Íæ¼ÒÈËÊý³É³¤ÀàÐÍ£¬µ«ÊÇÎÞ·¨»ñÈ¡µ½¶ÔÓ¦µÄÍæ¼ÒÈËÊý£¡npcID=%s" % (npcID))  
 | 
                return  
 | 
              
 | 
    lvStrengthenType = strengthenIpyData.GetLVStrengthenType()  
 | 
    # ¸ù¾ÝÊÀ½çµÈ¼¶  
 | 
    if lvStrengthenType == 3:  
 | 
        strengthenLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)  
 | 
    # ¸ù¾Ý×î´óµÈ¼¶  
 | 
    elif lvStrengthenType == 2:  
 | 
        strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV)  
 | 
    # ¸ù¾Ýƽ¾ùµÈ¼¶  
 | 
    elif lvStrengthenType == 1:  
 | 
        strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenAverageLV)  
 | 
    # ¸ù¾Ý°´³É³¤µÈ¼¶µÄÉÏÏÂÏÞËæ»ú  
 | 
    elif lvStrengthenType == 4:  
 | 
        randMinLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMinLV)  
 | 
        randMaxLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV)  
 | 
        strengthenLV = random.randint(randMinLV, randMaxLV)  
 | 
          
 | 
    # Ä¾×®¹Ö×î´ó¡¢Æ½¾ù³É³¤µÈ¼¶´¦Àí£¬Ö±½ÓÈ¡¹éÊôÍæ¼ÒµÈ¼¶  
 | 
    if lvStrengthenType in [1, 2] and curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:  
 | 
        owner = None  
 | 
        summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)  
 | 
        if summonPlayerID:  
 | 
            owner = GameWorld.GetObj(summonPlayerID, IPY_GameWorld.gotPlayer)  
 | 
        if owner:  
 | 
            strengthenLV = owner.GetLV()  
 | 
              
 | 
    if strengthenIpyData.GetCmpNPCBaseLV():  
 | 
        strengthenLV = max(strengthenLV, curNPC.GetLV())  
 | 
      
 | 
    if lvStrengthenType in [1, 2] and not strengthenLV:  
 | 
        GameWorld.ErrLog("NPCÅäÖÃÁ˳ɳ¤µÈ¼¶ÀàÐÍ£¬µ«ÊÇÎÞ·¨»ñÈ¡µ½¶ÔÓ¦µÄ³É³¤µÈ¼¶Öµ£¡npcID=%s,lvStrengthenType=%s" % (npcID, lvStrengthenType))  
 | 
        return  
 | 
      
 | 
    # ¸±±¾ÌØÊâÖ¸¶¨  
 | 
    npcFBAttrDict = FBLogic.GetFBNPCStrengthenAttr(curNPC, isReborn)  
 | 
    if "LV" in npcFBAttrDict:  
 | 
        strengthenLV = npcFBAttrDict["LV"]  
 | 
          
 | 
    attrDict = GetNPCStrengthenAttrDict(npcID, strengthenLV, strengthenPlayerCnt, strengthenIpyData)  
 | 
    attrDict.update(npcFBAttrDict) # Èç¹û¸±±¾ÓÐÖ¸¶¨ÊôÐÔ£¬ÔòÒÔ¸±±¾ÎªÖ÷  
 | 
    if not attrDict:  
 | 
        return  
 | 
      
 | 
    # ³É³¤µÈ¼¶Ö»ÔÚÖØÉúµÄʱºòÉèÖÃÒ»´Î  
 | 
    if isReborn and curNPC.GetCurLV() != strengthenLV:  
 | 
        curNPC.SetCurLV(strengthenLV, False) # ÖØÉúµÄ²»Í¨ÖªµÈ¼¶±ä¸ü£¬ÊôÐԳɳ¤Ë¢ÐºóÓÉNPC³öÏÖ°ü֪ͨ  
 | 
          
 | 
    befMaxHP = GameObj.GetMaxHP(curNPC)  
 | 
    befHP = GameObj.GetHP(curNPC)  
 | 
    #GameWorld.DebugLog("NPCÊôÐԳɳ¤Ë¢Ð£¬isReborn=%s,npcID=%s,LV=%s,curLV=%s,befMaxHP=%s,befHP=%s,attrDict=%s"   
 | 
    #                   % (isReborn, npcID, curNPC.GetLV(), curNPC.GetCurLV(), befMaxHP, befHP, attrDict))  
 | 
    for attrKey, strengthenValue in attrDict.items():  
 | 
        if not hasattr(curNPC, "Set%s" % attrKey):  
 | 
            if attrKey == "FightPower":  
 | 
                SetSuppressFightPower(curNPC, strengthenValue)  
 | 
            continue  
 | 
          
 | 
        if attrKey == "MaxHP":  
 | 
            GameObj.SetMaxHP(curNPC, strengthenValue)  
 | 
        else:  
 | 
            strengthenValue = min(strengthenValue, ChConfig.Def_UpperLimit_DWord)  
 | 
            getattr(curNPC, "Set%s" % attrKey)(strengthenValue)  
 | 
        #GameWorld.DebugLog("    %s=%s" % (attrKey, strengthenValue))  
 | 
          
 | 
    aftMaxHP = GameObj.GetMaxHP(curNPC)  
 | 
    if befMaxHP != aftMaxHP:  
 | 
        if isReborn:  
 | 
            GameObj.SetHP(curNPC, aftMaxHP)  
 | 
        elif isDyn:  
 | 
            # ¶¯Ì¬Ë¢ÐÂÊôÐԵģ¬ÑªÁ¿°´°Ù·Ö±È¼Ì³Ð  
 | 
            aftHP = int(aftMaxHP * befHP / befMaxHP)  
 | 
            GameObj.SetHP(curNPC, aftHP)  
 | 
            curNPC.Notify_HPEx()  
 | 
            curNPC.Notify_MaxHPEx()  
 | 
            #GameWorld.DebugLog("    aftHP=%s,aftMaxHP=%s" % (aftHP, aftMaxHP))  
 | 
      
 | 
    # »úÆ÷È˸´»î³õʼ»¯¸ø¼¼ÄÜ  
 | 
    if isReborn and curNPC.GetType() == ChConfig.ntRobot:  
 | 
        __OnFBRobotReborn(curNPC, strengthenLV)  
 | 
          
 | 
    return  
 | 
  
 | 
def __OnFBRobotReborn(curNPC, npcLV):  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    lineID = GameWorld.GetGameWorld().GetLineID()  
 | 
    objID = curNPC.GetID()  
 | 
    jobSkillDict = IpyGameDataPY.GetFuncEvalCfg("FBRobotCfg", 1)  
 | 
    robotJob = random.choice(jobSkillDict.keys())  
 | 
    lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {})  
 | 
    lineRobotJobDict[objID] = robotJob  
 | 
    PyGameData.g_fbRobotJobDict[lineID] = lineRobotJobDict  
 | 
    skillInfoDict = jobSkillDict[robotJob]  
 | 
    skillIDList = []  
 | 
    for skillInfo, needLV in skillInfoDict.items():  
 | 
        if npcLV < needLV:  
 | 
            continue  
 | 
        if isinstance(skillInfo, int):  
 | 
            skillIDList.append(skillInfo)  
 | 
        else:  
 | 
            skillIDList += list(skillInfo)  
 | 
    GameWorld.DebugLog("¸ø»úÆ÷ÈËNPC¼¼ÄÜ: objID=%s,robotJob=%s,npcLV=%s, %s" % (objID, robotJob, npcLV, skillIDList))  
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
    for skillID in skillIDList:  
 | 
        skillManager.LearnSkillByID(skillID)  
 | 
    playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for index in xrange(playerManager.GetPlayerCount()):  
 | 
        curPlayer = playerManager.GetPlayerByIndex(index)  
 | 
        if not curPlayer:  
 | 
            continue  
 | 
        FBLogic.DoFBHelp(curPlayer, tick)  
 | 
    return  
 | 
  
 | 
  
 | 
def __DoGiveVSPlayerNPCSkill(curNPC, job, npcLV):  
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
    jobSkillDict = IpyGameDataPY.GetFuncEvalCfg("XMZZRobotSkill", 1)  
 | 
    if job not in jobSkillDict:  
 | 
        return  
 | 
    skillInfoDict = jobSkillDict[job]  
 | 
    #{1:{(100, 101, 102, 103):1, 50000:100, 50100:200, 50400:300}, 2:{(200, 201, 202, 203):1, 55000:100, 55100:200, 55200:300}}  
 | 
    skillIDList = []  
 | 
    for skillInfo, needLV in skillInfoDict.items():  
 | 
        if npcLV < needLV:  
 | 
            continue  
 | 
        if isinstance(skillInfo, int):  
 | 
            skillIDList.append(skillInfo)  
 | 
        else:  
 | 
            skillIDList += list(skillInfo)  
 | 
    GameWorld.DebugLog("¸øNPC¼¼ÄÜ: job=%s,npcLV=%s, %s" % (job, npcLV, skillIDList))  
 | 
    for skillID in skillIDList:  
 | 
        skillManager.LearnSkillByID(skillID)  
 | 
    return  
 | 
  
 | 
def GetNPCStrengthenAttrDict(npcID, strengthenLV=0, strengthenPlayerCnt=0, strengthenIpyData=None):  
 | 
    if not strengthenLV and not strengthenPlayerCnt:  
 | 
        return {}  
 | 
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)  
 | 
    if not npcData:  
 | 
        return {}  
 | 
      
 | 
    attrStrengthenInfo = ReadChConfig.GetEvalChConfig("NPCAttrStrengthen")  
 | 
    if not attrStrengthenInfo:  
 | 
        return {}  
 | 
      
 | 
    attrDict = {}  
 | 
    paramDict = attrStrengthenInfo[NPCAttr_ParamDict] # ¹ý³Ì²ÎÊý¹«Ê½×Öµä  
 | 
    attrStrengthenDict = attrStrengthenInfo[NPCAttr_AttrStrengthenList] # ÊôÐԳɳ¤¹«Ê½×Öµä  
 | 
    playerCntCoefficient = attrStrengthenInfo[NPCAttr_PlayerCntCoefficient] # ÈËÊýϵÊý  
 | 
    npcIDPlayerCntCoefficient = attrStrengthenInfo[NPCAttr_NPCPlayerCntCoefficient] # ÌØÊâNPCÈËÊýϵÊý  
 | 
    baseMaxHP = npcData.GetHPEx() * ShareDefine.Def_PerPointValue + npcData.GetHP()  
 | 
      
 | 
    if strengthenLV:  
 | 
        if not strengthenIpyData:  
 | 
            strengthenIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCStrengthen", npcID)  
 | 
        if not strengthenIpyData:  
 | 
            return {}  
 | 
          
 | 
        playerCurLVIpyData = PlayerControl.GetPlayerLVIpyData(strengthenLV) # È¡ÔöÇ¿¹ÖÎïµÈ¼¶¶ÔÓ¦´ËµÈ¼¶µÄÍæ¼Ò²Î¿¼ÊôÐÔÖµ  
 | 
        if not playerCurLVIpyData:  
 | 
            return {}  
 | 
          
 | 
        # NPC±í¿ÉÓòÎÊý  
 | 
        SkillAtkRate = GetSkillAtkRate(npcData) # ¼¼ÄÜÉ˺¦  
 | 
        FinalHurt = GetFinalHurt(npcData)  
 | 
          
 | 
        # ²Î¿¼Íæ¼ÒÊôÐÔ²ÎÊý  
 | 
        ReMaxHP = playerCurLVIpyData.GetReMaxHP() # ×î´óÉúÃüÖµ  
 | 
        ReAtk = playerCurLVIpyData.GetReAtk() # ¹¥»÷£¨×îС¡¢×î´ó¹¥»÷£©  
 | 
        ReDef = playerCurLVIpyData.GetReDef() # ·ÀÓù  
 | 
        ReHit = playerCurLVIpyData.GetReHit() # ÃüÖÐ  
 | 
        ReMiss = playerCurLVIpyData.GetReMiss() # ÉÁ±Ü  
 | 
        ReAtkSpeed = playerCurLVIpyData.GetReAtkSpeed() # ¹¥»÷ËÙ¶È  
 | 
        ReSkillAtkRate = playerCurLVIpyData.GetReSkillAtkRate() # ¼¼ÄÜÉ˺¦±ÈÀý  
 | 
        ReDamagePer = playerCurLVIpyData.GetReDamagePer() # Ôö¼ÓÉ˺¦  
 | 
        ReDamReduce = playerCurLVIpyData.GetReDamReduce() # ¼õÉÙÉ˺¦  
 | 
        ReIgnoreDefRate = playerCurLVIpyData.GetReIgnoreDefRate() # ÎÞÊÓ·ÀÓù±ÈÀý  
 | 
        ReLuckyHitRate = playerCurLVIpyData.GetReLuckyHitRate() # »áÐÄÒ»»÷ÂÊ  
 | 
        ReLuckyHit = playerCurLVIpyData.GetReLuckyHit() # »áÐÄÒ»»÷É˺¦  
 | 
        ReBleedDamage = playerCurLVIpyData.GetReBleedDamage() # Á÷ѪÉ˺¦Ôö¼Ó  
 | 
        ReIceAtk = playerCurLVIpyData.GetReIceAtk() # ÕæÊµÉ˺¦  
 | 
        ReIceDef = playerCurLVIpyData.GetReIceDef() # ÕæÊµµÖÓù  
 | 
        RePetAtk = playerCurLVIpyData.GetRePetAtk() # Áé³è¹¥»÷  
 | 
        RePetSkillAtkRate = playerCurLVIpyData.GetRePetSkillAtkRate() # Áé³è¼¼ÄÜ  
 | 
        RePetDamPer = playerCurLVIpyData.GetRePetDamPer() # Áé³èÉ˺¦Ôö¼Ó  
 | 
        ReFinalHurt = playerCurLVIpyData.GetReFinalHurt() # ¹Ì¶¨É˺¦Ôö¼Ó  
 | 
        ReFinalHurtReduce = playerCurLVIpyData.GetReFinalHurtReduce() # ¹Ì¶¨É˺¦¼õÉÙ  
 | 
        RePotionReply = playerCurLVIpyData.GetRePotionReply() # ÑªÆ¿»Ö¸´Á¿  
 | 
        RePotionCD = playerCurLVIpyData.GetRePotionCD() # ÑªÆ¿CD  
 | 
        ReFightPower = playerCurLVIpyData.GetReFightPower() # Õ½¶·Á¦  
 | 
          
 | 
        # Ôö¼ÓNPCÊôÐÔ²ÎÊý  
 | 
        HitTime = strengthenIpyData.GetHitTime() # ¹ÖÎïÊÜ»÷´ÎÊý  
 | 
        DefCoefficient = strengthenIpyData.GetDefCoefficient() # ÈËÎï·ÀÓùϵÊý  
 | 
        AtkCoefficient = strengthenIpyData.GetAtkCoefficient() # ÈËÎï¹¥»÷ϵÊý  
 | 
        AdjustCoefficient = strengthenIpyData.GetAdjustCoefficient() # µ÷ÕûϵÊý±ÈÀý  
 | 
        AtkInterval = strengthenIpyData.GetAtkInterval() # ¹ÖÎï¹¥»÷¼ä¸ô  
 | 
        HitRate = strengthenIpyData.GetHitRate() # ¶ÔÈËÎïµÄÃüÖÐÂÊ  
 | 
        MissRate = strengthenIpyData.GetMissRate() # ¶ÔÈËÎïµÄÉÁ±ÜÂÊ  
 | 
        MonterNum = strengthenIpyData.GetMonterNum() # ¹ÖÎïÊý  
 | 
        IceAtkCoefficient = strengthenIpyData.GetIceAtkCoefficient() # ÔªËع¥»÷±ÈÀý  
 | 
        IceDefCoefficient = strengthenIpyData.GetIceDefCoefficient() # ÔªËØ¿¹ÐÔ±ÈÀý  
 | 
        MaxEnduranceTime = strengthenIpyData.GetMaxEnduranceTime() # Íæ¼Ò×î´ó³ÐÊÜÉ˺¦Ê±¼ä  
 | 
        FightPowerCoefficient = strengthenIpyData.GetFightPowerCoefficient() # Ñ¹ÖÆÕ½¶·Á¦ÏµÊý  
 | 
          
 | 
        # ¹ý³Ì²ÎÊý  
 | 
        AtkReplyCoefficient = eval(FormulaControl.GetCompileFormula("NPCParam_AtkReplyCoefficient",  
 | 
                                                                    paramDict["AtkReplyCoefficient"])) # ¹ÖÎï¹¥»÷»Ø¸´µ÷ÕûÖµ  
 | 
        MonterHurt = eval(FormulaControl.GetCompileFormula("NPCParam_MonterHurt", paramDict["MonterHurt"])) # ¹ÖÎï¹Ì¶¨É˺¦  
 | 
        LostHPPerSecond = eval(FormulaControl.GetCompileFormula("NPCParam_LostHPPerSecond", paramDict["LostHPPerSecond"])) # Íæ¼ÒÿÃëµôѪÁ¿  
 | 
        LVStrengthenMark = strengthenIpyData.GetLVStrengthenMark()  
 | 
        attrStrengthenList = attrStrengthenDict.get(LVStrengthenMark, [])  
 | 
        for attrKey, strengthenFormat in attrStrengthenList:  
 | 
            strengthenValue = int(eval(FormulaControl.GetCompileFormula("NPCStrengthen_%s_%s" % (attrKey,LVStrengthenMark), strengthenFormat)))  
 | 
            #GameWorld.DebugLog("    %s=%s" % (attrKey, strengthenValue))  
 | 
            locals()[attrKey] = strengthenValue # ´´½¨¸ÃÊôÐÔ¾Ö²¿±äÁ¿×÷Ϊ²ÎÊýÌṩ¸øºóÃæÊôÐÔ¼ÆËãʱÓà  
 | 
            attrDict[attrKey] = strengthenValue  
 | 
              
 | 
        # µ±Õ½Á¦ÏµÊýΪ0ʱ£¬NPCÕ½Á¦Ä¬ÈÏΪNPC±íÑ¹ÖÆÕ½Á¦  
 | 
        if FightPowerCoefficient:  
 | 
            attrDict["FightPower"] = int(ReFightPower * FightPowerCoefficient / 10000.0)  
 | 
              
 | 
    if strengthenPlayerCnt:  
 | 
        mapID = GameWorld.GetMap().GetMapID()  
 | 
        dataMapID = FBCommon.GetRecordMapID(mapID)  
 | 
        formulaKey = "MapCoefficient_%s" % mapID  
 | 
        playerCntAttrCoefficient = playerCntCoefficient.get(mapID, {})  
 | 
        if not playerCntAttrCoefficient and dataMapID in playerCntCoefficient:  
 | 
            playerCntAttrCoefficient = playerCntCoefficient[dataMapID]  
 | 
            formulaKey = "MapCoefficient_%s" % dataMapID  
 | 
        if npcID in npcIDPlayerCntCoefficient:  
 | 
            playerCntAttrCoefficient = npcIDPlayerCntCoefficient[npcID]  
 | 
            formulaKey = "NPCCoefficient_%s" % npcID  
 | 
        for attrKey, coefficientDict in playerCntAttrCoefficient.items():  
 | 
            if attrKey in attrDict:  
 | 
                attrValue = attrDict[attrKey]  
 | 
            elif attrKey == "MaxHP":  
 | 
                attrValue = baseMaxHP  
 | 
            else:  
 | 
                attrFuncName = "Get%s" % attrKey  
 | 
                if not hasattr(npcData, attrFuncName):  
 | 
                    continue  
 | 
                attrValue = getattr(npcData, attrFuncName)()  
 | 
            # °´×ÖµäÅäÖà  
 | 
            if isinstance(coefficientDict, dict):  
 | 
                coefficient = GameWorld.GetDictValueByRangeKey(coefficientDict, strengthenPlayerCnt, 1)  
 | 
            # °´¹«Ê½ÅäÖà  
 | 
            elif isinstance(coefficientDict, str):  
 | 
                formulaKey = "%s_%s" % (formulaKey, attrKey)  
 | 
                coefficient = eval(FormulaControl.GetCompileFormula(formulaKey, coefficientDict))  
 | 
            else:  
 | 
                coefficient = 1  
 | 
            attrDict[attrKey] = int(attrValue * coefficient)  
 | 
              
 | 
    #GameWorld.DebugLog("¼ÆËãNPCÊôÐԳɳ¤: npcID=%s,strengthenLV=%s,strengthenPlayerCnt=%s,baseMaxHP=%s,attrDict=%s"   
 | 
    #                   % (npcID, strengthenLV, strengthenPlayerCnt, baseMaxHP, attrDict))  
 | 
    return attrDict  
 | 
  
 | 
def GiveKillNPCDropPrize(curPlayer, mapID, npcCountDict, exp_rate=None, mailTypeKey=None, isMail=False,   
 | 
                         extraItemList=[], prizeMultiple=1, dropItemMapInfo=[], curGrade=0, isVirtualDrop=False):  
 | 
    '''¸øÍæ¼Ò»÷ɱNPCµôÂä½±Àø  
 | 
    @param mapID: »÷ɱµÄNPCËùÔÚµØÍ¼ID£¬×¢Òâ´ÎµØÍ¼²¢²»Ò»¶¨ÊÇÍæ¼Òµ±Ç°µØÍ¼  
 | 
    @param npcCountDict: Ö´Ðе¥´ÎʱËù»÷ɱµÄnpcÊýÁ¿×Öµä {npcID:count, ...}  
 | 
    @param exp_rate: »÷ɱ¹ÖÎïÏíÊܵľÑé±ÈÀý  
 | 
    @param mailTypeKey: »ñÈ¡ÎïÆ·±³°ü¿Õ¼ä²»×ãʱ·¢Ë͵ÄÓʼþÄ£°åkey  
 | 
    @param isMail: ÊÇ·ñÇ¿ÖÆ·¢ËÍÓʼþ£¬ÈôÊÇÔò²»¿¼ÂDZ³°ü¿Õ¼ä£¬·ñµÄ»°Ö»ÔÚ±³°ü¿Õ¼ä²»×ãʱ²Å·¢ËÍÓʼþ  
 | 
    @param extraItemList: ¹Ì¶¨¸½¼ÓÎïÆ·ÁÐ±í£¬Èç¹ûÐèÖ´Ðжà´Î£¬Ôò´Ë¹Ì¶¨²ú³öÁбíÐèÔÚÍâ²ã´¦ÀíºÃ£¬Äڲ㲻×ö¶à´ÎÖ´Ðд¦Àí¡£[[itemID, itemCount, isAuctionItem], ...]  
 | 
    @param prizeMultiple: ½±Àø±¶Öµ, ¶ÔËùÓн±ÀøÓÐЧ£¬µÈÓÚ»÷ɱ¶à´ÎNPC£¬¶à±¶¸½¼ÓÎïÆ·  
 | 
    @param dropItemMapInfo: µôÂ䵨°åÐÅÏ¢ [dropPosX, dropPosY, ÊÇ·ñ½ö×Ô¼º¿É¼û, ¶ÑµþÎïÆ·ÊÇ·ñÉ¢¿ª]  
 | 
    @param curGrade: ÆÀ¼¶  
 | 
    @param isVirtualDrop: ÊÇ·ñ¸øÎïÆ·ÐéÄâµôÂä±íÏÖ  
 | 
    '''  
 | 
    if not exp_rate:  
 | 
        exp_rate = PlayerControl.GetPlayerExpRate(curPlayer)  
 | 
          
 | 
    npcID = 0  
 | 
    totalExp = 0  
 | 
    totalMoney = 0  
 | 
    itemCountDict = {}  
 | 
    auctionItemIDList = []  
 | 
      
 | 
    if prizeMultiple > 1:  
 | 
        hadDropItemKeyList, hadDropItemPlaceList = [], [] # ÒѾµôÂä¹ýµÄÎïÆ·¼¯ºÏkeyÁÐ±í£¬ ÒѾµôÂä¹ýµÄ×°±¸²¿Î»ÁÐ±í  
 | 
        mPrizeItemIDList = IpyGameDataPY.GetFuncEvalCfg("SealDemonDoubleDrop", 1) # ÔÊÐí¶à±¶½±ÀøµÄÎïÆ·IDÁÐ±í  
 | 
        mPrizePlaceList = IpyGameDataPY.GetFuncEvalCfg("SealDemonDoubleDrop", 2) # ÔÊÐí¶à±¶½±ÀøµÄ×°±¸²¿Î»  
 | 
        mPrizeItemKeyList = IpyGameDataPY.GetFuncEvalCfg("SealDemonDoubleDrop", 3) # ÔÊÐí¶à±¶½±ÀøµÄÎïÆ·ID¼¯ºÏ  
 | 
          
 | 
        itemKeyDict = IpyGameDataPY.GetFuncEvalCfg("JobItemDropSets") # {ÎïÆ·ID¼¯ºÏkey:[ְҵ˳ÐòÎïÆ·IDÁбí], ...}  
 | 
        itemIDKeyDict = {}  
 | 
        for itemKey, itemIDList in itemKeyDict.items():  
 | 
            for itemID in itemIDList:  
 | 
                itemIDKeyDict[itemID] = itemKey  
 | 
      
 | 
    for npcID, count in npcCountDict.items():  
 | 
        baseExp = GetNPCExp(curPlayer, npcID)  
 | 
        addExp = int(baseExp * exp_rate / float(ChConfig.Def_MaxRateValue)) # »ù´¡¼Ó³É  
 | 
        totalCount = count * prizeMultiple  
 | 
        totalExp += (addExp * totalCount)  
 | 
          
 | 
        # µôÂäÓиÅÂÊÒòËØ£¬Ðè¶à´ÎÖ´ÐÐ  
 | 
        for dCount in xrange(1, totalCount + 1):  
 | 
            isKillCountDrop = dCount == 1 # Í¬Ò»Ö»NPCÒ»´Î´¦ÀíÖжà´Î»÷ɱµÄÇé¿ö£¬Ö»ËãÒ»´Î¸½¼Ó×°±¸´¦Àí  
 | 
            dropInfo = GetNPCDropInfo(curPlayer, mapID, npcID, isKillCountDrop=isKillCountDrop, curGrade=curGrade)  
 | 
            if not dropInfo:  
 | 
                continue  
 | 
            dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo  
 | 
            totalMoney += (dropMoneyCnt * moneyValue)  
 | 
              
 | 
            for itemID in dropIDList:  
 | 
                if prizeMultiple > 1:  
 | 
                    itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  
 | 
                    if not itemData:  
 | 
                        continue  
 | 
                    itemPlace = itemData.GetEquipPlace()  
 | 
                    itemKey = itemIDKeyDict.get(itemID)  
 | 
                      
 | 
                    # ³¬¹ýÖ¸¶¨×î´óÖ»Êýʱ£¬´ú±í¶à±¶½±Àø£¬¶à±¶½±ÀøµÄÎïÆ·Ö»ÔÊÐí¸øÖ¸¶¨¹æÔòÄÚµÄÎïÆ·£¬Ö»¶ÔÒѾµô¹ýµÄÎïÆ·ÓÐÏÞÖÆ  
 | 
                    if dCount > count:  
 | 
                        if ItemCommon.GetIsEquip(itemData):  
 | 
                            if itemPlace in hadDropItemPlaceList and itemPlace not in mPrizePlaceList:  
 | 
                                GameWorld.DebugLog("    ¶à±¶½±Àø²»ÄܸøµÄÎïÆ·²¿Î»: itemID=%s,itemPlace=%s" % (itemID, itemPlace))  
 | 
                                continue  
 | 
                        elif itemKey != None:  
 | 
                            if itemKey in hadDropItemKeyList and itemKey not in mPrizeItemKeyList:  
 | 
                                GameWorld.DebugLog("    ¶à±¶½±Àø²»ÄܸøµÄÎïÆ·ID¼¯ºÏ: itemID=%s,itemKey=%s" % (itemID, itemKey))  
 | 
                                continue  
 | 
                        else:  
 | 
                            if itemID in itemCountDict and itemID not in mPrizeItemIDList:  
 | 
                                GameWorld.DebugLog("    ¶à±¶½±Àø²»ÄܸøµÄÎïÆ·ID: itemID=%s" % (itemID))  
 | 
                                continue  
 | 
                              
 | 
                    if itemPlace and itemPlace not in hadDropItemPlaceList:  
 | 
                        hadDropItemPlaceList.append(itemPlace)  
 | 
                    if itemKey != None and itemKey not in hadDropItemKeyList:  
 | 
                        hadDropItemKeyList.append(itemKey)  
 | 
                          
 | 
                itemCountDict[itemID] = itemCountDict.get(itemID, 0) + 1  
 | 
                if itemID in auctionIDList and itemID not in auctionItemIDList:  
 | 
                    auctionItemIDList.append(itemID)  
 | 
                  
 | 
    # ¹Ì¶¨¸½¼ÓÎïÆ·  
 | 
    for itemID, itemCount, isAuctionItem in extraItemList:  
 | 
        itemCountDict[itemID] = itemCountDict.get(itemID, 0) + itemCount * prizeMultiple  
 | 
        if isAuctionItem and itemID not in auctionItemIDList:  
 | 
            auctionItemIDList.append(itemID)  
 | 
          
 | 
    needSpace = 0  
 | 
    prizeItemList = []  
 | 
    jsonItemList = []  
 | 
    for itemID, itemCount in itemCountDict.items():  
 | 
        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  
 | 
        if not itemData:  
 | 
            continue  
 | 
          
 | 
        isAuctionItem = itemID in auctionItemIDList  
 | 
          
 | 
        if ItemCommon.GetIsEquip(itemData):  
 | 
            for _ in xrange(itemCount):  
 | 
                curItem = ItemControler.GetOutPutItemObj(itemID, 1, isAuctionItem, curPlayer=curPlayer)  
 | 
                if curItem:  
 | 
                    needSpace += 1  
 | 
                    prizeItemList.append(curItem)  
 | 
                    jsonItemList.append(ItemCommon.GetJsonItem(curItem))  
 | 
        else:  
 | 
            needSpace += ItemControler.GetItemNeedPackCount(IPY_GameWorld.rptItem, itemData, itemCount, isAuctionItem)  
 | 
            prizeItemList.append([itemID, itemCount, isAuctionItem])  
 | 
            jsonItemList.append(ItemCommon.GetJsonItem([itemID, itemCount, isAuctionItem]))  
 | 
        #³É¾Í  
 | 
        if not dropItemMapInfo:  
 | 
            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_PickUpItem, itemCount, [itemID])  
 | 
          
 | 
    ## Ö±½ÓµôµØ°åÉÏ  
 | 
    if dropItemMapInfo:  
 | 
        dropPosX, dropPosY = dropItemMapInfo[:2]  
 | 
        isOnlySelfSee = dropItemMapInfo[2] if len(dropItemMapInfo) > 2 else False # ÊÇ·ñ½ö×Ô¼º¿É¼û  
 | 
        isDropDisperse = dropItemMapInfo[3] if len(dropItemMapInfo) > 3 else False # ¶ÑµþµÄÎïÆ·ÊÇ·ñÉ¢¿ªµôÂä  
 | 
        ## ÐéÄâµôÂä±íÏÖ      
 | 
        if isVirtualDrop:  
 | 
            DoGiveItemByVirtualDrop(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse, mailTypeKey)  
 | 
        else:  
 | 
            DoMapDropPrizeItem(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse, isOnlySelfSee)  
 | 
              
 | 
    ## ·¢Óʼþ »ò ±³°ü¿Õ¼ä²»×ã  
 | 
    elif isMail or needSpace > ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace):  
 | 
        mailItemList = []  
 | 
        for prizeItem in prizeItemList:  
 | 
            if isinstance(prizeItem, list):  
 | 
                mailItemList.append(prizeItem)  
 | 
            else:  
 | 
                mailItemList.append(ItemCommon.GetMailItemDict(prizeItem))  
 | 
                prizeItem.Clear() # ·¢ÓʼþÒѾ´´½¨µÄÎïÆ·ÊµÀýÒªÇå¿Õ, ²»È»»áµ¼ÖÂÄÚ´æÐ¹Â¶  
 | 
        #if totalExp:  
 | 
        #    expItemID = 0  
 | 
        #    mailItemList.append([expItemID, totalExp, 1])  
 | 
        PlayerControl.SendMailByKey(mailTypeKey, [curPlayer.GetPlayerID()], mailItemList, silver=totalMoney)  
 | 
          
 | 
    ## Ö±½Ó·ÅÈë±³°ü  
 | 
    else:  
 | 
        event = [ChConfig.ItemGive_NPCDrop, False, {"NPCID":npcID}]  
 | 
        for prizeItem in prizeItemList:  
 | 
            if isinstance(prizeItem, list):  
 | 
                itemID, itemCount, isAuctionItem = prizeItem  
 | 
                ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem],   
 | 
                                             event=event)  
 | 
            else:  
 | 
                ItemControler.DoLogic_PutItemInPack(curPlayer, prizeItem, event=event)  
 | 
                  
 | 
        if totalExp:  
 | 
            PlayerControl.PlayerControl(curPlayer).AddExp(totalExp)  
 | 
              
 | 
        if totalMoney:  
 | 
            PlayerControl.GiveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, totalMoney)  
 | 
              
 | 
    #GameWorld.DebugLog("¸øÍæ¼Ò»÷ɱNPCµôÂä½±Àø:  mapID=%s,npcCountDict=%s,exp_rate=%s,mailTypeKey=%s,isMail=%s,extraItemList=%s"   
 | 
    #                   % (mapID, npcCountDict, exp_rate, mailTypeKey, isMail, extraItemList))  
 | 
    #GameWorld.DebugLog("    totalExp=%s,totalMoney=%s,needSpace=%s,jsonItemList=%s" % (totalExp, totalMoney, needSpace, jsonItemList))  
 | 
    return jsonItemList, totalExp, totalMoney  
 | 
  
 | 
def DoMapDropPrizeItem(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse=True, isOnlySelfSee=True):  
 | 
    ## ½±ÀøÎïÆ·ÕæÊµµôÂäµØÍ¼£¬ÏȲ𿪷ÖÉ¢ÔÙµôÂä  
 | 
      
 | 
    if isDropDisperse:  
 | 
        dropItemList = []  
 | 
        for itemInfo in prizeItemList:  
 | 
            if isinstance(itemInfo, list):  
 | 
                itemID, itemCount, isAuctionItem = itemInfo  
 | 
                for _ in xrange(itemCount):  
 | 
                    dropItemList.append([itemID, 1, isAuctionItem])  
 | 
            else:  
 | 
                dropItemList.append(itemInfo)  
 | 
    else:  
 | 
        dropItemList = prizeItemList  
 | 
    index = 0  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    gameMap = GameWorld.GetMap()  
 | 
    for posX, posY in ChConfig.Def_DropItemAreaMatrix:  
 | 
        resultX = dropPosX + posX  
 | 
        resultY = dropPosY + posY  
 | 
          
 | 
        if not gameMap.CanMove(resultX, resultY):  
 | 
            #Íæ¼Ò²»¿ÉÒÆ¶¯Õâ¸öµã  
 | 
            continue  
 | 
          
 | 
        if index > len(dropItemList) - 1:  
 | 
            break  
 | 
          
 | 
        curItem = dropItemList[index]  
 | 
        index += 1  
 | 
        if isinstance(curItem, list):  
 | 
            itemID, itemCount, isAuctionItem = curItem  
 | 
            curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer)  
 | 
              
 | 
        if not curItem:  
 | 
            continue  
 | 
          
 | 
        ChItem.AddMapDropItem(resultX, resultY, curItem, ownerInfo=[ChConfig.Def_NPCHurtTypePlayer, playerID],   
 | 
                              dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee)  
 | 
    return  
 | 
  
 | 
def DoGiveItemByVirtualDrop(curPlayer, giveItemList, npcID, dropPosX=0, dropPosY=0, isDropDisperse=True, mailTypeKey="ItemNoPickUp", extraVirtualItemList=[]):  
 | 
    ## ¸øÎïÆ·²¢ÇÒ×ö¼ÙµôÂä±íÏÖ£¬Ö±½ÓÏȶѵþ¸øÎïÆ·£¬ÔÙ²ð¿ª×öÐé¼ÙµôÂä±íÏÖ  
 | 
      
 | 
    if not giveItemList:  
 | 
        return  
 | 
      
 | 
    mapID = PlayerControl.GetCustomMapID(curPlayer)  
 | 
    lineID = PlayerControl.GetCustomLineID(curPlayer)  
 | 
    if not mapID:  
 | 
        mapID = GameWorld.GetGameWorld().GetMapID()  
 | 
          
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    giveItemObjList = []  
 | 
    virtualItemDropList = []  
 | 
    itemControl = ItemControler.PlayerItemControler(curPlayer)  
 | 
    for itemInfo in giveItemList:  
 | 
        if isinstance(itemInfo, list) or isinstance(itemInfo, tuple):  
 | 
            itemID, itemCount, isAuctionItem = itemInfo  
 | 
            curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer)  
 | 
            if not curItem:  
 | 
                continue  
 | 
        elif hasattr(itemInfo, "GetItemTypeID"):  
 | 
            curItem = itemInfo  
 | 
            itemID = curItem.GetItemTypeID()  
 | 
            itemCount = curItem.GetCount()  
 | 
            isAuctionItem = ItemControler.GetIsAuctionItem(curItem)  
 | 
        else:  
 | 
            continue  
 | 
        dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)  
 | 
        giveItemObjList.append(curItem)  
 | 
              
 | 
        # É¢¿ªµôÂä  
 | 
        if isDropDisperse:  
 | 
            for _ in xrange(itemCount):  
 | 
                virtualItemDropList.append([itemID, dropItemDataStr])  
 | 
        else:  
 | 
            virtualItemDropList.append([itemID, dropItemDataStr])  
 | 
          
 | 
    # ÏÈ֪ͨµôÂ䣬ÔÙ¸øÎïÆ·£¬ÒòΪǰ¶Ë±íÏÖµ¯¿òÐèÒªÕâ¸ö˳ÐòÐèÇó  
 | 
    if extraVirtualItemList: #Ö»ÏÔʾ¼ÙµôÂä  
 | 
        for itemInfo in extraVirtualItemList:  
 | 
            itemID, itemCount, isAuctionItem = itemInfo  
 | 
            curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer)  
 | 
            if not curItem:  
 | 
                continue  
 | 
            dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)  
 | 
            # É¢¿ªµôÂä  
 | 
            if isDropDisperse:  
 | 
                for _ in xrange(itemCount):  
 | 
                    virtualItemDropList.append([itemID, dropItemDataStr])  
 | 
            else:  
 | 
                virtualItemDropList.append([itemID, dropItemDataStr])  
 | 
            curItem.Clear()  
 | 
              
 | 
    gameMap = GameWorld.GetMap()  
 | 
    index = 0  
 | 
    for posX, posY in ChConfig.Def_DropItemAreaMatrix:  
 | 
        if dropPosX or dropPosY:  
 | 
            resultX = dropPosX + posX  
 | 
            resultY = dropPosY + posY  
 | 
            if not gameMap.CanMove(resultX, resultY):  
 | 
                #Íæ¼Ò²»¿ÉÒÆ¶¯Õâ¸öµã  
 | 
                continue  
 | 
        else:  
 | 
            resultX, resultY = 0, 0  
 | 
        if index > len(virtualItemDropList) - 1:  
 | 
            break  
 | 
        itemID, dropItemDataStr = virtualItemDropList[index]  
 | 
        index += 1  
 | 
        SendVirtualItemDrop(curPlayer, itemID, resultX, resultY, dropItemDataStr)  
 | 
          
 | 
    # ÔÙ¸øÎïÆ·  
 | 
    mailItemList = []  
 | 
    for itemObj in giveItemObjList:  
 | 
        itemID = itemObj.GetItemTypeID()  
 | 
        mailItem = ItemCommon.GetMailItemDict(itemObj)  
 | 
        equipInfo = [itemObj.GetEquipPlace(), ItemCommon.GetItemClassLV(itemObj), itemObj.GetItemColor(),   
 | 
                     itemObj.GetSuiteID(), itemObj.GetUserData()]  
 | 
        packIndex = ChConfig.GetItemPackType(itemObj.GetType())  
 | 
        if not itemControl.PutInItem(packIndex, itemObj, event=[ChConfig.ItemGive_Pickup, False, {"NPCID":npcID}]):  
 | 
            mailItemList.append(mailItem)  
 | 
              
 | 
        if npcID:  
 | 
            SendGameServerGoodItemRecord(curPlayer, mapID, lineID, npcID, itemID, equipInfo)  
 | 
           
 | 
    # ·Å²»Ïµķ¢Óʼþ     
 | 
    if mailItemList:  
 | 
        PlayerControl.SendMailByKey(mailTypeKey, [playerID], mailItemList, [mapID])  
 | 
    return  
 | 
  
 | 
################################### NPCµôÂä ###################################  
 | 
Def_NPCMaxDropRate = 1000000 # NPCµôÂäÏà¹ØµÄ×î´ó¸ÅÂÊ, ÊýÖµÉ趨  
 | 
  
 | 
def GetNPCDropIpyData(npcID):  
 | 
    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("NPCDropItem", npcID)  
 | 
    if not ipyDataList:  
 | 
        GameWorld.DebugLog("¸ÃNPCûÅäÖõôÂ䣡npcID=%s" % npcID)  
 | 
        return  
 | 
    ipyDrop = None  
 | 
    maxWorldLV = 0  
 | 
    curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)  
 | 
    if len(ipyDataList) == 1:  
 | 
        ipyDrop = ipyDataList[0]  
 | 
        maxWorldLV = ipyDrop.GetMaxWorldLV()  
 | 
        if maxWorldLV and curWorldLV > maxWorldLV:  
 | 
            GameWorld.DebugLog("¸ÃNPCµ±Ç°ÊÀ½çµÈ¼¶ÎÞ·¨µôÂäÎïÆ·!npcID=%s,curWorldLV(%s) > maxWorldLV(%s)" % (npcID, curWorldLV, maxWorldLV))  
 | 
            return  
 | 
    else:  
 | 
        for ipyData in ipyDataList:  
 | 
            maxWorldLV = ipyData.GetMaxWorldLV()  
 | 
            if curWorldLV <= maxWorldLV:  
 | 
                ipyDrop = ipyData  
 | 
                break  
 | 
        if not ipyDrop:  
 | 
            GameWorld.DebugLog("¸ÃNPCµ±Ç°ÊÀ½çµÈ¼¶ÎÞ·¨µôÂäÎïÆ·!npcID=%s,curWorldLV=%s,maxWorldLV=%s" % (npcID, curWorldLV, maxWorldLV))  
 | 
            return  
 | 
    return ipyDrop  
 | 
  
 | 
def GetNPCDropInfoTJG(dropPlayer, mapID, npcID, killCount):  
 | 
    '''ÍÑ»ú¹Òɱ¹ÖµôÂäרÓú¯Êý  
 | 
    Ö»Ëã: 1.±ýͼװ±¸µôÂä + 2.Ö¸¶¨ÎïÆ·IDµôÂä + 3.½ð±ÒµôÂä  
 | 
    '''  
 | 
    ipyDrop = GetNPCDropIpyData(npcID)  
 | 
    if not ipyDrop:  
 | 
        return  
 | 
      
 | 
    playerLV = dropPlayer.GetLV()  
 | 
    maxDropLV = ipyDrop.GetMaxDropLV()  
 | 
    if maxDropLV and playerLV > maxDropLV:  
 | 
        GameWorld.DebugLog("³¬¹ý×î´ó¿ÉµôÂäµÈ¼¶£¬²»µôÂäÎïÆ·£¡npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))  
 | 
        return  
 | 
      
 | 
    playerID = dropPlayer.GetPlayerID()  
 | 
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)  
 | 
    if not npcData:  
 | 
        return  
 | 
      
 | 
    dropIDList = [] # µôÂäµÄIDÁÐ±í  
 | 
    itemJobList = [dropPlayer.GetJob()] if ipyDrop.GetIsDropJobSelf() else IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # µôÂä×°±¸Ö°ÒµÁÐ±í  
 | 
      
 | 
    equipDropRatePlus = PlayerControl.GetDropEquipPer(dropPlayer)  
 | 
    equipDropDoCountPlus = PlayerControl.GetDropEquipDoCount(dropPlayer)  
 | 
      
 | 
    dropRatePlusValue = ipyDrop.GetCanDropRatePlus()  
 | 
    if not dropRatePlusValue & pow(2, 0):  
 | 
        equipDropRatePlus = 0  
 | 
          
 | 
    if not dropRatePlusValue & pow(2, 1):  
 | 
        equipDropDoCountPlus = 0  
 | 
          
 | 
    doCountAdd = 0  
 | 
    doCountRate = ChConfig.Def_MaxRateValue  
 | 
      
 | 
    GameWorld.DebugLog("ÍÑ»ú¹Òɱ¹ÖµôÂä: npcID=%s,killCount=%s,itemJobList=%s,dropRatePlusValue=%s,equipDropRatePlus=%s,equipDropDoCountPlus=%s"   
 | 
                       % (npcID, killCount, itemJobList, dropRatePlusValue, equipDropRatePlus, equipDropDoCountPlus), playerID)  
 | 
      
 | 
    dropEquipInfoList = [] # [(½×,ÑÕÉ«, ¼þÊý), ...]  
 | 
    # 1.×°±¸Ö»Ëã±ýͼ¸ÅÂÊ  
 | 
    pieRateDoCnt = ipyDrop.GetPieRateDoCnt()  
 | 
    if pieRateDoCnt and ipyDrop.GetPieRateDrop():  
 | 
        pieRateDoCnt = __GetNPCDropDoCountChange(pieRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd)  
 | 
        pieRateDoCnt *= killCount  
 | 
        pieRateDropList = ipyDrop.GetPieRateDrop() # [(¸ÅÂÊ,0),(¸ÅÂÊ,(½×,ÑÕÉ«)),...]  
 | 
        if equipDropRatePlus:  
 | 
            dropRateList = GameWorld.GetPlusPieList(pieRateDropList, equipDropRatePlus)  
 | 
            GameWorld.DebugLog("    ×°±¸ÅäÖñýͼ: %s,equipDropRatePlus=%s" % (pieRateDropList, equipDropRatePlus), playerID)  
 | 
        else:  
 | 
            dropRateList = pieRateDropList  
 | 
        preRate = 0  
 | 
        maxRate = dropRateList[-1][0]  
 | 
        GameWorld.DebugLog("    ×°±¸µôÂä±ýͼ: %s,maxRate=%s" % (dropRateList, maxRate), playerID)  
 | 
        for rateInfo in dropRateList:  
 | 
            rate, equipInfo = rateInfo  
 | 
            curRate = rate - preRate  
 | 
            if not curRate:  
 | 
                break  
 | 
            preRate = rate  
 | 
            if not equipInfo:  
 | 
                continue  
 | 
            classLV, color = equipInfo  
 | 
            totalRate = curRate * pieRateDoCnt # ×ܸÅÂÊ  
 | 
            dropCount = totalRate / maxRate # ¿ÉµôÂä¼þÊý  
 | 
            rateEx = totalRate % maxRate # Ê£Óà¸ÅÂÊ  
 | 
            if GameWorld.CanHappen(rateEx, maxRate):  
 | 
                dropCount += 1  
 | 
            GameWorld.DebugLog("    ×°±¸µôÂÊ: curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,classLV=%s,color=%s"   
 | 
                               % (curRate, totalRate, rateEx, dropCount, classLV, color), playerID)  
 | 
            if not dropCount:  
 | 
                continue  
 | 
            dropEquipInfoList.append([classLV, color, dropCount])  
 | 
        GameWorld.DebugLog("    ×°±¸µôÂä½á¹û: killCount=%s,[½×,ÑÕÉ«,¼þÊý]=%s" % (killCount, dropEquipInfoList), playerID)  
 | 
          
 | 
    colorSuitRateDict = ipyDrop.GetEquipColorSuitInfo() # ×°±¸ÑÕÉ«¶ÔÓ¦Ì××°¸ÅÂÊ {ÑÕÉ«:Ì××°¸ÅÂÊ, ...}  
 | 
    colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # ×°±¸²¿Î»¼¯ºÏÐÅÏ¢ {(ÑÕÉ«,ÊÇ·ñÌ××°):²¿Î»¼¯ºÏkey, ...}  
 | 
    dropEquipIDDict = {}  
 | 
    for classLV, color, dropCount in dropEquipInfoList:  
 | 
        suitCountDict = {} # {Ì××°:¼þÊý, ...}  
 | 
        if color in colorSuitRateDict:  
 | 
            suitRate = colorSuitRateDict[color]  
 | 
            for _ in xrange(dropCount):  
 | 
                isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate)  
 | 
                suitCountDict[isSuit] = suitCountDict.get(isSuit, 0) + 1  
 | 
        else:  
 | 
            suitCountDict[0] = dropCount  
 | 
              
 | 
        for isSuit, curDropCount in suitCountDict.items():  
 | 
            colorSuitKey = (color, isSuit)  
 | 
            if colorSuitKey not in colorSuitPlaceKeyInfoDict:  
 | 
                GameWorld.ErrLog("δÅäÖÃÑÕÉ«ÊÇ·ñÌ××°¶ÔÓ¦²¿Î»¼¯ºÏkey! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit))  
 | 
                continue  
 | 
            placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey]  
 | 
            placeList = GetEquipPlaceByPlaceKey(placeKey)  
 | 
            if not placeList:  
 | 
                GameWorld.ErrLog("²¿Î»¼¯ºÏkey²»´æÔÚ!npcID=%s,placeKey=%s" % (npcID, placeKey))  
 | 
                continue  
 | 
            randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, itemJobList)  
 | 
            if not randEquipIDList:  
 | 
                continue  
 | 
            for _ in xrange(curDropCount):  
 | 
                randItemID = random.choice(randEquipIDList)  
 | 
                dropIDList.append(randItemID)  
 | 
                dropEquipIDDict[randItemID] = [color, placeKey]  
 | 
                GameWorld.DebugLog("    µôÂä×°±¸: npcID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,itemJobList=%s,randEquipIDList=%s"   
 | 
                                   % (npcID, randItemID, classLV, color, isSuit, placeKey, itemJobList, randEquipIDList), playerID)  
 | 
                  
 | 
    # 2. Ö¸¶¨ÎïÆ·ID¿â  
 | 
    itemIDDropRateDict = ipyDrop.GetItemIDDropRate() # {ÎïÆ·ID:¸ÅÂÊ, ...}  
 | 
    itemIDDropMaxCntDict = ipyDrop.GetItemIDMaxDropCount() # {ÎïÆ·ID:×î´óµôÂä¸öÊý,...}  
 | 
    for itemID, dropRate in itemIDDropRateDict.items():  
 | 
          
 | 
        if not dropRate:  
 | 
            continue  
 | 
          
 | 
        doCnt = itemIDDropMaxCntDict.get(itemID, 1) # Ä¬ÈÏ1¸ö  
 | 
        doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd)  
 | 
        doCnt *= killCount  
 | 
          
 | 
        totalRate = dropRate * doCnt  
 | 
        dropCount = totalRate / Def_NPCMaxDropRate # ¿ÉµôÂä¼þÊý  
 | 
        rateEx = totalRate % Def_NPCMaxDropRate # Ê£Óà¸ÅÂÊ  
 | 
        if GameWorld.CanHappen(rateEx, Def_NPCMaxDropRate):  
 | 
            dropCount += 1  
 | 
        dropIDList += [itemID] * dropCount  
 | 
        GameWorld.DebugLog("    Ö¸¶¨ÎïÆ·µôÂä: itemID=%s,dropRate=%s,doCnt=%s,totalRate=%s,dropCount=%s"   
 | 
                           % (itemID, dropRate, doCnt, totalRate, dropCount), playerID)  
 | 
      
 | 
    # ¼ì²éµôÂ以³âID×é  
 | 
    dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1))  
 | 
      
 | 
    # µôÂä½ð±Ò  
 | 
    dropMoneyDoCnt = ipyDrop.GetDropMoneyDoCnt()  
 | 
    dropMoneyRate = ipyDrop.GetDropMoneyRate()  
 | 
    moneyTotalRate = dropMoneyRate * dropMoneyDoCnt * killCount  
 | 
    dropMoneyCnt = moneyTotalRate / ChConfig.Def_NPCMapDropRate  
 | 
    if GameWorld.CanHappen(moneyTotalRate % ChConfig.Def_NPCMapDropRate, ChConfig.Def_NPCMapDropRate):  
 | 
        dropMoneyCnt += 1  
 | 
    dropMoney = 0  
 | 
    if dropMoneyCnt:  
 | 
        dropMoney = __GetDropMoneyValue(dropPlayer, ipyDrop) * dropMoneyCnt  
 | 
        GameWorld.DebugLog("    ½ð±ÒµôÂÊ: dropMoneyRate=%s,moneyTotalRate=%s,dropMoneyCnt=%s,dropMoney=%s"   
 | 
                           % (dropMoneyRate, moneyTotalRate, dropMoneyCnt, dropMoney), playerID)  
 | 
    dropIDCountDict = {}  
 | 
    for dropID in dropIDList:  
 | 
        dropIDCountDict[dropID] = dropIDCountDict.get(dropID, 0) + 1  
 | 
          
 | 
    # ¼¯×ÖµôÂä  
 | 
    dropWordsCountDict = PlayerActCollectWords.OnGetDropWordsItemDict(dropPlayer, npcData, killCount)  
 | 
    for dropID, dropCount in dropWordsCountDict.items():  
 | 
        dropIDCountDict[dropID] = dropIDCountDict.get(dropID, 0) + dropCount  
 | 
          
 | 
    auctionIDList = []  
 | 
    if ipyDrop.GetAucionItemCanSell():  
 | 
        for dropID in dropIDCountDict.keys():  
 | 
            if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropID):  
 | 
                auctionIDList.append(dropID)  
 | 
                  
 | 
    if dropIDCountDict:  
 | 
        GameWorld.DebugLog("    ×îÖÕµôÂä: npcID=%s,killCount=%s,dropIDCountDict=%s,auctionIDList=%s,dropMoney=%s"   
 | 
                           % (npcID, killCount, dropIDCountDict, auctionIDList, dropMoney), playerID)  
 | 
    return dropIDCountDict, auctionIDList, dropMoney  
 | 
  
 | 
def GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList=[], ipyDrop=None, isSingle=True, isKillCountDrop=True, curGrade=0):  
 | 
    '''»ñÈ¡NPCµôÂäÐÅÏ¢, »÷ɱ¼°É¨µ´Í¨Ó㬵÷Óøú¯Êý»ñµÃµôÂäÐÅÏ¢£¬È»ºóÔÙ¿´µôÂ䵨°åÉÏ»¹ÊÇÖ±½Ó·ÅÈë±³°ü  
 | 
        @param dropPlayer: ÓÃÓÚÅжϵ÷ÓÃÏà¹ØÓõÄÍæ¼ÒʾÀý£¬¸ÃÍæ¼Ò²¢²»Ò»¶¨ÊÇ»÷ɱÕߣ¬Ö»Êǰ´Ò»¶¨¹æÔòÉ趨µÄµôÂäÅжÏÒÀ¾ÝµÄÍæ¼Ò  
 | 
                            Èç¶ÓÎ飬ȡµÈ¼¶×î´óµÄÍæ¼Ò£¬¸ÃÍæ¼Ò²¢²»Ò»¶¨ÊÇ»÷ɱÕß  
 | 
        @param mapID: µôÂäÎïÆ·ËùÊôµØÍ¼£¬×¢Òâ´ËµØÍ¼²¢²»Ò»¶¨Êǵ±Ç°µØÍ¼£¬Èçɨµ´Ê±ÐèʹÓÃÄ¿±ê¸±±¾µØÍ¼  
 | 
        @param npcID: µôÂäÎïÆ·µÄNPCID  
 | 
        @param ownerPlayerList: ÓйéÊôµÄÍæ¼ÒÁÐ±í  
 | 
        @param isSingle: ÊÇ·ñÖ»´¦Àíµ¥¶ÀÍæ¼ÒµôÂäÂß¼£¬Ò»°ã¶¼Ä¬ÈÏTrue£¬Ä¿Ç°Ö»Óг¡¾°É±¹ÖµôÂäÐèÒª¿¼ÂÇÃþ¹ÖµÄÇé¿öϲÅΪFalse£¨Íâ²ãÌØÊâ´¦Àí£©  
 | 
        @return: dropIDList, auctionIDList, dropMoneyCnt, moneyValue  
 | 
                None-ûÓеôÂä  
 | 
                ---------------  
 | 
                dropIDList        -    µôÂäµÄÎïÆ·IDÁбí, Í¬¸öitemID¿ÉÄÜÔÚÁбíÖÐÓжà¸ö [itemID, itemID, ...]  
 | 
                auctionIDList    -    µôÂäµÄÅÄÆ·ÎïÆ·IDÁбí, [itemID, itemID, ...]  
 | 
                dropMoneyCnt      -    µôÂä½ð±ÒλÖÃÊý  
 | 
                moneyValue        -    Ã¿¸öλÖõĽð±ÒÊýÁ¿  
 | 
    '''  
 | 
    if not ipyDrop:  
 | 
        ipyDrop = GetNPCDropIpyData(npcID)  
 | 
        if not ipyDrop:  
 | 
            return  
 | 
          
 | 
    if not ownerPlayerList:  
 | 
        ownerPlayerList = [dropPlayer]  
 | 
          
 | 
    playerID = dropPlayer.GetPlayerID()  
 | 
    playerLV = dropPlayer.GetLV()  
 | 
    maxDropLV = ipyDrop.GetMaxDropLV()  
 | 
    if maxDropLV and playerLV > maxDropLV:  
 | 
        GameWorld.DebugLog("³¬¹ý×î´ó¿ÉµôÂäµÈ¼¶£¬²»µôÂäÎïÆ·£¡npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))  
 | 
        return  
 | 
      
 | 
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)  
 | 
    if not npcData:  
 | 
        GameWorld.ErrLog("»ñÈ¡NPCµôÂäÅäÖôíÎó!±í²»´æÔÚ¸ÃNPCID=%s" % npcID, playerID)  
 | 
        return  
 | 
      
 | 
    curGrade = curGrade if curGrade else GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)  
 | 
      
 | 
    dropIDList = [] # µôÂäµÄIDÁÐ±í  
 | 
    auctionIDList = []  
 | 
    dropMoneyCnt, moneyValue = 0, 0  
 | 
    itemJobList = [dropPlayer.GetJob()] if ipyDrop.GetIsDropJobSelf() else IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # µôÂä×°±¸Ö°ÒµÁÐ±í  
 | 
                      
 | 
    # Í¨ÓõôÂÊÏà¹Ø  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    doCountAdd = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_DropDoCountAdd)  
 | 
    doCountRate = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_DropDoCountRate) # Ö±½Ó¸²¸Ç»ùÖµ, ÎÞֵʱȡĬÈÏÖµ  
 | 
    if not doCountRate:  
 | 
        doCountRate = ChConfig.Def_MaxRateValue  
 | 
          
 | 
    # ¹éÊôÕßÏà¹ØÐÅÏ¢  
 | 
    tagJob = 0  
 | 
    dropEquipKillCountPub = 0 # ×°±¸¸½¼ÓµôÂä×ۺϻ÷ɱ´ÎÊý£¬È¡´ÎÊý×î´óµÄÄǸö£¬ÖÁÉÙµÚÒ»´Î  
 | 
    dropItemIDKillCountPub = 0 # ÎïÆ·ID¸½¼ÓµôÂä×ۺϻ÷ɱ´ÎÊý£¬È¡´ÎÊý×î´óµÄÄǸö£¬ÖÁÉÙµÚÒ»´Î  
 | 
    equipDropRatePlus = 0 # ×°±¸µôÂä¸ÅÂÊÌáÉý  
 | 
    equipDropDoCountPlus = 0 # ×°±¸µôÂäÖ´ÐдÎÊýÌáÉý  
 | 
    for ownerPlayer in ownerPlayerList:  
 | 
        killCountValue = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID)  
 | 
        equipPubKillCount = killCountValue % 100 + 1  
 | 
        itemIDPubKillCount = killCountValue % 10000 / 100 + 1  
 | 
          
 | 
        if dropEquipKillCountPub < equipPubKillCount:  
 | 
            dropEquipKillCountPub = equipPubKillCount  
 | 
            tagJob = ownerPlayer.GetJob()  
 | 
              
 | 
        if dropItemIDKillCountPub < itemIDPubKillCount:  
 | 
            dropItemIDKillCountPub = itemIDPubKillCount  
 | 
              
 | 
        equipDropRatePlus = max(equipDropRatePlus, PlayerControl.GetDropEquipPer(ownerPlayer))  
 | 
        equipDropDoCountPlus = max(equipDropDoCountPlus, PlayerControl.GetDropEquipDoCount(ownerPlayer))  
 | 
          
 | 
    dropRatePlusValue = ipyDrop.GetCanDropRatePlus()  
 | 
    if not dropRatePlusValue & pow(2, 0):  
 | 
        equipDropRatePlus = 0  
 | 
          
 | 
    if not dropRatePlusValue & pow(2, 1):  
 | 
        equipDropDoCountPlus = 0  
 | 
          
 | 
    #GameWorld.DebugLog("NPCµôÂä: npcID=%s,itemJobList=%s,dropRatePlusValue=%s,equipDropRatePlus=%s,equipDropDoCountPlus=%s,doCountRate=%s,doCountAdd=%s"   
 | 
    #                   % (npcID, itemJobList, dropRatePlusValue, equipDropRatePlus, equipDropDoCountPlus, doCountRate, doCountAdd), playerID)  
 | 
      
 | 
    dropEquipInfoList = [] # [(½×,ÑÕÉ«), ...]  
 | 
    # 1. ×°±¸¿â - ±ýͼ¸ÅÂÊ  
 | 
    pieRateDoCnt = ipyDrop.GetPieRateDoCnt()  
 | 
    if pieRateDoCnt:  
 | 
        pieRateDoCnt = __GetNPCDropDoCountChange(pieRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd)  
 | 
        dropEquipInfoList += __GetNPCPieRateEquipDrop(ipyDrop, pieRateDoCnt, equipDropRatePlus)  
 | 
          
 | 
    # 2. ×°±¸¿â -  ¶ÀÁ¢¸ÅÂÊ  
 | 
    indepRateDoCnt = ipyDrop.GetIndepRateDoCnt()  
 | 
    if indepRateDoCnt:  
 | 
        indepRateDoCnt = __GetNPCDropDoCountChange(indepRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd)  
 | 
        dropEquipInfoList += __GetNPCIndepRateEquipDrop(mapID, ipyDrop, indepRateDoCnt, equipDropRatePlus, curGrade)      
 | 
    #GameWorld.DebugLog("½×,ÑÕÉ« key,dropEquipInfoList=%s" % (dropEquipInfoList))  
 | 
      
 | 
    # 3. µÚx´Î»÷ɱ£¬ ¹éÊôÕß¹«¹²¸½¼ÓµôÂ䣬ËùÓйéÊôÕß¶¼Ôö¼Ó»÷ɱ´ÎÊý£»   
 | 
    tagClassLV, tagColor, tagIsSuit, tagPlaceKey = 0, 0, 0, 0  
 | 
    killCountDropEquipPub = ipyDrop.GetKillCountDropEquipPub() # µÚx´Î»÷ɱ¸½¼Ó±Øµô×°±¸ {´ÎÊý:[½×,ÑÕÉ«,ÊÇ·ñÌ××°,²¿Î»¼¯ºÏkey], ...}  
 | 
    killCountDropItemPub = ipyDrop.GetKillCountDropPub() # »÷ɱ´ÎÊý±Øµô£¨¹«¹²£©{»÷ɱ´ÎÊý:[[ÎïÆ·ID, ...], [Ëæ»úÎïÆ·ID, ...]], ...}  
 | 
    maxRecordDropEquipKillCountPub = 0 if not killCountDropEquipPub else max(killCountDropEquipPub) # ÐèÒª¼Ç¼µÄ×î´ó»÷ɱ´ÎÊý, ³¬¹ý´Ë»÷ɱ´ÎÊýºóÔÝʱ²»ÀۼӼǼ  
 | 
    maxRecordDropItemIDKillCountPub = 0 if not killCountDropItemPub else max(killCountDropItemPub)  
 | 
    #GameWorld.DebugLog("maxRecordDropEquipKillCountPub=%s,maxRecordDropItemIDKillCountPub=%s" % (maxRecordDropEquipKillCountPub, maxRecordDropItemIDKillCountPub))  
 | 
    #GameWorld.DebugLog("dropEquipKillCountPub=%s,dropItemIDKillCountPub=%s" % (dropEquipKillCountPub, dropItemIDKillCountPub))  
 | 
    if isKillCountDrop and killCountDropEquipPub and dropEquipKillCountPub in killCountDropEquipPub:  
 | 
        tagClassLV, tagColor, tagIsSuit, tagPlaceKey = killCountDropEquipPub[dropEquipKillCountPub]  
 | 
        if (tagClassLV, tagColor) not in dropEquipInfoList:  
 | 
            dropEquipInfoList.insert(0, (tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob))  
 | 
        else:  
 | 
            tagIndex = dropEquipInfoList.index((tagClassLV, tagColor))  
 | 
            dropEquipInfoList[tagIndex] = (tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob)  
 | 
        GameWorld.DebugLog("µÚ%s´Î»÷ɱµôÂäÖ¸¶¨Ä¿±ê×°±¸ÐÅÏ¢: npcID=%s,tagClassLV=%s,tagColor=%s,tagIsSuit=%s,tagPlaceKey=%s,tagJob=%s,dropEquipInfoList=%s"   
 | 
                           % (dropEquipKillCountPub, npcID, tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob, dropEquipInfoList), playerID)  
 | 
    elif isKillCountDrop and killCountDropItemPub and dropItemIDKillCountPub in killCountDropItemPub:  
 | 
        killCountItemIDList, killCountRandItemIDList = killCountDropItemPub[dropItemIDKillCountPub]  
 | 
        if killCountItemIDList:  
 | 
            dropIDList += killCountItemIDList  
 | 
        if killCountRandItemIDList:  
 | 
            klllCountRandItemID = random.choice(killCountRandItemIDList)  
 | 
            dropIDList.append(klllCountRandItemID)  
 | 
        GameWorld.DebugLog("µÚ%s´Î»÷ɱµôÂäÖ¸¶¨Ä¿±êÎïÆ·ÐÅÏ¢: npcID=%s,killCountItemIDList=%s,killCountRandItemIDList=%s,dropIDList=%s"   
 | 
                           % (dropItemIDKillCountPub, npcID, killCountItemIDList, killCountRandItemIDList, dropIDList), playerID)  
 | 
              
 | 
    for ownerPlayer in ownerPlayerList:  
 | 
        # Ôö¼Ó»÷ɱ´ÎÊý  
 | 
        killCountValue = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID)  
 | 
        equipPubKillCount = killCountValue % 100  
 | 
        itemIDPubKillCount = killCountValue % 10000 / 100  
 | 
        isUpd = False  
 | 
        if equipPubKillCount < maxRecordDropEquipKillCountPub:  
 | 
            equipPubKillCount += 1  
 | 
            isUpd = True  
 | 
        if itemIDPubKillCount < maxRecordDropItemIDKillCountPub:  
 | 
            itemIDPubKillCount += 1  
 | 
            isUpd = True  
 | 
              
 | 
        if isUpd:  
 | 
            itemIDPriKillCount = killCountValue / 10000  
 | 
            updKillCountValue = itemIDPriKillCount * 10000 + itemIDPubKillCount * 100 + equipPubKillCount  
 | 
            PlayerControl.NomalDictSetProperty(ownerPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, updKillCountValue)  
 | 
            GameWorld.DebugLog("¸üÐÂÍæ¼Ò»÷ɱ´ÎÊýÖµ: npcID=%s,killCountValue=%s,updKillCountValue=%s" % (npcID, killCountValue, updKillCountValue), ownerPlayer.GetPlayerID())  
 | 
              
 | 
    gradeColorSuitRateDict = {}  
 | 
    fbGradeColorSuitRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 2) # ÆÀ¼¶Ó°ÏìÑÕÉ«Ì××°¸ÅÂÊ {npcID:{ÑÕÉ«:[D¼¶Ó°Ïì¸ÅÂÊ, ..., S¼¶Ó°Ïì¸ÅÂÊ], ...}, ...}  
 | 
    if npcID in fbGradeColorSuitRateDict:  
 | 
        gradeColorSuitRateDict = fbGradeColorSuitRateDict[npcID]  
 | 
          
 | 
    colorDropCntDict = {} # ×°±¸ÑÕÉ«ÒѾµôÂäÊý {ÑÕÉ«:ÊýÁ¿, ...}  
 | 
    colorMaxDropCntDict = ipyDrop.GetEquipColorMaxDropCount() # {ÑÕÉ«:ÉÏÏÞÊýÁ¿,...}  
 | 
    colorSuitRateDict = ipyDrop.GetEquipColorSuitInfo() # ×°±¸ÑÕÉ«¶ÔÓ¦Ì××°¸ÅÂÊ {ÑÕÉ«:Ì××°¸ÅÂÊ, ...}  
 | 
    colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # ×°±¸²¿Î»¼¯ºÏÐÅÏ¢ {(ÑÕÉ«,ÊÇ·ñÌ××°):²¿Î»¼¯ºÏkey, ...}  
 | 
    colorSuitPartOptimization = ipyDrop.GetColorSuitPartOptimization() # ²¿Î»ÑÕÉ«ÌׯÀ·ÖÓÅÑ¡µôÂ䣬ʮλ´ú±íÑÕÉ«£¬¸öλ´ú±íÌ××°  
 | 
    optColor, optIsSuit = colorSuitPartOptimization / 10, colorSuitPartOptimization % 10  
 | 
    optPlace = None # ÓÅÑ¡²¿Î»  
 | 
      
 | 
    for dropEquipInfo in dropEquipInfoList:  
 | 
        classLV, color = dropEquipInfo[:2]  
 | 
        if color in colorMaxDropCntDict:  
 | 
            maxCount = colorMaxDropCntDict[color]  
 | 
            dropCount = colorDropCntDict.get(color, 0)  
 | 
            if dropCount >= maxCount:  
 | 
                GameWorld.DebugLog("Òѳ¬¹ý¸ÃÑÕɫװ±¸×î´óµôÂäÊý£¬²»µô£¡color=%s,maxCount=%s" % (color, maxCount), playerID)  
 | 
                continue  
 | 
              
 | 
        if len(dropEquipInfo) == 5:  
 | 
            isSuit, placeKey, tagJob = dropEquipInfo[2:]  
 | 
            jobList = [tagJob]  
 | 
        else:  
 | 
            isSuit = 0  
 | 
            if color in colorSuitRateDict:  
 | 
                suitRate = colorSuitRateDict[color]  
 | 
                # ÆÀ¼¶¶ÔÌ××°ÂʵÄÓ°Ïì  
 | 
                if color in gradeColorSuitRateDict:  
 | 
                    suitRateEffList = gradeColorSuitRateDict[color]  
 | 
                    suitRateEff = 10000 if (curGrade <= 0 or curGrade > len(suitRateEffList)) else suitRateEffList[curGrade - 1]  
 | 
                    suitRate = int(suitRate * suitRateEff / 10000.0)  
 | 
                isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate)  
 | 
            colorSuitKey = (color, isSuit)  
 | 
            if colorSuitKey not in colorSuitPlaceKeyInfoDict:  
 | 
                GameWorld.ErrLog("δÅäÖÃÑÕÉ«ÊÇ·ñÌ××°¶ÔÓ¦²¿Î»¼¯ºÏkey! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit))  
 | 
                continue  
 | 
            placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey]  
 | 
            # µôÂäÓÅÑ¡²¿Î»´¦Àí  
 | 
            if color == optColor and isSuit == optIsSuit and optPlace == None:  
 | 
                allEquipPlaceList = GetAllEquipPlaceByPlaceKey(placeKey)  
 | 
                #GameWorld.DebugLog("    ËùÓпÉÓÅÑ¡²¿Î»: %s" % allEquipPlaceList)  
 | 
                if allEquipPlaceList:  
 | 
                    optPlace = __GetOptimizationEquipPlace(dropPlayer, classLV, optColor, optIsSuit, allEquipPlaceList)  
 | 
            jobList = itemJobList  
 | 
        if optPlace > 0:  
 | 
            GameWorld.DebugLog("    ×îÖÕÓÅÑ¡²¿Î»: %s" % optPlace)  
 | 
            placeList = [optPlace]  
 | 
            jobList = [dropPlayer.GetJob()]  
 | 
            optPlace = 0 # Ö»ÓÐÒ»´ÎÐԵģ¬ÖÃΪ0  
 | 
        else:  
 | 
            placeList = GetEquipPlaceByPlaceKey(placeKey)  
 | 
            if not placeList:  
 | 
                GameWorld.ErrLog("²¿Î»¼¯ºÏkey²»´æÔÚ!npcID=%s,placeKey=%s" % (npcID, placeKey))  
 | 
                continue  
 | 
        randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, jobList)  
 | 
        if not randEquipIDList:  
 | 
            continue  
 | 
        if color in colorMaxDropCntDict:  
 | 
            colorDropCntDict[color] = dropCount + 1  
 | 
        if isSuit and len(jobList) > 1:  
 | 
            randItemID = __GetRandDropSuitEquipID(dropPlayer, randEquipIDList)  
 | 
        else:  
 | 
            randItemID = random.choice(randEquipIDList)  
 | 
        dropIDList.append(randItemID)  
 | 
        GameWorld.DebugLog("µôÂä×°±¸: npcID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,jobList=%s,randEquipIDList=%s"   
 | 
                           % (npcID, randItemID, classLV, color, isSuit, placeKey, jobList, randEquipIDList), playerID)  
 | 
          
 | 
    # 4. Ö¸¶¨ÎïÆ·ID¿â  
 | 
    dropIDList += __GetAppointDropItemIDList(dropPlayer, npcID, ipyDrop, doCountRate, doCountAdd)  
 | 
      
 | 
    # 5. Ë½ÓеôÂä  
 | 
    if isSingle:  
 | 
        # »÷ɱ´ÎÊýµôÂä  
 | 
        killCountDropInfo = ipyDrop.GetKillCountDropPri()  
 | 
        if killCountDropInfo:  
 | 
            needKillCount, killDropItemList = killCountDropInfo[:2]  
 | 
            killCountDropIDList = GetKillCountDropItemList(dropPlayer, npcID, needKillCount, killDropItemList)  
 | 
            for kDropItemID in killCountDropIDList:  
 | 
                dropIDList.append(kDropItemID) # µ¥¶ÀÍæ¼ÒµôÂä´¦ÀíµÄ£¬Ö±½Ó¼Óµ½µôÂäÁбíÀ²»¿¼ÂÇÊÇ·ñ·ÅÈë±³°ü»òµôÂäµÄÇé¿ö£¬ÓÉʹÓõŦÄÜ×ÔÐд¦Àí  
 | 
                #GameWorld.DebugLog("»÷ɱ´ÎÊýµôÂä: kDropItemID=%s,needKillCount=%s" % (kDropItemID, needKillCount))  
 | 
                  
 | 
        # ¹Ì¶¨²ú³ö£¬ËùÓеôÂä¹éÊôÕßÿÈËÒ»·Ý£¬Ä¬Èϰ󶨣¬²»Çø·ÖÖ°Òµ  
 | 
        fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3)  
 | 
        if npcID in fbGradePriItemIDDropDict:  
 | 
            gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID]  
 | 
            priDropInfoList = gradePriItemIDDropDict.get(curGrade, [])  
 | 
            priDropIDList = []  
 | 
            for priItemID, priItemCount in priDropInfoList:  
 | 
                priDropIDList += [priItemID] * priItemCount  
 | 
        else:  
 | 
            priDropIDList = ipyDrop.GetPriItemIDDrop()  
 | 
        for priDropID in priDropIDList:  
 | 
            dropIDList.append(priDropID)  
 | 
            #GameWorld.DebugLog("˽ÓÐÎïÆ·µôÂä: priDropID=%s" % priDropID)  
 | 
              
 | 
    # 6. µØÍ¼ÆÀ¼¶¶îÍâµôÂä  
 | 
    fbGradeDropItemExDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate2", 2) # µØÍ¼ÆÀ¼¶¶îÍâÎïÆ·µôÂä {"mapID":{"ÆÀ¼¶":[[ÎïÆ·ID,¸öÊý], ...], ...}}  
 | 
    if curGrade and str(mapID) in fbGradeDropItemExDict:  
 | 
        gradeItemExDict = fbGradeDropItemExDict[str(mapID)]  
 | 
        gradeItemExList = gradeItemExDict.get(str(curGrade), [])  
 | 
        #GameWorld.DebugLog("ÆÀ¼¶¶îÍâµôÂäÎïÆ·: curGrade=%s,gradeItemExList=%s" % (curGrade, gradeItemExList))  
 | 
        for gItemExID, gItemExCount in gradeItemExList:  
 | 
            dropIDList += [gItemExID] * gItemExCount  
 | 
              
 | 
    # 7.Ïà¹Ø»î¶¯µôÂä  
 | 
    feastWishDropIDList = PlayerFeastWish.GetFeastWishDropItemIDList(dropPlayer, npcData)  
 | 
    if feastWishDropIDList:  
 | 
        dropIDList.extend(feastWishDropIDList)  
 | 
          
 | 
    # ¼ì²éµôÂ以³âID×é  
 | 
    dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1))  
 | 
          
 | 
    # µôÂä½ð±Ò  
 | 
    dropMoneyDoCnt = ipyDrop.GetDropMoneyDoCnt()  
 | 
    dropMoneyRate = ipyDrop.GetDropMoneyRate()  
 | 
    if dropMoneyRate == ChConfig.Def_NPCMapDropRate:  
 | 
        dropMoneyCnt = dropMoneyDoCnt  
 | 
    else:  
 | 
        dropMoneyCnt = 0  
 | 
        for _ in xrange(dropMoneyDoCnt):  
 | 
            if GameWorld.CanHappen(dropMoneyRate, ChConfig.Def_NPCMapDropRate):  
 | 
                dropMoneyCnt += 1  
 | 
                  
 | 
    #GameWorld.DebugLog("NPCID=%s,½ð±ÒµôÂÊ: %s, Ö´ÐдÎÊý=%s, µôÂä½ð±ÒÊý=%s" % (npcID, dropMoneyRate, dropMoneyDoCnt, dropMoneyCnt))  
 | 
    if dropMoneyCnt:  
 | 
        moneyValue = __GetDropMoneyValue(dropPlayer, ipyDrop)  
 | 
        #GameWorld.DebugLog("    µôÂä½ð±Òvalue=%s" % (moneyValue))  
 | 
          
 | 
    if dropIDList:  
 | 
        if ipyDrop.GetAucionItemCanSell():  
 | 
            for dropID in dropIDList:  
 | 
                if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropID):  
 | 
                    auctionIDList.append(dropID)  
 | 
        GameWorld.DebugLog("×îÖÕµôÂäÎïÆ·: npcID=%s,dropIDList=%s" % (npcID, dropIDList), playerID)  
 | 
        GameWorld.DebugLog("    auctionIDList=%s" % (auctionIDList), playerID)  
 | 
    elif ChConfig.IsGameBoss(npcData):  
 | 
        GameWorld.ErrLog("BossûÓеôÂäÎïÆ·,NPCID=%s" % (npcID), dropPlayer.GetPlayerID())  
 | 
    return dropIDList, auctionIDList, dropMoneyCnt, moneyValue  
 | 
  
 | 
def __GetRandDropSuitEquipID(curPlayer, randEquipIDList):  
 | 
    ## »ñÈ¡Ëæ»úµôÂäµÄÌ××°ID£¬ÎªÁËÍæ¼ÒµôÂäÌåÑ飬 µ±·Ç±¾Ö°ÒµÌ×װʱ¿ÉÖÁ¶àÖØÐÂËæ»úX´Î  
 | 
    randItemID = 0  
 | 
    suitRandCountEx = IpyGameDataPY.GetFuncCfg("EquipSuitDrop", 1) + 1  
 | 
    for _ in xrange(suitRandCountEx):  
 | 
        randItemID = random.choice(randEquipIDList)  
 | 
        itemData = GameWorld.GetGameData().GetItemByTypeID(randItemID)  
 | 
        if not itemData:  
 | 
            continue  
 | 
        if ItemCommon.CheckJob(curPlayer, itemData):  
 | 
            break  
 | 
    return randItemID  
 | 
  
 | 
def GetAllEquipPlaceByPlaceKey(placeKey):  
 | 
    placeKeyRateListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 2, {}) # {¼¯ºÏÊý×Ökey1:[[¸ÅÂÊ1,²¿Î»1],...],...}  
 | 
    if placeKey in placeKeyRateListDict:  
 | 
        return [rateInfo[1] for rateInfo in placeKeyRateListDict[placeKey]]  
 | 
    placeKeyListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 1, {}) # {¼¯ºÏÊý×Ökey1:[²¿Î»1,²¿Î»2,...],...}  
 | 
    if placeKey in placeKeyListDict:  
 | 
        return placeKeyListDict[placeKey]  
 | 
    return []  
 | 
  
 | 
def GetEquipPlaceByPlaceKey(placeKey):  
 | 
    ## »ñȡװ±¸Î»¼¯ºÏ¶ÔÓ¦µÄ²¿Î»ÐÅÏ¢£¬¼¯ºÏIDÖØ¸´Ê±£¬ÓÅÏȱýͼ  
 | 
    placeList = []  
 | 
    placeKeyRateListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 2, {}) # {¼¯ºÏÊý×Ökey1:[[¸ÅÂÊ1,²¿Î»1],...],...}  
 | 
    if placeKey in placeKeyRateListDict:  
 | 
        placeRateList = placeKeyRateListDict[placeKey]  
 | 
        place = GameWorld.GetResultByRandomList(placeRateList)  
 | 
        if place:  
 | 
            placeList = [place]  
 | 
            #GameWorld.DebugLog("    µôÂ䲿λ¸ÅÂʼ¯ºÏ: placeKey=%s,placeRateList=%s,place=%s,placeList=%s" % (placeKey, placeRateList, place, placeList))  
 | 
              
 | 
    if not placeList:  
 | 
        placeKeyListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 1, {}) # {¼¯ºÏÊý×Ökey1:[²¿Î»1,²¿Î»2,...],...}  
 | 
        if placeKey in placeKeyListDict:  
 | 
            placeList = placeKeyListDict[placeKey]  
 | 
            #GameWorld.DebugLog("    µôÂ䲿λ¾ùºâ¼¯ºÏ: placeKey=%s,placeList=%s" % (placeKey, placeList))  
 | 
              
 | 
    return placeList  
 | 
  
 | 
def __GetOptimizationEquipPlace(dropPlayer, classLV, optColor, optIsSuit, optPlaceList):  
 | 
    ''' »ñÈ¡µôÂäÓÅÑ¡²¿Î»  
 | 
        ¼¸¸öĬÈϹæÔò  
 | 
    1. ÑÕÉ«´óÓÚÖ¸¶¨ÓÅÑ¡ÑÕÉ«µÄ£¬ÎÞÂÛÊÇ·ñÌ××°¶¼²»¼ÆËãÔÚÄÚ  
 | 
    2. ÑÕɫСÓÚÖ¸¶¨ÓÅÑ¡ÑÕÉ«µÄ£¬ÎÞÂÛÊÇ·ñÌ××°¶¼¼ÆËãÔÚÄÚ  
 | 
    '''  
 | 
    #GameWorld.DebugLog("´¦ÀíÓÅÑ¡²¿Î»µôÂä: classLV=%s,optColor=%s,optIsSuit=%s,optPlaceList=%s" % (classLV, optColor, optIsSuit, optPlaceList))  
 | 
    minGSPlace = None  
 | 
    minGS = None  
 | 
    equipPack = dropPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  
 | 
    for optPlace in optPlaceList:  
 | 
        ipyData = IpyGameDataPY.GetIpyGameData('EquipPlaceIndexMap', classLV, optPlace)  
 | 
        if not ipyData:  
 | 
            continue  
 | 
        equipIndex = ipyData.GetGridIndex()  
 | 
        curEquip = equipPack.GetAt(equipIndex)  
 | 
        if not curEquip or curEquip.IsEmpty():  
 | 
            #GameWorld.DebugLog("    Ã»´©×°±¸£¬Ö±½ÓĬÈÏ·µ»Ø¸Ã²¿Î»: optPlace=%s" % optPlace)  
 | 
            return optPlace  
 | 
        curColor = curEquip.GetItemColor()  
 | 
        curIsSuit = 1 if curEquip.GetSuiteID() else 0  
 | 
        if curColor > optColor:  
 | 
            # ³¬¹ýÓÅѡָ¶¨ÑÕÉ«µÄ²»Ë㣬ÎÞÂÛÊÇ·ñÓÐÌ××°  
 | 
            #GameWorld.DebugLog("    ÑÕÉ«³¬¹ýÓÅÑ¡ÑÕÉ«£¬²»Ëã¸Ã²¿Î»: optPlace=%s,curColor=%s,curIsSuit=%s" % (optPlace, curColor, curIsSuit))  
 | 
            continue  
 | 
        if curColor == optColor and curIsSuit >= optIsSuit:  
 | 
            # ÓëÓÅѡָ¶¨ÑÕÉ«Ïàͬ£¬ÇÒÂú×ãÊÇ·ñÌ××°µÄ²»Ëã  
 | 
            #GameWorld.DebugLog("    ÑÕÉ«Ì××°Âú×ãÓÅÑ¡£¬²»Ëã¸Ã²¿Î»: optPlace=%s,curColor=%s,curIsSuit=%s" % (optPlace, curColor, curIsSuit))  
 | 
            continue  
 | 
        curGS = ItemCommon.GetEquipGearScore(curEquip)  
 | 
        if minGS == None or curGS < minGS:  
 | 
            minGS = curGS  
 | 
            minGSPlace = optPlace  
 | 
              
 | 
    return minGSPlace  
 | 
  
 | 
def __GetNPCDropDoCountChange(doCount, doCountRate, doCountAdd):  
 | 
    ## »ñÈ¡µôÂäÖ´ÐдÎÊý±ä¸ü½á¹û£¬¿ÉÄÜÔö¼Ó »ò ¼õÉÙ  
 | 
    if doCountRate != ChConfig.Def_MaxRateValue:  
 | 
        doCount = max(1, int(doCount * doCountRate / 10000.0))  
 | 
    if doCountAdd:  
 | 
        doCount = max(1, doCount + doCountAdd) # Ö§³ÖÕý¸º£¬±£µ×1£¬¸ºÖµ´ýÀ©Õ¹  
 | 
    return doCount  
 | 
  
 | 
def __RemoveMutexDropID(dropIDList, mutexDropInfo):  
 | 
    ## ÒƳý»¥³âµÄµôÂäÎïÆ·£¬Ã¿×黥³âµÄID×î¶àÖ»ÄܵôÂäÒ»¸ö£¬Áбí˳ÐòΪµôÂäÓÅÏȼ¶ [[»¥³â×é1ID, ID, ...], [»¥³â×é2ID, ID, ...], ...]  
 | 
    for mutexDropList in mutexDropInfo:  
 | 
        isMutex = False  
 | 
        for mutexID in mutexDropList:  
 | 
            if mutexID not in dropIDList:  
 | 
                continue  
 | 
            if not isMutex:  
 | 
                isMutex = True  
 | 
                curDropIDCnt = dropIDList.count(mutexID)  
 | 
                # Èç¹û³¬¹ý1¸ö£¬ÔòÒÆ³ý¶àÓàµÄ£¬Ö»±£ÁôÒ»¸ö  
 | 
                if curDropIDCnt > 1:  
 | 
                    for _ in xrange(curDropIDCnt - 1):  
 | 
                        dropIDList.remove(mutexID)  
 | 
                continue  
 | 
              
 | 
            # ÒѾÊÇ»¥³âµÄÁË£¬¸ÃID²»¿ÉµôÂ䣬ȫ²¿ÒƳý  
 | 
            while mutexID in dropIDList:  
 | 
                dropIDList.remove(mutexID)  
 | 
                  
 | 
    return dropIDList  
 | 
  
 | 
def __GetAppointDropItemIDList(curPlayer, npcID, ipyDrop, doCountRate, doCountAdd):  
 | 
    ## Ö¸¶¨ÎïÆ·IDµôÂä  
 | 
      
 | 
    dropItemIDList = []  
 | 
      
 | 
    # 1. Ö°ÒµÎïÆ·ID¼¯ºÏ  
 | 
    job = curPlayer.GetJob()  
 | 
    JobItemDropSets = IpyGameDataPY.GetFuncCfg("JobItemDropSets", 1) # {ÎïÆ·ID¼¯ºÏkey:[ְҵ˳ÐòÎïÆ·IDÁбí], ...}  
 | 
    itemDropSets = IpyGameDataPY.GetFuncCfg("JobItemDropSets", 2) # {ÎïÆ·ID¼¯ºÏkey:[Ëæ»úÎïÆ·IDÁбí], ...}  
 | 
    itemDropRateSets = IpyGameDataPY.GetFuncCfg("JobItemDropSets", 3) # {ÎïÆ·ID¼¯ºÏkey:[Ëæ»úÎïÆ·ID±ýͼÁбí], ...}  
 | 
    ItemKeyMaxDropCountDict = ipyDrop.GetItemKeyMaxDropCount() # {ÎïÆ·ID¼¯ºÏkey:Ëæ»ú´ÎÊý,...}  
 | 
      
 | 
    #     1.1 Ö»µô±¾Ö°ÒµµÄ  
 | 
    ItemKeyDropRateJobDict = ipyDrop.GetItemKeyDropRateJob() # {ÎïÆ·ID¼¯ºÏkey:¸ÅÂÊ, ...}£¬ Ö»µô±¾Ö°ÒµµÄ£¬ÓÅÏȼ¶¸ß  
 | 
    if ItemKeyDropRateJobDict:  
 | 
        for jobItemKey, dropRate in ItemKeyDropRateJobDict.items():  
 | 
            if jobItemKey not in JobItemDropSets:  
 | 
                continue  
 | 
            jobItemList = JobItemDropSets[jobItemKey]  
 | 
            if len(jobItemList) < job:  
 | 
                GameWorld.ErrLog("Ö°ÒµÎïÆ·¼¯ºÏkeyûÓÐÅäÖöÔÓ¦Ö°ÒµID: npcID=%s,jobItemKey=%s,job=%s" % (npcID, jobItemKey, job))  
 | 
                continue  
 | 
            mustDropCount = dropRate / Def_NPCMaxDropRate  
 | 
            dropRate = dropRate % Def_NPCMaxDropRate # »ù´¡¸ÅÂÊ  
 | 
            canDropCount = mustDropCount  
 | 
            doCnt = ItemKeyMaxDropCountDict.get(jobItemKey, 1) # Ä¬ÈÏ1¸ö  
 | 
            doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd)  
 | 
            for _ in xrange(doCnt):  
 | 
                if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):  
 | 
                    continue  
 | 
                canDropCount += 1  
 | 
                  
 | 
            jobItemID = jobItemList[job - 1]  
 | 
            for _ in xrange(canDropCount):  
 | 
                dropItemIDList.append(jobItemID)  
 | 
                #GameWorld.DebugLog("µôÂä×ÔÉíÖ°ÒµÖ¸¶¨ÎïÆ·ID: jobItemKey=%s,jobItemID=%s" % (jobItemKey, jobItemID))  
 | 
                  
 | 
    #     1.2 Ëæ»úµôÂäÒ»¸ö  
 | 
    ItemKeyDropRateDict = ipyDrop.GetItemKeyDropRate() # {ÎïÆ·ID¼¯ºÏkey:¸ÅÂÊ, ...}£¬ Ëæ»úµôÒ»¸ö£¬ÓÅÏȼ¶µÍ  
 | 
    if ItemKeyDropRateDict:  
 | 
        for itemKey, dropRate in ItemKeyDropRateDict.items():  
 | 
            # ÔÚÖ»µô±¾Ö°ÒµÀïµÄ²»´¦Àí  
 | 
            if itemKey in ItemKeyDropRateJobDict:  
 | 
                continue  
 | 
            mustDropCount = dropRate / Def_NPCMaxDropRate  
 | 
            dropRate = dropRate % Def_NPCMaxDropRate # »ù´¡¸ÅÂÊ  
 | 
            canDropCount = mustDropCount  
 | 
            doCnt = ItemKeyMaxDropCountDict.get(itemKey, 1) # Ä¬ÈÏ1¸ö  
 | 
            doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd)  
 | 
            for _ in xrange(doCnt):  
 | 
                if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):  
 | 
                    continue  
 | 
                canDropCount += 1  
 | 
                  
 | 
            for _ in xrange(canDropCount):  
 | 
                if itemKey in itemDropRateSets:  
 | 
                    randItemRateList = itemDropRateSets[itemKey]  
 | 
                    randItemID = GameWorld.GetResultByRandomList(randItemRateList)  
 | 
                    #GameWorld.DebugLog("µôÂä±ýͼÎïÆ·ID: itemKey=%s,randItemRateList=%s,randItemID=%s" % (itemKey, randItemRateList, randItemID))  
 | 
                elif itemKey in itemDropSets:  
 | 
                    randItemList = itemDropSets[itemKey]  
 | 
                    randItemID = random.choice(randItemList)  
 | 
                    #GameWorld.DebugLog("µôÂäËæ»úÎïÆ·ID: itemKey=%s,randItemList=%s,randItemID=%s" % (itemKey, randItemList, randItemID))  
 | 
                else:  
 | 
                    continue  
 | 
                if not randItemID:  
 | 
                    continue  
 | 
                dropItemIDList.append(randItemID)  
 | 
                #GameWorld.DebugLog("µôÂäËæ»úÖ¸¶¨ÎïÆ·ID: itemKey=%s,randItemID=%s" % (itemKey, randItemID))  
 | 
                  
 | 
    # 2. Ö¸¶¨µôÂäID´¦Àí, ÊÜÈ«¾ÖÉ趨ӰÏì  
 | 
    itemIDDropRateDict = ipyDrop.GetItemIDDropRate() # {ÎïÆ·ID:¸ÅÂÊ, ...}  
 | 
    itemIDDropMaxCntDict = ipyDrop.GetItemIDMaxDropCount() # {ÎïÆ·ID:×î´óµôÂä¸öÊý,...}  
 | 
      
 | 
    # È«¾Ö²ÄÁϵôÂä¿ØÖÆ  
 | 
    globalDropCDDict = IpyGameDataPY.GetFuncCfg("GlobalDropCD", 1) # {ÎïÆ·ID:·ÖÖÓ, ...}  
 | 
    globalDropRateDict = IpyGameDataPY.GetFuncCfg("NPCGlobalDropRate", 1) # {ÎïÆ·ID:[[npcIDÁбí], "¸ÅÂʹ«Ê½"], ...}  
 | 
    gw = GameWorld.GetGameWorld()  
 | 
      
 | 
    for itemID, dropRate in itemIDDropRateDict.items():  
 | 
          
 | 
        if not dropRate:  
 | 
            continue  
 | 
          
 | 
        # ¸ù¾Ý»÷ɱ´ÎÊýÀ´µÄÁíÍâ¼ÆË㣬²»ÔÚ´ËÅÐ¶Ï  
 | 
        if itemID in globalDropRateDict:  
 | 
            continue  
 | 
          
 | 
        doCnt = itemIDDropMaxCntDict.get(itemID, 1) # Ä¬ÈÏ1¸ö  
 | 
          
 | 
        # ÅжÏÊÇ·ñÈ«¾ÖµôÂäCDÖÐ  
 | 
        if itemID in globalDropCDDict:  
 | 
            curTime = int(time.time())  
 | 
            lastDropTime = gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_LastDropTime % itemID)  
 | 
            cdTime = globalDropCDDict[itemID] * 60  
 | 
            remainTime = cdTime - (curTime - lastDropTime)  
 | 
            if remainTime > 0:  
 | 
                GameWorld.DebugLog("¸ÃÎïÆ·È«¾ÖµôÂäCDÖУ¬²»µôÂ䣡itemID=%s,cdTime=%s,curTime=%s,lastDrop=%s,remainTime=%s"   
 | 
                                   % (itemID, cdTime, curTime, lastDropTime, remainTime))  
 | 
                continue  
 | 
        else:  
 | 
            doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd)  
 | 
              
 | 
        #GameWorld.DebugLog("    Ö¸¶¨ÅжÏ: itemID=%s, dropRate=%s, doCnt=%s" % (itemID, dropRate, doCnt))  
 | 
        for _ in xrange(doCnt):  
 | 
            if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):  
 | 
                continue  
 | 
              
 | 
            dropItemIDList.append(itemID)  
 | 
            if itemID in globalDropCDDict:  
 | 
                # Í¨ÖªGameServer¼Ç¼  
 | 
                msgInfo = str([itemID, curTime])  
 | 
                GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalDropCD", msgInfo, len(msgInfo))  
 | 
                DataRecordPack.DR_GlobalDropCD(curPlayer, npcID, itemID)  
 | 
                break  
 | 
              
 | 
    # 3. Ö¸¶¨»÷ɱ´ÎÊýÈ«¾ÖµôÂÊ  
 | 
    for itemID, dropInfo in globalDropRateDict.items():  
 | 
        npcIDList, rateFormat = dropInfo  
 | 
        if npcID not in npcIDList:  
 | 
            continue  
 | 
          
 | 
        killedCnt = gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DropNPCKilledCnt % itemID)  
 | 
        dropRate = eval(FormulaControl.GetCompileFormula("KilledCntDropRate_%s" % itemID, rateFormat))  
 | 
        isDrop = GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate)  
 | 
        if isDrop:  
 | 
            dropItemIDList.append(itemID)  
 | 
            DataRecordPack.DR_GlobalDropRate(curPlayer, npcID, itemID, killedCnt, dropRate)  
 | 
              
 | 
        # Í¨ÖªGameServer¼Ç¼  
 | 
        updKilledCnt = 0 if isDrop else (killedCnt + 1)  
 | 
        msgInfo = str([itemID, updKilledCnt])  
 | 
        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalDropRate", msgInfo, len(msgInfo))  
 | 
           
 | 
    # 4. Ö¸¶¨È«·þ»÷ɱ´ÎÊý±Øµô£¬Ëã¶îÍâµôÂä  
 | 
    globalKillDropDict = IpyGameDataPY.GetFuncEvalCfg("GlobalDropCD", 2) # {NPCID:{»÷ɱ´ÎÊý:[ÊÇ·ñ±¾Ö°Òµ, {ÎïÆ·ID:¸öÊý, ...}, [[Ëæ»úÎïÆ·ID,¸öÊý], ...]]}, ...}  
 | 
    if npcID in globalKillDropDict:  
 | 
        killCountDropDict = globalKillDropDict[npcID]  
 | 
        updNPCKilledCount = min(gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_NPCKilledCount % npcID) + 1, ShareDefine.Def_UpperLimit_DWord)  
 | 
        GameWorld.Log("¸üÐÂÈ«·þ»÷ɱ´ÎÊý£ºnpcID=%s, %s" % (npcID, updNPCKilledCount))  
 | 
        # Í¨ÖªGameServer¼Ç¼  
 | 
        msgInfo = str([npcID, updNPCKilledCount])  
 | 
        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalKillCount", msgInfo, len(msgInfo))  
 | 
        if updNPCKilledCount in killCountDropDict:  
 | 
            isJobLimit, itemIDCountDict, randItemIDCountList = killCountDropDict[updNPCKilledCount]  
 | 
            for itemID, itemCount in itemIDCountDict.items():  
 | 
                if isJobLimit:  
 | 
                    itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  
 | 
                    if not itemData:  
 | 
                        continue  
 | 
                    itemJob = itemData.GetJobLimit()  
 | 
                    if itemJob and itemJob != curPlayer.GetJob():  
 | 
                        # ·Ç±¾Ö°Òµ¿ÉÓ㬲»µôÂä  
 | 
                        GameWorld.DebugLog("È«·þ»÷ɱ´ÎÊý±Øµô£¬·Ç±¾Ö°Òµ¿ÉÓ㬲»µôÂä! itemID=%s" % itemID)  
 | 
                        continue  
 | 
                dropItemIDList += [itemID] * itemCount  
 | 
                GameWorld.Log("È«·þ»÷ɱ´ÎÊý±ØµôÎïÆ·: itemID=%s,itemCount=%s" % (itemID, itemCount))  
 | 
            if randItemIDCountList:  
 | 
                if isJobLimit:  
 | 
                    randJobItemList = []  
 | 
                    for rItemID, rItemCount in randItemIDCountList:  
 | 
                        itemData = GameWorld.GetGameData().GetItemByTypeID(rItemID)  
 | 
                        if not itemData:  
 | 
                            continue  
 | 
                        itemJob = itemData.GetJobLimit()  
 | 
                        if itemJob and itemJob != curPlayer.GetJob():  
 | 
                            # ·Ç±¾Ö°Òµ¿ÉÓ㬲»µôÂä  
 | 
                            GameWorld.DebugLog("È«·þ»÷ɱ´ÎÊý±ØµôËæ»ú£¬·Ç±¾Ö°Òµ¿ÉÓ㬲»µôÂä! rItemID=%s" % rItemID)  
 | 
                            continue  
 | 
                        randJobItemList.append([rItemID, rItemCount])  
 | 
                    randItemID, randItemCount = random.choice(randJobItemList)  
 | 
                else:  
 | 
                    randItemID, randItemCount = random.choice(randItemIDCountList)  
 | 
                dropItemIDList += [randItemID] * randItemCount  
 | 
                GameWorld.Log("È«·þ»÷ɱ´ÎÊý±ØµôËæ»úÎïÆ·: randItemID=%s,randItemCount=%s" % (randItemID, randItemCount))  
 | 
                  
 | 
    return dropItemIDList  
 | 
  
 | 
def __GetEquipIDList(findID, classLV, color, isSuit, placeList, itemJobList, findType="NPC"):  
 | 
    #´æÒ»¸öÂú×ãÒªÇóµÄËùÓеÄÎïÆ·µÄÁбí È»ºó´Óµ±ÖÐËæ»úѡһ¸ö  
 | 
    #×¢£º ½×¡¢ÑÕÉ«¡¢Ì××°ID¡¢Ö°Òµ¡¢²¿Î»£¬Õâ5¸öÌõ¼þ¿ÉÈ·ÈÏΨһһ¼þ×°±¸  
 | 
      
 | 
    if not PyGameData.InitPyItem:  
 | 
        GameWorld.ErrLog("µØÍ¼»¹Î´Æô¶¯ºÃÔØÎïÆ·!")  
 | 
        return []  
 | 
      
 | 
    key = "%s_%s" % (classLV, color)  
 | 
      
 | 
    if key in PyGameData.g_filterEquipDict:  
 | 
        filterItemIDDict = PyGameData.g_filterEquipDict[key]  
 | 
    else:  
 | 
        filterItemIDDict = {}  
 | 
        gameData = GameWorld.GetGameData()  
 | 
        for itemTypeList in ChConfig.Def_PlaceEquipType.values():  
 | 
            for itemType in itemTypeList:  
 | 
                gameData.FilterItemByType(itemType)  
 | 
                for i in xrange(gameData.GetFilterItemCount()):  
 | 
                    itemData = gameData.GetFilterItem(i)  
 | 
                      
 | 
                    # NPC²»µôÂäµÄ  
 | 
                    if not itemData.GetCanNPCDrop():  
 | 
                        continue  
 | 
                      
 | 
                    if ItemCommon.GetItemClassLV(itemData) != classLV:  
 | 
                        continue  
 | 
                    if itemData.GetItemColor() != color:  
 | 
                        continue  
 | 
                    suiteID = itemData.GetSuiteID()  
 | 
                    itemJob = itemData.GetJobLimit()  
 | 
                    itemPlace = itemData.GetEquipPlace()  
 | 
                    itemID = itemData.GetItemTypeID()  
 | 
                    if itemPlace not in filterItemIDDict:  
 | 
                        filterItemIDDict[itemPlace] = []  
 | 
                    placeItemList = filterItemIDDict[itemPlace]  
 | 
                    placeItemList.append([itemJob, suiteID, itemID])  
 | 
        PyGameData.g_filterEquipDict[key] = filterItemIDDict  
 | 
        GameWorld.Log("»º´æ²ú³ö×°±¸ID: classLV_color=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict))  
 | 
          
 | 
    itemIDList = []  
 | 
    for itemPlace, placeItemList in filterItemIDDict.items():  
 | 
        if placeList and itemPlace not in placeList:  
 | 
            continue  
 | 
        for itemInfo in placeItemList:  
 | 
            itemJob, suiteID, itemID = itemInfo  
 | 
            if itemJob and itemJobList and itemJob not in itemJobList:  
 | 
                continue  
 | 
            curIsSuit = suiteID > 0  
 | 
            if curIsSuit != isSuit:  
 | 
                continue  
 | 
            itemIDList.append(itemID)  
 | 
              
 | 
    if not itemIDList:  
 | 
        GameWorld.ErrLog("ÕÒ²»µ½¿É²ú³öµÄ×°±¸ID: %sID=%s,classLV=%s,color=%s,isSuit=%s,placeList=%s,itemJobList=%s"   
 | 
                         % (findType, findID, classLV, color, isSuit, placeList, itemJobList))  
 | 
    return itemIDList  
 | 
  
 | 
def __GetNPCPieRateEquipDrop(ipyDrop, doCnt, equipDropPlus):  
 | 
    ## »ñÈ¡NPC±ýͼµôÂÊ×°±¸µôÂäÐÅÏ¢  
 | 
    dropEquipInfoList = []  
 | 
    pieRateDropList = ipyDrop.GetPieRateDrop()  # ±ýͼ¸ÅÂʵôÂäÐÅÏ¢ [(¸ÅÂÊ,0),(¸ÅÂÊ,(½×,ÑÕÉ«)),...]  
 | 
    dropRateList = pieRateDropList if not equipDropPlus else GameWorld.GetPlusPieList(pieRateDropList, equipDropPlus)  
 | 
    #GameWorld.DebugLog("µôÂä±ýͼ¸ÅÂÊ: %s, equipDropPlus=%s" % (pieRateDropList, equipDropPlus))  
 | 
    #GameWorld.DebugLog("ʵ¼Ê±ýͼ¸ÅÂÊ: %s" % (dropRateList))  
 | 
    for _ in xrange(doCnt):  
 | 
        dropInfo = GameWorld.GetResultByRandomList(dropRateList)  
 | 
        if dropInfo:  
 | 
            dropEquipInfoList.append(dropInfo)  
 | 
    #GameWorld.DebugLog("±ýͼװ±¸µôÂä½á¹û: doCnt=%s, %s" % (doCnt, dropEquipInfoList))  
 | 
    return dropEquipInfoList  
 | 
  
 | 
def __GetNPCIndepRateEquipDrop(mapID, ipyDrop, doCnt, equipDropPlus, curGrade=0):  
 | 
    ## »ñÈ¡NPC¶ÀÁ¢µôÂÊ×°±¸µôÂäÐÅÏ¢  
 | 
    npcID = ipyDrop.GetNPCID()  
 | 
    indepRateDict = ipyDrop.GetIndepRateDrop() # ¶ÀÁ¢¸ÅÂʵôÂäÐÅÏ¢ {(½×,ÑÕÉ«):¸ÅÂÊ,...}  
 | 
    #GameWorld.DebugLog("¶ÀÁ¢¸ÅÂÊ×°±¸µôÂä´¦Àí: indepRateDict=%s,equipDropPlus=%s" % (indepRateDict, equipDropPlus))  
 | 
    gradeColorRateDict = {}  
 | 
    fbGradeColorRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 1) #{npcID:{ÑÕÉ«:[D¼¶Ó°Ïì¸ÅÂÊ, ..., S¼¶Ó°Ïì¸ÅÂÊ], ...}, ...}  
 | 
    if npcID in fbGradeColorRateDict:  
 | 
        gradeColorRateDict = fbGradeColorRateDict[npcID]  
 | 
          
 | 
    orangeEquipPer = 0  
 | 
    fbGradeOrangeEquipPerDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate2", 1) # µØÍ¼ÆÀ¼¶Ó°Ïì³È×°¸ÅÂʰٷÖÂÊ {"mapID":[D¼¶Ó°Ïì¸ÅÂÊ, ..., S¼¶Ó°Ïì¸ÅÂÊ], ..}  
 | 
    if str(mapID) in fbGradeOrangeEquipPerDict and curGrade:  
 | 
        orangeEquipPerList = fbGradeOrangeEquipPerDict[str(mapID)]  
 | 
        orangeEquipPer = 0 if (curGrade <= 0 or curGrade > len(orangeEquipPerList)) else orangeEquipPerList[curGrade - 1]  
 | 
          
 | 
    #colorDropCntDict = {} # ×°±¸ÑÕÉ«ÒѾµôÂäÊý {ÑÕÉ«:ÊýÁ¿, ...}  
 | 
    dropEquipInfoList = []  
 | 
    for _ in xrange(doCnt):  
 | 
        for dropInfo, rate in indepRateDict.iteritems():  
 | 
            dropRate = rate  
 | 
            color = dropInfo[1]  
 | 
            if color in gradeColorRateDict:  
 | 
                colorRateList = gradeColorRateDict[color]  
 | 
                colorRate = 10000 if (curGrade <= 0 or curGrade > len(colorRateList)) else colorRateList[curGrade - 1]  
 | 
                dropRate = int(dropRate * colorRate / 10000.0)  
 | 
                #GameWorld.DebugLog("    ÆÀ¼¶Ó°ÏìÑÕÉ«¸ÅÂÊ: curGrade=%s,colorRate=%s,dropRate=%s" % (curGrade, colorRate, dropRate))  
 | 
                  
 | 
            if color == ChConfig.Def_Quality_Orange and orangeEquipPer:  
 | 
                dropRate = int(dropRate * orangeEquipPer / 100.0)  
 | 
                #GameWorld.DebugLog("ÆÀ¼¶³È×°µôÂʼӳÉ: orangeEquipPer=%s,dropRate=%s" % (orangeEquipPer, dropRate))  
 | 
                  
 | 
            dropRate = dropRate if not equipDropPlus else (dropRate + int(dropRate * equipDropPlus / 10000.0))  
 | 
            mustDropCount = dropRate / Def_NPCMaxDropRate  
 | 
            dropRate = dropRate % Def_NPCMaxDropRate # »ù´¡¸ÅÂÊ  
 | 
            #GameWorld.DebugLog("    dropInfo=%s,rate=%s,mustDropCount=%s,dropRate=%s" % (dropInfo, rate, mustDropCount, dropRate))  
 | 
            curDropCount = mustDropCount  
 | 
            if GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):  
 | 
                curDropCount += 1  
 | 
            if not curDropCount:  
 | 
                continue  
 | 
              
 | 
            for _ in xrange(curDropCount):  
 | 
                dropEquipInfoList.append(dropInfo)  
 | 
    #GameWorld.DebugLog("¶ÀÁ¢¸ÅÂÊ×°±¸µôÂä½á¹û: doCnt=%s, %s" % (doCnt, dropEquipInfoList))  
 | 
    return dropEquipInfoList  
 | 
  
 | 
def __GetDropMoneyValue(curPlayer, ipyDrop):  
 | 
    baseMoney = FBLogic.OnGetNPCDropMoney(curPlayer)  
 | 
    if baseMoney <= 0:  
 | 
        # »ñµÃµôÂäÊýÁ¿  
 | 
        baseMoney = random.randint(ipyDrop.GetDropMoneyMin(), ipyDrop.GetDropMoneyMax())  
 | 
      
 | 
    if baseMoney <= 0:  
 | 
        return 0  
 | 
      
 | 
    moneyValue = baseMoney  
 | 
    # Íæ¼Ò½ðÇ®µôÂä¼Ó³É  
 | 
    if curPlayer != None:  
 | 
          
 | 
        addRateEx = 0  
 | 
              
 | 
        addRate = float(curPlayer.GetGoldFoundRate() + addRateEx) / ShareDefine.Def_MaxRateValue  
 | 
        moneyValue = int(moneyValue + moneyValue * addRate)  
 | 
        #ÌØÊâµØÍ¼É±¹Ö½ð±ÒÍâ²ã¼Ó³É  
 | 
        outerMoneyRate = FBLogic.OnGetOuterMoneyRate(curPlayer)  
 | 
        if outerMoneyRate > 0:  
 | 
            moneyValue = int(moneyValue * outerMoneyRate / float(ShareDefine.Def_MaxRateValue))  
 | 
              
 | 
    if moneyValue >= 65535:  
 | 
        moneyValue = random.randint(65000, 65530)  
 | 
    return moneyValue  
 | 
  
 | 
def GetKillCountDropItemList(curPlayer, npcID, needKillCount, killDropItemList):  
 | 
    ## »ñÈ¡»÷ɱ´ÎÊý¶îÍâµôÂä  
 | 
    killCountValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID)  
 | 
    killCountPri = killCountValue / 10000  
 | 
    if killCountPri >= needKillCount:  
 | 
        #GameWorld.DebugLog("ɱµô´ÎÊýÒѾµôÂä¹ý! npcID=%s,killCountValue=%s,dropRecord=%s" % (npcID, killCountValue, dropRecord), curPlayer.GetPlayerID())  
 | 
        return []  
 | 
      
 | 
    killCountPri += 1  
 | 
    updRecordValue = killCountPri * 10000 + killCountValue % 10000  
 | 
      
 | 
    jobDropInfo = []  
 | 
    if killCountPri >= needKillCount:  
 | 
        isJobLimit = 1  
 | 
        #[itemID,...]  
 | 
        for dropItemID in killDropItemList:  
 | 
            itemData = GameWorld.GetGameData().GetItemByTypeID(dropItemID)  
 | 
            if not itemData:  
 | 
                GameWorld.ErrLog("µôÂäÎïÆ·ID²»´æÔÚ, dropItemID=%s" % dropItemID)  
 | 
                continue  
 | 
            itemJob = itemData.GetJobLimit()  
 | 
            if isJobLimit and itemJob and itemJob != curPlayer.GetJob():  
 | 
                # ·Ç±¾Ö°Òµ¿ÉÓ㬲»µôÂä  
 | 
                #GameWorld.DebugLog("·Ç±¾Ö°Òµ¿ÉÓ㬲»µôÂä! dropItemID=%s" % dropItemID)  
 | 
                continue  
 | 
            jobDropInfo.append(dropItemID)  
 | 
        GameWorld.DebugLog("»÷ɱ´ÎÊý±ØµôÂä! npcID=%s,needKillCount=%s,jobDropInfo=%s,killDropItemList=%s,updRecordValue=%s"   
 | 
                           % (npcID, needKillCount, jobDropInfo, killDropItemList, updRecordValue), curPlayer.GetPlayerID())  
 | 
                  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, updRecordValue)  
 | 
    GameWorld.DebugLog("¸üл÷ɱ´ÎÊý±ÈµôÂäÖµ: killCountValue=%s,killCountPri=%s,updRecordValue=%s" % (killCountValue, killCountPri, updRecordValue), curPlayer.GetPlayerID())  
 | 
    return jobDropInfo  
 | 
######################################################################  
 | 
#---------------------------------------------------------------------  
 | 
#ÒÆ¶¯Ïà¹Ø  
 | 
##NPCÊÇ·ñµ½Òƶ¯Ê±¼ä  
 | 
# @param minTime ×îСʱ¼ä  
 | 
# @param maxTime ×î´óʱ¼ä  
 | 
# @param curTick Ê±¼ä´Á  
 | 
# @param lastActionTick ÉÏ´ÎÒÆ¶¯µÄʱ¼ä  
 | 
# @return ·µ»ØÖµÕæ, ¿ÉÒÔÒÆ¶¯  
 | 
# @remarks NPCÊÇ·ñµ½Òƶ¯Ê±¼ä  
 | 
#def IsInActionTime(minTime, maxTime, curTick, lastActionTick):  
 | 
def IsInActionTime(curTick, lastActionTick):  
 | 
    #Ëæ»úÊÇΪÁËÈÃNPC µÚÒ»´Î½øÈëÊÓÒ°Ö®ºó£¬²»Í¬Ê±Òƶ¯£¬lastActionTickµ½ÕâÀïºÜÉÙΪ0  
 | 
    curTime = random.randint(0, 16)  
 | 
    if curTime < 12:  
 | 
        return 0  
 | 
      
 | 
    if curTick - lastActionTick >= curTime * 1000 :  
 | 
        return 1  
 | 
      
 | 
    return 0  
 | 
#---------------------------------------------------------------------  
 | 
##ÅжÏÊÇ·ñΪÕÙ»½ÊÞ  
 | 
# @param curNPC NPCʵÀý  
 | 
# @return ·µ»ØÖµÕæ, ÊÇÕÙ»½ÊÞ  
 | 
# @remarks ÅжÏÊÇ·ñΪÕÙ»½ÊÞ  
 | 
def IsSummonNPC(curNPC):  
 | 
    if (curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotSummon):  
 | 
        return  True  
 | 
      
 | 
    return False  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##Çå¿ÕÍæ¼ÒËùÓÐÕÙ»½Ê޵ijðºÞ  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks Çå¿ÕÍæ¼ÒËùÓÐÕÙ»½Ê޵ijðºÞ  
 | 
def ClearSummonAngry_Player(curPlayer):  
 | 
    for i in range(0, curPlayer.GetSummonCount()):  
 | 
        summonNPC = curPlayer.GetSummonNPCAt(i)  
 | 
        angry = summonNPC.GetNPCAngry()  
 | 
        angry.Clear()  
 | 
#---------------------------------------------------------------------  
 | 
##»ñÈ¡ÕÙ»½ÊÞÓµÓÐÕßʵÀý  
 | 
# @param summonNPC ÕÙ»½NPC  
 | 
# @return ÓµÓÐÕßʵÀý»òNone  
 | 
# @remarks »ñÈ¡ÕÙ»½ÊÞÓµÓÐÕßʵÀý  
 | 
def GetSummonOwnerDetel(summonNPC):  
 | 
    #»ñÈ¡¶ÔÏóObjÀà  
 | 
    if not summonNPC or not hasattr(summonNPC, "GetOwner"):  
 | 
        return  
 | 
      
 | 
    curSummonOwner = summonNPC.GetOwner()  
 | 
      
 | 
    if curSummonOwner == None:  
 | 
        return  
 | 
      
 | 
    #»ñÈ¡¶ÔÏó×ÓÀà(ÈçNPC, Íæ¼Ò)  
 | 
    return GameWorld.GetObjDetail(curSummonOwner)  
 | 
  
 | 
  
 | 
##»ñÈ¡NPCÖ÷ÈËÊÇ·ñÊÇÍæ¼Ò  
 | 
# @param npcObj NPCʵÀý  
 | 
# @return Ö÷ÈËÊÇ·ñÊÇÍæ¼Ò  
 | 
def GetNpcObjOwnerIsPlayer(npcObj):  
 | 
    ownerDetail = GetNpcObjOwnerDetail(npcObj)  
 | 
      
 | 
    if not ownerDetail:  
 | 
        #ûÓÐÖ÷ÈË  
 | 
        return False  
 | 
      
 | 
    if ownerDetail.GetGameObjType() != IPY_GameWorld.gotPlayer:  
 | 
        #Ö÷È˲»ÊÇÍæ¼Ò  
 | 
        return False  
 | 
      
 | 
    return True  
 | 
  
 | 
  
 | 
##»ñÈ¡NPCÖ÷ÈË£¨ÓÃÓÚÕÙ»½Ê޺ͳèÎ  
 | 
# @param npcObj NPCʵÀý  
 | 
# @return ÓµÓÐÕßʵÀý»òNone  
 | 
def GetNpcObjOwnerDetail(npcObj):  
 | 
    npcObjType = npcObj.GetGameNPCObjType()  
 | 
      
 | 
    ownerDetail = None  
 | 
      
 | 
    if npcObjType == IPY_GameWorld.gnotSummon:  
 | 
        #²éÕÒÕÙ»½ÊÞÖ÷ÈË  
 | 
        ownerDetail = GetSummonOwnerDetel(npcObj)  
 | 
          
 | 
    elif npcObjType == IPY_GameWorld.gnotPet:  
 | 
        #²éÕÒ³èÎïÖ÷ÈË  
 | 
        ownerDetail = PetControl.GetPetOwner(npcObj)    
 | 
  
 | 
    return ownerDetail  
 | 
#---------------------------------------------------------------------  
 | 
##»ñµÃÕÙ»½µÄÓµÓÐÕß  
 | 
# @param curobjType ÓµÓÐÕßÀàÐÍ(Íæ¼Ò,NPC)  
 | 
# @param curSummon ÕÙ»½ÊÞ  
 | 
# @return ·µ»ØÖµ, ÕÙ»½ÊÞÓµÓÐÕß(ʵÀý)  
 | 
# @remarks »ñµÃÕÙ»½µÄÓµÓÐÕß  
 | 
def GetSummonNPCOwner(curobjType, curSummon):  
 | 
    if curSummon == None:  
 | 
        return  
 | 
      
 | 
    # ¿ÉÄÜÊÇIPY_GameWorld.gnotSummon µ«ÊÇ ·Ç IPY_SummonNPC ÊµÀý£¬ ÔÝʱÏÈ×ö¸ö·À·¶  
 | 
    if not hasattr(curSummon, "GetOwner"):  
 | 
        #GameWorld.DebugLog("ÊÇIPY_GameWorld.gnotSummon µ«ÊÇ ·Ç IPY_SummonNPC ÊµÀý£¬ ÔÝʱÏÈ×ö¸ö·À·¶")  
 | 
        summonPlayerID = curSummon.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID)  
 | 
        if summonPlayerID:  
 | 
            return GameWorld.GetObj(summonPlayerID, IPY_GameWorld.gotPlayer)  
 | 
        return  
 | 
      
 | 
    #»ñÈ¡¶ÔÏóObjÀà  
 | 
    curSummonOwner = curSummon.GetOwner()  
 | 
      
 | 
    if curSummonOwner == None:  
 | 
        return  
 | 
      
 | 
    #»ñÈ¡¶ÔÏó×ÓÀà(ÈçNPC, Íæ¼Ò)  
 | 
    curSummonOwnerDetel = GameWorld.GetObj(curSummonOwner.GetID(), curobjType)  
 | 
      
 | 
    #ÈËÎïÐèÒªÅжÏÊÇ·ñΪ¿Õ  
 | 
    if curSummonOwnerDetel != None and curobjType == IPY_GameWorld.gotPlayer and curSummonOwnerDetel.IsEmpty():  
 | 
        return  
 | 
      
 | 
    return curSummonOwnerDetel  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##»ñµÃÖ¸¶¨Êý×鷶ΧÄÚÍæ¼ÒµÄÊýÁ¿  
 | 
# @param curNPC NPCʵÀý  
 | 
# @param matrix ÇøÓòÊý×é  
 | 
# @return ·µ»ØÖµ, ÇøÓòÊý×éÄÚµÄÍæ¼ÒÊý  
 | 
# @remarks »ñµÃÖ¸¶¨Êý×鷶ΧÄÚÍæ¼ÒµÄÊýÁ¿  
 | 
def GetPlayerCountInSightByMatrix(curNPC, matrix):  
 | 
    gameMap = GameWorld.GetMap()  
 | 
    srcPosX = curNPC.GetPosX()  
 | 
    srcPosY = curNPC.GetPosY()  
 | 
    curPlayerCount = 0  
 | 
      
 | 
    for curPos in matrix:  
 | 
        #¼ì²éÓÐûÓÐÍæ¼ÒÔÚÕâÒ»µãÉÏ  
 | 
        mapObj = gameMap.GetPosObj(srcPosX + curPos[0], srcPosY + curPos[1])  
 | 
          
 | 
        if not mapObj:  
 | 
            continue  
 | 
          
 | 
        #±éÀúµ±Ç°µã¶ÔÏó  
 | 
        for i in range(0, mapObj.GetObjCount()):  
 | 
            curObj = mapObj.GetObjByIndex(i)  
 | 
              
 | 
            if GameObj.GetHP(curObj) <= 0:  
 | 
                #¶ÔÏó²»´æÔÚ»òÕßÒѾËÀÍö  
 | 
                continue  
 | 
              
 | 
            if curObj.GetGameObjType() != IPY_GameWorld.gotPlayer :  
 | 
                continue  
 | 
          
 | 
            curPlayerCount += 1  
 | 
      
 | 
    return curPlayerCount  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##»ñµÃNPCÊÓÒ°ÖеÄÍæ¼ÒÁÐ±í  
 | 
# @param curNPC NPCʵÀý  
 | 
# @return ·µ»ØÖµ, Íæ¼ÒÁÐ±í  
 | 
# @remarks »ñµÃNPCÊÓÒ°ÖеÄÍæ¼ÒÁÐ±í  
 | 
def GetInSightPlayerList_NPC(curNPC):  
 | 
    playList = []  
 | 
    seeObjCount = curNPC.GetInSightObjCount()  
 | 
    for i in range(0, seeObjCount):  
 | 
        seeObj = curNPC.GetInSightObjByIndex(i)  
 | 
          
 | 
        #ÓпÉÄÜΪ¿Õ  
 | 
        if seeObj == None :  
 | 
            continue  
 | 
          
 | 
        #ÒþÉí  
 | 
        if seeObj.GetVisible() == False:  
 | 
            continue  
 | 
          
 | 
        seeObjType = seeObj.GetGameObjType()  
 | 
          
 | 
        #²»ÊÇÍæ¼Ò  
 | 
        if seeObjType != IPY_GameWorld.gotPlayer :  
 | 
            continue  
 | 
          
 | 
        if seeObj.IsEmpty():  
 | 
            continue  
 | 
          
 | 
        #ÒѾËÀÍö  
 | 
        if GameObj.GetHP(seeObj) <= 0 :  
 | 
            continue  
 | 
          
 | 
        curTagPlayer = GameWorld.GetObj(seeObj.GetID(), seeObjType)  
 | 
          
 | 
        if not curTagPlayer:  
 | 
            continue  
 | 
          
 | 
        playList.append(curTagPlayer)  
 | 
  
 | 
    return playList  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##»ñµÃÕÙ»½ÊÞÊÓÒ°ÖеÄÍæ¼ÒÁÐ±í  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param summonNPC ÕÙ»½NPCʵÀý  
 | 
# @param checkTeam ÊÇ·ñ¼ì²éͬһ¶ÓÎé  
 | 
# @return ·µ»ØÖµ, Íæ¼ÒÁÐ±í  
 | 
# @remarks »ñµÃÕÙ»½ÊÞÊÓÒ°ÖеÄÍæ¼ÒÁÐ±í  
 | 
def GetInSightPlayerList_SummonNPC(curPlayer, summonNPC, checkTeam):  
 | 
    playList = []  
 | 
    seePlayerCount = summonNPC.GetInSightObjCount()  
 | 
    for i in range(0, seePlayerCount):  
 | 
        seeObj = summonNPC.GetInSightObjByIndex(i)  
 | 
          
 | 
        #ÓпÉÄÜΪ¿Õ  
 | 
        if seeObj == None :  
 | 
            continue  
 | 
          
 | 
        if seeObj.GetVisible() == False:  
 | 
            continue  
 | 
          
 | 
        seeObjType = seeObj.GetGameObjType()  
 | 
          
 | 
        #²»ÊÇÍæ¼Ò  
 | 
        if seeObjType != IPY_GameWorld.gotPlayer :  
 | 
            continue  
 | 
          
 | 
        if seeObj.IsEmpty():  
 | 
            continue  
 | 
          
 | 
        #ÒѾËÀÍö  
 | 
        if GameObj.GetHP(seeObj) <= 0 :  
 | 
            continue  
 | 
          
 | 
        seeObjID = seeObj.GetID()  
 | 
          
 | 
        #ÊÇÖ÷ÈË  
 | 
        if seeObjID == curPlayer.GetID():  
 | 
            playList.append(curPlayer)  
 | 
            continue  
 | 
          
 | 
        #ÊÇ·ñ¼ì²é×é¶Ó  
 | 
        if not checkTeam :  
 | 
            continue  
 | 
          
 | 
        #ÐèÒª¼ì²é×é¶Ó  
 | 
        curPlayTeam = curPlayer.GetTeam()  
 | 
        curTagPlayer = GameWorld.GetObj(seeObjID, seeObjType)  
 | 
          
 | 
        if not curTagPlayer:  
 | 
            continue  
 | 
          
 | 
        curTagTeam = curTagPlayer.GetTeam()  
 | 
          
 | 
        if curPlayTeam == None or curTagTeam == None :  
 | 
            continue  
 | 
          
 | 
        if curPlayTeam.GetTeamID() != curTagTeam.GetTeamID():  
 | 
            continue  
 | 
          
 | 
        playList.append(curTagPlayer)  
 | 
  
 | 
    return playList  
 | 
  
 | 
##¼ì²éNPCÊÓÒ°Äڿɹ¥»÷¶ÔÏóµÄÊýÁ¿£¨ÓÐÉÏÏÞÏÞÖÆ£©  
 | 
# @param curNPC µ±Ç°NPC  
 | 
# @param checkDist ¼ì²é¾àÀë  
 | 
# @param checkCount ¼ì²éÊýÁ¿  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ·µ»ØÌõ¼þÅжÏÊÇ·ñ³É¹¦  
 | 
def CheckCanAttackTagLimitCountInSight_NPC(curNPC, checkDist, checkCount, tick):  
 | 
    count = 0  
 | 
    maxCount = 13    # ×î´óËÑË÷ÊýÁ¿  
 | 
      
 | 
    #Èç¹ûÁ½¸öÌõ¼þÓÐÒ»¸öΪ0 Ôò²»ÑéÖ¤  
 | 
    if checkDist == 0 or checkCount == 0:  
 | 
        return True  
 | 
      
 | 
    for i in range(0, curNPC.GetInSightObjCount()):  
 | 
        seeObj = curNPC.GetInSightObjByIndex(i)  
 | 
          
 | 
        #ÓпÉÄÜΪ¿Õ  
 | 
        if seeObj == None :  
 | 
            continue  
 | 
          
 | 
        #ʬÌå²»Ìí¼Ó  
 | 
        if GameObj.GetHP(seeObj) <= 0:  
 | 
            continue  
 | 
          
 | 
        if not seeObj.GetVisible():  
 | 
            continue  
 | 
  
 | 
        if GameWorld.IsSameObj(curNPC, seeObj):  
 | 
            continue  
 | 
          
 | 
        tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), seeObj.GetPosX(), seeObj.GetPosY())  
 | 
        #²»ÊÇÖ¸¶¨·¶Î§  
 | 
        if tagDist > checkDist:  
 | 
            continue  
 | 
          
 | 
        seeObjDetail = GameWorld.GetObj(seeObj.GetID(), seeObj.GetGameObjType())  
 | 
        if seeObjDetail == None:  
 | 
            GameWorld.Log("curNPC = %s ²éÕÒ¶ÔÏó, »ñµÃ¶ÔÏóʵÀýʧ°Ü" % (curNPC.GetNPCID()))  
 | 
            continue  
 | 
          
 | 
        if not AttackCommon.CheckCanAttackTag(curNPC, seeObjDetail):  
 | 
            continue  
 | 
          
 | 
        relation = BaseAttack.GetTagRelation(curNPC, seeObjDetail, None, tick)[0]  
 | 
        if relation != ChConfig.Type_Relation_Enemy:  
 | 
            continue  
 | 
          
 | 
          
 | 
        #ÊýÁ¿¼Ó1£¬¼ì²éÊÇ·ñµ½´ï×î´óÊýÁ¿, ±ÜÃâÊýÁ¿¹ý¶àÎÞЧ±éÀú  
 | 
        count += 1  
 | 
        if count == maxCount or count >= checkCount:  
 | 
            return True  
 | 
  
 | 
    return False  
 | 
#---------------------------------------------------------------------  
 | 
##ÔÚNPC³ðºÞÁбíÖÐÌæ»»¶ÔÏó  
 | 
# @param curNPC NPCʵÀý  
 | 
# @param oldTag ³ðºÞÖоɵĶÔÏó  
 | 
# @param newTag ³ðºÞÖÐÒªÌí¼ÓµÄжÔÏó  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks ÔÚNPC³ðºÞÁбíÖÐÌæ»»¶ÔÏó  
 | 
#===============================================================================  
 | 
# def ReplaceNPCAngryFromOldToNew(curNPC, oldTag, newTag):  
 | 
#    #ÅжÏÊÇ·ñÔÚÊÓÒ°¾àÀëÄÚ  
 | 
#    dist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),  
 | 
#                                 newTag.GetPosX(), newTag.GetPosY())  
 | 
#      
 | 
#    if dist > ChConfig.Def_Screen_Area:  
 | 
#        #GameWorld.Log("curNPC = %s , id = %s Ìæ»»³ðºÞ,ÒòжÔÏó²»ÔÚÆÁÄ»ÖÐ,ÎÞ·¨Ìæ»»"%(curNPC.GetName(),curNPC.GetID()))  
 | 
#        return  
 | 
#      
 | 
#    tagID = oldTag.GetID()  
 | 
#    tagType = oldTag.GetGameObjType()  
 | 
#    newTagID = newTag.GetID()  
 | 
#    newTagType = newTag.GetGameObjType()  
 | 
#      
 | 
#    npcAngry = curNPC.GetNPCAngry()  
 | 
#      
 | 
#    for i in range(0, npcAngry.GetAngryCount()):  
 | 
#        curAngry = npcAngry.GetAngryValueTag(i)  
 | 
#        angryObjID = curAngry.GetObjID()  
 | 
#          
 | 
#        if angryObjID == 0:  
 | 
#            continue  
 | 
#          
 | 
#        angryObjType = curAngry.GetObjType()  
 | 
#        angryObjValue = curAngry.GetAngryValue()  
 | 
#          
 | 
#        #ɾ³ý¾ÉµÄ³ðºÞ,Ìí¼ÓеijðºÞ  
 | 
#        if angryObjID == tagID and angryObjType == tagType:  
 | 
#            npcAngry.DeleteAngry(tagID, tagType)  
 | 
#            npcAngry.AddAngry(newTagID, newTagType, angryObjValue)  
 | 
#            #GameWorld.Log("Ìæ»»³ðºÞ³É¹¦ NPC = %s,¾É¶ÔÏó = %s,жÔÏó = %s"%(curNPC.GetID(),tagID,newTag.GetID()))  
 | 
#            break  
 | 
#      
 | 
#    return True  
 | 
#===============================================================================  
 | 
  
 | 
def GetDefaultMaxAngryNPCIDList():  
 | 
    return GameLogic_FamilyInvade.GetDefaultMaxAngryNPCIDList()  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##NPC½øÈëÕ½¶·×´Ì¬  
 | 
# @param curNPC NPCʵÀý  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks NPC½øÈëÕ½¶·×´Ì¬  
 | 
def SetNPCInBattleState(curNPC):  
 | 
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie:  
 | 
        return  
 | 
      
 | 
    #ÉèÖÃ  
 | 
    if not curNPC.GetIsNeedProcess() :  
 | 
        curNPC.SetIsNeedProcess(True)  
 | 
      
 | 
    #@Bug: ÕâÀï²»¿É±ä¸ü±»¹¥»÷NPC״̬Ϊ¹¥»÷, ÒòΪÕâ¸öʱºò, ÓпÉÄÜÕâ¸öNPCÔÚ×·»÷Ä¿±ê, ÖØÖÃ״̬ºó, ½«µ¼Ö¿¨×¡  
 | 
#===============================================================================  
 | 
#    if curNPC.GetCurAction() != IPY_GameWorld.laNPCAttack :  
 | 
#        curNPC.SetCurAction(IPY_GameWorld.laNPCAttack)  
 | 
#===============================================================================  
 | 
    return  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##»ñµÃNPCµÄ×î´ó¹¥»÷¾àÀë  
 | 
# @param curNPC NPCʵÀý  
 | 
# @return ·µ»ØÖµ, ×î´ó¹¥»÷¾àÀë  
 | 
# @remarks »ñµÃNPCµÄ×î´ó¹¥»÷¾àÀë  
 | 
def GetNPCMaxAtkDist(curNPC):  
 | 
    distList = [ curNPC.GetAtkDist() ]  
 | 
      
 | 
    skillManager = curNPC.GetSkillManager()  
 | 
      
 | 
    for index in range(skillManager.GetSkillCount()):  
 | 
        skill = skillManager.GetSkillByIndex(index)  
 | 
          
 | 
        if not skill:  
 | 
            continue  
 | 
          
 | 
        distList.append(skill.GetAtkDist())  
 | 
      
 | 
    #»ñÈ¡ÆÕ¹¥ + ¼¼ÄÜÖÐ, ×îÔ¶µÄ¹¥»÷¾àÀë  
 | 
    return max(distList)  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
##»ñµÃNPCË¢ÐÂЧ¹û¼¼ÄܹÜÀíÆ÷  
 | 
# @param curNPC NPCʵÀý  
 | 
# @return ¼¼ÄܹÜÀíÆ÷Áбí[[BuffState, CanPileup], [BuffState, CanPileup]]  
 | 
# @remarks »ñµÃNPCË¢ÐÂЧ¹û¼¼ÄܹÜÀíÆ÷  
 | 
def GetNPCBuffRefreshList(curNPC, getActionBuff=False, getAuraBuff=True):  
 | 
    #[[BuffState, CanPileup]]  
 | 
    buffRefreshList = [  
 | 
                       [curNPC.GetBuffState(), False], [curNPC.GetDeBuffState(), False],  
 | 
                       [curNPC.GetProcessBuffState(), False], [curNPC.GetProcessDeBuffState(), False],  
 | 
                       ]  
 | 
      
 | 
    if getAuraBuff:  
 | 
        buffRefreshList.append([curNPC.GetAura(), False])  
 | 
          
 | 
    #³èÎï¶àÒ»¸ö±»¶¯¹ÜÀíÆ÷  
 | 
    if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  
 | 
        buffRefreshList.append([curNPC.GetPassiveBuf(), True])  
 | 
      
 | 
    #»ñµÃÊÇ·ñÌí¼ÓÐÐΪBUFF¹ÜÀíÆ÷  
 | 
    if getActionBuff:  
 | 
        buffRefreshList.append([curNPC.GetActionBuffManager(), False])  
 | 
          
 | 
    return buffRefreshList  
 | 
#---------------------------------------------------------------------  
 | 
##NPCÇл»Òƶ¯×´Ì¬  
 | 
# @param curNPC NPCʵÀý  
 | 
# @param changMoveType Çл»µÄÒÆ¶¯ÀàÐÍ  
 | 
# @param changeSuperSpeed ÊÇ·ñÇл»ÖÁ³¬¼¶Òƶ¯ËÙ¶È  
 | 
# @return None  
 | 
# @remarks NPCÇл»Òƶ¯×´Ì¬, mtRun, mtSlow  
 | 
def ChangeNPCMoveType(curNPC, changMoveType, changeSuperSpeed=True):  
 | 
    #²»Öظ´±ä¸ü״̬  
 | 
    if curNPC.GetCurMoveType() == changMoveType:  
 | 
        return  
 | 
  
 | 
    #NPCµ±Ç°Òƶ¯ËÙ¶È  
 | 
    curNPCSpeed = curNPC.GetSpeed()  
 | 
    #NPC»ù´¡Òƶ¯ËÙ¶È  
 | 
    curNPCBaseSpeed = curNPC.GetOrgSpeed()  
 | 
      
 | 
    #Çл»µ½¿ìËÙÒÆ¶¯×´Ì¬  
 | 
    if changMoveType == IPY_GameWorld.mtRun:  
 | 
        curNPC.SetCurMoveType(changMoveType)  
 | 
        #Çл»ÖÁ³¬¼¶Òƶ¯ËÙ¶È  
 | 
        if curNPCSpeed != int(curNPCBaseSpeed / 2) and not curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SpeedPer):  
 | 
            curNPC.SetSpeed(int(curNPCBaseSpeed / 2))  
 | 
  
 | 
        return  
 | 
      
 | 
    #Çл»ÂýËÙÒÆ¶¯×´Ì¬  
 | 
    elif changMoveType == IPY_GameWorld.mtSlow:  
 | 
        curNPC.SetCurMoveType(changMoveType)  
 | 
        #Çл»ÂýËÙÒÆ¶¯  
 | 
        if curNPCSpeed != curNPCBaseSpeed * 2 and not curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SpeedPer):  
 | 
            curNPC.SetSpeed(curNPCBaseSpeed * 2)  
 | 
          
 | 
        return  
 | 
    elif changMoveType == IPY_GameWorld.mtNormal:  
 | 
        curNPC.SetCurMoveType(IPY_GameWorld.mtNormal)  
 | 
        if not curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SpeedPer):  
 | 
            curNPC.SetSpeed(curNPCBaseSpeed)  
 | 
        return  
 | 
  
 | 
    #Ò쳣״̬²»´¦Àí  
 | 
    GameWorld.ErrLog('ChangeNPCMoveType unKnowType = %s, curNPC = %s' % (changMoveType, curNPC.GetNPCID()))  
 | 
    return  
 | 
  
 | 
  
 | 
## ÔÚµØÍ¼ÀïÕÙ»½NPC ¸ù¾ÝNPCID ³öÉúµã AIÀàÐÍ ºÍTICK  
 | 
# @param npcId£º ÒªÕÙµÄNPCµÄNPCID  
 | 
# @param rebornX£º ³öÉúµãX  
 | 
# @param rebornY£º ³öÉúµãX  
 | 
# @param aiType£º AIÀàÐÍ  
 | 
# @return Èç¹ûÕÙ»½Ê§°Ü·µ»ØNone ·ñÔò·µ»ØÕÙ»½µÄNPCµÄʵÀý  
 | 
# @remarks ÔÚµØÍ¼ÀïÕÙ»½NPC ¸ù¾ÝNPCID ³öÉúµã AIÀàÐÍ ºÍTICK  
 | 
def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0):  
 | 
    curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()  
 | 
    if not curSummon:  
 | 
        return  
 | 
      
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    #---³õʼ»¯NPCÏà¹Ø ÉèNPCID ×î´ó³ðºÞÊý AIÀàÐÍ ³öÉúµã ³öÉúʱ¼ä---  
 | 
    curSummon.SetNPCTypeID(npcId)  
 | 
    curSummon.Reborn(rebornX, rebornY)  
 | 
    curSummon.SetBornTime(tick)  
 | 
    if aiType > 0:  
 | 
        curSummon.SetAIType(aiType)  
 | 
    InitNPC(curSummon)       
 | 
  
 | 
    if lastTime > 0:  
 | 
        curSummon.SetLastTime(lastTime)  
 | 
      
 | 
    if playerID > 0:  
 | 
        curSummon.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, playerID)  
 | 
      
 | 
    FBLogic.DoFBRebornSummonNPC(curSummon, tick)  
 | 
    __NotifyMapPlayerSummonMapNPC(npcId, rebornX, rebornY)  
 | 
    return curSummon  
 | 
  
 | 
## Í¨ÖªµØÍ¼ÄÚÍæ¼Ò£¬µØÍ¼³öÏÖÕÙ»½NPC  
 | 
# @param npcId£º NPCID  
 | 
# @param rebornX£º ³öÉúµãX  
 | 
# @param rebornY£º ³öÉúµãX  
 | 
# @return None  
 | 
def __NotifyMapPlayerSummonMapNPC(summonID, rebornPosX, rebornPosY):  
 | 
    mapNPC = ChPyNetSendPack.tagMCSummonMapNPC()  
 | 
    mapNPC.Clear()  
 | 
    mapNPC.NPCID = summonID  
 | 
    mapNPC.PosX = rebornPosX  
 | 
    mapNPC.PosY = rebornPosY  
 | 
      
 | 
    playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for index in range(playerManager.GetPlayerCount()):  
 | 
        curPlayer = playerManager.GetPlayerByIndex(index)  
 | 
        if not curPlayer:  
 | 
            continue  
 | 
        NetPackCommon.SendFakePack(curPlayer, mapNPC)  
 | 
          
 | 
    return  
 | 
  
 | 
#// B4 0F »ØÊÕ˽ÓÐרÊôľ׮¹Ö #tagCMRecyclePriWoodPile  
 | 
#  
 | 
#struct    tagCMRecyclePriWoodPile  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        ObjID;  
 | 
#};  
 | 
def OnRecyclePriWoodPile(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    objID = clientData.ObjID  
 | 
    curNPC = GameWorld.FindNPCByID(objID)  
 | 
    if not curNPC:  
 | 
        return  
 | 
    if curNPC.GetType() not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:  
 | 
        return  
 | 
    summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)  
 | 
    if curPlayer.GetPlayerID() != summonPlayerID:  
 | 
        #GameWorld.DebugLog("·ÇÍæ¼Ò˽ÓÐľ׮...")  
 | 
        return  
 | 
    SetDeadEx(curNPC)  
 | 
    return  
 | 
  
 | 
#// B4 0C ÕÙ»½Ë½ÓÐרÊôľ׮¹Ö #tagCMSummonPriWoodPile  
 | 
#  
 | 
#struct    tagCMSummonPriWoodPile  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        NPCID;  
 | 
#    BYTE        Count;    //ĬÈÏ1¸ö£¬×î¶à5¸ö  
 | 
#    DWORD        HP;    //ĬÈÏ0È¡×î´óÖµ£¬ÆäÖÐÒ»¸öѪÁ¿ÊýÖµ´óÓÚ0ÔòÓÃÖ¸¶¨ÑªÁ¿  
 | 
#    DWORD        HPEx;    //ĬÈÏ0È¡×î´óÖµ£¬ÆäÖÐÒ»¸öѪÁ¿ÊýÖµ´óÓÚ0ÔòÓÃÖ¸¶¨ÑªÁ¿  
 | 
#};  
 | 
def OnSummonPriWoodPile(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    npcID = clientData.NPCID  
 | 
    count = clientData.Count  
 | 
    hp = clientData.HP  
 | 
    hpEx = clientData.HPEx  
 | 
    SummonPriWoodPile(curPlayer, npcID, count, hp, hpEx)  
 | 
    return  
 | 
  
 | 
def SummonPriWoodPile(curPlayer, npcID, count, hp=0, hpEx=0):  
 | 
    ''' ÕÙ»½Ë½ÓÐרÊôľ׮¹Ö  
 | 
    '''  
 | 
      
 | 
    mapID = PlayerControl.GetCustomMapID(curPlayer)  
 | 
    lineID = PlayerControl.GetCustomLineID(curPlayer)  
 | 
    if mapID:  
 | 
        if not FBLogic.OnCanSummonPriWoodPile(curPlayer, mapID, lineID, npcID, count):  
 | 
            GameWorld.ErrLog("ÎÞ·¨ÕÙ»½Ä¾×®¹Ö!mapID=%s,lineID=%s,npcID=%s,count=%s" % (mapID, lineID, npcID, count))  
 | 
            return  
 | 
          
 | 
    if count != 1:  
 | 
        hp, hpEx = 0, 0 # Ö¸¶¨ÑªÁ¿µÄÔݽöÊÊÓÃÓÚµ¥Ö»µÄ  
 | 
          
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if playerID not in PyGameData.g_playerPriWoodPileNPCDict:  
 | 
        PyGameData.g_playerPriWoodPileNPCDict[playerID] = []  
 | 
    playerPriWoodNPCList = PyGameData.g_playerPriWoodPileNPCDict[playerID]  
 | 
    maxCount = 3  
 | 
    nowCount = len(playerPriWoodNPCList)  
 | 
    summonCount = min(count, maxCount - nowCount)  
 | 
    GameWorld.DebugLog("ÕÙ»½Ä¾×®: npcID=%s,count=%s,maxCount=%s,nowCount=%s,summonCount=%s,hp=%s,hpEx=%s"   
 | 
                       % (npcID, count, maxCount, nowCount, summonCount, hp, hpEx))  
 | 
    if summonCount <= 0:  
 | 
        return  
 | 
      
 | 
    npcManager = GameWorld.GetNPCManager()  
 | 
    for _ in xrange(summonCount):  
 | 
        #summonNPC = curPlayer.SummonNewNPC()  
 | 
        summonNPC = npcManager.AddPlayerSummonNPC()  
 | 
          
 | 
        #ÉèÖÃÕÙ»½ÊÞ»ù´¡ÐÅÏ¢  
 | 
        summonNPC.SetNPCTypeID(npcID)  
 | 
        summonNPC.SetSightLevel(curPlayer.GetSightLevel())  
 | 
        #³õʼ»¯  
 | 
        InitNPC(summonNPC)  
 | 
          
 | 
        #Íæ¼ÒÕÙ»½ÊÞÁбíÌí¼ÓÕÙ»½ÊÞ,ÕÙ»½ÊÞÌí¼ÓÖ÷ÈË  
 | 
        #summonNPC.SetOwner(curPlayer)  
 | 
        summonNPC.SetDict(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID, playerID)  
 | 
          
 | 
        #½«ÕÙ»½ÊÞÕÙ»½³öÀ´  
 | 
        #Íæ¼ÒÖÜÎ§Ëæ»ú³öÉúµã  
 | 
        #¼¼ÄÜÕÙ»½×ø±ê ChConfig.Def_SummonAppearDist  
 | 
        summonPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), 3)  
 | 
        summonNPC.Reborn(summonPos.GetPosX(), summonPos.GetPosY(), False)  
 | 
        NPCControl(summonNPC).ResetNPC_Init(isReborn=True)  
 | 
        if hp or hpEx:  
 | 
            summonNPC.SetHP(hp)  
 | 
            summonNPC.SetHPEx(hpEx)  
 | 
            summonNPC.SetMaxHP(hp)  
 | 
            summonNPC.SetMaxHPEx(hpEx)  
 | 
        summonNPC.NotifyAppear() # ×îÖÕͳһ֪ͨNPC³öÏÖ  
 | 
        playerPriWoodNPCList.append(summonNPC)  
 | 
          
 | 
    return  
 | 
  
 | 
def ClearPriWoodPile(curPlayer):  
 | 
    ## Çå³ý˽ÓÐľ׮  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if playerID not in PyGameData.g_playerPriWoodPileNPCDict:  
 | 
        return  
 | 
    playerPriWoodNPCList = PyGameData.g_playerPriWoodPileNPCDict.pop(playerID)  
 | 
    for summonNPC in playerPriWoodNPCList:  
 | 
        if not summonNPC:  
 | 
            continue  
 | 
        SetDeadEx(summonNPC)  
 | 
    return  
 | 
  
 | 
## ÉèÖÃnpcËÀÍö¼°×ÔÉí´¦Àí(Çë²»Òª½«ÓÎÏ·Âß¼¼ÓÔڴ˺¯ÊýÖÐ)  
 | 
#  @param curNPC£ºnpcʵÀý  
 | 
#  @return   
 | 
def SetDeadEx(curNPC):  
 | 
    summon_List = []  
 | 
    npcid = curNPC.GetNPCID()  
 | 
    #½«Éæ¼°µ½C++ÖÐÁбíɾ³ýµÄ¹¦ÄÜ,ͳһ¸Ä³É -> ¸´ÖÆPyÁбíºó,È»ºó½øÐÐɾ³ýÂß¼   
 | 
    for index in range(curNPC.GetSummonCount()):  
 | 
        curSummonNPC = curNPC.GetSummonNPCAt(index)  
 | 
        summon_List.append(curSummonNPC)  
 | 
      
 | 
    for summonNPC in summon_List:         
 | 
        # ÉèÖÃnpcËÀÍö¼°×ÔÉí´¦Àí  
 | 
        SetDeadEx(summonNPC)  
 | 
          
 | 
    if curNPC.GetGameObjType() == IPY_GameWorld.gotNPC:  
 | 
        FBLogic.DoFB_NPCDead(curNPC)  
 | 
      
 | 
    summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID)  
 | 
    if summonPlayerID > 0:  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, 0)  
 | 
      
 | 
    # °µ½ðboss  
 | 
    if ChConfig.IsGameBoss(curNPC):   
 | 
        # Í¨ÖªGameServer boss״̬ ·âħ̳ÔÚ¸±±¾Àïµ¥¶À´¦Àí  
 | 
        ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcid)  
 | 
        if ipyData and ipyData.GetMapID() not in [ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss]:  
 | 
            GameServe_GameWorldBossState(npcid, 0)  
 | 
            #GameWorld.GetGameWorld().SetGameWorldDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())  
 | 
            #ÒòΪ´æÔÚboss·ÖÁ÷£¬ËùÒÔÓÃgameFB×ֵ䣬µ«ÊÇ´æ»î״̬»¹ÊÇÓÃGameWorld×Öµä  
 | 
            GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())  
 | 
          
 | 
            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:  
 | 
                FamilyRobBoss.ClearFamilyOwnerBossHurt(curNPC)  
 | 
        ChNPC.OnNPCSetDead(curNPC)  
 | 
          
 | 
      
 | 
    # Çå³ý¶ÓÎé³ÉÔ±ÉËѪÁÐ±í  
 | 
    AttackCommon.ClearTeamPlayerHurtValue(curNPC)  
 | 
    # Çå³ý×Ô¶¨ÒåÉËѪÁÐ±í  
 | 
    #BossHurtMng.ClearHurtValueList(curNPC)  
 | 
    NPCHurtManager.DeletePlayerHurtList(curNPC)  
 | 
    NPCHurtMgr.DeletePlayerHurtList(curNPC)  
 | 
    if curNPC.GetType() == ChConfig.ntRobot:  
 | 
        lineID = GameWorld.GetGameWorld().GetLineID()  
 | 
        lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {})  
 | 
        lineRobotJobDict.pop(curNPC.GetID(), 0)  
 | 
        PyGameData.g_fbRobotJobDict[lineID] = lineRobotJobDict  
 | 
          
 | 
    priWoodPilePlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)  
 | 
    if priWoodPilePlayerID > 0 and priWoodPilePlayerID in PyGameData.g_playerPriWoodPileNPCDict:  
 | 
        priWoodPileNPCList = PyGameData.g_playerPriWoodPileNPCDict[priWoodPilePlayerID]  
 | 
        for priWoodNPC in priWoodPileNPCList:  
 | 
            if priWoodNPC and priWoodNPC.GetID() == curNPC.GetID():  
 | 
                priWoodPileNPCList.remove(priWoodNPC)  
 | 
                if not priWoodPileNPCList:  
 | 
                    PyGameData.g_playerPriWoodPileNPCDict.pop(priWoodPilePlayerID)  
 | 
                break  
 | 
              
 | 
    # C++ÉèÖÃnpcËÀÍö  
 | 
    curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason),  
 | 
                   curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerType),  
 | 
                   curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID))  
 | 
    return  
 | 
  
 | 
def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):  
 | 
    mapID = GameWorld.GetGameWorld().GetMapID()  
 | 
    realMapID = GameWorld.GetGameWorld().GetRealMapID()  
 | 
    copyMapID = GameWorld.GetGameWorld().GetCopyMapID()  
 | 
    killMsg = str([bossID, killPlayerName, hurtValue, isNotify, mapID, realMapID, copyMapID, killerIDList])  
 | 
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'KillGameWorldBoss', killMsg, len(killMsg))  
 | 
    GameWorld.DebugLog("Boss±»»÷ɱ: bossID=%s,mapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s" % (bossID, mapID, realMapID, copyMapID, killerIDList))  
 | 
    return  
 | 
  
 | 
def GameServe_GameWorldBossState(bossID, isAlive):  
 | 
    mapID = GameWorld.GetGameWorld().GetMapID()  
 | 
    realMapID = GameWorld.GetGameWorld().GetRealMapID()  
 | 
    copyMapID = GameWorld.GetGameWorld().GetCopyMapID()  
 | 
    stateMsg = str([bossID, isAlive, mapID, realMapID, copyMapID])  
 | 
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', '%s' % stateMsg, len(stateMsg))  
 | 
    GameWorld.DebugLog("Boss״̬±ä¸ü: bossID=%s,isAlive=%s,mapID=%s,realMapID=%s,copyMapID=%s"   
 | 
                       % (bossID, isAlive, mapID, realMapID, copyMapID))  
 | 
    if not isAlive:  
 | 
        if mapID in ChConfig.Def_CrossZoneMapTableName:  
 | 
            tableName = ChConfig.Def_CrossZoneMapTableName[mapID]  
 | 
            realMapID = GameWorld.GetGameWorld().GetRealMapID()  
 | 
            copyMapID = GameWorld.GetGameWorld().GetCopyMapID()  
 | 
            zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, mapID, copyMapID)  
 | 
            if not zoneIpyData:  
 | 
                return  
 | 
            zoneID = zoneIpyData.GetZoneID()  
 | 
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0)  
 | 
        elif mapID in ChConfig.Def_CrossDynamicLineMap:  
 | 
            zoneID = FBCommon.GetCrossDynamicLineMapZoneID()  
 | 
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0)  
 | 
        else:  
 | 
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 0)  
 | 
    return  
 | 
  
 | 
def OnPlayerKillBoss(curPlayer, npcID, mapID, isCrossServer):                  
 | 
    killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)  
 | 
    limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)  
 | 
    if limitIndex != None:  
 | 
        #½ñÈÕɱ¹Ö´ÎÊý+1  
 | 
        key = ChConfig.Def_PDict_Boss_KillCnt % limitIndex  
 | 
        newCnt = curPlayer.NomalDictGetProperty(key, 0) + 1  
 | 
        PlayerControl.NomalDictSetProperty(curPlayer, key, newCnt)  
 | 
        BossHurtMng.NotifyAttackBossCnt(curPlayer, limitIndex)  
 | 
        GameWorld.DebugLog("½ñÈÕɱ¹Ö´ÎÊý  playerID=%s, newCnt=%s" % (curPlayer.GetPlayerID(), newCnt))  
 | 
          
 | 
        dataDict = {"objID":npcID, "bossID":npcID, "touchCnt":newCnt,  
 | 
                    "AccID":curPlayer.GetAccID(), "PlayerID":curPlayer.GetPlayerID()}  
 | 
        DataRecordPack.SendEventPack("AddKillBossCnt", dataDict, curPlayer)  
 | 
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FeastRedPack_KillBoss, 1, [limitIndex])  
 | 
          
 | 
    if isCrossServer:  
 | 
        return  
 | 
      
 | 
    if limitIndex == ShareDefine.Def_Boss_Func_World:  
 | 
        # ÊÀ½çBOSS»÷ɱ³É¾Í  
 | 
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillWorldBoss, 1)  
 | 
        # Ã¿Èջ  
 | 
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS)  
 | 
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_WorldBOSS, 1)  
 | 
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1)  
 | 
        PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1)  
 | 
        PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_WorldBOSS, 1)  
 | 
        PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_WorldBoss, 1)  
 | 
        PlayerActLogin.AddLoginAwardActionCnt(curPlayer, ChConfig.Def_LoginAct_WorldBOSS, 1)  
 | 
  
 | 
    elif limitIndex == ShareDefine.Def_Boss_Func_Home:  
 | 
        #BOSSÖ®¼Ò  
 | 
        # BOSSÖ®¼ÒBOSS»÷ɱ³É¾Í  
 | 
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)  
 | 
        # Ã¿Èջ  
 | 
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)  
 | 
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)  
 | 
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)  
 | 
        PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)  
 | 
        PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_BOSSHome, 1)  
 | 
        PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_BossHome, 1)  
 | 
          
 | 
    if mapID == ChConfig.Def_FBMapID_CrossPenglai:  
 | 
        #¿ç·þÅîÀ³Ïɾ³  
 | 
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossPenglai)  
 | 
          
 | 
    # ¸öÈËÊ×ɱ¼Ç¼  
 | 
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", npcID)  
 | 
    if ipyData:  
 | 
        GY_Query_BossFirstKill.SetPlayerFirstKillBoss(curPlayer, npcID)  
 | 
          
 | 
    return  
 | 
      
 | 
#################################################  
 | 
## NPC¿ØÖƶ¨Òå  
 | 
#  
 | 
#  ¹ÜÀíNPCËÀÍö, Ë¢ÐµÈÐÅÏ¢  
 | 
class NPCControl:  
 | 
    __Instance = None  
 | 
    #---------------------------------------------------------------------  
 | 
    ## Àà³õʼ»¯  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param iNPC NPCʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Àà³õʼ»¯  
 | 
    def __init__(self, iNPC):  
 | 
        self.__Instance = iNPC  
 | 
        self.__LastHurtPlayer = None    # ×îºóÒ»»÷µÄÍæ¼Ò  
 | 
        self.__Killer = None # »÷ɱÕß, Óɸ÷ÖÖ¹æÔòµÃ³ö, Ò»°ãÒ²ÊÇÎïÆ·¹éÊôµÄ´ú±í, ÓÃÓڹ㲥¡¢¼Ç¼µÈÈ·±£Óë¹éÊôÒ»Ö  
 | 
        self.__AllKillerDict = {} # ËùÓл÷ɱµÄÍæ¼ÒID¶ÔÓ¦×Öµä, ·Ç¶ÓÎé, Ò»°ãÒ²ÊǹéÊôµÄÓµÓÐÕß  
 | 
        self.__FeelPlayerList = [] # ËùÓÐÃþ¹ÖÍæ¼ÒÁÐ±í£¬´¦ÀíÈÎÎñ¼°Ä³Ð©Âß¼Óà  
 | 
        self.__ownerPlayerList = [] # ¹éÊôÕßÁÐ±í  
 | 
          
 | 
        self.__OwnerHurtType = 0  
 | 
        self.__OwnerHurtID = 0  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## Òƶ¯µ½Ä³Ò»¸öµãµÄ¸½½üµã  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param destX Ä¿±ê×ø±êY  
 | 
    #  @param destY Ä¿±ê×ø±êX  
 | 
    #  @param dist ¾àÀë  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Òƶ¯µ½Ä³Ò»¸öµãµÄ¸½½üµã  
 | 
    def GetMoveNearPos(self, destX, destY, dist, fixPos=True):  
 | 
        curNPC = self.__Instance  
 | 
        posX = curNPC.GetPosX()  
 | 
        posY = curNPC.GetPosY()  
 | 
        #ÅжÏÄ¿±êÔÚµÚ¼¸ÏóÏÞ  
 | 
        dirX = posX - destX  
 | 
        dirY = posY - destY  
 | 
        #·ûºÅ * size  
 | 
        if abs(dirX) > dist:  
 | 
            dirX = dirX / abs(dirX) * dist  
 | 
        if abs(dirY) > dist:  
 | 
            dirY = dirY / abs(dirY) * dist  
 | 
  
 | 
        moveDestX = destX + dirX  
 | 
        moveDestY = destY + dirY    
 | 
        gameMap = GameWorld.GetMap()  
 | 
        if not gameMap.CanMove(moveDestX, moveDestY) and fixPos:  
 | 
            #Õâ¸öλÖò»¿É×ß, ¿ªÊ¼Ëæ»úÕÒµ½¿É×ßµã, ×ß¹ýÈ¥  
 | 
            resultPos = GameMap.GetEmptyPlaceInArea(destX, destY, dist)  
 | 
            moveDestX = resultPos.GetPosX()  
 | 
            moveDestY = resultPos.GetPosY()  
 | 
          
 | 
        return moveDestX, moveDestY  
 | 
      
 | 
    # ¸ù¾ÝÁ½ÕßÖ®¼äÒ»ÌõÏßÉϵÄ×ø±ê  
 | 
    def GetMoveNearPosEx(self, playerX, playerY, dist, fixPos=True):  
 | 
        curNPC = self.__Instance  
 | 
        posX = curNPC.GetPosX()  
 | 
        posY = curNPC.GetPosY()  
 | 
        moveDestX, moveDestY = GameWorld.PosInLineByDist(dist, playerX, playerY, posX, posY)  
 | 
        gameMap = GameWorld.GetMap()  
 | 
        if not gameMap.CanMove(moveDestX, moveDestY) and fixPos:  
 | 
            #Õâ¸öλÖò»¿É×ß, ¿ªÊ¼Ëæ»úÕÒµ½¿É×ßµã, ×ß¹ýÈ¥  
 | 
            resultPos = GameMap.GetEmptyPlaceInArea(moveDestX, moveDestY, 2)  
 | 
            moveDestX = resultPos.GetPosX()  
 | 
            moveDestY = resultPos.GetPosY()  
 | 
          
 | 
        return moveDestX, moveDestY  
 | 
    #---------------------------------------------------------------------  
 | 
    ## Òƶ¯µ½Ò»¸ö¶ÔÏó  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param objID Ä¿±ê¶ÔÏóID  
 | 
    #  @param objType Ä¿±ê¶ÔÏóÀàÐÍ  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Òƶ¯µ½Ò»¸ö¶ÔÏó  
 | 
    def MoveToObj(self, objID, objType):  
 | 
        curNPC = self.__Instance  
 | 
        #ÕÒµ½Íæ¼Ò¶ÔÏó  
 | 
        tagObjDetel = GameWorld.GetObj(objID, objType)  
 | 
        if not tagObjDetel:  
 | 
            GameWorld.Log("NPCÒÆ¶¯µ½Ä¿±êʧ°Ü,NPCID = %s Ä¿±êID=%d,Type=%d" % (curNPC.GetName(), objID, objType))  
 | 
            return  
 | 
          
 | 
        return self.MoveToObj_Detel(tagObjDetel)  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## Òƶ¯µ½Ò»¸öµØÖ· Ò»´ÎÖ»ÒÆ¶¯ sigleMoveDis¾àÀë  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param destPosX Ä¿±êµØµãX  
 | 
    #  @param destPosY Ä¿±êµØµãY  
 | 
    #  @param sigleMoveDis µ¥´ÎÒÆ¶¯¾àÀë  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Òƶ¯µ½Ò»¸ö¶ÔÏó      
 | 
    def MoveToPosStepByStep(self, destPosX, destPosY, sigleMoveDis=4):  
 | 
        curNPC = self.__Instance  
 | 
        curPosX, curPosY = curNPC.GetPosX(), curNPC.GetPosY()  
 | 
        curDis = GameWorld.GetDist(curPosX, curPosY, destPosX, destPosY)  
 | 
        if curDis > sigleMoveDis and curDis > 0:  
 | 
            destPosX = curPosX + (destPosX - curPosX) * sigleMoveDis / curDis  
 | 
            destPosY = curPosY + (destPosY - curPosY) * sigleMoveDis / curDis  
 | 
        curNPC.Move(destPosX, destPosY)  
 | 
          
 | 
    #---------------------------------------------------------------------  
 | 
    ## Òƶ¯µ½Ò»¸ö¶ÔÏó  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tagObjDetel Ä¿±êʵÀý  
 | 
    #  @param moveAreaDist Òƶ¯ÇøÓò¾àÀë  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Òƶ¯µ½Ò»¸ö¶ÔÏó  
 | 
    def MoveToObj_Detel(self, tagObjDetel, moveAreaDist=0):  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        #²»¿ÉÒÆ¶¯ÐÐΪ״̬, ·þÎñ¶ËÏÞÖÆ  
 | 
        if not OperControlManager.IsObjCanDoAction(curNPC,  
 | 
                                                   ChConfig.Def_Obj_ActState_ServerAct,  
 | 
                                                   IPY_GameWorld.oalMove):  
 | 
            return    
 | 
          
 | 
        posX = curNPC.GetPosX()  
 | 
        posY = curNPC.GetPosY()  
 | 
        destX = tagObjDetel.GetPosX()  
 | 
        destY = tagObjDetel.GetPosY()  
 | 
          
 | 
        #×î½üµÄÒÆ¶¯ÇøÓò¾àÀë, ÈçûÓÐÖ¸¶¨, °´ÕÕ¹¥»÷¾àÀëÀ´²éÕÒ, Ô¶¹¥µÄ¹ÖÎï¾Í¿ÉÒÔÖ±½Óµ½Éä³Ì¹¥»÷  
 | 
        if moveAreaDist == 0:  
 | 
            # ËõСÁ½¸ñ×ÓÓÃÓÚǰ·½Ò»Ð¡Æ¬ÇøÓò  
 | 
            moveAreaDist = max(curNPC.GetAtkDist()-1 , 1)  
 | 
          
 | 
        #¼ì²éÊÇ·ñ³¬³ö»î¶¯·¶Î§  
 | 
        if curNPC.GetRefreshPosCount() > 0:  
 | 
            curRefreshPos = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
            moveDist = GameWorld.GetDist(posX, posY, curRefreshPos.GetPosX(), curRefreshPos.GetPosY())  
 | 
            if curRefreshPos.GetMoveDist() != 0 and moveDist > curRefreshPos.GetMoveDist():  
 | 
                #Èç¹ûNPC³¬¹ý×Ô¼ºµÄÒÆ¶¯·¶Î§, ¾Í×Ô¶¯·µ»Ø  
 | 
                self.MoveBack()  
 | 
                return  
 | 
          
 | 
        #С¹Ö²»¿ÉÐнøÍ¨µÀ²»×·»÷  
 | 
        #=======================================================================  
 | 
        # if not AttackCommon.CanAttackByPath(curNPC, tagObjDetel):  
 | 
        #    #GameWorld.DebugLog("С¹Ö²»¿ÉÐнøÍ¨µÀ²»×·»÷")  
 | 
        #    tick = GameWorld.GetGameWorld().GetTick()  
 | 
        #    AICommon.NormalNPCFree_Move(curNPC , tick)  
 | 
        #    return  
 | 
        #=======================================================================  
 | 
          
 | 
        # ËõСÁ½¸ñ×ÓÓÃÓÚǰ·½Ò»Ð¡Æ¬ÇøÓò  
 | 
        moveDestX, moveDestY = self.GetMoveNearPosEx(destX, destY, moveAreaDist)  
 | 
        resultPos = GameMap.GetEmptyPlaceInArea(moveDestX, moveDestY, 1)  
 | 
        moveDestX = resultPos.GetPosX()  
 | 
        moveDestY = resultPos.GetPosY()  
 | 
          
 | 
        if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove and \  
 | 
        (GameWorld.GetGameWorld().GetTick() - curNPC.GetActionTick()) < 800:  
 | 
            # .Move( ½Ó¿Úµ÷ÓÃÌ«¿ì»áµ¼ÖÂÒÆ¶¯Ê±¼ä²»¹»³¤(²»×ãÒ»¸ñ)µ¼ÖÂÎÞ·¨Òƶ¯ »òÕßÒÆ¶¯¹ýÂýÎÊÌâ  
 | 
            # SetDestPos µ÷ÓûᵼÖ·´ÏòÒÆ¶¯Æ«¿ì  
 | 
            curNPC.SetDestPos(moveDestX, moveDestY)  
 | 
            return  
 | 
        #=======================================================================  
 | 
        # if curNPC.GetIsBoss() <= 1:  
 | 
        #    # Ð¡¹Ö±È½Ï¶à£¬ ±ÜÃâµÚÒ»´Î×·»÷¾Íվͬһ¸öµã, µÚÒ»ÏóÏÞÖ±Ïß¾àÀë×·»÷£¬ÆäËûÏóÏÞ¾¡Á¿¿¿½üÄ¿±ê  
 | 
        #    if moveAreaDist > 6 or random.randint(0, 3) == 1:  
 | 
        #        moveDestX, moveDestY = self.GetMoveNearPosEx(destX, destY, moveAreaDist, False)  
 | 
        #    else:  
 | 
        #        resultPos = GameMap.GetEmptyPlaceInSurround(destX, destY, 3)  
 | 
        #        moveDestX = resultPos.GetPosX()  
 | 
        #        moveDestY = resultPos.GetPosY()  
 | 
        # else:  
 | 
        #    moveDestX, moveDestY = self.GetMoveNearPosEx(destX, destY, moveAreaDist)  
 | 
        #=======================================================================  
 | 
        ChangeNPCMoveType(curNPC, IPY_GameWorld.mtNormal)  
 | 
  
 | 
        return curNPC.Move(moveDestX, moveDestY)  
 | 
  
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÐÞÕý×ø±ê  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param posX Ä¿±ê×ø±êX  
 | 
    #  @param posY Ä¿±ê×ø±êY  
 | 
    #  @param fixAreaDist ½ÃÕýÇøÓò¾àÀë  
 | 
    #  @return ·µ»ØÖµÕæ, ÐÞÕý³É¹¦  
 | 
    #  @remarks ÐÞÕý×ø±ê  
 | 
    def FixTagPos(self, posX, posY, fixAreaDist=0):  
 | 
        curNPC = self.__Instance  
 | 
        #²»¿ÉÒÆ¶¯ÐÐΪ״̬, ·þÎñ¶ËÏÞÖÆ  
 | 
        if not OperControlManager.IsObjCanDoAction(curNPC,  
 | 
                                                   ChConfig.Def_Obj_ActState_ServerAct,  
 | 
                                                   IPY_GameWorld.oalMove):  
 | 
            return    
 | 
          
 | 
        gameMap = GameWorld.GetMap()  
 | 
        npcPosX = curNPC.GetPosX()  
 | 
        npcPosY = curNPC.GetPosY()  
 | 
        mapObj = gameMap.GetPosObj(npcPosX, npcPosY)  
 | 
          
 | 
        #---Õâ¸öλÖÿÉÒÔÕ¾Á¢---  
 | 
        if not mapObj:  
 | 
            return False  
 | 
          
 | 
        if mapObj.GetObjCount() <= 1:  
 | 
            return False  
 | 
          
 | 
        #±éÀúµ±Ç°µã¶ÔÏó  
 | 
        for i in xrange(mapObj.GetObjCount()):  
 | 
            curObj = mapObj.GetObjByIndex(i)  
 | 
            curObjType = curObj.GetGameObjType()  
 | 
            if curObjType != IPY_GameWorld.gotNPC:  
 | 
                continue  
 | 
            curTag = GameWorld.GetObj(curObj.GetID(), curObjType)  
 | 
            if not curTag:  
 | 
                continue  
 | 
            if curTag.GetGameNPCObjType() == IPY_GameWorld.gnotSummon and curTag.GetOwner() and curTag.GetID() != curNPC.GetID():  
 | 
                #Èç¹¥»÷ÀàÕÙ»½ÊÞ±©·çÑ©µÈ£¬·ÀÖ¹NPCÒÆ¶¯ºóµ¼ÖÂÕÙ»½ÊÞ¹¥»÷²»µ½NPC£¬Èç¹ûÐèÒªÉ趨NPC¸ü´ÏÃ÷£¬¿É¿ª³öÊÇ·ñ¶ã±ÜÕÙ»½ÊÞ¹¥»÷É趨  
 | 
                #GameWorld.DebugLog("    µ±Ç°µã´æÔÚÕÙ»½ÊÞ£¬²»ÐÞÕý×ø±ê!i=%s,%s" % (i, curTag.GetName()))  
 | 
                return False  
 | 
              
 | 
        #ÓëÄ¿±êͬһλÖò»ÐÞÕý×ø±ê(ÈçÐý·çÕ¶ÒýÆðµÄÖØµþ)  
 | 
        if npcPosX == posX and npcPosX == posY:  
 | 
            return False  
 | 
          
 | 
        #--Õâ¸öλÖò»¿ÉÕ¾Á¢---  
 | 
        if fixAreaDist == 0:  
 | 
            #ĬÈϼì²â¾àÀëΪNPCµÄ¹¥»÷¾àÀë  
 | 
            fixAreaDist = min(curNPC.GetAtkDist(), 2)  
 | 
          
 | 
        resultPos = GameMap.GetEmptyPlaceInArea(npcPosX, npcPosY, fixAreaDist)  
 | 
        moveDestX = resultPos.GetPosX()  
 | 
        moveDestY = resultPos.GetPosY()  
 | 
          
 | 
        if moveDestX != npcPosX or moveDestY != npcPosY:  
 | 
            #Çл»ÖÁ¿ìËÙÒÆ¶¯×´Ì¬  
 | 
            #ChangeNPCMoveType(curNPC, IPY_GameWorld.mtRun)  
 | 
            #NPC¿ªÊ¼Òƶ¯  
 | 
            curNPC.Move(moveDestX, moveDestY)  
 | 
            return True  
 | 
          
 | 
        return False  
 | 
    #---------------------------------------------------------------------  
 | 
    ## È¡µÃ¶ÔÏó¾àÀë  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tagID ¶ÔÏóID  
 | 
    #  @param tagType ¶ÔÏóÀàÐÍ  
 | 
    #  @return ·µ»ØÖµ, ºÍ¶ÔÏó¼äµÄ¾àÀë  
 | 
    #  @remarks È¡µÃ¶ÔÏó¾àÀë  
 | 
    def GetTagDist(self, tagID, tagType):  
 | 
        curNPC = self.__Instance  
 | 
        posX = curNPC.GetPosX()  
 | 
        posY = curNPC.GetPosY()  
 | 
        tagObj = GameWorld.GetObj(tagID, tagType)  
 | 
        if tagObj == None:  
 | 
            return ChConfig.Def_NPCErrorMaxDist;  
 | 
  
 | 
        if tagObj.GetID() == 0:  
 | 
            return ChConfig.Def_NPCErrorMaxDist;  
 | 
  
 | 
        return GameWorld.GetDist(posX, posY, tagObj.GetPosX(), tagObj.GetPosY())  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ##¼ì²éÌí¼Ó³ðºÞÁÐ±í  
 | 
    # @param self ÀàʵÀý  
 | 
    # @param seeObj ÊÓÒ°ÖеĶÔÏó  
 | 
    # @param tick Ê±¼ä´Á  
 | 
    # @return ·µ»ØÖµÕæ, ¿ÉÒÔÌí¼ÓÕâ¸ö¶ÔÏó  
 | 
    # @remarks ¼ì²éÌí¼Ó³ðºÞÁÐ±í  
 | 
    def __CheckAddToAngryList(self, seeObj, tick):  
 | 
        curNPC = self.__Instance  
 | 
        seeObjType = seeObj.GetGameObjType()  
 | 
          
 | 
        if seeObjType == IPY_GameWorld.gotItem:  
 | 
            #²»´¦Àí¿´µ½µÄÎïÆ·  
 | 
            return False  
 | 
          
 | 
        #״̬¼ì²é  
 | 
        if GameWorld.IsSameObj(curNPC, seeObj):  
 | 
            #²»Ìí¼Ó×Ô¼ºµ½³ðºÞ¶È  
 | 
            return False  
 | 
          
 | 
        seeObjID = seeObj.GetID()  
 | 
          
 | 
        npcAngry = curNPC.GetNPCAngry()  
 | 
        angryValue = npcAngry.FindNPCAngry(seeObjID, seeObjType)  
 | 
          
 | 
        if angryValue != None and angryValue.GetAngryValue() != 0 :  
 | 
            #¸Ã¶ÔÏóÒѾÔÚ³ðºÞÁбíÖÐ,²»Öظ´Ìí¼Ó  
 | 
            return False  
 | 
          
 | 
        seeObjDetail = GameWorld.GetObj(seeObjID, seeObjType)  
 | 
          
 | 
        if seeObjDetail == None:  
 | 
            GameWorld.Log("curNPC = %s ²éÕÒ¶ÔÏó, »ñµÃ¶ÔÏóʵÀýʧ°Ü" % (curNPC.GetNPCID()))  
 | 
            return False  
 | 
          
 | 
        #ÊØÎÀ¹¥»÷ïÚ³µ,³ðºÞÌØÊâ´¦Àí  
 | 
        if self.__GuaedAttackTruck(seeObjDetail , tick):  
 | 
            return True  
 | 
          
 | 
        #С¹Ö²»¿ÉÐнøÍ¨µÀ¾Íµ±×÷¿´²»¼û  
 | 
        if not AttackCommon.CanAttackByPath(curNPC, seeObjDetail):  
 | 
            #GameWorld.DebugLog("ÓÐÕϰ  ¿´¼ûÒ²²»¼Ó³ðºÞ")  
 | 
            return False  
 | 
          
 | 
        #ÕâÀï²»Äܵ÷ÓÃBaseAttack.GetCanAttack,ÒòΪÄÇÀïÓÐÅжϹ¥»÷¾àÀë  
 | 
        #GetCanAttack Èç¹ûÓÃÓÚ¼¼ÄÜÉè¼ÆÔò»áÓ°Ïì³ðºÞ  
 | 
        if not AttackCommon.CheckCanAttackTag(curNPC, seeObjDetail):  
 | 
            return False  
 | 
          
 | 
        relation = BaseAttack.GetTagRelation(curNPC, seeObjDetail, None, tick)[0]  
 | 
          
 | 
        if relation != ChConfig.Type_Relation_Enemy:  
 | 
            #GameWorld.Log("%sÌí¼Ó³ðºÞ%sʧ°Ü"%(curNPC.GetName(), seeObjDetail.GetName()))  
 | 
            return False  
 | 
          
 | 
        #GameWorld.Log("%sÌí¼Ó³ðºÞ%s³É¹¦"%(curNPC.GetName(), seeObjDetail.GetName()))  
 | 
        return True  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ##ÊØÎÀ¹¥»÷ïÚ³µ,ÌØÊâ´¦Àí  
 | 
    # @param self ÀàʵÀý  
 | 
    # @param seeObj ÊÓÒ°ÖеĶÔÏó  
 | 
    # @param tick Ê±¼ä´Á  
 | 
    # @return ·µ»ØÖµÕæ, ¿ÉÒÔÌí¼ÓÕâ¸ö¶ÔÏó  
 | 
    # @remarks ÊØÎÀ¹¥»÷ïÚ³µ,ÌØÊâ´¦Àí  
 | 
    def __GuaedAttackTruck(self, seeObj, tick) :  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        if curNPC.GetType() != IPY_GameWorld.ntGuard:  
 | 
            return  
 | 
          
 | 
        if seeObj.GetGameObjType() != IPY_GameWorld.gotNPC or \  
 | 
            seeObj.GetGameNPCObjType() != IPY_GameWorld.gnotTruck :  
 | 
            return  
 | 
          
 | 
        #Èç¹ûÊÇÔ¶³ÌµÄÊØÎÀ,²»¿¼Âǹ¥»÷¾àÀë,×·»÷  
 | 
        #²»¿ÉÒÆ¶¯µÄ¹Ì¶¨ÊØÎÀ,³¬³ö¹¥»÷¾àÀë,·µ»Ø  
 | 
        if curNPC.GetSpeed() == 0 and not BaseAttack.GetCanAttack(curNPC, seeObj, None, tick):  
 | 
            return  
 | 
          
 | 
        relation = BaseAttack.GetTagRelation(curNPC, seeObj, None, tick)[0]  
 | 
          
 | 
        if relation != ChConfig.Type_Relation_Enemy :  
 | 
            return  
 | 
          
 | 
        return True  
 | 
      
 | 
  
 | 
  
 | 
    def GetIsBossView(self):  
 | 
        # Ö÷¶¯ÊÓÒ°Çé¿ö£¬GetIsBoss 0 1 4 ÎªÆÕͨNPCÊÓÒ°£¨ÓÐÊÓÒ°·¶Î§ÅäÖ㬵«È¥³ýÊÓҰˢУ©£¬ÆäËûΪBOSSÀàÊÓÒ°ÓÐˢР 
 | 
        curNPC = self.__Instance  
 | 
        if not ChConfig.IsGameBoss(curNPC) and not GetFaction(curNPC) and curNPC.GetType() != ChConfig.ntRobot:  
 | 
            return False  
 | 
          
 | 
        return True  
 | 
  
 | 
  
 | 
    ##Ìí¼ÓÊÓÒ°ÖеĶÔÏó½ø³ðºÞÁÐ±í  
 | 
    # @param self ÀàʵÀý  
 | 
    # @param tick Ê±¼ä´Á  
 | 
    # @return ·µ»ØÖµÎÞÒâÒå  
 | 
    # @remarks Ìí¼ÓÊÓÒ°ÖеĶÔÏó½ø³ðºÞÁÐ±í  
 | 
    def AddInSightObjToAngryList(self, tick, isUpdAngry=False):  
 | 
        curNPC = self.__Instance  
 | 
        needResort = False  
 | 
        #Èç¹ûÊÇÖ÷¶¯¹Ö, ¼ì²éÖÜΧµÄÍæ¼ÒÊÇ·ñÔÚ×Ô¼ºµÄ³ðºÞ¶ÈÖÐ, Èç¹û²»ÔÚ, ¾ÍÌí¼Ó  
 | 
        if curNPC.GetAtkType() == 1:  
 | 
            # 1Ϊ·ÇÖ÷¶¯¹Ö  
 | 
            return needResort  
 | 
          
 | 
        curAngry = curNPC.GetNPCAngry().GetAngryValueTag(0)  
 | 
        if not isUpdAngry and self.__IsValidAngryObj(curAngry):  
 | 
            # Ö»Ö÷¶¯¼ÓÒ»¸öÈ˵ÄÊÓÒ°³ðºÞ£¬ÆäËû¹¥»÷²ÅÓгðºÞ  
 | 
            return needResort  
 | 
  
 | 
        mapType = GameWorld.GetMap().GetMapFBType()  
 | 
        mapID = GameWorld.GetMap().GetMapID()  
 | 
        # Ö÷¶¯ÊÓÒ°Çé¿ö£¬GetIsBoss 0 1 4 ÎªÆÕͨNPCÊÓÒ°£¨ÓÐÊÓÒ°·¶Î§ÅäÖ㬵«È¥³ýÊÓҰˢУ©£¬ÆäËûΪBOSSÀàÊÓÒ°ÓÐˢР 
 | 
        # 1. ËùÓÐNPC¶ÔÍæ¼Ò£ºÍæ¼ÒÖ÷¶¯¿´µ½NPC£¬¼Ç¼µ½NPCÁÐ±í£¬²»±éÀúNPCÊÓÒ°£¬¿ØÖƵ±Ç°NPC¹¥»÷Ò»¸öÍæ¼ÒµÄÊýÁ¿  
 | 
        # 2. Íæ¼ÒÕÙ»½ÊÞ»ò³èÎï¶ÔNPC£º·ÇÖ÷¶¯ÔòΪ¹¥»÷Íæ¼ÒÄ¿±ê£¨Ä¿Ç°ÓÎÏ·Çé¿öÓÉAI¿ØÖÆÕ½¶·£©;¿ÉÖ÷¶¯¹¥»÷µÄÇé¿öÏ£¬Íæ¼ÒÓб»³ðºÞ¶ÔÏó²Å±éÀúÒ»´ÎÊÓÒ°£¨Î´¿ª·¢£©  
 | 
        # 3. BOSS¶ÔÆäËû£ºÊµÊ±Ë¢ÐÂÊÓÒ°£¬¿É×·»÷Íæ¼Ò£¬ÆäËûOBJ¸ù¾Ý¾ßÌåÉ趨  
 | 
        # 4. ÕóÓªÀàNPC£¨ÊØÎÀ£©¶ÔNPC£º¼ÓÈëBOSSÊÓҰˢжÓÁÐ; NPCÕ½¶·»á·¢ÉúÔÚ·ÇÍæ¼ÒÊÓÒ°ÄÚµÄÇé¿ö£¬ÀàDOTA¸ù¾ÝÇé¿öÁíÍ⿪·¢  
 | 
        if not self.GetIsBossView():  
 | 
            recordMapID = FBCommon.GetRecordMapID(mapID)  
 | 
            mapAngryNPCCountDict = IpyGameDataPY.GetFuncEvalCfg("AngryNPCCount", 1)  
 | 
            if recordMapID in mapAngryNPCCountDict:  
 | 
                angryNPCCountLimit = mapAngryNPCCountDict[recordMapID]  
 | 
            elif mapType == IPY_GameWorld.fbtNull:  
 | 
                angryNPCCountLimit = IpyGameDataPY.GetFuncCfg("AngryNPCCount", 2)  
 | 
            else:  
 | 
                angryNPCCountLimit = 0  
 | 
            # Ã»ÓÐÊÓÒ°¶ÔÏóµÄNPC  
 | 
            seePlayerCount = curNPC.GetAttentionPlayersCount()  
 | 
            for i in range(0, seePlayerCount):  
 | 
                seeObj = curNPC.GetAttentionPlayerByIndex(i)  
 | 
                  
 | 
                #ÓпÉÄÜΪ¿Õ  
 | 
                if seeObj == None :  
 | 
                    continue  
 | 
                  
 | 
                #ʬÌå²»Ìí¼Ó  
 | 
                if GameObj.GetHP(seeObj) <= 0:  
 | 
                    continue  
 | 
                  
 | 
                if not seeObj.GetVisible():  
 | 
                    continue  
 | 
                  
 | 
                if not self.__CheckAddToAngryList(seeObj, tick):  
 | 
                    continue  
 | 
                dist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), seeObj.GetPosX(), seeObj.GetPosY())  
 | 
                if dist > curNPC.GetSight():  
 | 
                    continue  
 | 
                  
 | 
                #Ìí¼ÓµÄ³ðºÞÖµ = µÚÒ»´Î¿´¼û¶ÔÏóµÄ³ðºÞ + (ÆÁÄ»¾àÀë - ºÍ¶ÔÏóµÄ¾àÀë)  
 | 
                addAngryValue = ChConfig.Def_NPCFirstSightAngryValue + (ChConfig.Def_Screen_Area - dist)  
 | 
      
 | 
                #Èç¹ûÊÇÍæ¼Ò, ¶à¼Ó20µã  
 | 
                if seeObj.GetGameObjType() == IPY_GameWorld.gotPlayer:  
 | 
                    if angryNPCCountLimit and seeObj.GetAngryNPCCount() >= angryNPCCountLimit:  
 | 
                        continue  
 | 
                    addAngryValue += ChConfig.Def_NPC_SeePlayerAddAngry  
 | 
                  
 | 
                #Ìí¼Ó¶ÔÏó  
 | 
                if self.AddObjToAngryList(seeObj, addAngryValue, False, False):  
 | 
                    needResort = True  
 | 
          
 | 
        else:  
 | 
            # ÓÐÊÓÒ°¶ÔÏóµÄNPC  
 | 
            refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
            seePlayerCount = curNPC.GetInSightObjCount()  
 | 
            for i in range(0, seePlayerCount):  
 | 
                seeObj = curNPC.GetInSightObjByIndex(i)  
 | 
                  
 | 
                #ÓпÉÄÜΪ¿Õ  
 | 
                if seeObj == None :  
 | 
                    continue  
 | 
                  
 | 
                #ʬÌå²»Ìí¼Ó  
 | 
                if GameObj.GetHP(seeObj) <= 0:  
 | 
                    continue  
 | 
                  
 | 
                if not seeObj.GetVisible():  
 | 
                    continue  
 | 
                  
 | 
                if not self.__CheckAddToAngryList(seeObj, tick):  
 | 
                    continue  
 | 
                  
 | 
                #bossÊÓÒ°µÄÖ»¹¥»÷×·»÷·¶Î§ÄÚµÄÄ¿±ê, ·ÇbossÊÓÒ°µÄÒ²¿ÉÒÔ¼Ó´ËÂß¼£¬²»¼ÓÒ²ÐÐ  
 | 
                if ChConfig.IsGameBoss(curNPC) and not self.GetIsInRefreshPoint(seeObj.GetPosX(), seeObj.GetPosY(), refreshPoint):  
 | 
                    continue  
 | 
                  
 | 
                dist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), seeObj.GetPosX(), seeObj.GetPosY())  
 | 
                #Ìí¼ÓµÄ³ðºÞÖµ = µÚÒ»´Î¿´¼û¶ÔÏóµÄ³ðºÞ + (ÆÁÄ»¾àÀë - ºÍ¶ÔÏóµÄ¾àÀë)  
 | 
                addAngryValue = ChConfig.Def_NPCFirstSightAngryValue + (ChConfig.Def_Screen_Area - dist)  
 | 
      
 | 
                #Èç¹ûÊÇÍæ¼Ò, ¶à¼Ó20µã  
 | 
                if seeObj.GetGameObjType() == IPY_GameWorld.gotPlayer:  
 | 
                    addAngryValue += ChConfig.Def_NPC_SeePlayerAddAngry  
 | 
                  
 | 
                #Ìí¼Ó¶ÔÏó  
 | 
                if self.AddObjToAngryList(seeObj, addAngryValue, False, False):  
 | 
                    needResort = True  
 | 
          
 | 
        return needResort  
 | 
  
 | 
  
 | 
    #---------------------------------------------------------------------  
 | 
    ##Ç¿ÖÆÌí¼Ó¶ÔÏó½ø³ðºÞÁбí.  
 | 
    # @param objDetel ¶ÔÏóʵÀý  
 | 
    # @param hurtValue É˺¦Á¿  
 | 
    # @param useSkill ¼¼ÄÜʵÀý  
 | 
    # @return ·µ»ØÖµÎÞÒâÒå  
 | 
    # @remarks Ç¿ÖÆÌí¼Ó¶ÔÏó½ø³ðºÞÁÐ±í  
 | 
    def AddObjDetelToAngryList_ByAttack(self, objDetel, hurtValue, useSkill):  
 | 
        #BUG ÒþÉí·Å¼¼ÄÜ»áA  
 | 
        if not objDetel:  
 | 
            return  
 | 
                  
 | 
        #Èç¹û¹¥»÷·½ÊÇNPC²¢ÇÒÊÇÏÝÚåÔò²»Ìí¼Ó³ðºÞ  
 | 
        if objDetel.GetGameObjType() == IPY_GameWorld.gotNPC and \  
 | 
        objDetel.GetType() == IPY_GameWorld.ntFairy:  
 | 
            return  
 | 
  
 | 
        #Ìí¼Ó³ðºÞ = ¼¼ÄܳðºÞ + ÉËѪֵ  
 | 
        addAngry = hurtValue  
 | 
          
 | 
        if useSkill != None:  
 | 
            addAngry += useSkill.GetSkillAngry()  
 | 
              
 | 
        # Íæ¼Ò¹¥»÷Ôö¼Ó¶îÍâ³ðºÞ  
 | 
        if objDetel.GetGameObjType() == IPY_GameWorld.gotPlayer:  
 | 
            addAngry += PlayerControl.GetAddAngry(objDetel)  
 | 
                      
 | 
        self.AddObjToAngryList(objDetel, addAngry)  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ##Ç¿ÖÆÌí¼Ó¶ÔÏó½ø³ðºÞÁÐ±í  
 | 
    # @param self ÀàʵÀý  
 | 
    # @param curObj ¶ÔÏó  
 | 
    # @param plusAngryValue Öµ  
 | 
    # @param canPile ÊÇ·ñÀÛ¼Ó  
 | 
    # @param check ÊÇ·ñ¼ì²é  
 | 
    # @return ·µ»ØÖµÎÞÒâÒå  
 | 
    # @remarks Ç¿ÖÆÌí¼Ó¶ÔÏó½ø³ðºÞÁÐ±í  
 | 
    def AddObjToAngryList(self, curObj, plusAngryValue, canPile=True, check=True):  
 | 
        curNPC = self.__Instance  
 | 
              
 | 
        if GameWorld.IsSameObj(curNPC, curObj):  
 | 
            #²»Ìí¼Ó×Ô¼ºµ½³ðºÞ¶È  
 | 
            return False  
 | 
          
 | 
        #Õâ¸öÄ¿±ê²»¿É¹¥»÷ ²»Ìí¼Ó  
 | 
        if not AttackCommon.CheckObjCanDoLogic(curObj):  
 | 
            return False  
 | 
          
 | 
        curObjType = curObj.GetGameObjType()  
 | 
        curObjID = curObj.GetID()  
 | 
          
 | 
        if (check and not self.__CheckCanAddAngry(curObjID , curObjType)):  
 | 
            #²»¿ÉÌí¼Ó³ðºÞ  
 | 
            return False  
 | 
          
 | 
        addAngryTeam = None  
 | 
        if curObjType == IPY_GameWorld.gotPlayer:  
 | 
            # Èç¹ûÊdzðºÞµôÂä¹éÊôµÄÔòÈ«¶Ó¼Ó³ðºÞ  
 | 
            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_MaxAngry:  
 | 
                curPlayer = GameWorld.GetObj(curObjID, curObjType)  
 | 
                if curPlayer and curPlayer.GetTeamID() > 0:  
 | 
                    addAngryTeam = GameWorld.GetTeamManager().FindTeam(curPlayer.GetTeamID())  
 | 
          
 | 
        #×ÜѪÁ¿Óг¬¹ýDWORDµÄÇé¿ö  
 | 
        plusAngryValue = FixValueByValueEx(curNPC.GetMaxHPEx(), plusAngryValue)  
 | 
              
 | 
        #×îСÌí¼Ó³ðºÞֵΪ1  
 | 
        plusAngryValue = max(plusAngryValue , 1)  
 | 
        npcAngry = curNPC.GetNPCAngry()  
 | 
          
 | 
        if addAngryTeam:  
 | 
            GameWorld.DebugLog("NPCÌí¼Ó¶ÓÎé³ðºÞ: teamID=%s,plusAngryValue=%s" % (addAngryTeam.GetTeamID(), plusAngryValue))  
 | 
            for i in xrange(addAngryTeam.GetMemberCount()):  
 | 
                curTeamPlayer = addAngryTeam.GetMember(i)  
 | 
                if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                    continue  
 | 
                  
 | 
                teamPlayerID = curTeamPlayer.GetPlayerID()  
 | 
                # ¹¥»÷Õß¶à1µã³ðºÞ, È·±£ÔÚ¶ÓԱͬ³ðºÞµÄÇé¿öÏÂÓÅÏȹ¥»÷¸Ã¶ÓÔ±  
 | 
                addAngryValue = plusAngryValue + 1 if teamPlayerID == curObjID else plusAngryValue  
 | 
                GameWorld.DebugLog("    i=%s,playerID=%s,addAngryValue=%s" % (i, teamPlayerID, addAngryValue))  
 | 
                self.__AddAngryValue(npcAngry, teamPlayerID, curObjType, addAngryValue, canPile)  
 | 
        else:  
 | 
            self.__AddAngryValue(npcAngry, curObjID, curObjType, plusAngryValue, canPile)  
 | 
          
 | 
        #¼¤»î´ôÖ͵ÄNPC  
 | 
        if GameObj.GetHP(curNPC) > 0 and not curNPC.GetIsNeedProcess() :  
 | 
            curNPC.SetIsNeedProcess(True)  
 | 
  
 | 
          
 | 
        return True  
 | 
      
 | 
    def __AddAngryValue(self, npcAngry, curObjID, curObjType, plusAngryValue, canPile):  
 | 
        angryValue = npcAngry.FindNPCAngry(curObjID, curObjType)  
 | 
      
 | 
        #δ·¢ÏÖ,Ìí¼Ó  
 | 
        if angryValue == None or angryValue.GetAngryValue() == 0:  
 | 
            npcAngry.AddAngry(curObjID, curObjType, plusAngryValue)  
 | 
          
 | 
        #Èç¹ûÐèÒª,µþ¼Ó  
 | 
        elif canPile:  
 | 
            angryValue.SetAngryValue(min(angryValue.GetAngryValue() + plusAngryValue, ChConfig.Def_UpperLimit_DWord))  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ¼ì²éÊÇ·ñ¿ÉÒÔÌí¼Ó³ðºÞ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tagID ¶ÔÏóID  
 | 
    #  @param tagType ¶ÔÏóÀàÐÍ  
 | 
    #  @return ·µ»ØÖµ, ÊÇ·ñ¼ì²éͨ¹ý  
 | 
    #  @remarks ¼ì²éÊÇ·ñ¿ÉÒÔÌí¼Ó³ðºÞ  
 | 
    def __CheckCanAddAngry(self , curObjID , curObjType):  
 | 
        curNPC = self.__Instance  
 | 
  
 | 
        #bug ÒÔǰ·µ»ØTrueµ¼ÖÂÒþÉíÍæ¼Ò·Å·¶Î§¼¼ÄܵÄʱºò·þÎñ¶ËA  
 | 
        curObjDetel = GameWorld.GetObj(curObjID, curObjType)  
 | 
        if not curObjDetel:  
 | 
            GameWorld.Log('###Ìí¼Ó³ðºÞ,ÎÞ·¨²éÕÒÄ¿±êʵÀý = %s , %s' % (curObjID , curObjType))  
 | 
            return False  
 | 
  
 | 
        relation = BaseAttack.GetTagRelation(curNPC, curObjDetel, None, 0)[0]  
 | 
        if relation != ChConfig.Type_Relation_Enemy:  
 | 
            return False  
 | 
          
 | 
        #²»ÊÇÕÙ»½ÊÞ¹¥»÷Ä¿±ê, Ä¿±êÖ±½ÓÌí¼Ó³ðºÞ  
 | 
        if curNPC.GetGameNPCObjType() != IPY_GameWorld.gnotSummon:  
 | 
            return True  
 | 
          
 | 
        curNPCDetel = GameWorld.GetObj(curNPC.GetID(), IPY_GameWorld.gotNPC)  
 | 
        curNPCOwner = GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPCDetel)  
 | 
          
 | 
        if not curNPCOwner:  
 | 
            #ϵͳµÄÕÙ»½ÊÞ , Ä¿±êÖ±½ÓÌí¼Ó³ðºÞ  
 | 
            return True  
 | 
          
 | 
        #ÕÙ»½ÊÞvsÍæ¼Ò  
 | 
        if curObjType == IPY_GameWorld.gotPlayer:  
 | 
                  
 | 
            #×Ô¼º´ò×Ô¼º  
 | 
            if GameWorld.IsSameObj(curNPCOwner, curObjDetel):  
 | 
                return False  
 | 
          
 | 
            #¼ì²é¹¥»÷ģʽ  
 | 
            if not AttackCommon.CheckPlayerAttackMode_Player(curNPCOwner, curObjDetel):  
 | 
                return False  
 | 
              
 | 
        #ÕÙ»½ÊÞvsNPC  
 | 
        elif curObjType == IPY_GameWorld.gotNPC :  
 | 
              
 | 
            if curObjDetel.GetGameNPCObjType() != IPY_GameWorld.gnotSummon:  
 | 
                #ÕÙ»½ÊÞvsÕÙ»½ÊÞ,,Ö±½ÓÌí¼Ó³ðºÞ  
 | 
                return True  
 | 
              
 | 
            curObjOwner = GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curObjDetel)  
 | 
              
 | 
            if not curObjOwner:  
 | 
                #²»Êǹ¥»÷Íæ¼ÒµÄÕÙ»½ÊÞ,Ö±½ÓÌí¼Ó³ðºÞ  
 | 
                return True  
 | 
                  
 | 
            #ͬһÖ÷È˵ÄÕÙ»½ÊÞ²»¹¥»÷  
 | 
            if GameWorld.IsSameObj(curNPCOwner, curObjOwner):  
 | 
                return False  
 | 
              
 | 
            if not AttackCommon.CheckPlayerAttackMode_Player(curNPCOwner, curObjOwner):  
 | 
                return False  
 | 
          
 | 
        #Ö±½ÓÌí¼Ó  
 | 
        return True  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ##ÔÚ³ðºÞ¶ÈÁбíÖÐɾ³ýËÀÍöµÄ¶ÔÏó  
 | 
    # @param self ÀàʵÀý  
 | 
    # @param tick Ê±¼ä´Á  
 | 
    # @return ·µ»ØÖµÎÞÒâÒå  
 | 
    # @remarks ÔÚ³ðºÞ¶ÈÁбíÖÐɾ³ýËÀÍöµÄ¶ÔÏó  
 | 
    def RemoveDeathInAngryList(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
        npcAngry = curNPC.GetNPCAngry()  
 | 
        defaultMaxAngryNPCIDList = GetDefaultMaxAngryNPCIDList()  
 | 
          
 | 
        needResort = False  
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
          
 | 
        #³ðºÞÁбíΪ¹Ì¶¨³¤¶ÈÁбí, ¿ÉÒÔÔÚforÖÐɾ³ý  
 | 
        for i in range(0, npcAngry.GetAngryCount()):  
 | 
              
 | 
            angryValue = npcAngry.GetAngryValueTag(i)  
 | 
            angryID = angryValue.GetObjID()  
 | 
            angryType = angryValue.GetObjType()  
 | 
              
 | 
            #²»¼ì²é¿ÕID  
 | 
            if not angryID:  
 | 
                continue  
 | 
              
 | 
            curObj = GameWorld.GetObj(angryID, angryType)  
 | 
              
 | 
            if not curObj:  
 | 
                #Õâ¸ö¶ÔÏó²»´æÔÚÁË,ɾ³ý  
 | 
                npcAngry.DeleteAngry(angryID, angryType)  
 | 
                needResort = True  
 | 
                continue  
 | 
              
 | 
            if angryType == IPY_GameWorld.gotNPC:  
 | 
                #ĬÈϳðºÞ¶ÔÏó²»ÒƳý  
 | 
                if curObj.GetNPCID() in defaultMaxAngryNPCIDList:  
 | 
                    continue  
 | 
                  
 | 
            if not AttackCommon.CheckCanAttackTag(curNPC, curObj):  
 | 
                #²»¿É¹¥»÷Õâ¸ö¶ÔÏóÁË,ɾ³ý  
 | 
                npcAngry.DeleteAngry(angryID, angryType)  
 | 
                needResort = True  
 | 
                continue  
 | 
              
 | 
            if not self.GetIsInRefreshPoint(curObj.GetPosX(), curObj.GetPosY(), refreshPoint):  
 | 
                npcAngry.DeleteAngry(angryID, angryType)  
 | 
                needResort = True  
 | 
                continue  
 | 
              
 | 
            dist = GameWorld.GetDist(curObj.GetPosX() , curObj.GetPosY() , curNPC.GetPosX() , curNPC.GetPosY())  
 | 
            # ³¬³öÊÓÒ°  
 | 
            if dist > curNPC.GetSight():  
 | 
                npcAngry.DeleteAngry(angryID, angryType)  
 | 
                needResort = True  
 | 
                continue  
 | 
            #¹Ì¶¨NPC£¬³¬³öÊÓÒ°»òÕß¹¥»÷¾àÀë¾Í·ÅÆúÄ¿±ê  
 | 
            if not curNPC.GetSpeed() :  
 | 
                  
 | 
                if not curNPC.CanSeeOther(curObj):  
 | 
                    npcAngry.DeleteAngry(angryID, angryType)  
 | 
                    needResort = True  
 | 
                    continue  
 | 
                  
 | 
                if dist > GetNPCMaxAtkDist(curNPC):  
 | 
                    npcAngry.DeleteAngry(angryID, angryType)  
 | 
                    needResort = True  
 | 
                    continue  
 | 
              
 | 
            #---------------ÒÔÏÂÂß¼Åж¨¹ØÏµ,³ÇÃųýÍâ  
 | 
            if GameWorld.GetNPC_Is_Gate(curNPC):  
 | 
                #³ÇÃŲ»¼ì²éµÐÈ˹ØÏµ,ÒòΪ³ÇÃųðºÞÓÃÀ´·Å¼¼ÄÜ  
 | 
                continue  
 | 
              
 | 
            relation = BaseAttack.GetTagRelation(curNPC, curObj, None, tick)  
 | 
              
 | 
            if relation[0] != ChConfig.Type_Relation_Enemy :  
 | 
                #Õâ¸ö¶ÔÏó²»ÊǵÐÈ˹ØÏµÁË,ɾ³ý  
 | 
                npcAngry.DeleteAngry(angryID, angryType)  
 | 
                needResort = True  
 | 
                continue  
 | 
              
 | 
        return needResort  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ##Íⲿµ÷ÓÃ, NPCˢгðºÞÁÐ±í  
 | 
    # @param tick Ê±¼ä´Á  
 | 
    # @return ·µ»ØÖµÎÞÒâÒå  
 | 
    # @remarks Íⲿµ÷ÓÃ, NPCˢгðºÞÁÐ±í  
 | 
    def RefreshAngryList(self, tick, refreshInterval=ChConfig.Def_NPCRefreshAngryValueInterval, isUpdAngry=False):  
 | 
        curNPC = self.__Instance  
 | 
        npcAngry = curNPC.GetNPCAngry()  
 | 
          
 | 
        #---¼ì²â¼ä¸ô  
 | 
        lastTick = tick - npcAngry.GetLastResortTick()  
 | 
          
 | 
        # resort»áÖØÖÃtick  
 | 
        if lastTick < (refreshInterval):  
 | 
            return  
 | 
          
 | 
        #ɾ³ý²»¿É¹¥»÷µÄ¶ÔÏó GetIsNeedProcess ÎªfalseʱӦ¸Ã±£Ö¤³ðºÞÒ²ÊÇ¿ÕµÄ  
 | 
        #if not curNPC.GetIsNeedProcess():  
 | 
        removeRsort = self.RemoveDeathInAngryList(tick)  
 | 
  
 | 
        #Ö÷¶¯¹ÖÌí¼ÓÊÓÒ°¶ÔÏó³ðºÞ  
 | 
        needResort = self.AddInSightObjToAngryList(tick, isUpdAngry) or removeRsort  
 | 
          
 | 
        #ѪÁ¿²»Îª0ʱ²Å MoveBack£¬²»È»»áµ¼ÖÂËÀÍöʱˢеÄʱºò³ðºÞÁÐ±í¡¢ÉËѪÁÐ±í±»Çå¿Õ; ÓÐÕóÓªµÄ²»´¦Àí MoveBack  
 | 
        if removeRsort and self.GetMaxAngryTag() == None and GameObj.GetHP(curNPC) and not GetFaction(curNPC):  
 | 
            # ³ðºÞÇå¿ÕʱÎÞгðºÞ¼°Ê±»ØÎ»  
 | 
            if curNPC.GetSpeed() != 0:  
 | 
                self.MoveBack()  
 | 
              
 | 
        if isUpdAngry or needResort:  
 | 
            #ÅÅÐò³ðºÞ  
 | 
            npcAngry.Resort(tick)  
 | 
        else:  
 | 
            npcAngry.SetLastResortTick(tick)  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## »ñµÃ×î´ó³ðºÞ¶ÔÏó  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµ, ×î´ó³ðºÞ¶ÔÏó  
 | 
    #  @remarks »ñµÃ×î´ó³ðºÞ¶ÔÏó  
 | 
    def GetMaxAngryTag(self):  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        angryManager = curNPC.GetNPCAngry()  
 | 
          
 | 
        for i in range(0, angryManager.GetAngryCount()) :  
 | 
            curAngry = angryManager.GetAngryValueTag(i)  
 | 
              
 | 
            if not self.__IsValidAngryObj(curAngry):  
 | 
                continue  
 | 
              
 | 
            #ÓÐÕâ¸ö³ðºÞ¶È, ²¢ÇÒ¿ÉÒÔ¹¥»÷Õâ¸öÈË  
 | 
            #ÔÚÇ°ÃæÒѾÅÅÐò¹ýÁË  
 | 
            return curAngry  
 | 
          
 | 
        return None  
 | 
      
 | 
      
 | 
    ## Åж¨³ðºÞ¶ÔÏóÊÇ·ñÓÐЧ  
 | 
    #  @param self curAngry ÀàʵÀý  
 | 
    #  @return ·µ»Ø¶ÔÏó  
 | 
    def __IsValidAngryObj(self, curAngry):  
 | 
        if curAngry == None or curAngry.GetObjID() == 0:  
 | 
            return None  
 | 
          
 | 
        #³ðºÞÖµ  
 | 
        curAngryValue = curAngry.GetAngryValue()  
 | 
          
 | 
        if curAngryValue == 0:  
 | 
            return None  
 | 
          
 | 
        if curAngry.GetIsDisable():  
 | 
            return None  
 | 
      
 | 
        return curAngry  
 | 
      
 | 
      
 | 
    ## Çå¿ÕNPC³ðºÞ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Çå¿ÕNPC³ðºÞ  
 | 
    def ClearNPCAngry(self):  
 | 
        curNPC = self.__Instance  
 | 
        curAngry = curNPC.GetNPCAngry()  
 | 
        curAngry.Clear()  
 | 
        return True  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## Çå¿ÕNPCÉËѪÁÐ±í  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Çå¿ÕNPCÉËѪÁÐ±í  
 | 
    def ClearNPCHurtList(self):  
 | 
        curNPC = self.__Instance  
 | 
        #Çå¿ÕÉËѪÁÐ±í  
 | 
        npcHurtList = curNPC.GetPlayerHurtList()  
 | 
        npcHurtList.Clear()  
 | 
        return True  
 | 
      
 | 
    def IsInHurtProtect(self):  
 | 
        '''NPCÊÇ·ñÉËѪ±£»¤ÖÐ  
 | 
        ÒòΪÊÖÓαȽϻá³öÏÖÍøÂçÇл»µÄÇé¿ö£¬´Ëʱ»á¿ÉÄÜ»áÒýÆðµôÏßÖØÁ¬  
 | 
        ËùÒÔÕë¶ÔÊÖÓÎ×öÁ˵ôÏß3·ÖÖÓÄÚÉËѪ±£»¤£¬·ÀÖ¹Íæ¼ÒÖØÁ¬ºóÉËѪ±»Çå¿Õ£¬ÌåÑé²»ºÃ£»  
 | 
        '''  
 | 
        curNPC = self.__Instance  
 | 
        return curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_InHurtProtect)  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## Çå¿ÕËùÓÐBuff  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Çå¿ÕËùÓÐBuff  
 | 
    def ClearAllBuff(self, isClearAuraBuff=True):  
 | 
        curNPC = self.__Instance  
 | 
        #»ñµÃNPCBuff¹ÜÀíÆ÷  
 | 
        buffRefreshList = GetNPCBuffRefreshList(curNPC, True, isClearAuraBuff)  
 | 
          
 | 
        for buffState, canPileup in buffRefreshList:  
 | 
            buffState.Clear()  
 | 
  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## Çå¿ÕËùÓÐNPC״̬  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Çå¿ÕËùÓÐNPC״̬  
 | 
    def __ClearNPCAllState(self, isClearAuraBuff=True):  
 | 
        #Çå³ý³ðºÞ  
 | 
        self.ClearNPCAngry()  
 | 
        #Çå³ýÉËѪÁÐ±í  
 | 
        self.ClearNPCHurtList()  
 | 
        #Çå³ýËùÓÐÉíÉÏbuff  
 | 
        self.ClearAllBuff(isClearAuraBuff)  
 | 
        curNPC = self.__Instance  
 | 
        NPCHurtManager.ClearPlayerHurtList(curNPC)  
 | 
        NPCHurtMgr.ClearPlayerHurtList(curNPC)  
 | 
        return True  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÖØÖÃNPC״̬  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ÖØÖÃNPC״̬  
 | 
    def ResetNPC_Init(self, isReborn=False):  
 | 
        curNPC = self.__Instance  
 | 
        #Çå³ý״̬  
 | 
        self.__ClearNPCAllState(False)  
 | 
        #Ö»ÔÚÖØÉú»òÕßÂúѪµÄ״̬ϲÅÖØÖÃÒÔÏÂÄÚÈÝ  
 | 
        if isReborn or GameObj.GetHP(curNPC) >= GameObj.GetMaxHP(curNPC):  
 | 
            #³õʼ»¯ÕÙ»½ÊÞ  
 | 
            self.__InitNPCSummon()  
 | 
            #ÖØÖü¼ÄÜCD  
 | 
            self.__NormalNPCInItCD()  
 | 
              
 | 
        #ÖØË¢ÊôÐÔ  
 | 
        self.RefreshNPCState(isReborn=isReborn)  
 | 
        #֪ͨѪÁ¿, ¸´»îµÄÇé¿ö²»Í¨ÖªÑªÁ¿£¬ÓÉNPC³öÏÖ°ü֪ͨ  
 | 
        if not isReborn:  
 | 
            curNPC.Notify_HPEx()  
 | 
  
 | 
        #ÕâÀï²»ÉèÖÃΪÂýËÙ´¦Àí,ÒòΪNPCÓпÉÄÜδÂúѪ   
 | 
        #¸ÄΪÔÚ¿ÕÏлØÑª,Èç¹ûÂúѪµÄʱºòÉèÖÃΪÂýËÙ´¦Àí  
 | 
        #curNPC.SetIsNeedProcess(False)  
 | 
        return True  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## »¹Ô¼¼ÄÜCD  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks »¹Ô¼¼ÄÜCD  
 | 
    def __NormalNPCInItCD(self):  
 | 
        curNPC = self.__Instance  
 | 
        #»¹ÔÆÕ¹¥¼ä¸ô  
 | 
        curNPC.SetAttackTick(0)  
 | 
        #»¹Ô¼¼Äܹ«¹²¼ä¸ô  
 | 
        curNPC.SetUseSkillTick(0)  
 | 
        curNPCManager = curNPC.GetSkillManager()  
 | 
        #»¹Ôµ¥¸ö¼¼Äܼä¸ô  
 | 
        for i in range(curNPCManager.GetSkillCount()):  
 | 
            curNPCSkill = curNPCManager.GetSkillByIndex(i)  
 | 
            if curNPCSkill == None:  
 | 
                continue  
 | 
            curNPCSkill.SetLastUseTick(0)  
 | 
              
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ³õʼ»¯NPCÕÙ»½ÊÞ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ³õʼ»¯NPCÕÙ»½ÊÞ  
 | 
    def __InitNPCSummon(self):  
 | 
        #½«Éæ¼°µ½C++ÖÐÁбíɾ³ýµÄ¹¦ÄÜ,ͳһ¸Ä³É -> ¸´ÖÆPyÁбíºó,È»ºó½øÐÐɾ³ýÂß¼ (ÒòWhileÓм¸Âʽ«µ¼ÖÂËÀËø)  
 | 
        curNPC = self.__Instance  
 | 
        curNPC_Summon_List = []  
 | 
        for index in range(curNPC.GetSummonCount()):  
 | 
            summonNPC = curNPC.GetSummonNPCAt(index)  
 | 
            curNPC_Summon_List.append(summonNPC)  
 | 
          
 | 
        for curSummonNPC in curNPC_Summon_List:  
 | 
            SetDeadEx(curSummonNPC)  
 | 
          
 | 
        return  
 | 
          
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPC×ßѲÂßµãÒÆ¶¯  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks NPC×ßѲÂßµãÒÆ¶¯  
 | 
    def __PatrolMove(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
        #NPC×ßѲÂߵ㣬»ñȡѲÂßµã×ø±ê  
 | 
        patrolIndex = curNPC.GetCurPatrolIndex()  
 | 
        patrolPos = curNPC.GetPatrolPosAt(patrolIndex)  
 | 
        patrolPosX = patrolPos.GetPosX()  
 | 
        patrolPosY = patrolPos.GetPosY()  
 | 
        curNPC_PosX = curNPC.GetPosX()  
 | 
        curNPC_PosY = curNPC.GetPosY()  
 | 
          
 | 
        #---µ±Ç°Î»Öò»ÔÚѲÂßµã×ø±ê, ¿ìËÙ±¼ÅÜÖÁѲÂßµã  
 | 
        if curNPC.GetCurMoveType() != IPY_GameWorld.mtSlow and \  
 | 
                (curNPC_PosX != patrolPosX or curNPC_PosY != patrolPosY):  
 | 
            #Çл»ÖÁ¿ìËÙÒÆ¶¯×´Ì¬  
 | 
            ChangeNPCMoveType(curNPC, IPY_GameWorld.mtRun)  
 | 
            #GameWorld.Log('%s - ¼ì²éµ±Ç°Î»ÖÃÊÇ·ñΪѲÂßµã×ø±ê speed = %s, patrolPosX=%s, patrolPosY=%s'%(curNPC.GetName(), curNPC.GetSpeed(), patrolPosX, patrolPosY))  
 | 
            curNPC.Move(patrolPosX, patrolPosY)  
 | 
            return  
 | 
          
 | 
        #---½ÇÉ«ÒѾÔÚѲÂßµãÉÏ, Òƶ¯µ½ÏÂÒ»¸öѲÂßµã---  
 | 
          
 | 
        #»¹Î´µ½¿ÉÒÔÒÆ¶¯µÄʱ¼ä  
 | 
        #if not IsInActionTime(patrolPos.GetMinStopTime(), patrolPos.GetMaxStopTime(), tick, curNPC.GetActionTick()):  
 | 
        if not IsInActionTime(tick, curNPC.GetActionTick()):  
 | 
            return  
 | 
         
 | 
        #ÊÇ·ñΪ×îºóÒ»¸öѲÂßµã,  
 | 
        patrolIndex = patrolIndex + 1  
 | 
          
 | 
        if patrolIndex >= curNPC.GetPatrolPosCount():  
 | 
            patrolIndex = 0  
 | 
          
 | 
        #ÉèÖÃÏÂÒ»¸öѲÂߵ㠠   
 | 
        curNPC.SetCurPatrolIndex(patrolIndex)  
 | 
        #»ñÈ¡ÏÂÒ»¸öѲÂßµã×ø±ê  
 | 
        patrolPos = curNPC.GetPatrolPosAt(patrolIndex)  
 | 
        patrolPosX = patrolPos.GetPosX()  
 | 
        patrolPosY = patrolPos.GetPosY()  
 | 
          
 | 
        #¼ÓÈëÒ»¸ö·À·¶, Èç¹ûÖ»ÓÐÒ»¸öˢеã, »òÕßË¢ÐÂµã²¼ÖØ¸´, NPC²»Òƶ¯  
 | 
        if curNPC_PosX == patrolPosX and curNPC_PosY == patrolPosY:  
 | 
            return  
 | 
              
 | 
        #ÒÆ¶¯µ½Ñ²Âßµã  
 | 
        #Çл»ÖÁÂýËÙÒÆ¶¯×´Ì¬  
 | 
        ChangeNPCMoveType(curNPC, IPY_GameWorld.mtSlow)  
 | 
        curNPC.Move(patrolPosX, patrolPosY)  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPCÆÕÍ¨ÒÆ¶¯  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks NPCÆÕÍ¨ÒÆ¶¯  
 | 
    def DoNormalNPCMove(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        if curNPC.GetPatrolPosCount() > 0:  
 | 
            self.__PatrolMove(tick)  
 | 
            return  
 | 
          
 | 
        #µÃµ½·¶Î§ÄÚËæ»úÒ»¸öµã, ÆÕͨС¹Ö×ß·¨  
 | 
        PosMap = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        if not PosMap:  
 | 
            return  
 | 
        moveArea = min(curNPC.GetMoveArea(), 2)  
 | 
  
 | 
        posX = curNPC.GetPosX()  
 | 
        posY = curNPC.GetPosY()  
 | 
        minMovePosX = posX - moveArea  
 | 
        maxMovePosX = posX + moveArea  
 | 
        minMovePosY = posY - moveArea  
 | 
        maxMovePosY = posY + moveArea  
 | 
  
 | 
        #·¶Î§Ð£Ñé  
 | 
        posMapX = PosMap.GetPosX()  
 | 
        posMapY = PosMap.GetPosY()  
 | 
        posMapArea = PosMap.GetArea()  
 | 
          
 | 
        minMovePosX = max(minMovePosX, posMapX - posMapArea)  
 | 
        maxMovePosX = min(maxMovePosX, posMapX + posMapArea)  
 | 
        minMovePosY = max(minMovePosY, posMapY - posMapArea)  
 | 
        maxMovePosY = min(maxMovePosY, posMapY + posMapArea)  
 | 
          
 | 
        if minMovePosX > maxMovePosX:  
 | 
            #NPCÒÆ¶¯Òì³£, Ë³ÒÆ»ØÈ¥  
 | 
            self.MoveBack()  
 | 
            return  
 | 
          
 | 
          
 | 
        if minMovePosY > maxMovePosY:  
 | 
            #NPCÒÆ¶¯Òì³£, Ë³ÒÆ»ØÈ¥  
 | 
            self.MoveBack()  
 | 
            return  
 | 
          
 | 
        #δµ½Òƶ¯Ê±¼ä  
 | 
        #if not IsInActionTime(curNPC.GetMinStopTime(), curNPC.GetMaxStopTime(), tick, curNPC.GetActionTick()):  
 | 
        if not IsInActionTime(tick, curNPC.GetActionTick()):      
 | 
            return  
 | 
          
 | 
        posX = random.randint(minMovePosX, maxMovePosX)  
 | 
        posY = random.randint(minMovePosY, maxMovePosY)  
 | 
          
 | 
        #Çл»ÖÁÂýËÙÒÆ¶¯×´Ì¬  
 | 
        ChangeNPCMoveType(curNPC, IPY_GameWorld.mtSlow)  
 | 
        #»ñµÃÒÆ¶¯µÄµã  
 | 
        newPoint = GameWorld.GetMap().LineNearToPos(curNPC.GetPosX(), curNPC.GetPosY(),  
 | 
                                                        posX, posY, 0)  
 | 
#       if posX != newPoint.GetPosX() or posY != newPoint.GetPosY():  
 | 
#           GameWorld.Log("Ô×ø±êX = %s,Y = %s ,ÐÞÕý×ø±ê X= %s,Y = %s"%(posX,posY,newPoint.GetPosX(),newPoint.GetPosY()))  
 | 
        #NPCÒÆ¶¯  
 | 
        curNPC.Move(newPoint.GetPosX(), newPoint.GetPosY())  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## µÃµ½Ë¢Ð·¶Î§ÄÚËæ»úµÄÒ»µã×ø±ê[x,y]  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return [x,y]  
 | 
    #  @remarks µÃµ½Ë¢Ð·¶Î§ÄÚËæ»úµÄÒ»µã×ø±êX  
 | 
    def GetRandPosInRefreshArea(self):  
 | 
        return GameWorld.GetPsycoFunc(self.__Func_GetRandPosInRefreshArea)()  
 | 
      
 | 
    ## µÃµ½Ë¢Ð·¶Î§ÄÚËæ»úµÄÒ»µã×ø±ê[x,y]  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return [x,y]  
 | 
    #  @remarks µÃµ½Ë¢Ð·¶Î§ÄÚËæ»úµÄÒ»µã×ø±êX  
 | 
    def __Func_GetRandPosInRefreshArea(self):  
 | 
        curNPC = self.__Instance  
 | 
        #µÃµ½µØÍ¼Ë¢Ð嵋  
 | 
        posMap = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        #·¶Î§Ð£Ñé  
 | 
        posMapX = posMap.GetPosX()  
 | 
        posMapY = posMap.GetPosY()  
 | 
          
 | 
        if curNPC.GetType() == IPY_GameWorld.ntFunctionNPC: #¹¦ÄÜNPC  
 | 
            posMapArea = 0  
 | 
        else:  
 | 
            posMapArea = posMap.GetArea()  
 | 
          
 | 
        #»ñÈ¡·¶Î§ÄÚÒ»µã¿ÉÒÔÒÆ¶¯µÄµã  
 | 
        posX, poxY = GameMap.GetNearbyPosByDis(posMapX, posMapY, posMapArea)  
 | 
          
 | 
        if posX == 0 and poxY == 0:  
 | 
            return [posMapX, posMapY]  
 | 
          
 | 
        return posX, poxY  
 | 
  
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÊÇ·ñÔÚÒÆ¶¯·¶Î§ÄÚ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÕæ, ÔÚÒÆ¶¯·¶Î§ÄÚ  
 | 
    #  @remarks ÊÇ·ñÔÚÒÆ¶¯·¶Î§ÄÚ  
 | 
    def IsInRefreshArea(self):  
 | 
        #Õâ¸öNPCÊÇ·ñÔÚÒÆ¶¯·¶Î§ÄÚ  
 | 
        curNPC = self.__Instance  
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        #GameWorld.Log("posX = %d posY = %d, dist = %d"%(refreshPoint.GetPosX(), refreshPoint.GetPosY(), refreshPoint.GetMoveDist()))  
 | 
        if self.GetIsInRefreshPoint(curNPC.GetPosX() , curNPC.GetPosY() , refreshPoint):  
 | 
            return True  
 | 
          
 | 
        #ÅжÏÊÇ·ñÕýÔÚÅÜ»ØÄ¿µÄµØ  
 | 
        if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove and \  
 | 
                    curNPC.GetCurMoveType() == IPY_GameWorld.mtRun :  
 | 
            #ÅжÏÄ¿µÄµØÊÇ·ñÔÚˢеãÄÚ  
 | 
            if self.GetIsInRefreshPoint(curNPC.GetDestPosX() , curNPC.GetDestPosY() , refreshPoint):  
 | 
                return True  
 | 
          
 | 
        return False  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÊÇ·ñÔÚˢеãÄÚ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param curPosX ×ø±êX  
 | 
    #  @param curPosY ×ø±êY  
 | 
    #  @param refreshPoint Ë¢ÐµãʵÀý  
 | 
    #  @return ·µ»ØÖµÕæ, ÔÚˢеãÄÚ  
 | 
    #  @remarks ÊÇ·ñÔÚˢеãÄÚ  
 | 
    def GetIsInRefreshPoint(self, curPosX, curPosY, refreshPoint):  
 | 
        if not refreshPoint:  
 | 
            return False  
 | 
          
 | 
        if (curPosX >= refreshPoint.GetPosX() - refreshPoint.GetMoveDist() and  
 | 
                curPosX <= refreshPoint.GetPosX() + refreshPoint.GetMoveDist() and  
 | 
                curPosY >= refreshPoint.GetPosY() - refreshPoint.GetMoveDist() and  
 | 
                curPosY <= refreshPoint.GetPosY() + refreshPoint.GetMoveDist()):  
 | 
            return True  
 | 
          
 | 
        return False  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## »Øµ½Ë¢Ð嵋  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks »Øµ½Ë¢Ð嵋  
 | 
    def MoveBack(self):  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        patrolCount = curNPC.GetPatrolPosCount()  
 | 
        #Èç¹ûNPCÓÐѲÂßµã, »Øµ½Ëæ»úÒ»¸öѲÂßµã, Èç¹ûûÓÐ, ÔòËæ»úÔÚˢз¶Î§ÄÚÕÒÒ»¸öµã  
 | 
        if patrolCount > 0:  
 | 
            patrolIndex = random.randint(0, patrolCount - 1)  
 | 
            patrolPos = curNPC.GetPatrolPosAt(patrolIndex)  
 | 
            posX = patrolPos.GetPosX()  
 | 
            posY = patrolPos.GetPosY()  
 | 
        else:  
 | 
            posX, posY = self.GetRandPosInRefreshArea()  
 | 
          
 | 
        #---×ß·»ØÈ¥Âß¼---  
 | 
          
 | 
        #³õʼ»¯, ·ÇÉËѪ±£»¤ÖвÅÖØÖà  
 | 
        if not self.IsInHurtProtect():  
 | 
            self.ResetNPC_Init()  
 | 
        #Çл»ÖÁ¿ìËÙÒÆ¶¯×´Ì¬, ²¢ÇÒ¼¤»î³¬¼¶Òƶ¯  
 | 
        ChangeNPCMoveType(curNPC, IPY_GameWorld.mtRun, True)  
 | 
        curNPC.Move(posX, posY)  
 | 
        #Ë²ÒÆ»ØÈ¥  
 | 
        #curNPC.ResetPos(posX, posY)  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÖØÉú  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ÖØÉú  
 | 
    def DoNPCReborn(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
        #ÖØÖÃNPCµÄÖØÉúµã  
 | 
        curNPC.SetCurRefreshPointIndex(random.randint(0 , curNPC.GetRefreshPosCount() - 1))  
 | 
        #¿ªÊ¼ÖØÉú  
 | 
        posX, posY = self.GetRandPosInRefreshArea()  
 | 
        #¸´»î  
 | 
        curNPC.Reborn(posX, posY, False)  
 | 
        self.DoNPCRebornCommLogic(tick)  
 | 
        return 1  
 | 
      
 | 
    ## NPCÖØÉúͨÓÃÂß¼(²¼¹Öµã¼°Ë¢Ð±êʶµãͨÓÃ)  
 | 
    def DoNPCRebornCommLogic(self, tick):   
 | 
        curNPC = self.__Instance  
 | 
        #³õʼ»¯  
 | 
        self.ResetNPC_Init(True)  
 | 
        #ÉèÖÃΪ×î´óѪÁ¿  
 | 
        GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC))  
 | 
        #ÉèÖÃˢгðºÞ¼ä¸ô  
 | 
        curNPC.GetNPCAngry().SetLastResortTick(tick)  
 | 
        #֪ͨ¸´»îÌáʾ  
 | 
        self.RebornNotify()  
 | 
        #ÖØÖðٷֱÈÂß¼±êʶ  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_HPPerLogicMark, 0)  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_RebornPreNotifyIndex, 0)  
 | 
        ChNPC.OnNPCReborn(curNPC)  
 | 
        FBLogic.DoFBRebornNPC(curNPC, tick)  
 | 
          
 | 
        curNPCID = curNPC.GetNPCID()  
 | 
              
 | 
        # °µ½ðboss  
 | 
        if ChConfig.IsGameBoss(curNPC):  
 | 
            # Í¨Öª¿Í»§¶ËbossË¢ÐÂÌáÐÑ¿ªÆô  
 | 
            #PlayerControl.WorldNotify(0, "Old_andyshao_671654", [curNPCID])  
 | 
            # Í¨ÖªGameServer bossˢгɹ¦  
 | 
            ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', curNPCID)  
 | 
            if ipyData:  
 | 
                GameServe_GameWorldBossState(curNPCID, 1)  
 | 
                if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:  
 | 
                    FamilyRobBoss.FamilyOwnerBossOnReborn(curNPC)  
 | 
                      
 | 
        # ¼ì²éÊÇ·ñÓй⻷, ÔÚÖØÉúʱ´¦Àí£¬²»È»¿ÉÄܵ¼ÖÂÓÐЩÎÞÕ½¶·Âß¼µÄ¹ÖÎïÎÞ·¨Ì×ÉϹ⻷buff  
 | 
        skillManager = curNPC.GetSkillManager()  
 | 
        for index in xrange(skillManager.GetSkillCount()):  
 | 
            useSkill = skillManager.GetSkillByIndex(index)  
 | 
            #ÒѾµ½Î²²¿ÁË  
 | 
            if not useSkill or useSkill.GetSkillTypeID() == 0:  
 | 
                break  
 | 
            if useSkill.GetSkillType() != ChConfig.Def_SkillType_Aura:  
 | 
                continue  
 | 
            GameWorld.DebugLog("NPC¸´»î£¬Ì×ÉϹ⻷: objID=%s,npcID=%s,skillID=%s" % (curNPC.GetID(), curNPC.GetNPCID(), useSkill.GetSkillID()))  
 | 
            SkillShell.NPCUseSkill(curNPC, useSkill, tick)  
 | 
              
 | 
        curNPC.NotifyAppear() # ×îÖÕͳһ֪ͨNPC³öÏÖ  
 | 
        self.NotifyNPCShow(curNPCID, tick) # ¹ã²¥NPCÐã  
 | 
        return  
 | 
      
 | 
    def NotifyNPCShow(self, npcID, tick):  
 | 
        ## ¹ã²¥NPCÐã  
 | 
        mapID = GameWorld.GetMap().GetMapID()  
 | 
        npcShowIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCShow", npcID, mapID)  
 | 
        if not npcShowIpyData:  
 | 
            #GameWorld.DebugLog("²»ÐèÒªNPCÐã: npcID=%s" % npcID)  
 | 
            return  
 | 
        #if npcShowIpyData.GetBindMissionID():  
 | 
        #    #GameWorld.DebugLog("Óаó¶¨ÈÎÎñIDµÄ£¬Ç°¶Ë×Ô¼ºÕ¹Ê¾NPCÐ㣡mapID=%s,npcID=%s" % (mapID, npcID))  
 | 
        #    return  
 | 
        if npcShowIpyData.GetShowType():  
 | 
            #GameWorld.DebugLog("ǰ¶Ë×Ô¼ºÕ¹Ê¾µÄNPCÐ㣡mapID=%s,npcID=%s" % (mapID, npcID))  
 | 
            return  
 | 
        endTick = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FBDict_NPCShowEndTick % npcID)  
 | 
        if endTick:  
 | 
            #GameWorld.DebugLog("ÒѾ´æÔÚͬ¸öNPCIDµÄNPCÐ㣬²»Öظ´Õ¹Ê¾£¡npcID=%s" % (npcID))  
 | 
            return  
 | 
        endTick = tick + npcShowIpyData.GetProtectTime()  
 | 
        GameWorld.GetGameFB().SetGameFBDict(ChConfig.Def_FBDict_NPCShowEndTick % npcID, endTick)  
 | 
          
 | 
        # ¹ã²¥µØÍ¼ÄÚÍæ¼ÒչʾNPCÐã  
 | 
        npcShowPack = ChPyNetSendPack.tagMCNPCShow()  
 | 
        npcShowPack.NPCID = npcID  
 | 
        playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
        for index in xrange(playerManager.GetPlayerCount()):  
 | 
            player = playerManager.GetPlayerByIndex(index)  
 | 
            if not player.GetPlayerID():  
 | 
                continue  
 | 
            NetPackCommon.SendFakePack(player, npcShowPack)  
 | 
              
 | 
        GameWorld.DebugLog("¿ªÊ¼NPCÐã: npcID=%s,tick=%s,endTick=%s" % (npcID, tick, endTick))  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÖØÉúÈ«·þ¹ã²¥  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    def RebornNotify(self):  
 | 
        #֪ͨ¸´»îÌáʾ  
 | 
        #self.__NotifyBossReborn()  
 | 
      
 | 
        #֪ͨnpc¸´»îÌáʾ  
 | 
        #self.__NotifySpecialNPCReborn()  
 | 
        return  
 | 
  
 | 
    #---------------------------------------------------------------------  
 | 
  
 | 
    ## NPCÊ£ÓàѪÁ¿°Ù·Ö±ÈÂß¼  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param dropType µôÂäÀàÐÍ  
 | 
    #  @param ownerID ÓµÓÐÕßid  
 | 
    #  @return  
 | 
    def DoHPPerLogic(self, dropType, ownerID):  
 | 
        curNPC = self.__Instance  
 | 
        curNPCID = curNPC.GetNPCID()  
 | 
          
 | 
        hpPerLogicNPCIDDict = IpyGameDataPY.GetFuncEvalCfg('BossHPInformation', 1, {})  
 | 
        hpPerLogicList = GameWorld.GetDictValueByKey(hpPerLogicNPCIDDict, curNPCID)  
 | 
        if not hpPerLogicList:  
 | 
            return  
 | 
        hpPerList, sysMark = hpPerLogicList  
 | 
        hpPerList = sorted(hpPerList, reverse=True)  
 | 
        nowHPPer = GameObj.GetHP(curNPC) * 100 / GameObj.GetMaxHP(curNPC) # µ±Ç°°Ù·Ö±È  
 | 
        hpPerLogicMark = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_HPPerLogicMark)  
 | 
        logicHPPerList = hpPerList[hpPerLogicMark:]  
 | 
        #[80, 60, 40, 20, 10, 5]  
 | 
        for hpPer in logicHPPerList:  
 | 
              
 | 
            if nowHPPer > hpPer:  
 | 
                break  
 | 
              
 | 
            #GameWorld.DebugLog("DoHPPerLogic npcID=%s,hpPerLogicDict=%s,nowHPPer=%s,hpPerLogicMark=%s,logicHPPerList=%s"   
 | 
            #                   % (curNPCID, str(hpPerLogicDict), nowHPPer, hpPerLogicMark, str(logicHPPerList)))  
 | 
              
 | 
  
 | 
            PlayerControl.WorldNotify(0, sysMark, [curNPCID, hpPer])  
 | 
              
 | 
#            if dropItemTemplate > 0:  
 | 
#                self.__DropItemByTemplate(dropItemTemplate, dropType, ownerID)  
 | 
#                PlayerControl.WorldNotify(0, "GeRen_admin_481766", [GameWorld.GetMap().GetMapID(), curNPCID, curNPCID])  
 | 
              
 | 
            hpPerLogicMark += 1  
 | 
            #GameWorld.DebugLog("DoHPPerLogic update hpPerLogicMark=%s" % (hpPerLogicMark))  
 | 
                  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_HPPerLogicMark, hpPerLogicMark)  
 | 
        return  
 | 
      
 | 
      
 | 
    ## ¸ø¸½½üÍæ¼Ò¼Ó¹¦Ñ«  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param addPrestigeFormat ¼Ó¹¦Ñ«¹«Ê½  
 | 
    #  @param matrix ·¶Î§´óС  
 | 
    #  @return  
 | 
    def __GiveNearbyPlayerPrestige(self, addPrestigeFormat, matrix=ChConfig.Def_Matrix_Three):  
 | 
#        if addPrestigeFormat == '':  
 | 
#            return  
 | 
#        curNPC = self.__Instance  
 | 
#        npcPosX = curNPC.GetPosX()  
 | 
#        npcPosY = curNPC.GetPosY()  
 | 
#        npcLV = curNPC.GetLV()  
 | 
#        gameMap = GameWorld.GetMap()  
 | 
#          
 | 
#        for curPos in matrix:  
 | 
#          
 | 
#            #¼ì²éÓÐûÓжÔÏóÔÚÕâÒ»µãÉÏ  
 | 
#            mapObj = gameMap.GetPosObj(npcPosX + curPos[0], npcPosY + curPos[1])  
 | 
#              
 | 
#            if not mapObj:  
 | 
#                continue  
 | 
#          
 | 
#            #±éÀúµ±Ç°µã¶ÔÏó  
 | 
#            for i in range(0, mapObj.GetObjCount()):  
 | 
#              
 | 
#                curObj = mapObj.GetObjByIndex(i)  
 | 
#                curObjType = curObj.GetGameObjType()  
 | 
#                  
 | 
#                #²»ÊÇÍæ¼Ò£¬Ìø¹ý  
 | 
#                if curObjType != IPY_GameWorld.gotPlayer:  
 | 
#                    continue  
 | 
#                  
 | 
#                curTag = GameWorld.GetObj(curObj.GetID(), curObjType)  
 | 
#                if not curTag:  
 | 
#                    continue  
 | 
#                playerLV = curTag.GetLV()  
 | 
#                addPrestige = eval(addPrestigeFormat)  
 | 
#                PlayerPrestigeSys.AddPrestigeOffcialLV(curTag, addPrestige, ChConfig.Def_AddPrestige_NPC)  
 | 
  
 | 
        return  
 | 
          
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPCËÀµÄʱºò, ¼ì²é×Ô¼ºÊÇ·ñÐèÒªÖØÉú. 0: tickºóÈÔÈ»ËÀÍö 1: tickºó¿ÉÒÔÖØÉú  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÕæ, ÖØÉú³É¹¦  
 | 
    #  @remarks NPCËÀµÄʱºò, ¼ì²é×Ô¼ºÊÇ·ñÐèÒªÖØÉú. 0: tickºóÈÔÈ»ËÀÍö 1: tickºó¿ÉÒÔÖØÉú  
 | 
    def DieTick(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        if curNPC.GetRefreshTime() == 0:  
 | 
            #Ë¢ÐÂʱ¼äΪ0, ²»Ë¢Ð  
 | 
            return 0  
 | 
          
 | 
        if curNPC.GetActionTick() == 0:  
 | 
            GameWorld.DebugLog("¼ì²âµ½NPC¿ìËÙ¸´»î %s" % curNPC.GetID())  
 | 
            curNPC.SetActionTick(tick)  
 | 
              
 | 
        remainTime = curNPC.GetRefreshTime() - (tick - curNPC.GetActionTick())  
 | 
        if remainTime >= 0:  
 | 
            #NPCËÀÍöʱ¼ä²»µ½Ë¢ÐÂʱ¼ä  
 | 
            #self.__DoNPCRebornPreNotify(curNPC, remainTime)  
 | 
            return 0  
 | 
          
 | 
        self.DoNPCReborn(tick)  
 | 
        return 1  
 | 
      
 | 
    def __DoNPCRebornPreNotify(self, curNPC, remainTime):  
 | 
        # ÔÝʱ¹Ø±Õ  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        preRebornNotifyNPCDict = ReadChConfig.GetEvalChConfig("RebornPreNotifyNPC")  
 | 
        if npcID not in preRebornNotifyNPCDict:  
 | 
            return  
 | 
        notifyMinuteList, notifyMark = preRebornNotifyNPCDict[npcID]  
 | 
        notifyIndex = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_RebornPreNotifyIndex)  
 | 
        if notifyIndex >= len(notifyMinuteList):  
 | 
            return  
 | 
          
 | 
        reaminM = int(math.ceil(remainTime / 60000.0))  
 | 
        notifyMinute = notifyMinuteList[notifyIndex]  
 | 
        if reaminM > notifyMinute:  
 | 
            return  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_RebornPreNotifyIndex, notifyIndex + 1)  
 | 
        mapID = GameWorld.GetGameWorld().GetMapID()  
 | 
        PlayerControl.WorldNotify(0, notifyMark, [npcID, npcID, notifyMinute, mapID, npcID, npcID])  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## Ë¢ÐÂNPCÊôÐÔºÍÐÐΪ״̬  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param canSyncClient ÊÇ·ñ֪ͨ¿Í»§¶ËË¢ÐÂÐÅÏ¢(³èÎï)  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Ë¢ÐÂNPCÊôÐÔºÍÐÐΪ״̬  
 | 
    def RefreshNPCState(self, canSyncClient=True, isReborn=False):  
 | 
        self.RefreshNPCAttrState(canSyncClient, isReborn)  
 | 
          
 | 
        self.RefreshNPCActionState()  
 | 
  
 | 
  
 | 
          
 | 
    ## Ë¢ÐÂNPCÊôÐÔ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param canSyncClient ÊÇ·ñ֪ͨ¿Í»§¶ËË¢ÐÂÐÅÏ¢(³èÎï)  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Ë¢ÐÂNPCÊôÐÔ  
 | 
    def RefreshNPCAttrState(self, canSyncClient=True, isReborn=False):  
 | 
        curNPC = self.__Instance  
 | 
        #curNPCMaxHP_Before = GameObj.GetMaxHP(curNPC)  
 | 
        #Çå¿ÕNPCÕ½¶·ÊôÐÔ  
 | 
        curNPC.ClearBattleEffect()  
 | 
        #--------------------------------------------  
 | 
        #ÖØÖÃNPCÕ½¶·ÊôÐÔ  
 | 
        curNPC.ResetNPCBattleState()  
 | 
        ############################################  
 | 
        #³õʼ»¯×´Ì¬  
 | 
        curNPC.SetSpeed(curNPC.GetOrgSpeed())  
 | 
        curNPC.SetAtkInterval(curNPC.GetBaseAtkInterval())  
 | 
  
 | 
#        #ÏÈÇå¿ÕÒì³£  
 | 
#        if curNPC.GetAbnormalState() != IPY_GameWorld.sctInvalid:  
 | 
#            curNPC.SetAbnormalState(IPY_GameWorld.sctInvalid)  
 | 
#  
 | 
#        #Çå¿Õ½ûÖ¹  
 | 
#        curNPC.ForbiddenSkillTypeList_Clear()  
 | 
      
 | 
        #³èÎïÌØÊâ´¦Àí  
 | 
        if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotPet:  
 | 
            PetControl.RefurbishPetAttr(curNPC, canSyncClient)  
 | 
            return  
 | 
          
 | 
        DoNPCAttrStrengthen(curNPC, isReborn)  
 | 
  
 | 
        #¼ÆËãbuf¶ÔÕ½¶·ÊôÐÔµÄ¸Ä±ä  
 | 
        allAttrList = SkillShell.CalcBuffer_NPCBattleEffect(curNPC)  
 | 
          
 | 
        self.RefreshNPCSpeed(allAttrList)  
 | 
        #¼ì²éѪÁ¿ÊÇ·ñ±ä»¯, Ôݲ»×öѪÁ¿Ôö¼ÓÉÏÏÞ֪ͨ£¬½öÊôÐÔÉÏÏÞÖ§³Ö£»  
 | 
        #¿Í»§¶Ë×Ô¼ºËãѪÁ¿ÉÏÏÞ  
 | 
#        if curNPC.GetMaxHP() != curNPCMaxHP_Before:  
 | 
#            curNPC.Notify_MaxHP()  
 | 
              
 | 
        return  
 | 
      
 | 
    def SetHelpBattleRobotRebornAttr(self, fightPower):  
 | 
        '''ÖúÕ½»úÆ÷ÈËÖ»ÉèÖÃѪÁ¿ÊôÐÔ  
 | 
                        ÑªÁ¿Ëã·¨£¬£¨ÖúÕ½Íæ¼Ò=ÖúÕ½»úÆ÷ÈË£©£ºÃ¿¸ö¸±±¾ÅäÖÃÉ˺¦*£¨ÖúÕ½Íæ¼ÒÕ½Á¦/¸±±¾¹æ¶¨Õ½Á¦£©*ϵÊýÖµ  ÏµÊýÖµÔݶ¨Îª50  
 | 
        '''  
 | 
        curNPC = self.__Instance  
 | 
        mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())  
 | 
        funcLineID = FBCommon.GetFBPropertyMark()  
 | 
        ipyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", mapID, funcLineID)  
 | 
        if not ipyData:  
 | 
            return  
 | 
          
 | 
        SetSuppressFightPower(curNPC, fightPower)  
 | 
        fbFightPower = ipyData.GetFightPowerMin()  
 | 
        baseHurt = ipyData.GetRobotBaseHurt()  
 | 
        hpCoefficient = ipyData.GetRobotHPCoefficient()  
 | 
        maxHP = int(eval(IpyGameDataPY.GetFuncCompileCfg("HelpBattleRobot", 2)))  
 | 
        GameWorld.DebugLog("ÉèÖÃÖúÕ½»úÆ÷ÈËÊôÐÔ: objID=%s,fightPower=%s,maxHP=%s" % (curNPC.GetID(), fightPower, maxHP))  
 | 
        GameObj.SetMaxHP(curNPC, maxHP)  
 | 
        GameObj.SetHP(curNPC, maxHP)  
 | 
        curNPC.Notify_HPEx()  
 | 
        curNPC.Notify_MaxHPEx()  
 | 
        return  
 | 
      
 | 
    # NPCÒÆ¶¯ËÙ¶ÈÌØÊâ´¦Àí£¬Ö»´¦Àí°Ù·Ö±È²»ÄÜ´¦Àí¹Ì¶¨Öµ   
 | 
    # ÒòΪ ChConfig.TYPE_Calc_AttrSpeed ·Ç·þÎñ¶ËÒÆ¶¯ËÙ¶È£¬ÍµÀÁ´¦Àí·¨  
 | 
    def RefreshNPCSpeed(self, allAttrList):  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        speedPer = allAttrList[ChConfig.CalcAttr_BattleNoline].get(ChConfig.TYPE_Calc_AttrSpeed, 0)  
 | 
        if not speedPer:  
 | 
            if curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SpeedPer):  
 | 
                curNPC.SetDict(ChConfig.Def_NPC_Dict_SpeedPer, 0)  
 | 
        else:  
 | 
            speed = int(curNPC.GetSpeed() * (ShareDefine.Def_MaxRateValue) / max(100.0, float(ShareDefine.Def_MaxRateValue + speedPer)))  
 | 
            curNPC.SetSpeed(speed)  
 | 
            curNPC.SetDict(ChConfig.Def_NPC_Dict_SpeedPer, speedPer)  
 | 
        if GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_GatherSoul:  
 | 
            #ĿǰֻÔھۻ긱±¾Àï֪ͨ  
 | 
            NPCSpeedChangeNotify(curNPC, curNPC.GetSpeed())  
 | 
        return  
 | 
      
 | 
      
 | 
    ## Ë¢ÐÂNPCÐÐΪÊôÐÔ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Ë¢ÐÂNPCÐÐΪÊôÐÔ  
 | 
    def RefreshNPCActionState(self):  
 | 
        curNPC = self.__Instance  
 | 
        OperControlManager.ClearObjActionState(curNPC)  
 | 
          
 | 
        #¸ù¾ÝBUFF ¼ÓÉÏ״̬  
 | 
        SkillShell.CalcBuffer_ActionState(curNPC)  
 | 
          
 | 
          
 | 
    #---------------------------------------------------------------------  
 | 
    ## Ë¢ÐÂBuff״̬  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Ë¢ÐÂBuff״̬  
 | 
    def RefreshBuffState(self, tick):  
 | 
        #´¦Àí²»¼°Ê±Ë¢ÐµÄBUFF  
 | 
        refreshA = self.RefreshBuffStateNoTimely(tick)  
 | 
        #´¦Àí¼°Ê±Ë¢ÐµÄBUFF  
 | 
        refreshB = self.RefreshBuffStateTimely(tick)  
 | 
          
 | 
        if refreshA or refreshB:  
 | 
            self.RefreshNPCAttrState()  
 | 
              
 | 
              
 | 
    ## Ë¢ÐÂBuff״̬, ´¦Àí²»Ð輰ʱˢеÄBUFF £¬¹ØºõË¢ÐÂÊôÐ﵀  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Ë¢ÐÂBuff״̬,´¦Àí²»Ð輰ʱˢеÄBUFF £¬¹ØºõË¢ÐÂÊôÐ﵀  
 | 
    def RefreshBuffStateNoTimely(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
        if tick - curNPC.GetTickByType(ChConfig.TYPE_NPC_Tick_Buff) <= ChConfig.TYPE_NPC_Tick_Time[ChConfig.TYPE_NPC_Tick_Buff]:  
 | 
            #ˢмä¸ôûµ½  
 | 
            return  
 | 
          
 | 
        #¼ì²âÊÇ·ñÓÐbuffÒªÏûʧ  
 | 
        curNPC.SetTickByType(ChConfig.TYPE_NPC_Tick_Buff, tick)  
 | 
        refresh = False  
 | 
  
 | 
        result = BuffSkill.RefreshBuff(curNPC, curNPC.GetBuffState(), tick)  
 | 
        refresh = refresh or result[0]  
 | 
          
 | 
        result = BuffSkill.RefreshBuff(curNPC, curNPC.GetDeBuffState(), tick)  
 | 
        refresh = refresh or result[0]  
 | 
          
 | 
        result = BuffSkill.RefreshBuff(curNPC, curNPC.GetAura(), tick)  
 | 
        refresh = refresh or result[0]  
 | 
  
 | 
        #¹â»·ÐÍBuff¼ì²é¹âÔ´  
 | 
        SkillCommon.CheckAddAuraSkill(curNPC, tick)  
 | 
        result = SkillCommon.CheckAuraSkill(curNPC, tick)  
 | 
  
 | 
        return refresh or result  
 | 
              
 | 
      
 | 
    ## Ë¢ÐÂBuff״̬, ´¦ÀíÐ輰ʱˢеÄBUFF £¬Ä¿Ç°²»Ë¢ÐÂÊôÐÔ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Ë¢ÐÂBuff״̬ ´¦ÀíÐ輰ʱˢеÄBUFF £¬Ä¿Ç°²»Ë¢ÐÂÊôÐÔ  
 | 
    def RefreshBuffStateTimely(self, tick):  
 | 
        curNPC = self.__Instance  
 | 
        if tick - curNPC.GetTickByType(ChConfig.TYPE_NPC_Tick_Buff_Timely) \  
 | 
                <= ChConfig.TYPE_NPC_Tick_Time[ChConfig.TYPE_NPC_Tick_Buff_Timely]:  
 | 
            #ˢмä¸ôûµ½  
 | 
            return  
 | 
          
 | 
        #¼ì²âÊÇ·ñÓÐbuffÒªÏûʧ  
 | 
        curNPC.SetTickByType(ChConfig.TYPE_NPC_Tick_Buff_Timely, tick)  
 | 
          
 | 
        BuffSkill.RefreshBuff(curNPC, curNPC.GetProcessBuffState(), tick)  
 | 
        BuffSkill.RefreshBuff(curNPC, curNPC.GetProcessDeBuffState(), tick)  
 | 
  
 | 
        #ÐÐΪBUFFˢР ÊÇ·ñÓÐBUFFÏûʧ  
 | 
        result = BuffSkill.RefreshBuff(curNPC, curNPC.GetActionBuffManager(), tick)  
 | 
  
 | 
        if result[1]:  
 | 
            self.RefreshNPCActionState()  
 | 
          
 | 
        #³ÖÐøÐÔBUFF´¦Àí  
 | 
        SkillShell.ProcessPersistBuff(curNPC, tick)  
 | 
          
 | 
        # ÊÇ·ñÐèҪˢÊôÐÔ  
 | 
        return result[0]  
 | 
          
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPCËÀÍöÏà¹ØÂß¼  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµËµÃ÷  
 | 
    #  @remarks NPCËÀÍöÏà¹ØÂß¼  
 | 
    def __KillLogic(self):  
 | 
        curNPC = self.__Instance  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        #######################ÌØÊâNPCµÄ´¦Àí  
 | 
        #=====================================================================================================  
 | 
        # if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotTruck:  
 | 
        #    #Èç¹ûÊÇæô³µËÀÍö, µ÷ÓÃæô³µËÀÍöÂß¼  
 | 
        #    PlayerTruck.DoTruckDestroy(curNPC)  
 | 
        #=====================================================================================================  
 | 
          
 | 
        #bossÉËѪÅÅÐаñ»÷ɱÂß¼  
 | 
        #BossHurtMng.BossOnKilled(curNPC)  
 | 
          
 | 
        #µôÂäÐèÒªÓõ½Ãþ¹Ö£¬ËùÒÔÔÚ´¦ÀíµôÂä½±ÀøÖ®Ç°ÉèÖà  
 | 
        self.__SetFeelNPCPlayerList()  
 | 
          
 | 
        #ɱËÀNPC,¶ÔÏó½±Àø  
 | 
        self.__GiveObjPrize()  
 | 
          
 | 
        #ɱËÀNPC, ´¥·¢ÈÎÎñ  
 | 
        self.__EventKillNpc()  
 | 
              
 | 
        mapID = GameWorld.GetMap().GetMapID()  
 | 
        killerName = "" if not self.__Killer else self.__Killer.GetPlayerName()  
 | 
        # ¼Ç¼boss»÷ɱÐÅÏ¢µÄNPC  
 | 
        bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID)  
 | 
        if bossIpyData and mapID not in [ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_SealDemon]:  
 | 
            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:  
 | 
                killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID)  
 | 
            #KillerJob = 0 if not self.__Killer else self.__Killer.GetJob()  
 | 
            killerIDList = [player.GetPlayerID() for player in self.__ownerPlayerList]  
 | 
            GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0, True, killerIDList)  
 | 
              
 | 
        if npcID == IpyGameDataPY.GetFuncCfg("BossRebornServerBoss", 3):  
 | 
            PlayerControl.WorldNotify(0, "BossRebornBossKilled", [curNPC.GetNPCID()])  
 | 
              
 | 
        #===========================================================================================  
 | 
        # # °µ½ðboss  
 | 
        # if curNPC.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark:  
 | 
        #    #PlayerControl.WorldNotify(0, "Old_andyshao_861048", [curNPC.GetNPCID()])  
 | 
        #    if mapID == ChConfig.Def_MapID_DouHunTan:  
 | 
        #        NPCCustomRefresh.DoRefreshNeutralBoss(npcID)  
 | 
        #   
 | 
        # # ÖÜÎ§Íæ¼Ò¼ÓÍþÍû  
 | 
        # npcKilledAddPrestigeDict = ReadChConfig.GetEvalChConfig('NPCKilledAddPrestige')  
 | 
        # if npcID in npcKilledAddPrestigeDict:  
 | 
        #    addPrestigeFormat = npcKilledAddPrestigeDict[npcID]  
 | 
        #    self.__GiveNearbyPlayerPrestige(addPrestigeFormat, ChConfig.Def_Matrix_Six)  
 | 
        #===========================================================================================  
 | 
                  
 | 
        #Çå¿ÕNPCµÄ³ðºÞ  
 | 
        curNPC.GetNPCAngry().Clear()  
 | 
        return  
 | 
      
 | 
    def __SetFeelNPCPlayerList(self):  
 | 
        ## ÉèÖÃÓÐÃþ¹ÖµÄÍæ¼ÒÁÐ±í£¬º¬»÷ɱÕß  
 | 
        curNPC = self.__Instance  
 | 
        self.__FeelPlayerList = []  
 | 
          
 | 
        npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)  
 | 
        if not npcHurtList:  
 | 
            npcHurtList = curNPC.GetPlayerHurtList()  
 | 
        #npcHurtList.Sort()  #ÕâÀï²»ÅÅÐò£¬Ö»ÒªÓÐÉ˺¦¾ÍËã  
 | 
          
 | 
        eventPlayerList = []  
 | 
        for index in xrange(npcHurtList.GetHurtCount()):  
 | 
              
 | 
            #»ñµÃÉËѪ¶ÔÏó  
 | 
            hurtObj = npcHurtList.GetHurtAt(index)  
 | 
            hurtObjType = self.__GetTagByHurtObj(hurtObj)  
 | 
              
 | 
            #µ±Ç°ÉËѪ¶ÔÏ󳬳öÖ¸¶¨·¶Î§»òÒѾËÀÍö  
 | 
            if not hurtObjType :  
 | 
                continue  
 | 
              
 | 
            curPlayer = hurtObjType[0]  
 | 
            curTeam = hurtObjType[1]  
 | 
              
 | 
            #¸öÈË  
 | 
            if curPlayer:  
 | 
                if curPlayer not in eventPlayerList:  
 | 
                    eventPlayerList.append(curPlayer)  
 | 
            #¶ÓÎé  
 | 
            if curTeam:  
 | 
                #¶ÓÔ±ÁÐ±í  
 | 
                playerlist = PlayerControl.GetAreaTeamMember(curTeam, curNPC.GetPosX(), curNPC.GetPosY())  
 | 
                #±éÀú¶ÓÎé,°ë¾¶ÎªÒ»ÆÁ°ëµÄ¾àÀëÄÚµÄËùÓжÓÎé/ÍŶӳÉÔ±£¬¿ÉÒÔ»ñµÃ¾Ñé  
 | 
                for teamPlayer in playerlist:  
 | 
                    if teamPlayer not in eventPlayerList:  
 | 
                        eventPlayerList.append(teamPlayer)  
 | 
        self.__FeelPlayerList = eventPlayerList  
 | 
        return  
 | 
      
 | 
    ## É±ËÀNPC, ´¥·¢ÈÎÎñ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return None  
 | 
    def __EventKillNpc(self):  
 | 
          
 | 
        # ´¥·¢¹éÊôÈÎÎñʼþ  
 | 
        if self.__Killer:  
 | 
            self.__MissionOnKillNPC(self.__Killer)  
 | 
              
 | 
        for eventPlayer in self.__FeelPlayerList:  
 | 
            if self.__Killer and self.__Killer.GetPlayerID() == eventPlayer.GetPlayerID():  
 | 
                continue  
 | 
            self.__MissionOnKillNPC(eventPlayer, True)  
 | 
        return  
 | 
      
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    def __GetDropMoneyModelID(self, moneyValue):  
 | 
        ## »ñÈ¡µôÂä½ð±ÒÄ£ÐÍID  
 | 
        if not moneyValue:  
 | 
            return 0  
 | 
        moneyItemList = IpyGameDataPY.GetFuncEvalCfg("GoldModel", 1) # ½ð±ÒµôÂäÊýÁ¿¶ÔӦģÐÍ-[(×î´ó½ð±ÒÊý,ÎïÆ·Ä£ÐÍID), ...]  
 | 
        if not moneyItemList:  
 | 
            return 0  
 | 
        for count, moneyID in moneyItemList:  
 | 
            if moneyValue <= count:  
 | 
                return moneyID  
 | 
        return moneyItemList[-1][1]  
 | 
      
 | 
    def __NPCSpecialDropItem(self, dropPlayer, ownerPlayerList, ipyDrop):  
 | 
        '''ÌØÊâµôÂä (˽ÓÐÌØÊâµôÂä + »÷ɱ´ÎÊýÌØÊâµôÂä), Ö§³ÖÃþ¹Ö  
 | 
        @return: None  
 | 
        @return: [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...]  
 | 
        '''  
 | 
        curNPC = self.__Instance  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        specDropItemList = []  
 | 
          
 | 
        playerLV = dropPlayer.GetLV()  
 | 
        maxDropLV = ipyDrop.GetMaxDropLV()  
 | 
        if maxDropLV and playerLV > maxDropLV:  
 | 
            GameWorld.DebugLog("³¬¹ý×î´ó¿ÉµôÂäµÈ¼¶£¬²»µôÂäÎïÆ·£¬ÌØÊâµôÂ䣡npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))  
 | 
            return specDropItemList  
 | 
          
 | 
        auctionItemCanSell = ipyDrop.GetAucionItemCanSell()  
 | 
        # »÷ɱ´ÎÊýµôÂäËãÃþ¹Ö  
 | 
        killCountDropInfo = ipyDrop.GetKillCountDropPri()  
 | 
        if killCountDropInfo:  
 | 
            for feelPlayer in self.__FeelPlayerList:  
 | 
                needKillCount, killDropItemList, isDropInItemPack = killCountDropInfo  
 | 
                killCountDropItemList = GetKillCountDropItemList(feelPlayer, npcID, needKillCount, killDropItemList)  
 | 
                for dropItemID in killCountDropItemList:  
 | 
                    isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropItemID) else 0  
 | 
                    specDropItemList.append([feelPlayer, dropItemID, isAuctionItem, isDropInItemPack])  
 | 
                    GameWorld.DebugLog("»÷ɱ´ÎÊý±Øµô(¿ÉÃþ¹Ö): npcID=%s,dropItemID=%s,needKillCount=%s,isDropInItemPack=%s,isAuctionItem=%s"   
 | 
                                       % (npcID, dropItemID, needKillCount, isDropInItemPack, isAuctionItem), feelPlayer.GetPlayerID())  
 | 
                      
 | 
        # Ë½ÓеôÂä  
 | 
        isDropInItemPack = False  
 | 
        fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3)  
 | 
        if npcID in fbGradePriItemIDDropDict:  
 | 
            gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID]  
 | 
            curGrade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)  
 | 
            priDropInfoList = gradePriItemIDDropDict.get(curGrade, [])  
 | 
            priDropIDList = []  
 | 
            for priItemID, priItemCount in priDropInfoList:  
 | 
                priDropIDList += [priItemID] * priItemCount  
 | 
        else:  
 | 
            priDropIDList = ipyDrop.GetPriItemIDDrop()  
 | 
        for dropItemID in priDropIDList:  
 | 
            isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropItemID) else 0  
 | 
            for ownerPlayer in ownerPlayerList:  
 | 
                specDropItemList.append([ownerPlayer, dropItemID, isAuctionItem, isDropInItemPack]) # Ä¬ÈÏ°ó¶¨  
 | 
                #GameWorld.DebugLog("˽ÓÐÎïÆ·µôÂä: dropItemID=%s" % dropItemID, ownerPlayer.GetPlayerID())  
 | 
                  
 | 
        return specDropItemList  
 | 
  
 | 
    def __NPCDropItemByPlayers(self, dropPlayerList, mapID, ipyDrop):  
 | 
        '''NPCµôÂäÎïÆ·, ¶àÍæ¼ÒÿÈËÒ»·Ý, »ìºÏµôÂä'''  
 | 
        curNPC = self.__Instance  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        if not dropPlayerList:  
 | 
            return  
 | 
          
 | 
        #GameWorld.DebugLog("NPC¶àÍæ¼Ò»ìºÏµôÂä: dropPlayerCount=%s" % len(dropPlayerList))  
 | 
        auctionItemIDList = []  
 | 
        dropItemList = []  
 | 
        for dropPlayer in dropPlayerList:  
 | 
            dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ipyDrop=ipyDrop)  
 | 
            if not dropInfo:  
 | 
                continue  
 | 
            dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo  
 | 
            moneyID = self.__GetDropMoneyModelID(moneyValue)  
 | 
            if dropMoneyCnt:  
 | 
                dropIDList += [moneyID] * dropMoneyCnt  
 | 
                  
 | 
            dropPlayerID = dropPlayer.GetPlayerID()  
 | 
            #GameWorld.DebugLog("    dropPlayerID=%s,dropIDList=%s" % (dropPlayerID, dropIDList))  
 | 
            for dropID in dropIDList:  
 | 
                dropItemList.append([dropID, dropPlayerID])  
 | 
            auctionItemIDList += auctionIDList  
 | 
              
 | 
        #´òÂÒÎïÆ·Ë³Ðò  
 | 
        random.shuffle(dropItemList)  
 | 
          
 | 
        gameMap = GameWorld.GetMap()  
 | 
        dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # ÒÔNPCΪÖÐÐĵ㿪ʼµôÂä  
 | 
        index = 0  
 | 
        for posX, posY in ChConfig.Def_DropItemAreaMatrix:  
 | 
            resultX = dropPosX + posX  
 | 
            resultY = dropPosY + posY  
 | 
              
 | 
            if not gameMap.CanMove(resultX, resultY):  
 | 
                #Íæ¼Ò²»¿ÉÒÆ¶¯Õâ¸öµã  
 | 
                continue  
 | 
              
 | 
            if index > len(dropItemList) - 1:  
 | 
                break                          
 | 
            itemID, ownerID = dropItemList[index]  
 | 
            index += 1  
 | 
            itemCnt = moneyValue if itemID == moneyID else 1  
 | 
            iaAuctionItem = itemID in auctionItemIDList  
 | 
            curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, iaAuctionItem, dropPlayer)  
 | 
            if not curItem:  
 | 
                continue  
 | 
            self.__MapCreateItem(curItem, resultX, resultY, ChConfig.Def_NPCHurtTypePlayer, ownerID)  
 | 
              
 | 
        return  
 | 
      
 | 
    ## ÎïÆ·µôÂä  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param dropPlayer µôÂäÅжÏÏà¹ØÍæ¼Ò  
 | 
    #  @param HurtType ÉËѪÀàÐÍ  
 | 
    #  @param HurtID ÉËѪID  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    def __NPCDropItem(self, dropPlayer, hurtType, hurtID, ownerPlayerList=[], isOnlySelfSee=False):  
 | 
        if not dropPlayer:  
 | 
            return  
 | 
        curNPC = self.__Instance  
 | 
        PlayerActCollectWords.OnKillNPCDrop(dropPlayer, curNPC)  
 | 
        if curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:  
 | 
            GameWorld.DebugLog("ľ׮¹Ö£¬²»µôÂäÎïÆ·£¡")  
 | 
            return  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        mapID = GameWorld.GetMap().GetMapID()  
 | 
        mapID = FBCommon.GetRecordMapID(mapID)  
 | 
        isGameBoss = ChConfig.IsGameBoss(curNPC)  
 | 
        if mapID in [ChConfig.Def_FBMapID_MunekadoTrial, ChConfig.Def_FBMapID_DemonKing, ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss,  
 | 
                     ChConfig.Def_FBMapID_KillDevil]:  
 | 
            GameWorld.DebugLog("¸ÃµØÍ¼²»×ßÖ±½ÓµôÂäÎïÆ·Âß¼£¡mapID=%s" % mapID)              
 | 
            return  
 | 
        if isGameBoss:  
 | 
            GameWorld.Log("NPC¿ªÊ¼µôÂä: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID())  
 | 
        ipyDrop = GetNPCDropIpyData(npcID)  
 | 
        if not ipyDrop:  
 | 
            if isGameBoss:  
 | 
                curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)  
 | 
                GameWorld.ErrLog("È¡²»µ½NPCµôÂäÐÅÏ¢!npcID=%s,curWorldLV=%s" % (npcID, curWorldLV))  
 | 
            return  
 | 
          
 | 
        #if mapID == ChConfig.Def_FBMapID_MunekadoTrial:  
 | 
        #    dropPlayerList = GameLogic_MunekadoTrial.GetCanDropPlayerList()  
 | 
        #    return self.__NPCDropItemByPlayers(dropPlayerList, mapID, ipyDrop)  
 | 
          
 | 
        dropIDList, auctionIDList, dropMoneyCnt, moneyValue = [], [], 0, 0  
 | 
        dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList, ipyDrop, False)  
 | 
        if dropInfo:  
 | 
            dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo  
 | 
              
 | 
        moneyID = self.__GetDropMoneyModelID(moneyValue)  
 | 
        if moneyID and dropMoneyCnt:  
 | 
            dropIDList += [moneyID] * dropMoneyCnt  
 | 
              
 | 
        specItemSign = "SpecItem"  
 | 
        playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # ÌØÊâµôÂä [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...]  Ë½ÓÐÌØÊâµôÂä + »÷ɱ´ÎÊýÌØÊâµôÂä  
 | 
        dropIDList += [specItemSign] * len(playerSpecDropList)  
 | 
          
 | 
        if len(dropIDList) > 5:  
 | 
            #´òÂÒÎïÆ·Ë³Ðò  
 | 
            random.shuffle(playerSpecDropList)  
 | 
            random.shuffle(dropIDList)  
 | 
              
 | 
        if not dropIDList and isGameBoss:  
 | 
            GameWorld.ErrLog("BossûÓеôÂä: dropPlayerLV=%s,ipyWorldLV=%s,maxDropLV=%s"   
 | 
                             % (dropPlayer.GetLV(), ipyDrop.GetMaxWorldLV(), ipyDrop.GetMaxDropLV()), dropPlayer.GetPlayerID())  
 | 
              
 | 
        gameMap = GameWorld.GetMap()  
 | 
        dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # ÒÔNPCΪÖÐÐĵ㿪ʼµôÂä  
 | 
        index = 0  
 | 
        for posX, posY in ChConfig.Def_DropItemAreaMatrix:  
 | 
            resultX = dropPosX + posX  
 | 
            resultY = dropPosY + posY  
 | 
              
 | 
            if not gameMap.CanMove(resultX, resultY):  
 | 
                #Íæ¼Ò²»¿ÉÒÆ¶¯Õâ¸öµã  
 | 
                continue  
 | 
              
 | 
            if index > len(dropIDList) - 1:  
 | 
                break  
 | 
              
 | 
            isDropInItemPack = False  
 | 
            itemID = dropIDList[index]  
 | 
            index += 1  
 | 
            if itemID == specItemSign:  
 | 
                if not playerSpecDropList:  
 | 
                    continue  
 | 
                itemCnt = 1  
 | 
                ownerPlayer, itemID, isAuctionItem, isDropInItemPack = playerSpecDropList[0]  
 | 
                ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, ownerPlayer.GetPlayerID()  
 | 
                playerSpecDropList = playerSpecDropList[1:]  
 | 
            else:  
 | 
                ownerPlayer = dropPlayer  
 | 
                ownerType, ownerID = hurtType, hurtID  
 | 
                itemCnt = moneyValue if itemID == moneyID else 1  
 | 
                isAuctionItem = itemID in auctionIDList  
 | 
                  
 | 
            curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, isAuctionItem, dropPlayer)  
 | 
            if not curItem:  
 | 
                continue  
 | 
              
 | 
            if mapID == ChConfig.Def_FBMapID_GatherSoul:#¾Û»ê¸±±¾ÌØÊâ´¦Àí  
 | 
                GameLogic_GatherSoul.KillGatherSoulNPCDropAward(itemID, itemCnt, isAuctionItem)  
 | 
                dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)  
 | 
                SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)  
 | 
                curItem.Clear()  
 | 
                continue  
 | 
              
 | 
            if isDropInItemPack:  
 | 
                curItem.SetUserAttr(ShareDefine.Def_IudetSource, ShareDefine.Item_Source_VirtualItemDrop)  
 | 
                dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)  
 | 
                #¿ÉÒÔ·ÅÈë±³°ü  
 | 
                if ItemControler.DoLogic_PutItemInPack(ownerPlayer, curItem, event=["NPCDrop", False, {"npcID":npcID}]):  
 | 
                    #֪ͨ¿Í»§¶Ë  
 | 
                    SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)  
 | 
                      
 | 
            else:  
 | 
                self.__MapCreateItem(curItem, resultX, resultY, ownerType, ownerID, isOnlySelfSee=isOnlySelfSee)  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPC±»É±ËÀÂß¼´¦Àí  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks NPC±»É±ËÀÂß¼´¦Àí  
 | 
    def SetKilled(self):  
 | 
        curNPC = self.__Instance  
 | 
        #µ÷ÓÃÍæ¼Ò½±Àø  
 | 
        self.__KillLogic()  
 | 
        #ÉèÖôËNPCΪ¿ÕѪ״̬  
 | 
        GameObj.SetHP(curNPC, 0)  
 | 
        #Ìæ»»³ðºÞ  
 | 
        #self.__NPCReplaceAngry()  
 | 
        #Çå³ý״̬  
 | 
        self.__ClearNPCAllState()  
 | 
        #»ñµÃÓÎÏ·ÖеÄNPCÀàÐÍ  
 | 
        curNPC_GameNPCObjType = curNPC.GetGameNPCObjType()  
 | 
        #---ÌØÊâËÀÍöÂß¼---  
 | 
          
 | 
        #ïÚ³µ²»ÄÜ֪ͨËÀÍö  
 | 
        if curNPC_GameNPCObjType == IPY_GameWorld.gnotTruck:  
 | 
            return  
 | 
          
 | 
        #³èÎïËÀÍöµ÷ÓöÀÁ¢½Ó¿Ú  
 | 
        if curNPC_GameNPCObjType == IPY_GameWorld.gnotPet:  
 | 
            PetControl.SetPetDead(curNPC)  
 | 
            return  
 | 
          
 | 
        #---ͨÓÃËÀÍöÂß¼---  
 | 
          
 | 
#        #ɱËÀ×Ô¼ºµÄÕÙ»½ÊÞ  
 | 
#        self.__InitNPCSummon()  
 | 
        #ÉèÖô¦ÀíÖÜÆÚ  
 | 
        curNPC.SetIsNeedProcess(False)  
 | 
        #µ÷Óõײã -> Í¨Öª¿Í»§¶ËËÀÍö  
 | 
        SetDeadEx(curNPC)  
 | 
        return  
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÕÙ»½ÊÞËÀÍö,Ìæ»»³ðºÞ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ÕÙ»½ÊÞËÀÍö,Ìæ»»³ðºÞ  
 | 
    #===========================================================================  
 | 
    # def __NPCReplaceAngry(self):  
 | 
    #    curNPC = self.__Instance  
 | 
    #    #½ö´¦Àí³èÎïºÍÕÙ»½ÊÞ  
 | 
    #    if curNPC.GetGameNPCObjType() not in [IPY_GameWorld.gnotSummon, IPY_GameWorld.gnotPet]:  
 | 
    #        return  
 | 
    #      
 | 
    #    if curNPC.GetType() not in [IPY_GameWorld.ntSummon, IPY_GameWorld.ntElf,  
 | 
    #                                IPY_GameWorld.ntTrap, IPY_GameWorld.ntTruck,  
 | 
    #                                IPY_GameWorld.ntFairy]:  
 | 
    #        return  
 | 
    #              
 | 
    #    summonOwner = GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)  
 | 
    #      
 | 
    #    if summonOwner == None:  
 | 
    #        summonOwner = GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC)  
 | 
    #      
 | 
    #    #Òì³£´íÎó  
 | 
    #    if summonOwner == None:  
 | 
    #        #GameWorld.Log("Ìæ»»³ðºÞ,²éÕÒÕÙ»½ÊÞÖ÷ÈËʧ°Ü curNPC = %s"%(curNPC.GetNPCID()))  
 | 
    #        return  
 | 
    #      
 | 
    #    #³ðºÞNPCÁÐ±í  
 | 
    #    angryNPCList = list()  
 | 
    #    for index in range(curNPC.GetAngryNPCCount()):  
 | 
    #        angryNPC = curNPC.GetAngryNPCByIndex(index)  
 | 
    #        #ÒѾËÀÍö  
 | 
    #        if angryNPC.GetHP() <= 0:  
 | 
    #            continue  
 | 
    #          
 | 
    #        angryNPCList.append(angryNPC)  
 | 
    #      
 | 
    #    #ÔÚReplaceNPCAngryFromOldToNewµÄʱºò, »áɾ³ý³ðºÞ,   
 | 
    #    #¸Ä±ä summonNPC.GetAngryNPCCount() µÄ³¤¶È, ËùÒÔ±ØÐëÏȹ¹½¨Áбí,  
 | 
    #    #ÔÚÌæ»»³ðºÞ  
 | 
    #    for angryListNPC in angryNPCList:  
 | 
    #        #Ìæ»»³ðºÞ  
 | 
    #        ReplaceNPCAngryFromOldToNew(angryListNPC, curNPC, summonOwner)  
 | 
    #      
 | 
    #    return  
 | 
    #===========================================================================  
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPC·ÇÕ½¶·ÖлØÑª  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks NPC·ÇÕ½¶·ÖлØÑª  
 | 
    def ProcessHPRestore(self, tick):  
 | 
        ## NPC»ØÑª¹æÔò  
 | 
        curNPC = self.__Instance  
 | 
        #npcID = curNPC.GetNPCID()  
 | 
        hpRestoreRate = curNPC.GetHPRestore() # Ã¿ÃëHP»Ö¸´ËÙ¶ÈÍò·ÖÂÊ  
 | 
        if not hpRestoreRate:  
 | 
            return False  
 | 
          
 | 
        curNPCMaxHP = GameObj.GetMaxHP(curNPC)  
 | 
        if GameObj.GetHP(curNPC) == curNPCMaxHP:  
 | 
            #ÖØÖðٷֱÈÂß¼±êʶ  
 | 
            curNPC.SetDict(ChConfig.Def_NPC_Dict_HPPerLogicMark, 0)  
 | 
            return False  
 | 
          
 | 
        #NPCÅÜ»ØÈ¥²»»ØÑª  
 | 
        if curNPC.GetCurAction() != IPY_GameWorld.laNPCNull:  
 | 
            return True  
 | 
          
 | 
        if self.IsInHurtProtect():  
 | 
            #GameWorld.DebugLog("ÉËѪ±£»¤ÖУ¬²»»ØÑª£¡")  
 | 
            return True  
 | 
          
 | 
        lastRestoreTime = curNPC.GetRestoreTime()  
 | 
        if not lastRestoreTime or (tick - curNPC.GetRestoreTime()) >= ChConfig.Def_NPC_ProcessHP_Tick * 5:  
 | 
            curNPC.SetRestoreTime(tick + 2000) # ÑÓ³Ù2Ãë»ØÑª, ·ÀÖ¹»ØÔµãʱËÑË÷ÏÂһĿ±êÆÚ¼ä˲»Ø  
 | 
            return True  
 | 
          
 | 
        if tick - curNPC.GetRestoreTime() < ChConfig.Def_NPC_ProcessHP_Tick:  
 | 
            #GameWorld.DebugLog("»Ö¸´Ê±¼äδµ½")  
 | 
            return True  
 | 
          
 | 
        restoreValue = int(curNPCMaxHP * hpRestoreRate / 10000.0)  
 | 
        SkillCommon.SkillAddHP(curNPC, 0, restoreValue, False)  
 | 
        #ÉèÖõ±Ç°Ê±¼äΪ»Ö¸´Æðʼʱ¼ä  
 | 
        curNPC.SetRestoreTime(tick)  
 | 
        return True  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPCÕ½¶·»ØÑª  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param tick Ê±¼ä´Á  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks NPCÕ½¶·»ØÑª  
 | 
    def ProcessBattleHPRestore(self, tick):  
 | 
        #2010/4/30Õ½¶·»ØÑª¹¦ÄÜÔÝʱ¹Ø±Õ  
 | 
        #ÕâÀï»áµ¼Ö¿ͻ§¶Ë½ÓÊÕ¹¥»÷µôѪ·â°ü,ˢѪÒì³£  
 | 
        return  
 | 
#===============================================================================  
 | 
#        curNPC = self.__Instance  
 | 
#          
 | 
#        if curNPC.GetHP() == curNPC.GetMaxHP():  
 | 
#            #ÂúѪÁË  
 | 
#            return  
 | 
#          
 | 
#        if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie:  
 | 
#            #ËÀÍö²»»ØÑª  
 | 
#            return  
 | 
#          
 | 
#        if tick - curNPC.GetRestoreTime() < ChConfig.Def_NPC_ProcessBattleHP_Tick:  
 | 
#            #»Ö¸´Ê±¼äδµ½  
 | 
#            return  
 | 
#          
 | 
#        hpRestore = curNPC.GetHPRestore()  
 | 
#        #Õ½¶·ÖлØÑª  
 | 
#        if hpRestore != 0:  
 | 
#            SkillCommon.SkillAddHP(curNPC, 0, hpRestore)  
 | 
#          
 | 
#        #ÉèÖõ±Ç°Ê±¼äΪ»Ö¸´Æðʼʱ¼ä  
 | 
#        curNPC.SetRestoreTime(tick)  
 | 
#===============================================================================  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÉèÖöÔÏó½±Àø  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ÉèÖöÔÏó½±Àø  
 | 
    def __GiveObjPrize(self):  
 | 
        curNPC = self.__Instance  
 | 
        #objID = curNPC.GetID()  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx()  
 | 
          
 | 
        isGameBoss = ChConfig.IsGameBoss(curNPC)  
 | 
        self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo(isGameBoss)  
 | 
        self.__OwnerHurtType, self.__OwnerHurtID = hurtType, hurtID  
 | 
        if isGameBoss:  
 | 
            GameWorld.Log("__GiveObjPrize npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))  
 | 
          
 | 
        #×îºóÒ»»÷´¦Àí  
 | 
        self.__DoLastTimeHurtLogic()  
 | 
          
 | 
        #±»Íæ¼ÒɱËÀ  
 | 
        if len(self.__AllKillerDict) > 0:  
 | 
            dropPlayer = None  
 | 
            maxPlayerLV = 0  
 | 
            ownerPlayerList = []  
 | 
            for curPlayer in self.__AllKillerDict.values():  
 | 
                if not self.__LastHurtPlayer:  
 | 
                    self.__LastHurtPlayer = curPlayer  
 | 
                if not self.__Killer:  
 | 
                    self.__Killer = curPlayer  
 | 
                      
 | 
                if maxPlayerLV < curPlayer.GetLV():  
 | 
                    maxPlayerLV = curPlayer.GetLV()  
 | 
                    dropPlayer = curPlayer  
 | 
                      
 | 
                if isGameBoss and curPlayer.GetOfficialRank() < GetRealmLV(curNPC):  
 | 
                    playerRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", curPlayer.GetOfficialRank())  
 | 
                    npcRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", GetRealmLV(curNPC))  
 | 
                    playerRealmLVLarge = playerRealmIpyData.GetLvLarge() if playerRealmIpyData else 0  
 | 
                    npcRealmLVLarge = npcRealmIpyData.GetLvLarge() if npcRealmIpyData else 0  
 | 
                    if npcRealmLVLarge > playerRealmLVLarge:  
 | 
                        GameWorld.Log("Íæ¼Ò´ó¾³½ç²»×㣬ÎÞ·¨»ñµÃBoss¹éÊô½±Àø! playerRealmLVLarge=%s,npcID=%s,npcRealmLVLarge=%s"   
 | 
                                      % (playerRealmLVLarge, npcID, npcRealmLVLarge), curPlayer.GetPlayerID())  
 | 
                        continue  
 | 
                      
 | 
                self.__KilledByPlayerSetPrize(curPlayer)  
 | 
                ownerPlayerList.append(curPlayer)  
 | 
            self.__ownerPlayerList = ownerPlayerList  
 | 
              
 | 
            #µ÷ÓÃÎïÆ·µôÂ䣬bossÒ»ÈËÒ»·Ý  
 | 
            if isGameBoss and hurtType in [ChConfig.Def_NPCHurtTypePlayer, ChConfig.Def_NPCHurtTypeTeam, ChConfig.Def_NPCHurtTypeSpecial]:  
 | 
                isOnlySelfSee = len(ownerPlayerList) > 1  
 | 
                for curPlayer in ownerPlayerList:  
 | 
                    self.__NPCDropItem(curPlayer, ChConfig.Def_NPCHurtTypePlayer, curPlayer.GetPlayerID(), [curPlayer], isOnlySelfSee=isOnlySelfSee)  
 | 
            elif dropPlayer:  
 | 
                self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)  
 | 
                      
 | 
        #±»¶ÓÎéɱËÀ  
 | 
        elif curTeam != None:  
 | 
            self.__KilledByTeamSetPrize(curTeam, hurtType, hurtID)  
 | 
          
 | 
        #±»ÏÉÃËɱËÀ  
 | 
        elif hurtType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
            self.__KilledByFamilySetPrize(hurtType, hurtID)  
 | 
              
 | 
        elif isGameBoss:  
 | 
            GameWorld.ErrLog("NPC¹éÊôÒì³£:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))  
 | 
          
 | 
        if isGameBoss:  
 | 
            dataDict = {"objID":curNPC.GetID(), "bossID":npcID, "mapID":GameWorld.GetMap().GetMapID(),  
 | 
                        "lineID":GameWorld.GetGameWorld().GetLineID(), "teamID":curTeam.GetTeamID() if curTeam else 0,  
 | 
                            "killerID":self.__AllKillerDict.keys(), "hurtType":hurtType,"hurtID":hurtID}  
 | 
            DataRecordPack.SendEventPack("KillBossRecord", dataDict)  
 | 
                  
 | 
        if OnNPCDie:  
 | 
            OnNPCDie(curNPC, hurtType, hurtID)  
 | 
              
 | 
        return  
 | 
      
 | 
    ## ×îºóÒ»»÷´¦Àí  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    def __DoLastTimeHurtLogic(self):  
 | 
        lastHurtPlayer = self.__LastHurtPlayer  
 | 
        if not lastHurtPlayer:  
 | 
            return  
 | 
          
 | 
        curObjType = lastHurtPlayer.GetGameObjType()  
 | 
        if curObjType != IPY_GameWorld.gotPlayer:  
 | 
            return  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        # VIPɱ¹Ö¼Ó¹¥  
 | 
        PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, curNPC)  
 | 
          
 | 
        # SPÖµ  
 | 
        PlayerControl.AddZhenQiByKillNPC(lastHurtPlayer, curNPC.GetSP())  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## NPCËÀÍö, ·ÖÏí¾ÑéÂß¼  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»Ø»÷É±Íæ¼ÒÐÅÏ¢Ôª×é, (Íæ¼ÒÁбíʵÀý,¶ÓÎéʵÀý,¹éÊôÀàÐÍ,¹éÊôID)  
 | 
    def __FindNPCKillerInfo(self, isGameBoss):  
 | 
        curNPC = self.__Instance  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        objID = curNPC.GetID()  
 | 
        key = (GameWorld.GetGameWorld().GetLineID(), objID, npcID)  
 | 
        if key in PyGameData.g_npcKillerInfo:  
 | 
            killerDict, killTeam, hurtType, hurtID = PyGameData.g_npcKillerInfo.pop(key)  
 | 
            teamID = killTeam.GetTeamID() if killTeam else 0  
 | 
            GameWorld.Log("NPC±»»÷ɱ£¬¹éÊôÐÅÏ¢: key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s"   
 | 
                          % (key, killerDict.keys(), teamID, hurtType, hurtID))  
 | 
            return killerDict, killTeam, hurtType, hurtID  
 | 
          
 | 
        hurtType = 0  
 | 
        hurtID = 0  
 | 
        killerDict = {} # ÓÃÓÚÖ§³Ö¶à¸öÍæ¼ÒÌØÊâ¹éÊôµÄ£¬ÊÖÓοÉÄÜÔÝʱ²»Óã¬Ö®Ç°Ò³ÓÎÓÐÓõ½£¬Ïȱ£Áô£¬ÒªÀ©Õ¹ÔÙ˵  
 | 
        killTeam = None  
 | 
          
 | 
        #isLog = self.__GetIsLog()  
 | 
        dropOwnerType = GetDropOwnerType(curNPC)  
 | 
        if isGameBoss:  
 | 
            GameWorld.Log("NPC±»»÷ɱ, key=%s,dropOwnerType=%s" % (key, dropOwnerType))  
 | 
              
 | 
        # ×î´óÉËѪ - ÉËѪ¿ÉÄܱ»ÖØÖà  
 | 
        if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:  
 | 
            npcHurtList = curNPC.GetPlayerHurtList()  
 | 
            npcHurtList.Sort()  
 | 
            if isGameBoss:  
 | 
                GameWorld.Log("hurtCount=%s" % (npcHurtList.GetHurtCount()))  
 | 
            for i in xrange(npcHurtList.GetHurtCount()):  
 | 
                #»ñµÃ×î´óÉËѪ¶ÔÏó  
 | 
                maxHurtObj = npcHurtList.GetHurtAt(i)  
 | 
                if isGameBoss:  
 | 
                    GameWorld.Log("hurtIndex=%s,hurtValueType=%s,valueID=%s" % (i, maxHurtObj.GetValueType(), maxHurtObj.GetValueID()))  
 | 
                curPlayer, curTeam = self.__GetTagByHurtObj(maxHurtObj, isLog=isGameBoss)  
 | 
                #µ±Ç°ÉËѪ¶ÔÏ󳬳öÖ¸¶¨·¶Î§»òÒѾËÀÍö  
 | 
                if curPlayer == None and curTeam == None:  
 | 
                    if isGameBoss:  
 | 
                        GameWorld.Log("    µ±Ç°ÉËѪ¶ÔÏ󳬳öÖ¸¶¨·¶Î§»òÒѾËÀÍö")  
 | 
                    continue  
 | 
                  
 | 
                if curPlayer:  
 | 
                    playerID = curPlayer.GetPlayerID()  
 | 
                    if playerID not in killerDict:  
 | 
                        killerDict[playerID] = curPlayer  
 | 
                    if isGameBoss:  
 | 
                        GameWorld.Log("    ¹éÊô×î´óÉËÑªÍæ¼Ò: npcID=%s,dropOwnerType=%s,playerID=%s" % (npcID, dropOwnerType, playerID))  
 | 
                    return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, playerID  
 | 
                  
 | 
                if curTeam:  
 | 
                    killTeam = curTeam  
 | 
                    if isGameBoss:  
 | 
                        GameWorld.Log("    ¹éÊô×î´óÉËѪ¶ÓÎé: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID()))  
 | 
                    return killerDict, curTeam, ChConfig.Def_NPCHurtTypeTeam, curTeam.GetTeamID()  
 | 
                  
 | 
        # ×î´ó³ðºÞ  
 | 
        elif dropOwnerType == ChConfig.DropOwnerType_MaxAngry:  
 | 
            maxAngryPlayer, maxAngryTeam = self.__GetMaxAngryInfo()  
 | 
            if maxAngryTeam:  
 | 
                #if isLog:  
 | 
                #    GameWorld.DebugLog("    ¹éÊô×î´ó³ðºÞ¶ÓÎé: npcID=%s,teamID=%s" % (npcID, maxAngryTeam.GetTeamID()))  
 | 
                #GameWorld.DebugLog("    ¹éÊô×î´ó³ðºÞ¶ÓÎé: %s" % maxAngryTeam.GetTeamID())  
 | 
                return killerDict, maxAngryTeam, ChConfig.Def_NPCHurtTypeTeam, maxAngryTeam.GetTeamID()  
 | 
            elif maxAngryPlayer:  
 | 
                killerDict[maxAngryPlayer.GetPlayerID()] = maxAngryPlayer  
 | 
                #if isLog:  
 | 
                #    GameWorld.DebugLog("    ¹éÊô×î´ó³ðºÞÍæ¼Ò: npcID=%s,playerID=%s" % (npcID, maxAngryPlayer.GetPlayerID()))  
 | 
                #GameWorld.DebugLog("    ¹éÊô×î´ó³ðºÞÍæ¼Ò: %s" % maxAngryPlayer.GetPlayerID())  
 | 
                return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, maxAngryPlayer.GetPlayerID()  
 | 
              
 | 
        # ÆäËûĬÈÏ×îºóÒ»»÷  
 | 
        if self.__LastHurtPlayer:  
 | 
            lastHurtPlayerID = self.__LastHurtPlayer.GetPlayerID()  
 | 
            teamID = self.__LastHurtPlayer.GetTeamID()  
 | 
            if isGameBoss:  
 | 
                GameWorld.Log("    ¹éÊô×îºóÒ»»÷£¬npcID=%s,lastHurtPlayerID=%s,teamID=%s" % (npcID, lastHurtPlayerID, teamID))  
 | 
            if teamID:  
 | 
                killTeam = GameWorld.GetTeamManager().FindTeam(teamID)  
 | 
            if not killTeam and lastHurtPlayerID not in killerDict:  
 | 
                killerDict[lastHurtPlayerID] = self.__LastHurtPlayer  
 | 
                  
 | 
        if dropOwnerType == ChConfig.DropOwnerType_All:  
 | 
            hurtType = ChConfig.Def_NPCHurtTypeAll  
 | 
            if isGameBoss:  
 | 
                GameWorld.Log("    ÎÞ¹éÊô...npcID=%s" % npcID)  
 | 
              
 | 
        elif dropOwnerType == ChConfig.DropOwnerType_Faction:  
 | 
            #ÕóÓª¹éÊô  
 | 
            protectFaction = FBLogic.GetNPCItemProtectFaction(curNPC)  
 | 
            if protectFaction > 0:  
 | 
                hurtType = ChConfig.Def_NPCHurtTypeFaction  
 | 
                hurtID = protectFaction  
 | 
                if isGameBoss:  
 | 
                    GameWorld.Log("    ÕóÓª¹éÊô...factionID=%s" % protectFaction)  
 | 
                  
 | 
        if hurtType == 0:  
 | 
            #¹éÊô¶ÓÎé  
 | 
            if killTeam:  
 | 
                hurtType = ChConfig.Def_NPCHurtTypeTeam  
 | 
                hurtID = killTeam.GetTeamID()  
 | 
                if isGameBoss:  
 | 
                    GameWorld.Log("    ¹éÊôĬÈ϶ÓÎé, npcID=%s,teamID=%s" % (npcID, hurtID))  
 | 
            #ÉËѪ¹éÊôÍæ¼Ò  
 | 
            elif killerDict:  
 | 
                hurtType = ChConfig.Def_NPCHurtTypePlayer  
 | 
                hurtID = killerDict.keys()[0]  
 | 
                if isGameBoss:  
 | 
                    GameWorld.Log("    ¹éÊôĬÈÏÍæ¼Ò, npcID=%s,playerID=%s" % (npcID, hurtID))  
 | 
            elif GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_GatherSoul:  
 | 
                player = FBCommon.GetCurSingleFBPlayer()  
 | 
                if player:  
 | 
                    hurtID = player.GetPlayerID()  
 | 
                    killerDict[hurtID] = player  
 | 
                    hurtType = ChConfig.Def_NPCHurtTypePlayer  
 | 
                    #GameWorld.Log("    ¾Û»ê¸±±¾¹éÊôĬÈÏÍæ¼Ò, npcID=%s,playerID=%s" % (npcID, hurtID))  
 | 
                  
 | 
        return killerDict, killTeam, hurtType, hurtID  
 | 
      
 | 
    def __GetMaxAngryInfo(self):  
 | 
        ''' »ñÈ¡×î´ó³ðºÞËù¹éÊôµÄÍæ¼Ò, ¶ÓÎé '''  
 | 
          
 | 
        curAngry = self.GetMaxAngryTag()  
 | 
        if not curAngry:  
 | 
            return None, None  
 | 
          
 | 
        angryID = curAngry.GetObjID()  
 | 
        angryObjType = curAngry.GetObjType()  
 | 
        if angryObjType != IPY_GameWorld.gotPlayer:  
 | 
            return None, None  
 | 
          
 | 
        curTag = GameWorld.GetObj(angryID, angryObjType)  
 | 
        if not curTag:  
 | 
            return None, None  
 | 
          
 | 
        teamID = curTag.GetTeamID()  
 | 
        if not teamID:  
 | 
            return curTag, None  
 | 
          
 | 
        return curTag, GameWorld.GetTeamManager().FindTeam(teamID)  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
      
 | 
    ## »ñÈ¡²¹µ¶Õß(Õâ¸ö¾ø¶ÔÊÇÍæ¼Ò)  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @return ·µ»ØÖµ Íæ¼Ò»òÕßNone  
 | 
    def __FindLastTimeHurtObjEx(self):  
 | 
        curNPC = self.__Instance  
 | 
        playerID = curNPC.GetDictByKey(ChConfig.Def_PlayerKey_LastHurt)  
 | 
          
 | 
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  
 | 
        if not curPlayer:  
 | 
            return None  
 | 
          
 | 
        return curPlayer  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## »ñµÃÉËѪ¶ÔÏó,Ö§³ÖÇÀ¹Ö  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param maxHurtObj ×î´óÉËѪ¶ÔÏó  
 | 
    #  @return ·µ»ØÖµ, ÉËѪ¶ÔÏó  
 | 
    #  @remarks »ñµÃÉËѪ¶ÔÏó,Ö§³ÖÇÀ¹Ö  
 | 
    def __GetTagByHurtObj(self, maxHurtObj, isCheckRefreshArea=False, isLog=False):  
 | 
        #»ñµÃËÀÍöµÄNPC  
 | 
        curNPC = self.__Instance  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        # É˺¦µÄobjÀàÐÍÔª×é(Íæ¼Ò, ¶ÓÎé)  
 | 
        hurtObjTuple = (None, None)  
 | 
        if maxHurtObj == None:  
 | 
            GameWorld.DebugLog("ÉËѪ¶ÔÏó´íÎó,npcID=%s" % (curNPC.GetNPCID()))  
 | 
            return hurtObjTuple  
 | 
          
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        #×î´óÉËѪÀàÐÍ  
 | 
        maxHurtValueType = maxHurtObj.GetValueType()  
 | 
          
 | 
        if maxHurtValueType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
            curPlayer = GameWorld.GetObj(maxHurtObj.GetValueID(), IPY_GameWorld.gotPlayer)  
 | 
              
 | 
            if curPlayer == None:  
 | 
                if isLog:  
 | 
                    GameWorld.Log("ÕÒ²»µ½¸ÃÄ¿±êÉËÑªÍæ¼Ò: npcID=%s,playerID=%s" % (npcID, maxHurtObj.GetValueID()))  
 | 
                return hurtObjTuple  
 | 
              
 | 
            #Ö§³ÖÇÀ¹Ö,¸öÈËɱËÀ,µ«×Ô¼ºËÀÍö,²»Ëã  
 | 
            if curPlayer.GetHP() <= 0 or curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  
 | 
                if isLog:  
 | 
                    GameWorld.Log("¸ÃÄ¿±êÉËÑªÍæ¼ÒÒÑËÀÍö: npcID=%s,playerID=%s" % (npcID, maxHurtObj.GetValueID()))  
 | 
                return hurtObjTuple  
 | 
              
 | 
            if isCheckRefreshArea:  
 | 
                if not self.GetIsInRefreshPoint(curPlayer.GetPosX(), curPlayer.GetPosY(), refreshPoint):  
 | 
                    if isLog:  
 | 
                        GameWorld.Log("¸ÃÄ¿±êÉËÑªÍæ¼Ò²»ÔÚNPCÇøÓòÄÚ: npcID=%s,playerID=%s,pos(%s,%s)"   
 | 
                                      % (npcID, maxHurtObj.GetValueID(), curPlayer.GetPosX(), curPlayer.GetPosY()))  
 | 
                    return hurtObjTuple  
 | 
            #Èç¹ûÍæ¼ÒÒѾ³¬³öÖ¸¶¨¾àÀë,²»¼Ó¾Ñé  
 | 
            elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),  
 | 
                                     curPlayer.GetPosX(), curPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:  
 | 
                if isLog:  
 | 
                    GameWorld.Log("¸ÃÄ¿±êÉËÑªÍæ¼Ò³¬³öÖ¸¶¨¾àÀë: npcID=%s,playerID=%s,npcPos(%s,%s),playerPos(%s,%s)"   
 | 
                                  % (npcID, maxHurtObj.GetValueID(), curNPC.GetPosX(), curNPC.GetPosY(), curPlayer.GetPosX(), curPlayer.GetPosY()))  
 | 
                return hurtObjTuple  
 | 
              
 | 
            #Õý³£·µ»Ø  
 | 
            hurtObjTuple = (curPlayer, None)  
 | 
            return curPlayer, None  
 | 
          
 | 
        elif maxHurtValueType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
            #»ñµÃµ±Ç°¶ÓÎé  
 | 
            teamID = maxHurtObj.GetValueID()  
 | 
            curTeam = GameWorld.GetTeamManager().FindTeam(teamID)  
 | 
            if isLog:  
 | 
                GameWorld.Log("Ä¿±êÉËѪ¶ÓÎé: npcID=%s,teamID=%s" % (npcID, teamID))  
 | 
            if curTeam == None:  
 | 
                if isLog:  
 | 
                    GameWorld.Log("ÕÒ²»µ½Ä¿±ê¶ÓÎé, teamID=%s" % (teamID))  
 | 
                return hurtObjTuple  
 | 
              
 | 
            if isLog:  
 | 
                GameWorld.Log("¶ÓÎé³ÉÔ±Êý: GetMemberCount=%s" % (curTeam.GetMemberCount()))                  
 | 
            #±éÀú¶ÓÎé,°ë¾¶ÎªÒ»ÆÁ°ëµÄ¾àÀëÄÚµÄËùÓжÓÎé/ÍŶӳÉÔ±£¬¿ÉÒÔ»ñµÃ¾Ñé  
 | 
            for i in xrange(curTeam.GetMemberCount()):  
 | 
                curTeamPlayer = curTeam.GetMember(i)  
 | 
                if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                    if isLog:  
 | 
                        GameWorld.Log("    i=%s, Î޸öÓÔ±£¡" % (i))  
 | 
                    continue  
 | 
                  
 | 
                if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  
 | 
                    if isLog:  
 | 
                        GameWorld.Log("    i=%s, ¶ÓÔ±ÒÑËÀÍö£¡memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))  
 | 
                    continue  
 | 
                  
 | 
                if isCheckRefreshArea:  
 | 
                    if not self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):  
 | 
                        if isLog:  
 | 
                            GameWorld.Log("    i=%s, ¶ÓÔ±²»ÔÚNPCÇøÓòÄÚ£¡memPlayerID=%s,pos(%s,%s)"   
 | 
                                          % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY()))  
 | 
                        continue  
 | 
                elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(),  
 | 
                                       curTeamPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:  
 | 
                    if isLog:  
 | 
                        GameWorld.Log("    i=%s, ¶ÓÔ±³¬³öÖ¸¶¨¾àÀ룡memPlayerID=%s,npcPos(%s,%s),playerPos(%s,%s)"   
 | 
                                      % (i, curTeamPlayer.GetPlayerID(), curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY()))  
 | 
                    continue  
 | 
                  
 | 
                hurtObjTuple = (None, curTeam)  
 | 
                return hurtObjTuple  
 | 
              
 | 
            return hurtObjTuple  
 | 
              
 | 
        #×î´óÉËѪ¶ÔÏóÊÇNPC,ÄÇôһ¶¨²»¸ø¾Ñé(Íæ¼ÒµÄÕÙ»½ÊÞÉËѪËãÍæ¼Ò)  
 | 
        elif maxHurtValueType == ChConfig.Def_NPCHurtTypeNPC:  
 | 
            return hurtObjTuple  
 | 
          
 | 
        #Òì³£ÐÅÏ¢,Ìí¼ÓÉËѪÀàÐÍ´íÎó  
 | 
        else:  
 | 
            pass  
 | 
          
 | 
        return hurtObjTuple  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## Íæ¼ÒɱËÀNPC½±ÀøÂß¼  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param curPlayer Íæ¼ÒʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks Íæ¼ÒɱËÀNPC½±ÀøÂß¼  
 | 
    def __KilledByPlayerSetPrize(self, curPlayer):  
 | 
        curNPC = self.__Instance  
 | 
        add_Exp = self.__GetExp(curPlayer.GetLV(), False, curPlayer)  
 | 
          
 | 
        #if self.__GetIsLog():  
 | 
        #    GameWorld.Log("Íæ¼ÒÔö¼Ó¸öÈ˾Ñé,npcID=%s,addExp=%s" % (curNPC.GetNPCID(), add_Exp), curPlayer.GetPlayerID())  
 | 
        addSkillID = 0  
 | 
        if curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID) == curPlayer.GetID():  
 | 
            addSkillID = curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason)  
 | 
  
 | 
        #É趨ÈËÎï»ñµÃ¾Ñé  
 | 
        playerControl = PlayerControl.PlayerControl(curPlayer)  
 | 
        playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC, addSkillID=addSkillID)  
 | 
          
 | 
          
 | 
        self.__KillNPCFuncEx(curPlayer, curNPC, curPlayer.GetPlayerID(), False)  
 | 
        #if curNPC.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark:  
 | 
        #    #Ôö¼ÓÍæ¼Ò»÷ɱbossÊý  
 | 
        #    PlayerControl.AddPlayerKillBossCount(curPlayer, curNPC)  
 | 
          
 | 
        #GameWorld.Log("¸öÈËɱËÀ¹ÖÎï½±Àø,Âß¼³É¹¦½áÊø")  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## ¶ÓÎéɱËÀNPC½±ÀøÂß¼  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param curTeam ¶ÓÎéʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ¶ÓÎéɱËÀNPC½±ÀøÂß¼  
 | 
    def __KilledByTeamSetPrize(self, curTeam, hurtType, hurtID):  
 | 
        curNPC = self.__Instance  
 | 
        #¶ÓÔ±ÁÐ±í  
 | 
        playerlist = PlayerControl.GetAreaTeamMember(curTeam, curNPC.GetPosX(), curNPC.GetPosY(), isLog=self.__GetIsLog())  
 | 
        #playerlist = PlayerControl.GetMapTeamMember(curTeam)  
 | 
        if not playerlist:  
 | 
            GameWorld.ErrLog("½±Àø¹éÊô¶ÓÎ飬µ«ÊDz»´æÔÚ¿É»ñµÃ¸Ã½±ÀøµÄ¶ÓÔ±!npcID=%s,teamID=%s,hurtType=%s,hurtID=%s"   
 | 
                             % (curNPC.GetNPCID(), curTeam.GetTeamID(), hurtType, hurtID))  
 | 
            return  
 | 
          
 | 
        if not self.__LastHurtPlayer:  
 | 
            self.__LastHurtPlayer = playerlist[0]  
 | 
        if not self.__Killer:  
 | 
            self.__Killer = playerlist[0]  
 | 
        maxHurtID = playerlist[0].GetPlayerID()  
 | 
          
 | 
        teamMaxLV = 0  
 | 
        dropPlayer = None  
 | 
        ownerPlayerList = []  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        isGameBoss = ChConfig.IsGameBoss(curNPC)  
 | 
        #±éÀú¶ÓÎé,°ë¾¶ÎªÒ»ÆÁ°ëµÄ¾àÀëÄÚµÄËùÓжÓÎé/ÍŶӳÉÔ±£¬¿ÉÒÔ»ñµÃ¾Ñé  
 | 
        for curPlayer in playerlist:  
 | 
            if isGameBoss and curPlayer.GetOfficialRank() < GetRealmLV(curNPC):  
 | 
                playerRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", curPlayer.GetOfficialRank())  
 | 
                npcRealmIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Realm", GetRealmLV(curNPC))  
 | 
                playerRealmLVLarge = playerRealmIpyData.GetLvLarge() if playerRealmIpyData else 0  
 | 
                npcRealmLVLarge = npcRealmIpyData.GetLvLarge() if npcRealmIpyData else 0  
 | 
                if npcRealmLVLarge > playerRealmLVLarge:  
 | 
                    GameWorld.Log("¶ÓÔ±Íæ¼Ò´ó¾³½ç²»×㣬ÎÞ·¨»ñµÃBoss¹éÊô½±Àø! playerRealmLVLarge=%s,npcID=%s,npcRealmLVLarge=%s"   
 | 
                                  % (playerRealmLVLarge, npcID, npcRealmLVLarge), curPlayer.GetPlayerID())  
 | 
                    continue  
 | 
                  
 | 
            curPlayerLV = curPlayer.GetLV()  
 | 
            if teamMaxLV < curPlayerLV:  
 | 
                teamMaxLV = curPlayerLV  
 | 
                dropPlayer = curPlayer  
 | 
                  
 | 
            ownerPlayerList.append(curPlayer)  
 | 
              
 | 
            self.__DoNormalTeamExp(curPlayer)  
 | 
            self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, True)  
 | 
        self.__ownerPlayerList = ownerPlayerList  
 | 
          
 | 
        #µ÷ÓÃÎïÆ·µôÂ䣬bossÒ»ÈËÒ»·Ý  
 | 
        if isGameBoss and hurtType in [ChConfig.Def_NPCHurtTypePlayer, ChConfig.Def_NPCHurtTypeTeam, ChConfig.Def_NPCHurtTypeSpecial]:  
 | 
            isOnlySelfSee = len(ownerPlayerList) > 1  
 | 
            for curPlayer in ownerPlayerList:  
 | 
                self.__NPCDropItem(curPlayer, ChConfig.Def_NPCHurtTypePlayer, curPlayer.GetPlayerID(), [curPlayer], isOnlySelfSee=isOnlySelfSee)  
 | 
        elif dropPlayer:  
 | 
            self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)  
 | 
        #GameWorld.Log("¶ÓÎéɱËÀ¹ÖÎï½±Àø,Âß¼³É¹¦½áÊø")  
 | 
        return  
 | 
      
 | 
    def __KilledByFamilySetPrize(self, hurtType, hurtID):  
 | 
        ## ÏÉÃËɱËÀNPC½±ÀøÂß¼  
 | 
        curNPC = self.__Instance  
 | 
          
 | 
        maxLV = 0  
 | 
        dropPlayer = None  
 | 
        ownerPlayerList = []  
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()  
 | 
        for index in xrange(copyPlayerMgr.GetPlayerCount()):  
 | 
            player = copyPlayerMgr.GetPlayerByIndex(index)  
 | 
            if not player:  
 | 
                continue  
 | 
              
 | 
            if player.GetFamilyID() != hurtID or not self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):  
 | 
                continue  
 | 
              
 | 
            curPlayerLV = player.GetLV()  
 | 
            if maxLV < curPlayerLV:  
 | 
                maxLV = curPlayerLV  
 | 
                dropPlayer = player  
 | 
            ownerPlayerList.append(player)  
 | 
        self.__ownerPlayerList = ownerPlayerList  
 | 
              
 | 
        if not ownerPlayerList:  
 | 
            GameWorld.Log("½±Àø¹éÊôÏÉÃË£¬µ«ÊDz»´æÔÚ¿É»ñµÃ¸Ã½±ÀøµÄ³ÉÔ±!npcID=%s,hurtType=%s,hurtID=%s"   
 | 
                          % (curNPC.GetNPCID(), hurtType, hurtID))  
 | 
              
 | 
        # ÒòΪÏÉÃ˹éÊôboss¹éÊôÉËѪµÚÒ»µÄÏÉÃË£¬ÏÉÃËÉËѪÓб£»¤£¬¿ÉÄÜ´æÔÚÉËѪµÚÒ»ÏÉÃËÔÚbossËÀÍöµÄʱºò¶¼²»ÔÚ  
 | 
        # ´ËʱµôÂ伯ËãÍæ¼ÒËã×îºóÒ»»÷Íæ¼Ò£¬¹éÊô»¹ÊÇËãÉËѪµÚÒ»ÏÉÃ赀  
 | 
        if not dropPlayer:  
 | 
            dropPlayer = self.__LastHurtPlayer  
 | 
              
 | 
        if not dropPlayer:  
 | 
            GameWorld.ErrLog("½±Àø¹éÊôÏÉÃË£¬ÕÒ²»µ½µôÂäÍæ¼Ò!npcID=%s,hurtType=%s,hurtID=%s"   
 | 
                             % (curNPC.GetNPCID(), hurtType, hurtID))  
 | 
            return  
 | 
          
 | 
        # ¸Ïʱ¼ä£¬Ïȼòµ¥´¦ÀíÖ±½ÓÈ¡×î´óµÈ¼¶µÄ£¬Ö®ºó¿É°´Êµ¼ÊÇé¿öÀ´  
 | 
        if not self.__LastHurtPlayer:  
 | 
            self.__LastHurtPlayer = dropPlayer  
 | 
        if not self.__Killer:  
 | 
            self.__Killer = dropPlayer  
 | 
        maxHurtID = dropPlayer.GetPlayerID()  
 | 
          
 | 
        for curPlayer in ownerPlayerList:  
 | 
            self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, False)  
 | 
              
 | 
        #µ÷ÓÃÎïÆ·µôÂä  
 | 
        self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)  
 | 
        return  
 | 
      
 | 
    ## ¶ÓÎé»ò×Ô¼º»÷ɱNPCÀ©Õ¹¹¦ÄÜ  
 | 
    #  @param curPlayer  
 | 
    #  @return None  
 | 
    #  @remarks: ¿É×öһЩ»÷ɱNPCºóµÄÀ©Õ¹¹¦ÄÜ(Èç³É¾Í, ³ÆºÅ, »îÔ¾¶È, ¹ã²¥µÈ)£¬¿ÉÒÔͳһдÕâ±ß£¬ÒÔǰ±È½ÏÂÒ  
 | 
    def __KillNPCFuncEx(self, curPlayer, curNPC, killerID, isTeamKill):  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        defObjType = curNPC.GetGameObjType()   
 | 
        mapFBType = GameWorld.GetMap().GetMapFBType()  
 | 
        mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())  
 | 
        #playerID = curPlayer.GetPlayerID()  
 | 
          
 | 
        # Èç¹ûÊÇNPC  
 | 
        if defObjType != IPY_GameWorld.gotNPC:  
 | 
            return  
 | 
          
 | 
        # ¿ç·þ·þÎñÆ÷´¦Àí  
 | 
        if GameWorld.IsCrossServer():  
 | 
            #µôÂä¹éÊô  
 | 
            if mapFBType != IPY_GameWorld.fbtNull:  
 | 
                FBLogic.DoFB_DropOwner(curPlayer , curNPC)  
 | 
                  
 | 
            if ChConfig.IsGameBoss(curNPC):  
 | 
                OnPlayerKillBoss(curPlayer, npcID, mapID, True)  
 | 
            return  
 | 
          
 | 
        #µôÂä¹éÊô  
 | 
        if mapFBType != IPY_GameWorld.fbtNull:  
 | 
            FBLogic.DoFB_DropOwner(curPlayer , curNPC)  
 | 
        else:  
 | 
            if curNPC.GetLV()>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):  
 | 
                PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC)  
 | 
            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FeastRedPack_KillSpecificNPC, 1, [npcID])  
 | 
              
 | 
        if ChConfig.IsGameBoss(curNPC):  
 | 
            OnPlayerKillBoss(curPlayer, npcID, mapID, False)  
 | 
        return  
 | 
          
 | 
    #---------------------------------------------------------------------  
 | 
    ## »÷ɱNPC´¥·¢ÈÎÎñʼþ  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param curPlayer Íæ¼ÒʵÀý  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks »÷ɱNPC´¥·¢ÈÎÎñʼþ  
 | 
    def __MissionOnKillNPC(self, curPlayer, isFeel=False):  
 | 
        curNPC = self.__Instance  
 | 
        npcObjType = curNPC.GetGameNPCObjType()  
 | 
          
 | 
        #NPCÓÐÖ÷ÈË, ÊÇÕÙ»½ÊÞ  
 | 
        if npcObjType == IPY_GameWorld.gnotSummon:   
 | 
            curNPCOwner = GetSummonNPCOwner(IPY_GameWorld.gotPlayer , curNPC)  
 | 
            if curNPCOwner:  
 | 
                return  
 | 
              
 | 
        #²»ÊÇÆÕͨNPC      
 | 
        elif npcObjType != IPY_GameWorld.gnotNormal:  
 | 
            return  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        #GameWorld.DebugLog("__MissionOnKillNPC isFeel=%s" % (isFeel), curPlayer.GetPlayerID())  
 | 
        killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)  
 | 
        limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)  
 | 
        isWorldBoos = limitIndex == ShareDefine.Def_Boss_Func_World  
 | 
        if isFeel:  
 | 
            #»÷ɱNPC´¥·¢Ãþ¹ÖÈÎÎñʼþ  
 | 
            EventShell.EventRespons_OnKillByFeel(curPlayer, curNPC)  
 | 
            if isWorldBoos:  
 | 
                EventShell.EventRespons_KillWorldBossByFeel(curPlayer)  
 | 
        else:  
 | 
            #ÆÕͨNPC»÷ɱ´¥·¢  
 | 
            EventShell.EventRespons_OnKillById(curPlayer, curNPC)  
 | 
            if isWorldBoos:  
 | 
                EventShell.EventRespons_KillWorldBoss(curPlayer)  
 | 
        #»÷É±ÌØ¶¨NPC³É¾Í  
 | 
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID])  
 | 
        #BossͶ×Ê£¬»÷ɱ¼°Ãþ¹Ö¶¼Ëã  
 | 
        if limitIndex != None:  
 | 
            PlayerGoldInvest.OnKillBoss(curPlayer, npcID)  
 | 
        return  
 | 
          
 | 
    def __GetIsLog(self):  
 | 
        ## ²âÊÔ²é´íÈÕÖ¾£¬ÁÙʱÓà  
 | 
        ## Ïà¹Øbug£º ÏɽçÃØ¾³ÎÞ¾Ñé¡¢bossÎÞµôÂä  
 | 
        return ChConfig.IsGameBoss(self.__Instance)  
 | 
        #return GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_BZZD or ChConfig.IsGameBoss(self.__Instance)  
 | 
  
 | 
    #---------------------------------------------------------------------  
 | 
    ## ÆÕͨ×é¶Ó¸ø¾Ñé  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param curPlayer Íæ¼ÒʵÀý  
 | 
    #  @param playerCount Íæ¼ÒÊýÁ¿  
 | 
    #  @param playerCountAddRate Íæ¼ÒÊýÁ¿¼Ó³É  
 | 
    #  @param team_Relation ×é¶Ó¹ØÏµ¼Ó³É  
 | 
    #  @param team_AverageLV ¶ÓÎ鯽¾ùµÈ¼¶  
 | 
    #  @return ·µ»ØÖµÎÞÒâÒå  
 | 
    #  @remarks ÆÕͨ×é¶Ó¸ø¾Ñé  
 | 
    def __DoNormalTeamExp(self, curPlayer):  
 | 
        curNPC = self.__Instance  
 | 
        ##ÆÕͨ×é¶Ó¸öÈ˾ÑéÔö¼Ó Min(¸öÈ˾Ñé*ÈËÊý¼Ó³É*¸öÈ˵ȼ¶/µ±Ç°¶ÓÎ鯽¾ùµÈ¼¶,¸öÈ˾Ñé)*µ±Ç°×é¶Ó¹ØÏµ  
 | 
        add_Exp = self.__GetExp(curPlayer.GetLV(), True, curPlayer)  
 | 
        #if self.__GetIsLog():  
 | 
        #   GameWorld.Log("¶ÓÔ±Ôö¼Ó¸öÈ˾Ñé,npcID=%s,addExp=%s" % (curNPC.GetNPCID(), add_Exp), curPlayer.GetPlayerID())  
 | 
        if not add_Exp:  
 | 
            return  
 | 
        #GameWorld.Log("ÆÕͨ¶ÓÎéɱËÀ¹ÖÎï,¶ÓÎé·ÖÏíÈËÊý = %s,¸öÈ˾ÑéÔö¼Ó Íæ¼Ò = %s, Ôö¼Ó = %s"%(playerCount, curPlayer.GetPlayerID(), add_Exp))  
 | 
        #É趨ÈËÎï»ñµÃ¾Ñé  
 | 
        addSkillID = 0  
 | 
        if curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID) == curPlayer.GetID():  
 | 
            addSkillID = curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason)  
 | 
        playerControl = PlayerControl.PlayerControl(curPlayer)  
 | 
        playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC, addSkillID=addSkillID)  
 | 
        return  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
    ## »ñµÃ¾Ñé  
 | 
    #  @param self ÀàʵÀý  
 | 
    #  @param curPlayerLV Íæ¼ÒµÈ¼¶  
 | 
    #  @param isTeam ÊÇ·ñ×é¶Ó  
 | 
    #  @return ·µ»ØÖµ, »ñµÃ¾Ñé  
 | 
    #  @remarks »ñµÃ¾Ñé, ¿ÉÄÜÊÇСÊý  
 | 
    def __GetExp(self, playerLV, isTeam=False, player=None):  
 | 
        curNPC = self.__Instance  
 | 
        baseExp = 0  
 | 
        #Íæ¼Ò²»ÔÚ¸±±¾ÖÐ  
 | 
        if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:  
 | 
            baseExp = FBLogic.OnGetNPCExp(player, curNPC)  
 | 
        if baseExp > 0:  
 | 
            return baseExp  
 | 
          
 | 
        baseExp = curNPC.GetExp()  
 | 
        if baseExp == 0:  
 | 
            #GameWorld.Log("ɱ¹Ö¾ÑéÒì³£,¸ÃNPC = %s,ÎÞ¾Ñé"%(curNPC.GetID()))  
 | 
            return 0  
 | 
          
 | 
        playerID = 0 if not player else player.GetPlayerID()  
 | 
        # Èç¹ûÊǶÓÎ飬Ôò°´É˺¦¹±Ï׶ȼÆËãËù»ñµÃ¾Ñé±ÈÀý  
 | 
        if isTeam:  
 | 
            if not player:  
 | 
                return 0  
 | 
            hurtPer = AttackCommon.GetTeamPlayerHurtPer(player, curNPC)  
 | 
            if not hurtPer:  
 | 
                return 0  
 | 
            #GameWorld.DebugLog("¶ÓÔ±»÷ɱ»ù´¡¾Ñé: npcID=%s,baseExp=%s,hurtPer=%s" % (curNPC.GetNPCID(), baseExp, hurtPer), playerID)  
 | 
            baseExp *= hurtPer  
 | 
        #else:  
 | 
        #    GameWorld.DebugLog("¸öÈË»÷ɱ»ù´¡¾Ñé: npcID=%s,baseExp=%s" % (curNPC.GetNPCID(), baseExp), playerID)  
 | 
          
 | 
        #¾ÑéË¥¼õ¹«Ê½ = max(ɱ¹Ö¾Ñé * max(1-max(Íæ¼ÒµÈ¼¶-¹ÖÎïµÈ¼¶-10,0)*0.02)£¬0),1£©  
 | 
        npcLV = curNPC.GetLV()  
 | 
        exp = eval(FormulaControl.GetCompileFormula("ExpAttenuation", IpyGameDataPY.GetFuncCfg("ExpAttenuation", 1)))  
 | 
        #exp = CalcNPCExp(baseExp, playerLV, npcLV)  
 | 
        #GameWorld.DebugLog("»÷ɱNPC×îÖÕ»ù´¡¾Ñé: npcID=%s,npcLV=%s,playerLV=%s,baseExp=%s,exp=%s"   
 | 
        #                   % (curNPC.GetNPCID(), npcLV, playerLV, baseExp, exp), playerID)  
 | 
        return exp  
 | 
      
 | 
    #---------------------------------------------------------------------  
 | 
      
 | 
    ## ÔÚµØÍ¼ÉÏ´´½¨ÎïÆ·  
 | 
    #  @param posX: ×ø±êX  
 | 
    #  @param posY: ×ø±êY  
 | 
    #  @param dropType: µôÂäÀàÐÍ  
 | 
    #  @param ownerID: ¹éÊôÕß  
 | 
    #  @return: None  
 | 
    def __MapCreateItem(self, curItem, posX, posY, dropType, ownerID, isOnlySelfSee=False):  
 | 
        if not curItem:  
 | 
            return  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        curNPCID = curNPC.GetNPCID()  
 | 
          
 | 
        #===========================================================================================  
 | 
        # ²ß»®ÐèÇó¸ÄΪʰȡ¼Ç¼¼°¹ã²¥  
 | 
        # # boss²Å´¦ÀíµôÂäÎïÆ·¼Ç¼  
 | 
        # if curNPC.GetIsBoss():  
 | 
        #    killerName = "" if not self.__Killer else self.__Killer.GetPlayerName()  
 | 
        #    killerid = 0 if not self.__Killer else self.__Killer.GetPlayerID()  
 | 
        #    SendGameServerGoodItemRecord(curMapID, curNPCID, killerName, killerid, curItem)  
 | 
        #===========================================================================================  
 | 
          
 | 
        # ÔÚµØÉÏÌí¼ÓÎïÆ·(ͳһ½Ó¿Ú)  
 | 
        dropNPCID = 0 if not ChConfig.IsGameBoss(curNPC) else curNPCID  
 | 
        specOwnerIDList = [player.GetPlayerID() for player in self.__ownerPlayerList] if dropType == ChConfig.Def_NPCHurtTypeSpecial else []  
 | 
        curMapItem = ChItem.AddMapDropItem(posX, posY, curItem, ownerInfo=[dropType, ownerID, specOwnerIDList], dropNPCID=dropNPCID, isOnlySelfSee=isOnlySelfSee)  
 | 
          
 | 
        #ÉèÖøÃÎïÆ·ÉúǰӵÓÐÕß(ÄǸöNPCµôÂäµÄ)  
 | 
        if curMapItem == None:  
 | 
            GameWorld.Log("µôÂäÎïÆ·,ÎÞ·¨ÕÒµ½µØÍ¼µôÂäÎïÆ·")  
 | 
            return  
 | 
          
 | 
        curMapItem.SetByObj(curNPC.GetGameObjType(), curNPC.GetID())  
 | 
        #GameWorld.Log("NPC = %s->ID = %s µôÂäÎïÆ· = %s->ID = %s"%(curNPC.GetName(),curNPC.GetID(),curMapItem.GetItem().GetName(),curMapItem.GetItem().GetItemTypeID()))  
 | 
        #ÉèÖÃÎïÆ·Ê°È¡±£»¤  
 | 
        #self.__SetItemProtect(curMapItem, dropType, ownerID)  
 | 
        return  
 | 
      
 | 
    def __CreateDropItem(self, curNPC, itemID, count, isAuctionItem, dropPlayer):  
 | 
        ## ´´½¨µôÂäµÄÎïÆ·  
 | 
        curItem = ItemControler.GetOutPutItemObj(itemID, count, isAuctionItem, curPlayer=dropPlayer)  
 | 
        if not curItem:  
 | 
            return  
 | 
        return curItem  
 | 
      
 | 
    ##----------------------------------------- ¹éÊô -----------------------------------------------  
 | 
      
 | 
    def RefreshDropOwner(self, tick, refreshInterval=3000, isDead=False):  
 | 
        ## Ë¢ÐÂbossµôÂä¹éÊô  
 | 
        # @return: ¿É¹¥»÷µÄµôÂä¹éÊôÄ¿±êÍæ¼Ò  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        tagObj = None # ¼´½«¹¥»÷µÄÄ¿±ê, ¹éÊô×î´óÉËѪȡ×î´óÉËÑªÍæ¼Ò»ò¶ÓÎé¶ÓÔ±£¬ÆäËûÈ¡×î´ó³ðºÞ  
 | 
        ownerType, ownerID = 0, 0  
 | 
        dropOwnerType = GetDropOwnerType(curNPC)  
 | 
        if isDead:  
 | 
            GameWorld.Log("BossËÀÍö: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s"   
 | 
                          % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))  
 | 
        #if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:  
 | 
        maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead)  
 | 
        if not maxHurtInfo:  
 | 
            maxHurtInfo = NPCHurtMgr.RefreshHurtList(curNPC, tick, refreshInterval, isDead)  
 | 
              
 | 
        if maxHurtInfo:  
 | 
            tagObj, ownerType, ownerID = maxHurtInfo  
 | 
              
 | 
        elif dropOwnerType == ChConfig.DropOwnerType_Family:  
 | 
            ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval)  
 | 
            if ownerInfo:  
 | 
                tagObj, ownerFamilyID = ownerInfo  
 | 
                ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID  
 | 
                  
 | 
        elif dropOwnerType == ChConfig.DropOwnerType_Contend:  
 | 
            tagObj = self.__RefreshContendOwner()  
 | 
            if tagObj:  
 | 
                ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, tagObj.GetPlayerID()  
 | 
                  
 | 
        if isDead:  
 | 
            GameWorld.Log("ownerType=%s, ownerID=%s, tagObjID=%s" % (ownerType, ownerID, 0 if not tagObj else tagObj.GetPlayerID()))  
 | 
                  
 | 
        # Ã»Óй¥»÷Ä¿±ê£¬ÔòˢгðºÞ£¬Ö§³ÖÖ÷¶¯¹Ö  
 | 
        if not tagObj:  
 | 
            angryObjType, maxAngryObj = None, None  
 | 
            self.RefreshAngryList(tick, refreshInterval, isUpdAngry=True)  
 | 
            maxAngry = self.GetMaxAngryTag()  
 | 
            if maxAngry:  
 | 
                angryID = maxAngry.GetObjID()  
 | 
                angryObjType = maxAngry.GetObjType()  
 | 
                #GameWorld.DebugLog("×î´ó³ðºÞÄ¿±ê: ID=%s, Type=%s" % (angryID, angryObjType))  
 | 
                maxAngryObj = GameWorld.GetObj(angryID, angryObjType)  
 | 
                  
 | 
            tagObj = maxAngryObj  
 | 
            if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType:  
 | 
                if dropOwnerType == ChConfig.DropOwnerType_Contend:  
 | 
                    ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()  
 | 
                elif maxAngryObj.GetTeamID():  
 | 
                    ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, maxAngryObj.GetTeamID()  
 | 
                else:  
 | 
                    ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()  
 | 
              
 | 
            if isDead:  
 | 
                GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID))  
 | 
                  
 | 
        self.UpdateDropOwner(tick, ownerType, ownerID, isDead)  
 | 
        return tagObj  
 | 
      
 | 
    def __RefreshContendOwner(self):  
 | 
        ## Ë¢ÐÂbossÕù¶á¹éÊôÕߣ¬¹éÊôÒÆ³ýʱ²»×öË¢ÐÂйéÊô£¬Ä¬ÈÏÓɺóÃæµÄ³ðºÞˢР 
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)  
 | 
        ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)  
 | 
        if not ownerID or ownerType != ChConfig.Def_NPCHurtTypePlayer:  
 | 
            return  
 | 
          
 | 
        owner = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
        if not owner:  
 | 
            return  
 | 
          
 | 
        if not owner.GetVisible():  
 | 
            GameWorld.DebugLog("¾ºÕù¹éÊôÍæ¼Ò²»¿É¼û£¬ÒƳý¹éÊô!playerID=%s" % ownerID)  
 | 
            return  
 | 
          
 | 
        if owner.GetHP() <= 0 or owner.GetPlayerAction() == IPY_GameWorld.paDie:  
 | 
            GameWorld.DebugLog("¾ºÕù¹éÊôÍæ¼ÒËÀÍö£¬ÒƳý¹éÊô!playerID=%s" % ownerID)  
 | 
            return  
 | 
          
 | 
        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
        if not self.GetIsInRefreshPoint(owner.GetPosX(), owner.GetPosY(), refreshPoint):  
 | 
            GameWorld.DebugLog("¾ºÕù¹éÊôÍæ¼Ò²»ÔÚboss·¶Î§Àï£¬ÒÆ³ý¹éÊô!playerID=%s" % ownerID)  
 | 
            return  
 | 
          
 | 
        #GameWorld.DebugLog("¾ºÕù¹éÊôÍæ¼Ò¹éÊôÕý³££¡playerID=%s" % ownerID)  
 | 
        return owner  
 | 
  
 | 
    def __GetMaxHurtTeamPlayer(self, teamID, isDead):  
 | 
        ## »ñÈ¡×î´óÉËѪ¶ÓÎéÖй¥»÷µÄÄ¿±ê¶ÓÔ±  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        curTeam = GameWorld.GetTeamManager().FindTeam(teamID)  
 | 
        if curTeam:  
 | 
            refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
            if isDead:  
 | 
                GameWorld.Log("¶ÓÎé³ÉÔ±Êý: teamID=%s,memberCount=%s" % (teamID, curTeam.GetMemberCount()))  
 | 
            for i in xrange(curTeam.GetMemberCount()):  
 | 
                curTeamPlayer = curTeam.GetMember(i)  
 | 
                if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                    if isDead:  
 | 
                        GameWorld.Log("    i=%s, ¶ÓԱΪ¿Õ!" % i)  
 | 
                    continue  
 | 
                if curTeamPlayer.GetHP() <= 0:  
 | 
                    if isDead:  
 | 
                        GameWorld.Log("    i=%s, ¶ÓԱѪÁ¿Îª0!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))  
 | 
                    continue  
 | 
                if not curTeamPlayer.GetVisible():  
 | 
                    if isDead:  
 | 
                        GameWorld.Log("    i=%s, ¶ÓÔ±²»¿É¼û!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))  
 | 
                    continue  
 | 
                if isDead:  
 | 
                    GameWorld.Log("    i=%s, ¶ÓÔ±×ø±ê(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID()))  
 | 
                if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):  
 | 
                    return curTeamPlayer  
 | 
        else:  
 | 
            GameWorld.ErrLog("ÕÒ²»µ½¸Ã¶ÓÎé: teamID=%s" % teamID)  
 | 
        return  
 | 
      
 | 
    def UpdateDropOwner(self, tick, ownerType=0, ownerID=0, isDead=False):  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        npcID = curNPC.GetNPCID()  
 | 
        dropOwnerType = GetDropOwnerType(curNPC)  
 | 
        if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family, ChConfig.DropOwnerType_Contend]:  
 | 
            #GameWorld.DebugLog("²»ÐèҪչʾµôÂä¹éÊôµÄNPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))  
 | 
            return  
 | 
          
 | 
        lastDropOwnerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)  
 | 
        lastDropOwnerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)  
 | 
          
 | 
        key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)  
 | 
        if lastDropOwnerID and (lastDropOwnerType != ownerType or lastDropOwnerID != ownerID):  
 | 
            GameWorld.Log("¹éÊô±ä¸ü, Çå³ý¾É¹éÊô! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s"   
 | 
                          % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID))  
 | 
            self.__DelDropOwnerBuff(dropOwnerType, lastDropOwnerType, lastDropOwnerID, tick)  
 | 
          
 | 
        killerDict, curTeam, hurtType, hurtID = {}, None, 0, 0  
 | 
          
 | 
        # ¸üйéÊô  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerID, ownerID)  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerType, ownerType)  
 | 
              
 | 
        if isDead:  
 | 
            GameWorld.Log("Boss¹éÊô: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))  
 | 
              
 | 
        hurtList = NPCHurtManager.GetPlayerHurtList(curNPC)  
 | 
        # Ë¢Ð¹éÊô  
 | 
        if ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
            curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
            if curPlayer:  
 | 
                playerID = curPlayer.GetPlayerID()  
 | 
                if not hurtList or hurtList.HaveHurtValue(playerID):  
 | 
                    hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID  
 | 
                    killerDict[playerID] = curPlayer  
 | 
                    self.__AddDropOwnerPlayerBuff(curPlayer, tick)  
 | 
                    if dropOwnerType == ChConfig.DropOwnerType_Contend:  
 | 
                        curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, curNPC.GetID())  
 | 
                else:  
 | 
                    BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
                      
 | 
        elif ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
            curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)  
 | 
            if curTeam:  
 | 
                # ÒòΪÓл÷ɱ´ÎÊýÏÞÖÆ£¬ËùÒÔ²»ÊÇËùÓеĶÓÔ±¶¼¿ÉÒÔ»ñµÃ¹éÊô£¬ËùÒÔÕâÀïÉèÖÃÎªÌØÊâÖ¸¶¨Íæ¼ÒµôÂä  
 | 
                hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0  
 | 
                if isDead:  
 | 
                    GameWorld.Log("¶ÓÎé³ÉÔ±Êý: %s" % (curTeam.GetMemberCount()))  
 | 
                refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
                for i in xrange(curTeam.GetMemberCount()):  
 | 
                    curTeamPlayer = curTeam.GetMember(i)  
 | 
                    if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                        if isDead:  
 | 
                            GameWorld.Log("    i=%s, ³ÉÔ±²»´æÔÚ!" % (i))  
 | 
                        continue  
 | 
                      
 | 
                    if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \  
 | 
                        and (not hurtList or hurtList.HaveHurtValue(curTeamPlayer.GetPlayerID()))\  
 | 
                        and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible():  
 | 
                        self.__AddDropOwnerPlayerBuff(curTeamPlayer, tick)  
 | 
                        killerDict[curTeamPlayer.GetPlayerID()] = curTeamPlayer  
 | 
                        if isDead:  
 | 
                            GameWorld.Log("    i=%s, ³ÉÔ±ÓйéÊôȨ! memPlayerID=%s,±³°üÊ£Óà¿Õ¸ñ=%s"   
 | 
                                          % (i, curTeamPlayer.GetPlayerID(), ItemCommon.GetItemPackSpace(curTeamPlayer, IPY_GameWorld.rptItem)))  
 | 
                              
 | 
                    # ²»Í¬Ïß¡¢»òÕß¾àÀ볬³öboss·¶Î§µÄ¶ÓÔ±²»¼Ó¹éÊôbuff  
 | 
                    else:  
 | 
                        isOk = BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
                        if isOk:  
 | 
                            GameWorld.DebugLog("ɾ³ý¹éÊô¶ÓÔ±buff: teamID=%s,playerID=%s" % (ownerID, curTeamPlayer.GetPlayerID()))  
 | 
                        if isDead:  
 | 
                            GameWorld.Log("    i=%s, ³ÉÔ±ÎÞ¹éÊôȨ! memPlayerID=%s,copyMapID=%s,pos(%s,%s),CheckKillNPCByCnt=%s"   
 | 
                                          % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetCopyMapID(),   
 | 
                                             curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(),   
 | 
                                             AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False)))  
 | 
                          
 | 
        elif ownerType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
              
 | 
            hurtType, hurtID = ChConfig.Def_NPCHurtTypeFamily, ownerID  
 | 
            refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())  
 | 
            copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()  
 | 
            for index in xrange(copyPlayerMgr.GetPlayerCount()):  
 | 
                player = copyPlayerMgr.GetPlayerByIndex(index)  
 | 
                if not player:  
 | 
                    continue  
 | 
                  
 | 
                # ¹éÊôÏÉÃË ÇÒ ÔÚbossÇøÓòÄÚ  
 | 
                if player.GetFamilyID() == ownerID and self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint) and player.GetVisible():  
 | 
                    self.__AddDropOwnerPlayerBuff(player, tick)  
 | 
                      
 | 
                else:  
 | 
                    isOk = BuffSkill.DelBuffBySkillID(player, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
                    if isOk:  
 | 
                        GameWorld.DebugLog("ɾ³ý·Ç¹éÊôÏÉÃ˳ÉÔ±buff: teamID=%s,playerID=%s" % (ownerID, player.GetPlayerID()))  
 | 
                  
 | 
        if isDead:  
 | 
            #key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)  
 | 
            teamID = curTeam.GetTeamID() if curTeam else 0  
 | 
            # ÉËѪ¹éÊôµÄÇ¿ÖÆ¼Ç¼£¬¼´Ê¹¿ÕµÄÒ²¼Ç¼£¬ÒòΪÓÐÖúÕ½£¬ÉËѪµÚÒ»ÍŶÓÉ˺¦¿ÉÄÜ»¹ÔÚµ«ÊǹéÊôÍæ¼Ò¿ÉÄÜÀëÏß  
 | 
            if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:  
 | 
                PyGameData.g_npcKillerInfo[key] = killerDict, None, hurtType, hurtID  
 | 
                if not killerDict:  
 | 
                    GameWorld.Log("ÉËѪ¹éÊôbossûÓйéÊôÍæ¼Ò!")  
 | 
            elif ownerType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
                PyGameData.g_npcKillerInfo[key] = {}, None, hurtType, hurtID  
 | 
                  
 | 
            GameWorld.Log("Boss±»»÷ɱ: npcID=%s,key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s"   
 | 
                          % (npcID, key, killerDict.keys(), teamID, hurtType, hurtID))  
 | 
        return  
 | 
  
 | 
    def __AddDropOwnerPlayerBuff(self, curPlayer, tick):  
 | 
        curNPC = self.__Instance  
 | 
        findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]  
 | 
        if not findBuff:  
 | 
            SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
            GameWorld.DebugLog("Ìí¼Ó¹éÊôbuff: playerID=%s" % curPlayer.GetPlayerID())  
 | 
        return  
 | 
      
 | 
    def __DelDropOwnerBuff(self, dropOwnerType, ownerType, ownerID, tick):  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        if ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
            curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
            if not curPlayer:  
 | 
                return  
 | 
            GameWorld.DebugLog("ɾ³ý¹éÊôÍæ¼Òbuff: playerID=%s" % (ownerID))  
 | 
            BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
            if dropOwnerType == ChConfig.DropOwnerType_Contend:  
 | 
                curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, 0)  
 | 
                  
 | 
        elif ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
            curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)  
 | 
            if not curTeam:  
 | 
                return  
 | 
            GameWorld.DebugLog("ɾ³ý¹éÊô¶ÓÎébuff: teamID=%s" % (ownerID))  
 | 
            for i in xrange(curTeam.GetMemberCount()):  
 | 
                curTeamPlayer = curTeam.GetMember(i)  
 | 
                if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                    continue  
 | 
                BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)  
 | 
        return  
 | 
      
 | 
    def DelayDropOwnerBuffDisappearTime(self):  
 | 
        ''' ÑÓ³ÙµôÂä¹éÊôbuffÏûʧʱ¼ä '''  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)  
 | 
        ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)  
 | 
          
 | 
        if ownerType == ChConfig.Def_NPCHurtTypePlayer:  
 | 
            curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)  
 | 
            if not curPlayer:  
 | 
                return  
 | 
            self.__SetDropOwnerBuffDisappearTime(curPlayer)  
 | 
              
 | 
        elif ownerType == ChConfig.Def_NPCHurtTypeTeam:  
 | 
            curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)  
 | 
            if not curTeam:  
 | 
                return  
 | 
            for i in xrange(curTeam.GetMemberCount()):  
 | 
                curTeamPlayer = curTeam.GetMember(i)  
 | 
                if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:  
 | 
                    continue  
 | 
                self.__SetDropOwnerBuffDisappearTime(curTeamPlayer)  
 | 
        elif ownerType == ChConfig.Def_NPCHurtTypeFamily:  
 | 
            copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()  
 | 
            for index in xrange(copyPlayerMgr.GetPlayerCount()):  
 | 
                player = copyPlayerMgr.GetPlayerByIndex(index)  
 | 
                if not player:  
 | 
                    continue  
 | 
                self.__SetDropOwnerBuffDisappearTime(player)  
 | 
                  
 | 
        return  
 | 
      
 | 
    def __SetDropOwnerBuffDisappearTime(self, curPlayer):  
 | 
        ''' ÉèÖõôÂä¹éÊôbuffÏûʧʱ¼ä '''  
 | 
          
 | 
        curNPC = self.__Instance  
 | 
        findSkill = GameWorld.GetGameData().GetSkillBySkillID(ChConfig.Def_SkillID_DropOwnerBuff)  
 | 
        if not findSkill:  
 | 
            return  
 | 
          
 | 
        buffType = SkillCommon.GetBuffType(findSkill)  
 | 
        buffTuple = SkillCommon.GetBuffManagerByBuffType(curPlayer, buffType)  
 | 
        if buffTuple == ():  
 | 
            return  
 | 
          
 | 
        RemainTime = 10000 # ÑÓ³Ù10ÃëÏûʧ  
 | 
        tick = GameWorld.GetGameWorld().GetTick()  
 | 
          
 | 
        buffStateManager = buffTuple[0]  
 | 
        for index in xrange(buffStateManager.GetBuffCount()):  
 | 
            curBuff = buffStateManager.GetBuff(index)  
 | 
            buffSkill = curBuff.GetSkill()  
 | 
              
 | 
            if buffSkill.GetSkillTypeID() != ChConfig.Def_SkillID_DropOwnerBuff:  
 | 
                continue  
 | 
              
 | 
            if curNPC.GetID() != curBuff.GetOwnerID():  
 | 
                #GameWorld.DebugLog("·Çbuff¹éÊô×Å£¬²»ÉèÖÃÏûʧʱ¼ä£¡", curPlayer.GetPlayerID())  
 | 
                break  
 | 
              
 | 
            curBuff.SetCalcStartTick(tick)   
 | 
            curBuff.SetRemainTime(RemainTime)  
 | 
              
 | 
            # Í¨ÖªbuffˢР 
 | 
            buffStateManager.Sync_RefreshBuff(index, curBuff.GetRemainTime())  
 | 
            #GameWorld.DebugLog("µôÂä¹éÊôbuffÏûʧʱ¼ä: RemainTime=%s" % (RemainTime), curPlayer.GetPlayerID())  
 | 
            break  
 | 
        return  
 | 
    ##--------------------------------------------- -----------------------------------------------  
 | 
      
 | 
def OnPlayerKillNPCPlayer(curPlayer, defender, tick):  
 | 
    ## Íæ¼Ò»÷ɱÁËNPCÏà¹ØµÄÍæ¼Ò  
 | 
    contendNPCObjID = defender.GetDictByKey(ChConfig.Def_PlayerKey_ContendNPCObjID)  
 | 
    if contendNPCObjID:  
 | 
        curNPC = GameWorld.FindNPCByID(contendNPCObjID)  
 | 
        if not curNPC:  
 | 
            return  
 | 
        dropOwnerType = GetDropOwnerType(curNPC)  
 | 
        if dropOwnerType != ChConfig.DropOwnerType_Contend:  
 | 
            return  
 | 
        playerID = curPlayer.GetPlayerID()  
 | 
        GameWorld.DebugLog("Íæ¼Ò»÷ɱ¾ºÕù¹éÊôÕß! defPlayerID=%s,contendNPCObjID=%s,npcID=%s"   
 | 
                           % (defender.GetPlayerID(), contendNPCObjID, curNPC.GetNPCID()), playerID)  
 | 
        npcControl = NPCControl(curNPC)  
 | 
        npcControl.UpdateDropOwner(tick, ChConfig.Def_NPCHurtTypePlayer, playerID, False)  
 | 
          
 | 
    return  
 | 
  
 | 
#---------------------------------------------------------------------  
 | 
def SendVirtualItemDrop(player, itemID, posX, posY, userDataStr):  
 | 
    #֪ͨ¿Í»§¶Ë¼ÙÎïÆ·µôÂä  
 | 
    vItemDrop = ChPyNetSendPack.tagMCVirtualItemDrop()  
 | 
    vItemDrop.ItemTypeID = itemID  
 | 
    vItemDrop.PosX = posX  
 | 
    vItemDrop.PosY = posY  
 | 
    vItemDrop.UserData = userDataStr  
 | 
    vItemDrop.UserDataLen = len(vItemDrop.UserData)  
 | 
    NetPackCommon.SendFakePack(player, vItemDrop)  
 | 
    return  
 | 
      
 | 
def GetNPCExp(curPlayer, npcID):  
 | 
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)  
 | 
    if not npcData:  
 | 
        return 0  
 | 
    baseExp = npcData.GetExp()  
 | 
    if not baseExp:  
 | 
        return 0  
 | 
    npcLV = npcData.GetLV()  
 | 
    playerLV = curPlayer.GetLV()  
 | 
    return CalcNPCExp(baseExp, playerLV, npcLV)  
 | 
  
 | 
def CalcNPCExp(baseExp, playerLV, npcLV):  
 | 
    #¾ÑéË¥¼õ¹«Ê½ = max(ɱ¹Ö¾Ñé * max(1-max(Íæ¼ÒµÈ¼¶-¹ÖÎïµÈ¼¶-10,0)*0.02)£¬0),1£©  
 | 
    exp = eval(FormulaControl.GetCompileFormula("ExpAttenuation", IpyGameDataPY.GetFuncCfg("ExpAttenuation", 1)))  
 | 
    return exp  
 | 
  
 | 
## NPC±»Íæ¼ÒɱËÀ  
 | 
#  @param curNPC µ±Ç°NPC  
 | 
#  @param skill   
 | 
#  @param HurtID  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def OnPlayerAttackNPCDie(curNPC, curPlayer, skill):  
 | 
    callFunc = GameWorld.GetExecFunc(NPCAI, "AIType_%d.%s" % (curNPC.GetAIType(), "OnAttackDieByPlayer"))  
 | 
    if callFunc == None:  
 | 
        return None  
 | 
      
 | 
    callFunc(curNPC, curPlayer, skill)   
 | 
#---------------------------------------------------------------------  
 | 
# Ä¿±ê×ÜÖµ³¬¹ýDWORD¼Ç¼£¬ÐèÐÞÕýÊýÖµ  
 | 
# È磺ÉËѪºÍ³ðºÞ³¬¹ý20EµÄÇé¿ö£¬°´¸ßλ¼Ç¼ȡÓà, ×îµÍ1  
 | 
def FixValueByValueEx(valueEx, value):  
 | 
    if valueEx == 0:  
 | 
        return value  
 | 
      
 | 
    # È¡¸ßλ¼Ç¼µÄÊý×Ö³¤¶È£¬°´10N´Î·½ÇóÓà  
 | 
    nlen = len(str(valueEx))  
 | 
    return max(value / pow(10, nlen), 1)  
 | 
  
 | 
  
 | 
def CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):  
 | 
    # ¸ù¾ÝNPCIDÅжÏÊÇ·ñ¿ÉÒԲɼ¯  
 | 
      
 | 
    if GameWorld.IsCrossServer():  
 | 
        return True  
 | 
      
 | 
    limitMaxTime = collectNPCIpyData.GetMaxCollectCount()  
 | 
    if limitMaxTime > 0 and GetTodayCollectCount(curPlayer, npcID) >= limitMaxTime:  
 | 
        PlayerControl.NotifyCode(curPlayer, collectNPCIpyData.GetCollectCountLimitNotify(), [limitMaxTime])  
 | 
        return False  
 | 
      
 | 
    #±³°ü¿Õ¼äÅÐ¶Ï  
 | 
    if collectNPCIpyData.GetCollectAward() and not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):  
 | 
        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_202580")  
 | 
        return False  
 | 
      
 | 
    #ÏûºÄÎïÆ·²É¼¯£¬´ýÀ©Õ¹...  
 | 
      
 | 
    return True  
 | 
  
 | 
def GetTodayCollectCount(curPlayer, npcID):  
 | 
    ## »ñÈ¡²É¼¯NPC½ñÈÕÒѲɼ¯´ÎÊý  
 | 
    todayCollTime = 0  
 | 
    collectTimeShareIDList = IpyGameDataPY.GetFuncEvalCfg("CollectNPC", 1)  
 | 
    for npcIDList in collectTimeShareIDList:  
 | 
        if npcID not in npcIDList:  
 | 
            continue  
 | 
        for collNPCID in npcIDList:  
 | 
            todayCollTime += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % collNPCID)  
 | 
        return todayCollTime  
 | 
    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)  
 | 
  
 | 
def OnCollectNPCBegin(curPlayer, curNPC, tick):  
 | 
    ## ²É¼¯NPC¿ªÊ¼²É¼¯  
 | 
    npcID = curNPC.GetNPCID()  
 | 
    collectNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CollectNPC", npcID)  
 | 
    if not collectNPCIpyData:  
 | 
        #GameWorld.DebugLog("·ÇÌØ¶¨²É¼¯NPC...")  
 | 
        return False  
 | 
      
 | 
    if collectNPCIpyData.GetIsMissionCollectNPC():  
 | 
        #GameWorld.DebugLog("ÈÎÎñ²É¼¯ÎïÔݲ»´¦Àí")  
 | 
        return False  
 | 
      
 | 
    if not CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):  
 | 
        return True  
 | 
      
 | 
    canCollTogether = 1  
 | 
    collectPlayerID = GetCollectNPCPlayerID(curNPC)  
 | 
    # Èç¹û²»ÔÊÐíͬʱ²É£¬ÇÒÓÐÈËÔڲɣ¬ÔòÖ±½Ó·µ»Ø  
 | 
    if not canCollTogether and collectPlayerID > 0 and collectPlayerID != curPlayer.GetPlayerID():  
 | 
        GameWorld.DebugLog("²»ÔÊÐíͬʱ²É¼¯£¡")  
 | 
        sysMark = "GeRen_liubo_436832"  
 | 
        if sysMark:  
 | 
            PlayerControl.NotifyCode(curPlayer, sysMark)  
 | 
        return True  
 | 
      
 | 
    DoCollectNPCBegin(curPlayer, curNPC, collectNPCIpyData, tick)  
 | 
    return True  
 | 
  
 | 
def DoCollectNPCBegin(curPlayer, curNPC, collectNPCIpyData, tick):  
 | 
    ## ¿ªÊ¼²É¼¯  
 | 
      
 | 
    canCollTogether = 1  
 | 
    if not canCollTogether and not SetCollectNPC(curPlayer, curNPC):  
 | 
        GameWorld.ErrLog("SetCollectNPC fail!")  
 | 
        return  
 | 
      
 | 
    # ²É¼¯ºÄʱ  
 | 
    prepareTime = collectNPCIpyData.GetPrepareTime() * 1000  
 | 
    collTimeReduceRate = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_CollTimeReduceRate)  
 | 
    if collTimeReduceRate:  
 | 
        prepareTime = max(1000, int(prepareTime * (ShareDefine.Def_MaxRateValue - collTimeReduceRate) / float(ShareDefine.Def_MaxRateValue)))  
 | 
    PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, IPY_GameWorld.pstMissionCollecting, prepareID=curNPC.GetID())  
 | 
      
 | 
    if collectNPCIpyData.GetLostHPPer():  
 | 
        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)  
 | 
          
 | 
    FBLogic.OnBeginCollect(curPlayer, curNPC)  
 | 
    ##Ìí¼ÓÕâ¸öNPCµÄÉËѪÁÐ±í£¬ÓÃÓÚÅжϿɷñͬʱ²É¼¯£¬¸ÄΪ×ÖµäÅÐ¶Ï  
 | 
    AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1)  
 | 
    return  
 | 
  
 | 
def SetCollectNPC(curPlayer, curNPC):  
 | 
    ## ÉèÖÃÍæ¼Ò²É¼¯¸ÃNPC  
 | 
    curPlayerID = curPlayer.GetPlayerID()  
 | 
    curNPCObjID = curNPC.GetID()  
 | 
    curCollectPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_CollectPlayerID)  
 | 
    if curCollectPlayerID:  
 | 
        curCollectPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curCollectPlayerID)  
 | 
        # ÓÐÈËÔڲɼ¯ÇÒ²»ÊÇͬһ¸öÈË£¬Ôò²»¿ÉÖØÐÂÉèÖòɼ¯¶ÔÏó  
 | 
        if curCollectPlayer and curPlayerID != curCollectPlayerID:  
 | 
            GameWorld.DebugLog("SetNPCColleced ÓÐÈËÔڲɼ¯ÇÒ²»ÊÇͬһ¸öÈË£¬Ôò²»¿ÉÖØÐÂÉèÖòɼ¯¶ÔÏó")  
 | 
            return False  
 | 
              
 | 
    curNPC.SetDict(ChConfig.Def_NPC_Dict_CollectPlayerID, curPlayerID)  
 | 
    curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectNPCObjID, curNPCObjID)  
 | 
    return True  
 | 
  
 | 
  
 | 
## »ñÈ¡²É¼¯¸ÃNPCµÄÍæ¼Òid  
 | 
#  @param curNPC£º²É¼¯NPCʵÀý  
 | 
#  @return Íæ¼Òid£¬Ã»Óзµ»Ø0  
 | 
def GetCollectNPCPlayerID(curNPC):  
 | 
    curCollectPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_CollectPlayerID)  
 | 
    if curCollectPlayerID <= 0:  
 | 
        return 0  
 | 
      
 | 
    curCollectPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curCollectPlayerID)  
 | 
    # ÓÐÈËÔڲɼ¯ÇÒ²»ÊÇͬһ¸öÈË£¬µ«ÕÒ²»µ½¸ÃÍæ¼ÒÁË£¬ÔòÇå¿Õ²É¼¯¶ÔÏóid  
 | 
    if not curCollectPlayer:  
 | 
        GameWorld.DebugLog("GetCollectNPCID ÓÐcurCollectPlayerID=%s£¬µ«ÕÒ²»µ½¸ÃÍæ¼Ò£¬ÖØÖÃ!"   
 | 
                           % curCollectPlayerID)  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_CollectPlayerID, 0)  
 | 
        return 0  
 | 
      
 | 
    return curCollectPlayerID  
 | 
  
 | 
  
 | 
## Çå³ýÍæ¼Ò²É¼¯µÄNPCÐÅÏ¢  
 | 
#  @param curNPC£º²É¼¯NPCʵÀý  
 | 
#  @return  
 | 
def ClearCollectNPC(curPlayer):  
 | 
    collectNPCObjID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CollectNPCObjID)  
 | 
    #GameWorld.DebugLog("ClearCollectNPC collectNPCObjID=%s" % collectNPCObjID)  
 | 
    if collectNPCObjID <= 0:  
 | 
        return  
 | 
      
 | 
    curNPC = GameWorld.FindNPCByID(collectNPCObjID)  
 | 
    if curNPC:  
 | 
        curNPC.SetDict(ChConfig.Def_NPC_Dict_CollectPlayerID, 0)  
 | 
        #GameWorld.DebugLog("    collectNPCObjID=%s NPC set collectPlaerID 0" % collectNPCObjID)  
 | 
  
 | 
    curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectNPCObjID, 0)  
 | 
    #GameWorld.DebugLog("    set collectNPCObjID 0")  
 | 
    return  
 | 
  
 | 
def DoCollectNPCOK(curPlayer, npcID, tick):  
 | 
    ## ²É¼¯NPC²É¼¯½áÊø  
 | 
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)  
 | 
    if not collectNPCIpyData:  
 | 
        GameWorld.DebugLog("    ·ÇÌØ¶¨²É¼¯NPC...npcID=%s" % npcID)  
 | 
        return  
 | 
      
 | 
    if collectNPCIpyData.GetIsMissionCollectNPC():  
 | 
        #GameWorld.DebugLog("ÈÎÎñ²É¼¯ÎïÔݲ»´¦Àí")  
 | 
        return  
 | 
      
 | 
    PlayerState.DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, True)  
 | 
      
 | 
    if GameWorld.IsCrossServer():  
 | 
        # ·¢Ëͻر¾·þ²É¼¯Íê³É  
 | 
        serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)  
 | 
        msgInfo = {"Result":1, "PlayerID":curPlayer.GetPlayerID(), "NPCID":npcID}  
 | 
        GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_CollectNPCOK, msgInfo, [serverGroupID])  
 | 
    else:  
 | 
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)  
 | 
          
 | 
    FBLogic.OnCollectOK(curPlayer, npcID, tick)  
 | 
      
 | 
    ClearCollectNPC(curPlayer)      
 | 
    return True  
 | 
  
 | 
def CrossServerMsg_CollectNPCOK(curPlayer, msgData):  
 | 
    ## ÊÕµ½¿ç·þͬ²½µÄ²É¼¯Íê³É  
 | 
    if not msgData["Result"]:  
 | 
        return  
 | 
    npcID = msgData["NPCID"]  
 | 
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)  
 | 
    if collectNPCIpyData:  
 | 
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)  
 | 
    return  
 | 
  
 | 
#// A2 34 ×Ô¶¨Ò峡¾°ÖлñÈ¡²É¼¯½±Àø #tagCMGetCustomSceneCollectAward  
 | 
#  
 | 
#struct    tagCMGetCustomSceneCollectAward  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        NPCID;    //²É¼¯µÄNPCID  
 | 
#};  
 | 
def OnGetCustomSceneCollectAward(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    npcID = clientData.NPCID  
 | 
    if not curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):  
 | 
        GameWorld.ErrLog("·Ç×Ô¶¨Ò峡¾°ÖУ¬ÎÞ·¨»ñÈ¡¶¨Òå²É¼¯½±Àø!", playerID)  
 | 
        return  
 | 
    mapID = PlayerControl.GetCustomMapID(curPlayer)  
 | 
    lineID = PlayerControl.GetCustomLineID(curPlayer)  
 | 
    GameWorld.Log("ǰ¶Ë³¡¾°²É¼¯: mapID=%s,lineID=%s,npcID=%s" % (mapID, lineID, npcID), playerID)  
 | 
    if not mapID:  
 | 
        GameWorld.ErrLog("ÎÞ×Ô¶¨Ò峡¾°µØÍ¼ID£¬²»ÔÊÐí²É¼¯!", playerID)  
 | 
        return  
 | 
      
 | 
    if not FBLogic.OnCustomSceneCollectOK(curPlayer, mapID, lineID, npcID):  
 | 
        GameWorld.ErrLog("×Ô¶¨Ò峡¾°µØÍ¼²»ÔÊÐí²É¼¯! mapID=%s,lineID=%s,npcID=%s" % (mapID, lineID, npcID), playerID)  
 | 
        return  
 | 
      
 | 
    collectNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CollectNPC", npcID)  
 | 
    if collectNPCIpyData:  
 | 
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)  
 | 
    return  
 | 
  
 | 
def DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, collectCnt=1):  
 | 
    GameWorld.DebugLog("¸ø²É¼¯½±Àø: npcID=%s,collectCnt=%s" % (npcID, collectCnt))  
 | 
    if collectCnt <= 0:  
 | 
        return  
 | 
  
 | 
    if collectNPCIpyData.GetIsMissionCollectNPC():  
 | 
        #GameWorld.DebugLog("ÈÎÎñ²É¼¯ÎïÔݲ»´¦Àí")  
 | 
        return  
 | 
      
 | 
    isMaxTime = False # ÊÇ·ñ´ïµ½Á˲ɼ¯×î´ó´ÎÊý  
 | 
    limitMaxTime = collectNPCIpyData.GetMaxCollectCount()  
 | 
    if limitMaxTime > 0:  
 | 
        todayCollTime = GetTodayCollectCount(curPlayer, npcID)  
 | 
        canCollectCnt = max(0, limitMaxTime - todayCollTime)  
 | 
        collectCnt = min(collectCnt, canCollectCnt)  
 | 
        if collectCnt <= 0:  
 | 
            GameWorld.DebugLog("    ¸ÃNPCÒÑ´ïµ½×î´ó²É¼¯´ÎÊý: npcID=%s,todayCollTime=%s,limitMaxTime=%s" % (npcID, todayCollTime, limitMaxTime))  
 | 
            return  
 | 
          
 | 
        curCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)  
 | 
        updCollTime = curCollTime + collectCnt  
 | 
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)  
 | 
        SyncCollNPCTime(curPlayer, [npcID])  
 | 
        GameWorld.DebugLog("    Ôö¼Ó²É¼¯´ÎÊý: npcID=%s,todayCollTime=%s,curCollTime=%s,updCollTime=%s" % (npcID, todayCollTime, curCollTime, updCollTime))  
 | 
        isMaxTime = todayCollTime + collectCnt >= limitMaxTime  
 | 
          
 | 
    awardItemList = []  
 | 
    collectAwardCfg = collectNPCIpyData.GetCollectAward()  
 | 
    collectAppointAwardCfg = collectNPCIpyData.GetCollectAppointAward()  
 | 
    if collectAppointAwardCfg:  
 | 
        #çÎ翲ÝÔ°µÄ²É¼¯¶¨ÖÆÓÉçÎç¿Ñ°·Ã´ÎÊý¾ö¶¨  
 | 
        if collectNPCIpyData.GetCollectResetType() in [12, 14]:  
 | 
            fairyDomainVisitCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FairyDomainVisitCnt)  
 | 
            grasslandCollectAppointCfg = collectAppointAwardCfg.get(fairyDomainVisitCnt, {})  
 | 
            curCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)  
 | 
            if curCollTime in grasslandCollectAppointCfg:  
 | 
                awardItemList.append(grasslandCollectAppointCfg[curCollTime])  
 | 
            GameWorld.DebugLog("    ²ÝÔ°²É¼¯¶¨Öƽ±Àø: fairyDomainVisitCnt=%s,curCollTime=%s,awardItemList=%s" % (fairyDomainVisitCnt, curCollTime, awardItemList))  
 | 
        else:  
 | 
            collTotalTime = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID) + 1, ChConfig.Def_UpperLimit_DWord)  
 | 
            if collTotalTime in collectAppointAwardCfg:  
 | 
                awardItemList.append(collectAppointAwardCfg[collTotalTime])  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID, collTotalTime)  
 | 
            GameWorld.DebugLog("    ²É¼¯´ÎÊý¶¨Öƽ±Àø: collTotalTime=%s,awardItemList=%s" % (collTotalTime, awardItemList))  
 | 
          
 | 
    if not awardItemList:  
 | 
        alchemyDiffLV = collectNPCIpyData.GetAlchemyDiffLV()  
 | 
        giveItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(curPlayer, collectAwardCfg, alchemyDiffLV)  
 | 
        GameWorld.DebugLog("    ³£¹æ²É¼¯ÎïÆ·È¨ÖØÁбí: alchemyDiffLV=%s,collectAwardCfg=%s,giveItemWeightList=%s" % (alchemyDiffLV, collectAwardCfg, giveItemWeightList))  
 | 
        giveItemInfo = GameWorld.GetResultByWeightList(giveItemWeightList)  
 | 
        if giveItemInfo:  
 | 
            awardItemList.append(giveItemInfo)  
 | 
              
 | 
    GameWorld.DebugLog("    ×îÖղɼ¯½±Àø: awardItemList=%s" % awardItemList)  
 | 
    if awardItemList:  
 | 
        for itemID, itemCount, isAuctionItem in awardItemList:  
 | 
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])  
 | 
        if collectNPCIpyData.GetNotifyCollectResult():  
 | 
            awardPack = ChPyNetSendPack.tagMCCollectAwardItemInfo()  
 | 
            awardPack.CollectNPCID = npcID  
 | 
            for itemID, itemCount, isAuctionItem in awardItemList:  
 | 
                awardItem = ChPyNetSendPack.tagMCCollectAwardItem()  
 | 
                awardItem.ItemID = itemID  
 | 
                awardItem.Count = itemCount  
 | 
                awardItem.IsAuctionItem = isAuctionItem  
 | 
                awardPack.AwardItemList.append(awardItem)  
 | 
            awardPack.Count = len(awardPack.AwardItemList)  
 | 
            NetPackCommon.SendFakePack(curPlayer, awardPack)  
 | 
        GameLogic_CrossGrassland.RecordGrasslandAward(curPlayer, awardItemList)  
 | 
    else:  
 | 
        GameWorld.ErrLog("²É¼¯ÎïÆ·Ã»Óн±Àø£¡npcID=%s" % (npcID))  
 | 
          
 | 
    #²É¼¯³É¾Í  
 | 
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, collectCnt, [npcID])  
 | 
    #SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)  
 | 
      
 | 
    GameLogic_CrossGrassland.DecCustomSceneNPCCount(curPlayer, npcID)  
 | 
    if isMaxTime:  
 | 
        GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer)  
 | 
          
 | 
    return  
 | 
  
 | 
## ²É¼¯½á¹ûͬ²½  
 | 
#  @param None  
 | 
#  @param None  
 | 
def SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, syncItemInfoList, collectNPCID=0):  
 | 
    return #Ôݲ»Í¬²½  
 | 
  
 | 
def SyncCollNPCTime(curPlayer, npcIDList=[]):  
 | 
    ## Í¬²½²É¼¯NPC¹¦ÄܺŲɼ¯´ÎÊý  
 | 
      
 | 
    isSyncAll = False  
 | 
    if not npcIDList:  
 | 
        isSyncAll = True  
 | 
        ipyDataMgr = IpyGameDataPY.IPY_Data()  
 | 
        for index in xrange(ipyDataMgr.GetCollectNPCCount()):  
 | 
            ipyData = ipyDataMgr.GetCollectNPCByIndex(index)  
 | 
            if ipyData.GetMaxCollectCount():  
 | 
                npcIDList.append(ipyData.GetNPCID())  
 | 
                  
 | 
    if not npcIDList:  
 | 
        return  
 | 
      
 | 
    syncList = []  
 | 
    for npcID in npcIDList:  
 | 
        collCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)  
 | 
        if isSyncAll and not collCount:  
 | 
            continue  
 | 
        collCntInfo = ChPyNetSendPack.tagMCNPCIDCollectionCnt()  
 | 
        collCntInfo.Clear()  
 | 
        collCntInfo.NPCID = npcID  
 | 
        collCntInfo.CollectionCnt = collCount  
 | 
        syncList.append(collCntInfo)  
 | 
          
 | 
    if not syncList:  
 | 
        return  
 | 
      
 | 
    npcIDCollInfo = ChPyNetSendPack.tagMCNPCIDCollectionCntInfo()  
 | 
    npcIDCollInfo.Clear()  
 | 
    npcIDCollInfo.NPCCollCntList = syncList  
 | 
    npcIDCollInfo.CollNPCCnt = len(npcIDCollInfo.NPCCollCntList)  
 | 
    NetPackCommon.SendFakePack(curPlayer, npcIDCollInfo)  
 | 
    return  
 | 
  
 | 
def CollNPCTimeOnDay(curPlayer):  
 | 
    ## ²É¼¯NPCOnDay´¦Àí  
 | 
    DoResetCollectNPCTimeByType(curPlayer, [1])  
 | 
    return  
 | 
  
 | 
def DoResetCollectNPCTimeByType(curPlayer, resetTypeList=[]):  
 | 
    '''ÖØÖòɼ¯Îï²É¼¯´ÎÊý  
 | 
            ÖØÖÃÀàÐÍ: 0-²»ÖØÖã¬1-ÿÈÕ5µã£¬12-Áé²ÝÔ°ÖØÖã¬14-ÏɲÝÔ°ÖØÖà  
 | 
    '''  
 | 
    resetNPCIDList = []  
 | 
    ipyDataMgr = IpyGameDataPY.IPY_Data()  
 | 
    for index in xrange(ipyDataMgr.GetCollectNPCCount()):  
 | 
        ipyData = ipyDataMgr.GetCollectNPCByIndex(index)  
 | 
        npcID = ipyData.GetNPCID()  
 | 
        if resetTypeList and ipyData.GetCollectResetType() not in resetTypeList:  
 | 
            continue  
 | 
        if not ipyData.GetMaxCollectCount():  
 | 
            continue  
 | 
        if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID):  
 | 
            continue  
 | 
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)  
 | 
        resetNPCIDList.append(npcID)  
 | 
          
 | 
    if resetNPCIDList:  
 | 
        #GameWorld.DebugLog("ÖØÖòɼ¯´ÎÊý: resetTypeList=%s,resetNPCIDList=%s" % (resetTypeList, resetNPCIDList), curPlayer.GetPlayerID())  
 | 
        SyncCollNPCTime(curPlayer, resetNPCIDList)  
 | 
    return  
 | 
  
 | 
  
 | 
## »ñÈ¡±¾µØÍ¼NPC״̬, Ò»°ãÓÃÓÚBossË¢¹Öµã״̬²éѯ  
 | 
#  @param queryNPCIDList£º²éѯµÄNPCIDÁÐ±í  
 | 
#  @param tick  
 | 
#  @return {NPCID:[curHP,maxHP,Ê£Óà¶àÉÙÃëË¢ÐÂ]}  
 | 
def GetNPCInfo(queryNPCIDList, tick):  
 | 
    npcInfoDict = {}  
 | 
  
 | 
    if not queryNPCIDList:  
 | 
        return npcInfoDict  
 | 
      
 | 
    gameNPCManager = GameWorld.GetNPCManager()  
 | 
    GameWorld.DebugLog("GetNPCInfo...queryNPCIDList=%s" % (str(queryNPCIDList)))  
 | 
    findNPCIDList = []  
 | 
    for index in range(gameNPCManager.GetNPCCount()):  
 | 
        curNPC = gameNPCManager.GetNPCByIndex(index)  
 | 
        curID = curNPC.GetID()  
 | 
        if curID == 0:  
 | 
            continue  
 | 
          
 | 
        curNPCID = curNPC.GetNPCID()  
 | 
          
 | 
        if curNPCID not in queryNPCIDList:  
 | 
            continue  
 | 
          
 | 
        findNPCIDList.append(curNPCID)  
 | 
        isAlive = 1  
 | 
        curHP = GameObj.GetHP(curNPC)  
 | 
        posX = curNPC.GetPosX()  
 | 
        posY = curNPC.GetPosY()  
 | 
        maxHP = GameObj.GetMaxHP(curNPC)  
 | 
        refreshRemaindSecond = 0 # Ê£Óà¶àÉÙÃëˢР 
 | 
        if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():  
 | 
            isAlive = 0  
 | 
            refreshTime = curNPC.GetRefreshTime()  
 | 
              
 | 
            if refreshTime > 0:  
 | 
                passTick = max(0, tick - curNPC.GetActionTick())  
 | 
                refreshRemaindSecond = max(1000, refreshTime - passTick) / 1000  
 | 
                  
 | 
                  
 | 
        npcInfoDict[curID] = [curNPCID, curHP, maxHP, posX, posY, isAlive, refreshRemaindSecond]  
 | 
                  
 | 
    GameWorld.DebugLog("    npcInfoDict=%s" % (str(npcInfoDict)))  
 | 
    return npcInfoDict  
 | 
  
 | 
  
 | 
## Í¬²½µØÍ¼NPCÐÅÏ¢  
 | 
#  @param curPlayer£º²É¼¯Íæ¼ÒʵÀý  
 | 
#  @param mapID£º  
 | 
#  @param npcInfoDict£º  
 | 
#  @return None  
 | 
def SyncNPCInfo(curPlayer, mapID, playerCnt, npcInfoDict):  
 | 
      
 | 
    npcInfoPack = ChPyNetSendPack.tagMCNPCInfoList()  
 | 
    npcInfoPack.Clear()  
 | 
    npcInfoPack.MapID = mapID  
 | 
    npcInfoPack.PlayerCnt = playerCnt  
 | 
    npcInfoPack.NPCInfoList = []  
 | 
  
 | 
    for curID, npcInfo in npcInfoDict.items():  
 | 
        curNPCID, curHP, maxHP, posX, posY, isAlive, refreshRemaindSecond = npcInfo  
 | 
        npcInfo = ChPyNetSendPack.tagMCNPCInfo()  
 | 
        npcInfo.Clear()  
 | 
        npcInfo.ObjID = curID  
 | 
        npcInfo.NPCID = curNPCID  
 | 
        npcInfo.NPCHP = curHP  
 | 
        npcInfo.MaxHP = maxHP  
 | 
        npcInfo.PosX = posX  
 | 
        npcInfo.PosY = posY  
 | 
        npcInfo.IsActive = isAlive  
 | 
        npcInfo.RefreshSecond = refreshRemaindSecond  
 | 
        npcInfoPack.NPCInfoList.append(npcInfo)  
 | 
          
 | 
    npcInfoPack.NPCInfoCnt = len(npcInfoPack.NPCInfoList)  
 | 
    NetPackCommon.SendFakePack(curPlayer, npcInfoPack)  
 | 
    return  
 | 
  
 | 
  
 | 
## »ñÈ¡±¾µØÍ¼NPCÊýÁ¿  
 | 
#  @param queryNPCIDList£º²éѯµÄNPCIDÁÐ±í  
 | 
#  @param tick  
 | 
#  @return {NPCID:cnt}  
 | 
def GetNPCCntInfo(queryNPCIDList, tick, copyMapID=None):  
 | 
    npcCntDict = {}  
 | 
  
 | 
    #if not queryNPCIDList:  
 | 
    #    return npcCntDict  
 | 
      
 | 
    gameNPCManager = GameWorld.GetNPCManager()  
 | 
    GameWorld.DebugLog("GetNPCCntInfo...queryNPCIDList=%s" % (str(queryNPCIDList)))  
 | 
      
 | 
    if isinstance(copyMapID, int):  
 | 
        for index in xrange(gameNPCManager.GetNPCCountByGWIndex(copyMapID)):  
 | 
            curNPC = gameNPCManager.GetNPCByIndexByGWIndex(copyMapID, index)  
 | 
            curID = curNPC.GetID()  
 | 
            if curID == 0:  
 | 
                continue  
 | 
              
 | 
            curNPCID = curNPC.GetNPCID()  
 | 
              
 | 
            if queryNPCIDList and curNPCID not in queryNPCIDList:  
 | 
                continue  
 | 
            if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():  
 | 
                continue  
 | 
            npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1  
 | 
    else:  
 | 
        for index in xrange(gameNPCManager.GetNPCCount()):  
 | 
            curNPC = gameNPCManager.GetNPCByIndex(index)  
 | 
            curID = curNPC.GetID()  
 | 
            if curID == 0:  
 | 
                continue  
 | 
              
 | 
            curNPCID = curNPC.GetNPCID()  
 | 
              
 | 
            if queryNPCIDList and curNPCID not in queryNPCIDList:  
 | 
                continue  
 | 
            if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():  
 | 
                continue  
 | 
            npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1  
 | 
                  
 | 
    GameWorld.DebugLog("    npcCntDict=%s" % (str(npcCntDict)))  
 | 
    return npcCntDict  
 | 
  
 | 
## Í¬²½µØÍ¼NPCÊýÁ¿ÐÅÏ¢  
 | 
#  @param curPlayer£º²É¼¯Íæ¼ÒʵÀý  
 | 
#  @param mapID£º  
 | 
#  @param npcInfoDict£º  
 | 
#  @return None  
 | 
def SyncNPCCntInfo(curPlayer, mapID, npcCntDict):  
 | 
    npcInfoPack = ChPyNetSendPack.tagMCNPCCntList()  
 | 
    npcInfoPack.Clear()  
 | 
    npcInfoPack.MapID = mapID  
 | 
    npcInfoPack.NPCInfoList = []  
 | 
  
 | 
    for npcid, npcCnt in npcCntDict.items():  
 | 
        npcInfo = ChPyNetSendPack.tagMCNPCCntInfo()  
 | 
        npcInfo.Clear()  
 | 
        npcInfo.NPCID = npcid  
 | 
        npcInfo.Cnt = npcCnt  
 | 
        npcInfoPack.NPCInfoList.append(npcInfo)  
 | 
          
 | 
    npcInfoPack.NPCInfoCnt = len(npcInfoPack.NPCInfoList)  
 | 
    NetPackCommon.SendFakePack(curPlayer, npcInfoPack)  
 | 
    return  
 | 
  
 | 
def SendGameServerGoodItemRecord(curPlayer, mapID, lineID, npcID, itemID, equipInfo=[]):  
 | 
    # @param equipInfo: [equipPlace, itemClassLV, itemColor, itemQuality, itemUserData]  
 | 
#    GameWorld.DebugLog("¼ì²éÎïÆ·ÊÇ·ñ·¢ËÍGameServer: mapID=%s, npcID=%s, playerName=%s, itemID=%s"   
 | 
#                       % (mapID, npcID, playerName, itemID))  
 | 
    recBossIDList = IpyGameDataPY.GetFuncEvalCfg('DropRecordBossID', 1)  
 | 
    if npcID not in recBossIDList:  
 | 
        return  
 | 
    recDropEquipInfoDict = IpyGameDataPY.GetFuncEvalCfg('DropRecordEquipment', 1, {})  
 | 
    recSpecialItemIDList = IpyGameDataPY.GetFuncEvalCfg('DropRecordValue', 1)  
 | 
    recItemIDList = IpyGameDataPY.GetFuncEvalCfg('DropRecordNormal', 1)  
 | 
    # weightValue  Õäϧ¶È ÊýÖµÔ½´óÔ½Õä¹ó(ÓÃÓÚÅÅÐò)  
 | 
    needRecord = False  
 | 
    itemUserData = ""  
 | 
    if itemID in recItemIDList:  
 | 
        needRecord = True  
 | 
        weightValue = recItemIDList.index(itemID)  
 | 
    elif itemID in recSpecialItemIDList:  
 | 
        needRecord = True  
 | 
        weightValue = recSpecialItemIDList.index(itemID) + 10000  
 | 
    else:  
 | 
        equipPlace, itemClassLV, itemColor, suiteID, itemUserData = equipInfo  
 | 
        isSuit = 1 if suiteID else 0  
 | 
        weightValue = itemColor*1000+isSuit*100+itemClassLV  
 | 
          
 | 
        recordCondition = GameWorld.GetDictValueByKey(recDropEquipInfoDict, equipPlace)  
 | 
        if recordCondition:  
 | 
            needClassLV, needItemColor, needItemSuite = recordCondition  
 | 
            if itemClassLV >= needClassLV and itemColor >= needItemColor and isSuit >= needItemSuite:  
 | 
                needRecord = True  
 | 
    if not needRecord:  
 | 
        return  
 | 
    playerID = curPlayer.GetID()  
 | 
    playerName = curPlayer.GetName()  
 | 
    serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)  
 | 
    dropEquipMsg = str([playerID, playerName, mapID, lineID, npcID, itemID, itemUserData, weightValue, serverGroupID, curPlayer.GetLV()])  
 | 
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'BossDropGoodItem', dropEquipMsg, len(dropEquipMsg))  
 | 
    GameWorld.DebugLog("·¢ËÍGameServer¼Ç¼ʰȡµôÂäºÃÎïÆ·: %s" % dropEquipMsg, playerID)  
 | 
    return  
 | 
  
 | 
#// A5 52 ¹ºÂò¹¦ÄÜNPC²É¼¯´ÎÊý #tagCMBuyCollectionCnt  
 | 
#  
 | 
#struct    tagCMBuyCollectionCnt  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        FuncType;    //NPC¹¦ÄÜÀàÐÍ  
 | 
#    BYTE        BuyCnt;    //¹ºÂò´ÎÊý  
 | 
#};  
 | 
## ÁìÈ¡½±Àø  
 | 
#  @param None None  
 | 
#  @return None  
 | 
def OnBuyCollectionCnt(index, clientData, tick):  
 | 
    return  
 | 
  
 | 
#// A5 0A ¹ºÂò¿É»÷ɱboss´ÎÊý #tagCMBuyKillBossCnt  
 | 
#  
 | 
#struct    tagCMBuyKillBossCnt  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    WORD        KillBossMark;    // BOSSΨһË÷Òý  
 | 
#};  
 | 
## ¹ºÂòBOSS¿É»÷ɱ´ÎÊý  
 | 
def OnBuyKillBossCnt(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    killBossMark = clientData.KillBossMark  
 | 
    buyTimesVIPPriID = IpyGameDataPY.GetFuncEvalCfg("KillBossCntLimit1", 1, {}).get(killBossMark)  
 | 
    if not buyTimesVIPPriID:  
 | 
        return  
 | 
    canBuyCnt = PlayerVip.GetPrivilegeValue(curPlayer, buyTimesVIPPriID)  
 | 
    hasBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Boss_KillCntBuyCnt%killBossMark, 0)  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    if hasBuyCnt >= canBuyCnt:  
 | 
        GameWorld.DebugLog('¹ºÂòBOSS¿É»÷ɱ´ÎÊý, ÒÑ´ïµ½½ñÈÕ×î´ó¿É¹ºÂò´ÎÊý£¬hasBuyCnt=%s, canBuyCnt=%s'%(hasBuyCnt, canBuyCnt), playerID)  
 | 
        return  
 | 
    canKillCnt, dayTimesLimit = BossHurtMng.GetCanKillBossCnt(curPlayer, killBossMark)  
 | 
    if canKillCnt >= dayTimesLimit:  
 | 
        GameWorld.DebugLog('¹ºÂòBOSS¿É»÷ɱ´ÎÊý, Ê£Óà´ÎÊýÒÑÂú£¡£¬canKillCnt=%s'%(canKillCnt), playerID)  
 | 
        return  
 | 
      
 | 
    costGold = IpyGameDataPY.GetFuncEvalCfg("KillBossCntLimit1", 2, {}).get(killBossMark)  
 | 
    if not costGold:  
 | 
        costGoldList = IpyGameDataPY.GetFuncEvalCfg("KillBossCntLimit1", 3, {}).get(str(killBossMark), [])  
 | 
        if not costGoldList:  
 | 
            GameWorld.DebugLog("ûÓÐÅäÖÿɹºÂòboss´ÎÊýÏûºÄ£¬ÎÞ·¨¹ºÂò! killBossMark=%s" % killBossMark)  
 | 
            return  
 | 
          
 | 
        if hasBuyCnt >= len(costGoldList):  
 | 
            costGold = costGoldList[-1]  
 | 
        else:  
 | 
            costGold = costGoldList[hasBuyCnt]  
 | 
              
 | 
    if not costGold:  
 | 
        return  
 | 
      
 | 
    infoDict = {"index":killBossMark, ChConfig.Def_Cost_Reason_SonKey:killBossMark}  
 | 
    isOK = PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold,   
 | 
                                  ChConfig.Def_Cost_BuyKillBossCnt, infoDict)  
 | 
      
 | 
    if not isOK:  
 | 
        return  
 | 
    # Ôö¼Ó¹ºÂò´ÎÊý  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Boss_KillCntBuyCnt%killBossMark, hasBuyCnt + 1)  
 | 
    BossHurtMng.NotifyAttackBossCnt(curPlayer, killBossMark)  
 | 
    return  
 | 
  
 | 
#// A2 23 NPCÐã½áÊø #tagCMNPCShowEnd  
 | 
#  
 | 
#struct    tagCMNPCShowEnd  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    DWORD        NPCID;  
 | 
#    BYTE        EndType; // 0-ĬÈÏ£»1-Ìø¹ý  
 | 
#};  
 | 
def OnNPCShowEnd(index, clientData, tick):  
 | 
    npcID = clientData.NPCID  
 | 
    endType = clientData.EndType  
 | 
    endTick = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FBDict_NPCShowEndTick % npcID)  
 | 
    if not endTick:  
 | 
        return  
 | 
    GameWorld.GetGameFB().SetGameFBDict(ChConfig.Def_FBDict_NPCShowEndTick % npcID, 0)  
 | 
    GameWorld.DebugLog("ClientNPCShowEnd npcID=%s,endType=%s,tick=%s" % (npcID, endType, tick))  
 | 
    return  
 | 
  
 | 
def IsMapNeedBossShunt(mapID):  
 | 
    ## Ä¿±êµØÍ¼ÊÇ·ñÐèÒª´¦Àíboss·ÖÁ÷  
 | 
    bossShuntMaxServerDay = IpyGameDataPY.GetFuncCfg("BossShunt", 3)  
 | 
    openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1  
 | 
    if openServerDay <= bossShuntMaxServerDay:  
 | 
        bossShuntMapIDList = IpyGameDataPY.GetFuncEvalCfg("BossShunt", 1)  
 | 
        return mapID in bossShuntMapIDList  
 | 
    return False  
 | 
  
 | 
def AddBossShuntRelatedPlayer(curPlayer, mapID, lineID, npcID, tick):  
 | 
    ## Ä¿±êµØÍ¼ÊÇ·ñÐèÒª´¦Àíboss·ÖÁ÷  
 | 
    key = (mapID, lineID)  
 | 
    shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})  
 | 
    shuntPlayerDict[curPlayer.GetPlayerID()] = [npcID, curPlayer.GetTeamID(), tick]  
 | 
    PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict  
 | 
    GameServer_WorldBossShuntInfo(mapID, lineID)  
 | 
    return  
 | 
  
 | 
def GameServer_WorldBossShuntInfo(mapID, lineID):  
 | 
    key = (mapID, lineID)  
 | 
    shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})  
 | 
    msgStr = str([mapID, lineID, shuntPlayerDict])  
 | 
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "WorldBossShuntInfo", msgStr, len(msgStr))  
 | 
    GameWorld.DebugLog("֪ͨGameServerµØÍ¼Boss·ÖÁ÷ÐÅÏ¢: mapID=%s,lineID=%s,shuntPlayerDict=%s" % (mapID, lineID, shuntPlayerDict), lineID)  
 | 
    return  
 | 
  
 | 
def NPCSpeedChangeNotify(curNPC, speed):  
 | 
    ##֪ͨNPCËÙ¶È  
 | 
    sendPack = ChNetSendPack.tagObjInfoRefresh()  
 | 
    sendPack.Clear()  
 | 
    sendPack.ObjID = curNPC.GetID()  
 | 
    sendPack.ObjType = curNPC.GetGameObjType()  
 | 
    sendPack.RefreshType = IPY_GameWorld.CDBPlayerRefresh_Speed  
 | 
    sendPack.Value = speed  
 | 
    curNPC.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())  
 | 
    return  
 | 
  
 | 
def UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount=0):  
 | 
    ## ¸üÐÂÍæ¼Ò¹¥»÷NPC´ÎÊý  
 | 
    if not npcID:  
 | 
        return  
 | 
    GameWorld.DebugLog("¸üÐÂÍæ¼Ò¹¥»÷NPC´ÎÊý: npcID=%s,attackCount=%s,maxCount=%s" % (npcID, attackCount, maxCount))  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCAttackCount % npcID, attackCount)  
 | 
      
 | 
    if GameWorld.IsCrossServer():  
 | 
        serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)  
 | 
        msgInfo = {"PlayerID":curPlayer.GetPlayerID(), "NPCID":npcID, "AttackCount":attackCount, "MaxCount":maxCount}  
 | 
        GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_NPCAttackCount, msgInfo, [serverGroupID])  
 | 
    else:  
 | 
        SyncNPCAttackCount(curPlayer, [npcID])  
 | 
        if attackCount and attackCount >= maxCount:  
 | 
            GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer)  
 | 
    return  
 | 
  
 | 
def CrossServerMsg_NPCAttackCount(curPlayer, msgData):  
 | 
    ## ÊÕµ½¿ç·þ·þÎñÆ÷ͬ²½µÄ¹¥»÷NPC´ÎÊý  
 | 
    npcID = msgData["NPCID"]  
 | 
    attackCount = msgData["AttackCount"]  
 | 
    maxCount = msgData["MaxCount"]  
 | 
    UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount)  
 | 
    return  
 | 
  
 | 
def SyncNPCAttackCount(curPlayer, npcIDList):  
 | 
    ## Í¬²½NPC¹¥»÷´ÎÊý  
 | 
    if not npcIDList:  
 | 
        return  
 | 
      
 | 
    clientPack = ChPyNetSendPack.tagMCNPCAttackCountInfo()  
 | 
    for npcID in npcIDList:  
 | 
        attackCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCAttackCount % npcID)  
 | 
        atkCountObj = ChPyNetSendPack.tagMCNPCAttackCount()  
 | 
        atkCountObj.NPCID = npcID  
 | 
        atkCountObj.AttackCount = attackCount  
 | 
        clientPack.NPCAttackCountList.append(atkCountObj)  
 | 
    clientPack.Count = len(clientPack.NPCAttackCountList)  
 | 
    NetPackCommon.SendFakePack(curPlayer, clientPack)  
 | 
    return  
 | 
  
 | 
  
 | 
def OnNPCAttacked(atkObj, curNPC, skill, tick):  
 | 
    ## NPC±»¹¥»÷  
 | 
    __OnAttackedDropItem(atkObj, curNPC)  
 | 
    return  
 | 
  
 | 
## Ã¿´Î±»¹¥»÷µôÂäÎïÆ·  
 | 
#  @param atkObj ¹¥»÷·¢ÆðÕß  
 | 
#  @param curNPC ±»¹¥»÷NPC  
 | 
#  @return None  
 | 
def __OnAttackedDropItem(atkObj, curNPC):  
 | 
    attackPlayer, npcObjType = AttackCommon.GetAttackPlayer(atkObj)  
 | 
    if npcObjType:  
 | 
        return  
 | 
    if not attackPlayer:  
 | 
        return  
 | 
    npcID = curNPC.GetNPCID()  
 | 
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("TreasureNPC", npcID)  
 | 
    if not ipyData:  
 | 
        return  
 | 
    attackCountDropWeightInfo = ipyData.GetAttackCountDropWeightInfo()  
 | 
    attackDropWeightList = ipyData.GetAttackDropWeightList()  
 | 
    attackDropWeightListEx = ipyData.GetAttackDropWeightListEx()  
 | 
    dropCountEx = ipyData.GetDropCountEx()  
 | 
    alchemyDiffLV = ipyData.GetAlchemyDiffLV()  
 | 
      
 | 
    mainItemWeightList = []  
 | 
    if attackCountDropWeightInfo:  
 | 
        maxCount = max(attackCountDropWeightInfo)  
 | 
        attackCount = attackPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCAttackCount % npcID) + 1  
 | 
        if attackCount <= maxCount:  
 | 
            if attackCount in attackCountDropWeightInfo:  
 | 
                mainItemWeightList = attackCountDropWeightInfo[attackCount]  
 | 
            UpdateNPCAttackCount(attackPlayer, npcID, attackCount, maxCount)  
 | 
              
 | 
    if mainItemWeightList:  
 | 
        mainItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, mainItemWeightList, alchemyDiffLV)  
 | 
    elif attackDropWeightList:  
 | 
        mainItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, attackDropWeightList, alchemyDiffLV)  
 | 
          
 | 
    mainItemInfo = GameWorld.GetResultByWeightList(mainItemWeightList)  
 | 
      
 | 
    if not mainItemInfo:  
 | 
        notDropNotify = ipyData.GetNotDropNotify()  
 | 
        if notDropNotify:  
 | 
            PlayerControl.NotifyCode(attackPlayer, notDropNotify)  
 | 
        return  
 | 
      
 | 
    dropItemList = []  
 | 
    if mainItemInfo:  
 | 
        dropItemList.append(mainItemInfo)  
 | 
          
 | 
    if attackDropWeightListEx and dropCountEx:  
 | 
        weightListEx = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, attackDropWeightListEx, alchemyDiffLV)  
 | 
        for _ in xrange(dropCountEx):  
 | 
            itemInfo = GameWorld.GetResultByWeightList(weightListEx)  
 | 
            if itemInfo:  
 | 
                dropItemList.append(itemInfo)  
 | 
                  
 | 
    if not dropItemList:  
 | 
        return  
 | 
      
 | 
    mapID = PlayerControl.GetCustomMapID(attackPlayer)  
 | 
    if mapID:  
 | 
        DoGiveItemByVirtualDrop(attackPlayer, dropItemList, npcID)  
 | 
        GameLogic_CrossGrassland.RecordGrasslandAward(attackPlayer, dropItemList)  
 | 
    else:  
 | 
        dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()  
 | 
        ChItem.DoMapDropItem(attackPlayer, dropItemList, npcID, dropPosX, dropPosY, isOnlySelfSee=False)  
 | 
    return  
 | 
  
 | 
                 
 |