From 32004fc5071f6da69d8b9e0bfc4a3080d04f9f03 Mon Sep 17 00:00:00 2001 From: xdh <xiefantasy@qq.com> Date: 星期六, 22 十二月 2018 09:58:00 +0800 Subject: [PATCH] 5372 【后端】【1.4】聚魂副本开发(代码还原) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py | 132 +++++++++++++++++++++++++++++++++++++++---- 1 files changed, 119 insertions(+), 13 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py index 1978c26..0520331 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py @@ -25,19 +25,22 @@ # @change: "2014-12-31 14:40" Alee 降低NPCAI消耗 # @change: "2016-11-22 21:00" hxp 支持添加最大仇恨buff #------------------------------------------------------------------------------ -"""Version = 2016-11-22 21:00""" +#"""Version = 2016-11-22 21:00""" #------------------------------------------------------------------------------- import ChConfig import NPCCommon import AICommon import IPY_GameWorld +import FamilyRobBoss import AttackCommon import GameWorld import BaseAttack import PlayerState import SkillCommon +import PyGameData import BuffSkill import GameObj +import ItemCommon ## 初始化 # @param curNPC 当前npc @@ -92,7 +95,7 @@ npcControl.DoHPPerLogic(ChConfig.Def_NPCHurtTypeAll, 0) return -def __RefreshDropOwner(curNPC, tick, refreshInterval=3000): +def __RefreshDropOwner(curNPC, tick, refreshInterval=3000, isDead=False): ## 刷新boss掉落归属 # @return: 可攻击的掉落归属目标玩家 @@ -100,15 +103,27 @@ tagObj = None # 即将攻击的目标, 归属最大伤血取最大伤血玩家或队伍队员,其他取最大仇恨 ownerType, ownerID = 0, 0 dropOwnerType = NPCCommon.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 = npcControl.RefreshHurtList(tick, refreshInterval) if maxHurtObj: ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID() if ownerType == ChConfig.Def_NPCHurtTypeTeam: - tagObj = __GetMaxHurtTeamPlayer(curNPC, npcControl, ownerID) + tagObj = __GetMaxHurtTeamPlayer(curNPC, npcControl, ownerID, isDead) elif ownerType == ChConfig.Def_NPCHurtTypePlayer: tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) + elif dropOwnerType == ChConfig.DropOwnerType_Family: + ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(npcControl, curNPC, tick, refreshInterval) + if ownerInfo: + tagObj, ownerFamilyID = ownerInfo + ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID + + 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 @@ -121,53 +136,76 @@ maxAngryObj = GameWorld.GetObj(angryID, angryObjType) tagObj = maxAngryObj - if dropOwnerType == ChConfig.DropOwnerType_MaxAngry and angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj: + if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType: teamID = maxAngryObj.GetTeamID() if teamID: ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, teamID else: ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID() - __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType, ownerID) + + if isDead: + GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID)) + + __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType, ownerID, isDead) return tagObj -def __GetMaxHurtTeamPlayer(curNPC, npcControl, teamID): +def __GetMaxHurtTeamPlayer(curNPC, npcControl, teamID, isDead): ## 获取最大伤血队伍中攻击的目标队员 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 isDead: + GameWorld.Log(" i=%s, 队员坐标(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID())) if npcControl.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint): return curTeamPlayer + else: + GameWorld.ErrLog("找不到该队伍: teamID=%s" % teamID) return -def __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType=0, ownerID=0): +def __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType=0, ownerID=0, isDead=False): npcID = curNPC.GetNPCID() dropOwnerType = NPCCommon.GetDropOwnerType(curNPC) - if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry]: + if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family]: #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.DebugLog("归属变更, 清除旧归属! ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s" - % (ownerType, ownerID, lastDropOwnerType, lastDropOwnerID)) + GameWorld.Log("归属变更, 清除旧归属! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s" + % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID)) __DelBossDropOwnerBuff(curNPC, 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 __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC) elif ownerType == ChConfig.Def_NPCHurtTypeTeam: @@ -175,22 +213,67 @@ 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 npcControl.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \ and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False): __AddBossDropOwnerPlayerBuff(curTeamPlayer, tick, curNPC) - + 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 npcControl.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint): + __AddBossDropOwnerPlayerBuff(player, tick, curNPC) + + 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 __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC): @@ -242,6 +325,14 @@ if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0: continue __SetBossDropOwnerBuffDisappearTime(curTeamPlayer, curNPC) + elif ownerType == ChConfig.Def_NPCHurtTypeFamily: + copyPlayerMgr = GameWorld.GetMapCopyPlayerManager() + for index in xrange(copyPlayerMgr.GetPlayerCount()): + player = copyPlayerMgr.GetPlayerByIndex(index) + if not player: + continue + __SetBossDropOwnerBuffDisappearTime(player, curNPC) + return def __SetBossDropOwnerBuffDisappearTime(curPlayer, curNPC): @@ -290,13 +381,25 @@ PlayerState.SetBossStateTick(atkObj, tick) return +def OnCheckCanDie(atkObj, curNPC, skill, tick): + ## 检查NPC是否可死亡 + dropOwnerType = NPCCommon.GetDropOwnerType(curNPC) + if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt]: + return True + tagObj = __RefreshDropOwner(curNPC, tick, 0) + if not atkObj or not tagObj: + GameObj.SetHP(curNPC, 1) + GameWorld.ErrLog("Boss当前状态下不可以死亡!npcID=%s" % curNPC.GetNPCID()) + return False + return True + ## NPC被玩家杀死 def OnAttackDieByPlayer(curNPC, curPlayer, skill): tick = GameWorld.GetGameWorld().GetTick() PlayerState.SetBossStateTick(curPlayer, tick) #被击杀时强制刷新归属 - __RefreshDropOwner(curNPC, tick, 0) + __RefreshDropOwner(curNPC, tick, 0, True) return ## NPC死亡处理 @@ -307,9 +410,12 @@ # @return None def OnDie(curNPC, HurtType, HurtID): AICommon.DoNPCUseSkillOnDie(curNPC) + return + +def OnNPCSetDead(curNPC): __DelayBossDropOwnerBuff(curNPC) return - + ## npc攻击逻辑 # @param curNPC 当前npc # @param tagID curNPCAngryID -- Gitblit v1.8.0