From ad158391ff62df48198a5411e5950e578dc3c43c Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 11 四月 2019 14:42:21 +0800 Subject: [PATCH] 6459 【后端】【2.0】缥缈仙域开发单(可进入跨服妖王地图支持分区,增加竞争归属逻辑) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 348 insertions(+), 0 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py index 787692c..fd34538 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -5086,6 +5086,354 @@ return return curItem + ##----------------------------------------- 归属 ----------------------------------------------- + + def RefreshDropOwner(self, tick, refreshInterval=3000, isDead=False): + ## 刷新boss掉落归属 + # @return: 可攻击的掉落归属目标玩家 + + curNPC = self.__Instance + tagObj = None # 即将攻击的目标, 归属最大伤血取最大伤血玩家或队伍队员,其他取最大仇恨 + ownerType, ownerID = 0, 0 + dropOwnerType = GetDropOwnerType(curNPC) + if isDead: + GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s" + % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType)) + if dropOwnerType == ChConfig.DropOwnerType_MaxHurt: + maxHurtObj = self.RefreshHurtList(tick, refreshInterval) + if maxHurtObj: + ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID() + if ownerType == ChConfig.Def_NPCHurtTypeTeam: + tagObj = self.__GetMaxHurtTeamPlayer(ownerID, isDead) + elif ownerType == ChConfig.Def_NPCHurtTypePlayer: + tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) + + elif dropOwnerType == ChConfig.DropOwnerType_Family: + ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(curNPC, tick, refreshInterval) + if ownerInfo: + tagObj, ownerFamilyID = ownerInfo + ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID + + elif dropOwnerType == ChConfig.DropOwnerType_Contend: + tagObj = self.__RefreshContendOwner() + if tagObj: + ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, tagObj.GetPlayerID() + + if isDead: + GameWorld.Log("ownerType=%s, ownerID=%s, tagObjID=%s" % (ownerType, ownerID, 0 if not tagObj else tagObj.GetPlayerID())) + + # 没有攻击目标,则刷新仇恨,支持主动怪 + if not tagObj: + angryObjType, maxAngryObj = None, None + self.RefreshAngryList(tick, refreshInterval, isUpdAngry=True) + maxAngry = self.GetMaxAngryTag() + if maxAngry: + angryID = maxAngry.GetObjID() + angryObjType = maxAngry.GetObjType() + #GameWorld.DebugLog("最大仇恨目标: ID=%s, Type=%s" % (angryID, angryObjType)) + maxAngryObj = GameWorld.GetObj(angryID, angryObjType) + + tagObj = maxAngryObj + if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType: + if dropOwnerType == ChConfig.DropOwnerType_Contend: + ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID() + elif maxAngryObj.GetTeamID(): + ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, maxAngryObj.GetTeamID() + else: + ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID() + + if isDead: + GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID)) + + self.UpdateDropOwner(tick, ownerType, ownerID, isDead) + return tagObj + + def __RefreshContendOwner(self): + ## 刷新boss争夺归属者,归属移除时不做刷新新归属,默认由后面的仇恨刷新 + + curNPC = self.__Instance + ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID) + ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType) + if not ownerID or ownerType != ChConfig.Def_NPCHurtTypePlayer: + return + + owner = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) + if not owner: + return + + if not owner.GetVisible(): + GameWorld.DebugLog("竞争归属玩家不可见,移除归属!playerID=%s" % ownerID) + return + + if owner.GetHP() <= 0 or owner.GetPlayerAction() == IPY_GameWorld.paDie: + GameWorld.DebugLog("竞争归属玩家死亡,移除归属!playerID=%s" % ownerID) + return + + refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) + if not self.GetIsInRefreshPoint(owner.GetPosX(), owner.GetPosY(), refreshPoint): + GameWorld.DebugLog("竞争归属玩家不在boss范围里,移除归属!playerID=%s" % ownerID) + return + + GameWorld.DebugLog("竞争归属玩家归属正常!playerID=%s" % ownerID) + return owner + + def __GetMaxHurtTeamPlayer(self, teamID, isDead): + ## 获取最大伤血队伍中攻击的目标队员 + + curNPC = self.__Instance + curTeam = GameWorld.GetTeamManager().FindTeam(teamID) + if curTeam: + refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) + if isDead: + GameWorld.Log("队伍成员数: teamID=%s,memberCount=%s" % (teamID, curTeam.GetMemberCount())) + for i in xrange(curTeam.GetMemberCount()): + curTeamPlayer = curTeam.GetMember(i) + if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0: + if isDead: + GameWorld.Log(" i=%s, 队员为空!" % i) + continue + if curTeamPlayer.GetHP() <= 0: + if isDead: + GameWorld.Log(" i=%s, 队员血量为0!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID())) + continue + if not curTeamPlayer.GetVisible(): + if isDead: + GameWorld.Log(" i=%s, 队员不可见!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID())) + continue + if isDead: + GameWorld.Log(" i=%s, 队员坐标(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID())) + if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint): + return curTeamPlayer + else: + GameWorld.ErrLog("找不到该队伍: teamID=%s" % teamID) + return + + def UpdateDropOwner(self, tick, ownerType=0, ownerID=0, isDead=False): + + curNPC = self.__Instance + npcID = curNPC.GetNPCID() + dropOwnerType = GetDropOwnerType(curNPC) + if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family, ChConfig.DropOwnerType_Contend]: + #GameWorld.DebugLog("不需要展示掉落归属的NPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType)) + return + + lastDropOwnerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID) + lastDropOwnerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType) + + key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID) + if lastDropOwnerID and (lastDropOwnerType != ownerType or lastDropOwnerID != ownerID): + GameWorld.Log("归属变更, 清除旧归属! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s" + % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID)) + self.__DelDropOwnerBuff(dropOwnerType, lastDropOwnerType, lastDropOwnerID, tick) + + killerDict, curTeam, hurtType, hurtID = {}, None, 0, 0 + + # 更新归属 + curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerID, ownerID) + curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerType, ownerType) + + if isDead: + GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID)) + + # 刷新归属 + if ownerType == ChConfig.Def_NPCHurtTypePlayer: + curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) + if curPlayer: + playerID = curPlayer.GetPlayerID() + 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()) + + elif ownerType == ChConfig.Def_NPCHurtTypeTeam: + curTeam = GameWorld.GetTeamManager().FindTeam(ownerID) + if not curTeam: + return + + # 因为有击杀次数限制,所以不是所有的队员都可以获得归属,所以这里设置为特殊指定玩家掉落 + 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 self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \ + 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 killerDict: + PyGameData.g_npcKillerInfo[key] = killerDict, curTeam, hurtType, hurtID + 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): #通知客户端假物品掉落 -- Gitblit v1.8.0