#!/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 PlayerPrestigeSys
|
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)
|
PlayerPrestigeSys.AddRealmTaskValue(curPlayer, PlayerPrestigeSys.RealmTaskType_KillNPC, 1)
|
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
|
|
|