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