#!/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 PlayerCrossYaomoBoss import PlayerActCollectWords import PlayerNewFairyCeremony import GameLogic_CrossGrassland import PlayerActGarbageSorting import PlayerActBossTrial import PlayerTongTianLing import CrossPlayerData import PlayerFeastWish import PlayerFeastTravel import PlayerGoldInvest import PlayerWeekParty import NPCRealmRefresh import NPCHurtManager import PlayerActLogin import PlayerActTask import PlayerZhanling import FamilyRobBoss import IpyGameDataPY import PlayerGubao import PlayerState import PyGameData import PlayerTeam import NPCHurtMgr import PlayerVip import GameObj import ChNPC import random import math import time import copy #--------------------------------------------------------------------- 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, curPlayer=None): # NPCµÈ¼¶ if hasattr(curNPC, "GetCurLV"): return max(curNPC.GetCurLV(), curNPC.GetLV()) if curPlayer and PlayerControl.GetRealmDifficulty(curPlayer): npcID = curNPC.GetNPCID() needRealmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer)) realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, needRealmLV) if realmNPCIpyData: return realmNPCIpyData.GetLV() return curNPC.GetLV() def GetNPCDataEx(npcID): ## »ñÈ¡NPCÀ©Õ¹Êý¾Ý±í£¬¿ÉÈȸü npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPCEx", npcID) if not npcDataEx: if False: # ²»¿ÉÄܳÉÁ¢µÄÌõ¼þ£¬Ö»ÎªÁË . ³ö´úÂëÌáʾ npcDataEx = IpyGameDataPY.IPY_NPCEx() return npcDataEx return npcDataEx def GetRealmLV(curNPC): return curNPC.GetMAtkMin() # NPC±íÖдË×ֶκ¬Òå¸Ä³É¾³½çµÈ¼¶ def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV) # NPC±íÖдË×ֶκ¬Òå¸Ä³É¾³½çµÈ¼¶ def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # ·ç·À´ú±íÊÇ·ñµÈ¼¶Ñ¹ÖÆ def GetFightPowerLackAtkLimit(curNPC): # Õ½Á¦²»×ãÏÞÖÆ¹¥»÷£¬Ä¬Èϲ»ÏÞÖÆ npcDataEx = GetNPCDataEx(curNPC.GetNPCID()) return npcDataEx.GetFightPowerLackAtkLimit() if npcDataEx else 0 def GetSuppressFightPower(curNPC): npcDataEx = GetNPCDataEx(curNPC.GetNPCID()) return npcDataEx.GetSuppressFightPower() if npcDataEx else curNPC.GetThunderDef() # À×·À´ú±íÑ¹ÖÆÕ½Á¦ def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord)) 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) # ¸ù¾Ý¾³½çÄÑ¶È elif lvStrengthenType == 5: realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel()) realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) if realmNPCIpyData: strengthenLV = realmNPCIpyData.GetLV() else: lvStrengthenType = 0 # ľ׮¹Ö×î´ó¡¢Æ½¾ù³É³¤µÈ¼¶´¦Àí£¬Ö±½ÓÈ¡¹éÊôÍæ¼ÒµÈ¼¶ 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_HP() curNPC.Notify_MaxHP() #GameWorld.DebugLog(" aftHP=%s,aftMaxHP=%s" % (aftHP, aftMaxHP)) # »úÆ÷È˸´»î³õʼ»¯¸ø¼¼ÄÜ if isReborn and curNPC.GetType() == ChConfig.ntRobot: __OnFBRobotReborn(curNPC, strengthenLV) return def __OnFBRobotReborn(curNPC, npcLV): 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) FBLogic.OnRandomRobotJob(curNPC, lineRobotJobDict) 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 = GameObj.GetHP(npcData) # NPCData ûÓÐÌṩMax½Ó¿Ú£¬¶ÔӦʹÓÃ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() sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer) 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, sightLevel=sightLevel) 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) 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 realmNPCIpyData = None realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1) realmDifficulty = PlayerControl.GetRealmDifficulty(dropPlayer) if mapID in realmMapIDList and realmDifficulty: realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty) realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) #if realmNPCIpyData: # maxDropLV = realmNPCIpyData.GetMaxDrapLV() #ÍÑ»úÔݲ»ÏÞÖÆ×î´óµÈ¼¶µôÂä #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: if realmNPCIpyData: classLV = realmNPCIpyData.GetEquipClassLV() GameWorld.DebugLog(" ÍÑ»úµôÂä¶ÔÓ¦ÄѶȾ³½ç×°±¸: classLV=%s" % classLV, playerID) 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, realmNPCIpyData) * 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 # À¬»ø·ÖÀà giveGarbageItemList = PlayerActGarbageSorting.AddActGarbageTaskProgress(dropPlayer, ChConfig.Def_GarbageTask_KillNPC, killCount, isTJG=True) for dropID, dropCount, _ in giveGarbageItemList: 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() realmNPCIpyData = None realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1) realmDifficulty = PlayerControl.GetRealmDifficulty(dropPlayer) if mapID in realmMapIDList and realmDifficulty: realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty) realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) if realmNPCIpyData: maxDropLV = realmNPCIpyData.GetMaxDrapLV() 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 tianxuanState = False # ÊÇ·ñÓÐÌìÐþ¶îÍâµôÂä״̬ tianxuanBuff = SkillCommon.FindBuffByID(dropPlayer, ChConfig.Def_SkillID_TianxuanBuff)[0] 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)) # ÌìÐþµ¤ tianxuanEquipRateList = ipyDrop.GetTianxuanEquipRateList() if tianxuanBuff and tianxuanEquipRateList: tianxuanState = True dropInfo = GameWorld.GetResultByRandomList(tianxuanEquipRateList) if dropInfo: dropEquipInfoList.append(dropInfo) # 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] equipColorDropLimitDay = IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 1, {}) # ÿÈÕ¸öÈ˵ôÂä×°±¸¸öÊýÏÞÖÆ {Æ·ÖÊ:ÿÈÕµôÂä¸öÊý, ...} 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 realmNPCIpyData: classLV = realmNPCIpyData.GetEquipClassLV() GameWorld.DebugLog("µôÂä¶ÔÓ¦ÄѶȾ³½ç×°±¸: classLV=%s" % classLV, playerID) colorCountToday = 0 if color in equipColorDropLimitDay: colorCountMax = equipColorDropLimitDay[color] colorCountToday = dropPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropColorToday % color) if colorCountToday >= colorCountMax: GameWorld.DebugLog("Òѳ¬¹ý¸ÃÑÕɫװ±¸½ñÈÕ×î´óµôÂäÊý£¬²»µô£¡color=%s,colorCountMax=%s" % (color, colorCountMax), playerID) continue 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 equipColorDropLimitDay: colorCountToday += 1 PlayerControl.NomalDictSetProperty(dropPlayer, ChConfig.Def_PDict_DropColorToday % color, colorCountToday) 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) if colorCountToday: GameWorld.DebugLog(" ¸üеôÂäÌØÊâÆ·ÖÊ×°±¸½ñÈÕ´ÎÊý: color=%s,colorCountToday=%s" % (color, colorCountToday), playerID) # 4. Ö¸¶¨ÎïÆ·ID¿â dropIDList += __GetAppointDropItemIDList(dropPlayer, npcID, ipyDrop, doCountRate, doCountAdd, tianxuanBuff) if tianxuanBuff and (ipyDrop.GetTianxuanItemKeyRate() or ipyDrop.GetTianxuanItemIDRate()): tianxuanState = True # 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) #bossƾ֤ killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1) if mapID == ChConfig.Def_FBMapID_PersonalBoss: limitIndex = ChConfig.Def_FBMapID_PersonalBoss else: limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID) if limitIndex != None: bossTrialDrop = PlayerActBossTrial.GetBossTrialDropItemIDList(dropPlayer, limitIndex) if bossTrialDrop: bossTrialItemID, bossTrialItemCount = bossTrialDrop GameWorld.DebugLog("µôÂäbossƾ֤: bossTrialItemID=%s, bossTrialItemCount=%s" % (bossTrialItemID, bossTrialItemCount)) dropIDList += [bossTrialItemID] * bossTrialItemCount # ¼ì²éµôÂ以³â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, realmNPCIpyData) #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()) if tianxuanBuff and tianxuanState: GameWorld.DebugLog(" È¥³ýÌìÐþµ¤buff: Layer=%s" % tianxuanBuff.GetLayer(), playerID) BuffSkill.SetBuffLayer(dropPlayer, tianxuanBuff, max(tianxuanBuff.GetLayer() - 1, 0), True, ChConfig.Def_SkillID_TianxuanBuff, isSync=True) 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, tianxuanBuff): ## Ö¸¶¨ÎïÆ·IDµôÂä dropItemIDList = [] itemDropLimitDayInfo = IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 2, {}) # ÿÈÕ¸öÈ˵ôÂäÎïÆ·¸öÊýÏÞÖÆ {ÎïÆ·ID:ÿÈÕµôÂäÉÏÏÞ, ...} # 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:¸ÅÂÊ, ...}£¬ Ëæ»úµôÒ»¸ö£¬ÓÅÏȼ¶µÍ tianxuanItemKeyRateDict = ipyDrop.GetTianxuanItemKeyRate() # ÌìÐþµ¤Ö¸¶¨ID¼¯ºÏKey¸ÅÂÊ{ÎïÆ·ID¼¯ºÏkey:¸ÅÂÊ, ...} if tianxuanBuff and tianxuanItemKeyRateDict: ItemKeyDropRateDict = copy.deepcopy(ItemKeyDropRateDict) ItemKeyDropRateDict.update(tianxuanItemKeyRateDict) if ItemKeyDropRateDict: GameWorld.DebugLog("ItemKeyDropRateDict:%s" % 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 if __dropIDCountLimitToday(curPlayer, randItemID, itemDropLimitDayInfo): continue dropItemIDList.append(randItemID) #GameWorld.DebugLog("µôÂäËæ»úÖ¸¶¨ÎïÆ·ID: itemKey=%s,randItemID=%s" % (itemKey, randItemID)) # 2. Ö¸¶¨µôÂäID´¦Àí, ÊÜÈ«¾ÖÉ趨ӰÏì itemIDDropRateDict = ipyDrop.GetItemIDDropRate() # {ÎïÆ·ID:¸ÅÂÊ, ...} itemIDDropMaxCntDict = ipyDrop.GetItemIDMaxDropCount() # {ÎïÆ·ID:×î´óµôÂä¸öÊý,...} tianxuanItemIDRate = ipyDrop.GetTianxuanItemIDRate() # ÌìÐþµ¤Ö¸¶¨ID¸ÅÂÊ {ÎïÆ·ID:¸ÅÂÊ, ...} if tianxuanBuff and tianxuanItemIDRate: itemIDDropRateDict = copy.deepcopy(itemIDDropRateDict) itemIDDropRateDict.update(tianxuanItemIDRate) # È«¾Ö²ÄÁϵôÂä¿ØÖÆ globalDropCDDict = IpyGameDataPY.GetFuncCfg("GlobalDropCD", 1) # {ÎïÆ·ID:·ÖÖÓ, ...} globalDropRateDict = IpyGameDataPY.GetFuncCfg("NPCGlobalDropRate", 1) # {ÎïÆ·ID:[[npcIDÁбí], "¸ÅÂʹ«Ê½"], ...} gw = GameWorld.GetGameWorld() if itemIDDropRateDict: GameWorld.DebugLog("itemIDDropRateDict=%s" % itemIDDropRateDict) 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 if __dropIDCountLimitToday(curPlayer, itemID, itemDropLimitDayInfo): 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 __dropIDCountLimitToday(curPlayer, itemID, itemDropLimitDayInfo): ## ´¦Àí½ñÈÕµôÂäÎïÆ·ID¸öÊýÏÞÖÆ # @return: ÊÇ·ñÏÞÖÆ if itemID not in itemDropLimitDayInfo: return False dropCountTodayMax = itemDropLimitDayInfo[itemID] if not dropCountTodayMax: return False dropCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropCountToday % itemID) if dropCountToday >= dropCountTodayMax: GameWorld.DebugLog(" ÎïÆ·ID½ñÈÕµôÂä´ÎÊýÒÑ´ïÉÏÏÞ: itemID=%s,dropCountToday=%s" % (itemID, dropCountToday), curPlayer.GetPlayerID()) return True dropCountToday += 1 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DropCountToday % itemID, dropCountToday) GameWorld.DebugLog(" ¸üÐÂÎïÆ·ID½ñÈÕµôÂä´ÎÊý: itemID=%s,dropCountToday=%s" % (itemID, dropCountToday), curPlayer.GetPlayerID()) return False 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, realmNPCIpyData): baseMoney = FBLogic.OnGetNPCDropMoney(curPlayer) if baseMoney <= 0: # »ñµÃµôÂäÊýÁ¿ if realmNPCIpyData: baseMoney = random.randint(realmNPCIpyData.GetDropMoneyMin(), realmNPCIpyData.GetDropMoneyMax()) else: 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 = GameObj.GetAngryValue(curAngry) # # #ɾ³ý¾ÉµÄ³ðºÞ,Ìí¼Óе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, sightLevel=0, refreshID=0): curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC() if not curSummon: return tick = GameWorld.GetGameWorld().GetTick() #---³õʼ»¯NPCÏà¹Ø ÉèNPCID ×î´ó³ðºÞÊý AIÀàÐÍ ³öÉúµã ³öÉúʱ¼ä--- curSummon.SetNPCTypeID(npcId) 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) if sightLevel > 0: curSummon.SetSightLevel(sightLevel) if refreshID > 0: curSummon.SetDict(ChConfig.Def_NPC_Dict_SummonRefreshID, refreshID) if curSummon.GetType() == ChConfig.ntRobot: __OnFBRobotReborn(curSummon, curSummon.GetLV()) curSummon.Reborn(rebornX, rebornY, False) NPCControl(curSummon).DoNPCRebornCommLogic(tick) 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: hpTotal = hpEx * ShareDefine.Def_PerPointValue + hp GameObj.SetHP(summonNPC, hpTotal) GameObj.SetMaxHP(summonNPC, hpTotal) 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) refreshObj = NPCRealmRefresh.GetTagNPCRefresh(curNPC) if refreshObj: refreshObj.SetDead(GameWorld.GetGameWorld().GetTick()) # °µ½ð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) if npcid == IpyGameDataPY.GetFuncCfg("CrossYaomoBoss", 1): PlayerCrossYaomoBoss.OnCrossYaomoBossDead(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): npcData = GameWorld.GetGameData().FindNPCDataByID(npcID) if not npcData: return killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1) limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID) if limitIndex != None: totalKey = ChConfig.Def_PDict_Boss_KillCntTotal % limitIndex totalCnt = min(curPlayer.NomalDictGetProperty(totalKey, 0) + 1, ChConfig.Def_UpperLimit_DWord) PlayerControl.NomalDictSetProperty(curPlayer, totalKey, totalCnt) #½ñÈÕɱ¹Ö´ÎÊý+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("¸üл÷ɱBoss´ÎÊý: index=%s, todayCnt=%s, totalCnt=%s" % (limitIndex, newCnt, totalCnt), curPlayer.GetPlayerID()) dataDict = {"objID":npcID, "bossID":npcID, "touchCnt":newCnt, "totalCnt":totalCnt, "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) PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_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) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_WorldBoss, 1) PlayerZhanling.AddZhanlingValue(curPlayer, PlayerZhanling.ZhanlingType_Huanjingge, 1) PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_WorldBoss, 1) elif limitIndex == ShareDefine.Def_Boss_Func_Home: #BOSSÖ®¼Ò # BOSSÖ®¼ÒBOSS»÷ɱ³É¾Í PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1) PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillBossHome, 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) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_BossHome, 1) if mapID == ChConfig.Def_FBMapID_CrossPenglai: #¿ç·þÅîÀ³Ïɾ³ PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossPenglai) PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillCrossPenglaiBoss, 1) PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillCrossPenglaiBoss, 1) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_CrossPenglaiBoss, 1) elif mapID == ChConfig.Def_FBMapID_CrossDemonLand: #¿ç·þħ»¯Ö®µØ PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossDemonLand) PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillCrossDemonLandBoss, 1) PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillCrossDemonLandBoss, 1) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_CrossDemonLandBoss, 1) if mapID in [ChConfig.Def_FBMapID_CrossPenglai, ChConfig.Def_FBMapID_CrossDemonLand]: PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_CrossBoss) PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_CrossBoss, 1) if npcData.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark: PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_KillBoss) # ¸öÈËÊ×ɱ¼Ç¼ ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", npcID) if ipyData: GY_Query_BossFirstKill.SetPlayerFirstKillBoss(curPlayer, npcID) #BossͶ×Ê PlayerGoldInvest.OnKillBoss(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()) if not curRefreshPos: return 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 GameObj.GetAngryValue(angryValue) != 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()) #×îСÌí¼Ó³ðºÞֵΪ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 GameObj.GetAngryValue(angryValue) == 0: npcAngry.AddAngry(curObjID, curObjType, plusAngryValue % ShareDefine.Def_PerPointValue, plusAngryValue / ShareDefine.Def_PerPointValue) #Èç¹ûÐèÒª,µþ¼Ó elif canPile: updAngryValue = GameObj.GetAngryValue(angryValue) + plusAngryValue GameObj.SetAngryValue(angryValue, updAngryValue) 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 = GameObj.GetAngryValue(curAngry) 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_HP() #ÕâÀï²»ÉèÖÃΪÂýËÙ´¦Àí,ÒòΪ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 = self.GetRefreshPoint() #·¶Î§Ð£Ñé if not posMap: GameWorld.ErrLog("__Func_GetRandPosInRefreshArea GetRefreshPosAt error: return None! npcID=%s" % curNPC.GetNPCID()) return 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 #--------------------------------------------------------------------- def GetRefreshPoint(self): curNPC = self.__Instance refreshObj = NPCRealmRefresh.GetTagNPCRefresh(curNPC) if refreshObj: refreshPoint = refreshObj.GetRefreshPoint() else: refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) return refreshPoint ## ÊÇ·ñÔÚÒÆ¶¯·¶Î§ÄÚ # @param self ÀàʵÀý # @return ·µ»ØÖµÕæ, ÔÚÒÆ¶¯·¶Î§ÄÚ # @remarks ÊÇ·ñÔÚÒÆ¶¯·¶Î§ÄÚ def IsInRefreshArea(self): #Õâ¸öNPCÊÇ·ñÔÚÒÆ¶¯·¶Î§ÄÚ curNPC = self.__Instance refreshPoint = self.GetRefreshPoint() #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 GameObj.GetMaxHP(curNPC) != 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_HP() curNPC.Notify_MaxHP() 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 ## ÎïÆ·µôÂä # @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 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 = [] if dropInfo: 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()) sightLevel = PlayerControl.GetMapRealmDifficulty(dropPlayer) 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, sightLevel=sightLevel) 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 GameObj.GetHP(angryNPC) <= 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 GameObj.GetHP(curNPC) == GameObj.GetMaxHP(curNPC): # #ÂúѪÁË # 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, GetNPCLV(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 GameObj.GetHP(curPlayer) <= 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 GameObj.GetHP(curTeamPlayer) <= 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 fbOwnerInfo = FBLogic.GetFBEveryoneDropInfo(curNPC) if fbOwnerInfo != None: ownerPlayerList, isOnlySelfSee = fbOwnerInfo for curPlayer in ownerPlayerList: self.__NPCDropItem(curPlayer, ChConfig.Def_NPCHurtTypePlayer, curPlayer.GetPlayerID(), [curPlayer], isOnlySelfSee=isOnlySelfSee) #µ÷ÓÃÎïÆ·µôÂ䣬bossÒ»ÈËÒ»·Ý elif 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 GetNPCLV(curNPC) >= curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'): PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC) PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_KillNPC) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_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]) 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 npcID = curNPC.GetNPCID() realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel()) realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) if realmNPCIpyData: baseExp = realmNPCIpyData.GetExp() npcLV = realmNPCIpyData.GetLV() else: baseExp = curNPC.GetExp() npcLV = curNPC.GetLV() 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£© 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, sightLevel=0): 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, sightLevel=sightLevel) #ÉèÖøÃÎïÆ·ÉúǰӵÓÐÕß(ÄǸö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, checkCanDead=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 checkCanDead: 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, checkCanDead) 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 or checkCanDead: 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) if isDead or checkCanDead: GameWorld.Log("×î´ó³ðºÞÄ¿±ê: ID=%s, Type=%s,maxAngryObj=%s" % (angryID, angryObjType, maxAngryObj)) 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 or checkCanDead: 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 GameObj.GetHP(owner) <= 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 GameObj.GetHP(curTeamPlayer) <= 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 needRealmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer)) realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, needRealmLV) if realmNPCIpyData: baseExp = realmNPCIpyData.GetExp() else: 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) #--------------------------------------------------------------------- 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 curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectNPCObjID, curNPC.GetID()) # ²É¼¯ºÄʱ 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))) prepareType = IPY_GameWorld.pstCollecting if curNPC.GetType() == IPY_GameWorld.ntCollection else IPY_GameWorld.pstMissionCollecting PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, prepareType, prepareID=curNPC.GetID()) if collectNPCIpyData.GetLostHPPer(): curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick) ##Ìí¼ÓÕâ¸öNPCµÄÉËѪÁÐ±í£¬ÓÃÓÚÅжϿɷñͬʱ²É¼¯£¬¸ÄΪ×ÖµäÅÐ¶Ï AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1) FBLogic.OnBeginCollect(curPlayer, curNPC) 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") FBLogic.OnExitCollect(curPlayer, curNPC) 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, crossCollectOK=True) 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, crossCollectOK=False, isSweep=False): GameWorld.DebugLog("¸ø²É¼¯½±Àø: npcID=%s,collectCnt=%s,crossCollectOK=%s" % (npcID, collectCnt, crossCollectOK)) 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) jsonItemList = [] if awardItemList: for itemID, itemCount, isAuctionItem in awardItemList: if ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]): jsonItemList.append(ItemCommon.GetJsonItem([itemID, itemCount, isAuctionItem])) if not isSweep: 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]) if crossCollectOK: PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_CrossCollect) #SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID) if not isSweep: GameLogic_CrossGrassland.DecCustomSceneNPCCount(curPlayer, npcID) if isMaxTime: GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer) return jsonItemList ## ²É¼¯½á¹ûͬ²½ # @param None # @param None def SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, syncItemInfoList, collectNPCID=0): return #Ôݲ»Í¬²½ def SyncCollNPCTime(curPlayer, npcIDList=None): ## ͬ²½²É¼¯NPC¹¦ÄܺŲɼ¯´ÎÊý isSyncAll = False if npcIDList == None: 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 PlayerOnDay(curPlayer): #²É¼¯´ÎÊýÖØÖà CollNPCTimeOnDay(curPlayer) itemDropLimitDayInfo = IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 2, {}) for itemID in itemDropLimitDayInfo.keys(): if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropCountToday % itemID): PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DropCountToday % itemID, 0) for color in range(20): if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropColorToday % color): PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DropColorToday % color, 0) 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) canBuyCnt += PlayerGoldInvest.GetAddBossBuyCnt(curPlayer, killBossMark) 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 moneyType = IpyGameDataPY.GetFuncEvalCfg("KillBossCntLimit1", 4, {}).get(str(killBossMark), IPY_GameWorld.TYPE_Price_Gold_Money) infoDict = {"index":killBossMark, ChConfig.Def_Cost_Reason_SonKey:killBossMark} isOK = PlayerControl.PayMoney(curPlayer, moneyType, 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) CrossPlayerData.SendMergePlayerDataNow(curPlayer) 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