From ae8e857873ba53e55392ab06237cd7b16426d93e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期日, 25 十一月 2018 17:55:06 +0800
Subject: [PATCH] 4762 【后端】助战机器人AI及伤血;

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_QueenRelics.py |    8 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                                  |   31 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py          |    8 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_20.py                            |   75 ++++++++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py                |   26 ++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                       |    3 +
 6 files changed, 145 insertions(+), 6 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
index 5666adf..7b5a0be 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -1668,6 +1668,7 @@
     suppressLV, suppressFightPower = 0, 0 # 压制等级差、战力差
     suppressReMaxHP = 0 # NPC压制等级生命值, 等级表中NPC等级对应的数据, 压制等级差大于0时才有值
     suppressNPCFightPower = 0 # 压制NPC战力
+    fbFightPower, fbBaseHurt = 0, 0 # 副本战力, 副本保底伤害
     #当攻击方为NPC,防守方为玩家时,计算压制等级 及 压制战力
     if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer:
         
@@ -1687,10 +1688,25 @@
         if suppressNPCFightPower:
             suppressFightPower = max(0, suppressNPCFightPower - defObj.GetFightPower())
             
+    mustHit = False
+    helpBattleFormatKey = ""
+    if atkObjType == IPY_GameWorld.gotNPC and atkObj.GetType() == ChConfig.ntHelpBattleRobot:
+        mustHit = True
+        suppressNPCFightPower = NPCCommon.GetSuppressFightPower(atkObj)
+        fbFightPower = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBFightPower)
+        fbBaseHurt = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBBaseHurt)
+        helpBattleFormatKey = "HelpRobot_Atk"
+    if defObjType == IPY_GameWorld.gotNPC and defObj.GetType() == ChConfig.ntHelpBattleRobot:
+        mustHit = True
+        suppressNPCFightPower = NPCCommon.GetSuppressFightPower(defObj)
+        fbFightPower = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBFightPower)
+        fbBaseHurt = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBBaseHurt)
+        helpBattleFormatKey = "HelpRobot_Def"
+        
     #命中公式 攻击方类型不同,公式不同
     hitFormula = ReadChConfig.GetChConfig('CalcCanHit')
     
-    if not PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, 
+    if not mustHit and not PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, 
                            ChConfig.TriggerType_Buff_MustBeHit):
         # 技能对指定BOSS无效果的返回MISS
         if defObjType == IPY_GameWorld.gotNPC and defObj.GetIsBoss() not in ChConfig.Def_SkillAttack_NPCIsBoss \
@@ -1898,7 +1914,11 @@
         suppressLVHurtKey = "%s_%s" % (hurtFormulaKey, suppressLVGroup)
         if suppressLVHurtKey in hurtDist:
             hurtFormulaKey = suppressLVHurtKey
-            
+    
+    # 助战机器人特殊伤血key
+    if helpBattleFormatKey:
+        hurtFormulaKey = helpBattleFormatKey
+        
     if hurtFormulaKey not in hurtDist:
         GameWorld.ErrLog("CalcAttackValue.txt 伤害公式未配置, key=%s" % (hurtFormulaKey))
         return 0, ChConfig.Def_HurtType_Miss
@@ -1964,6 +1984,8 @@
     if atkObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
         # 记录最后一次伤害值
         atkObj.SetDict(ChConfig.Def_PlayerKey_LastHurtValue, resultHurtType.RealHurtHP)
+        if defObj.GetGameObjType() == IPY_GameWorld.gotNPC:
+            atkObj.SetDict(ChConfig.Def_PlayerKey_LastHurtNPCObjID, defObj.GetID())
         
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index c95a629..3d334bc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1885,6 +1885,8 @@
 FBPlayerDict_IsHelpFight = 'FBPlayerDict_IsHelpFight' # 是否助战
 
 FBPD_HelpBattleRefreshCount = 'FBPD_HelpBattleRefreshCount' # 助战已刷新次数
+FBPD_HelpBattleFBFightPower = 'FBPD_HelpBattleFBFightPower' # 副本战力
+FBPD_HelpBattleFBBaseHurt = 'FBPD_HelpBattleFBBaseHurt' # 副本伤害
 
 #领取奖励标识
 (
@@ -3128,6 +3130,7 @@
 Def_PlayerKey_SuperHitRateReduce = "SuperHitRateReduce"  # 抗致命一击概率
 Def_PlayerKey_IgnoreDefRateReduce = "IgnoreDefRateReduce"  # 抗无视防御概率
 Def_PlayerKey_LastHurtValue = "LastHurtValue" # 最后一次伤害值
+Def_PlayerKey_LastHurtNPCObjID = "LastHurtNPCObjID" # 最后攻击的NPCObjID
 Def_PlayerKey_ReduceSkillCDPer = "ReduceSkillCDPer" # 减技能CD万分率
 Def_PlayerKey_CommMapExpRate = "CommMapExpRate" # 常规地图经验倍率加成
 Def_PlayerKey_FinalHurtPer = "FinalHurtPer" # 最终伤害百分比
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py
index 9158120..c64f99c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py
@@ -201,6 +201,9 @@
         GameWorld.Log("召唤助战成功: calledPlayerID=%s,objID=%s,fightPower=%s" % (calledPlayerID, objID, fightPower), playerID)
         gameFB.SetGameFBDict(ChConfig.Def_FB_HelpBattleFBObjID % calledPlayerID, objID)
         calledCount += 1
+        # 设置助战属性
+        npcControl = NPCCommon.NPCControl(helpBattleNPC)
+        npcControl.SetHelpBattleRobotRebornAttr(fightPower)
         __DoGiveHelpBattleRobotSkill(helpBattleNPC, jobSkillDict, job, npcLV)
         
         # 通知前端召唤成功
@@ -251,7 +254,7 @@
     SendGameServer_RefreshHelpBattlePlayer(curPlayer, isClientRefresh=True)
     return
 
-def SendGameServer_RefreshHelpBattlePlayer(curPlayer, mapID=0, funcLineID=0, isClientRefresh=True):
+def SendGameServer_RefreshHelpBattlePlayer(curPlayer, mapID=0, funcLineID=0, isClientRefresh=False):
     ## 发送GameServer请求刷新助战玩家列表
     if not mapID:
         mapID = FBCommon.GetRecordMapID(curPlayer.GetMapID())
@@ -294,6 +297,9 @@
     # 非客户端刷新的视为重新开始,重置刷新次数 
     else:
         gameFB.SetPlayerGameFBDict(playerID, ChConfig.FBPD_HelpBattleRefreshCount, 0)
+        gameFB.SetGameFBDict(ChConfig.FBPD_HelpBattleFBFightPower, ipyData.GetFightPowerMin())
+        gameFB.SetGameFBDict(ChConfig.FBPD_HelpBattleFBBaseHurt, ipyData.GetRobotBaseHurt())
+        GameWorld.DebugLog("设置副本战力=%s,保底伤害=%s" % (ipyData.GetFightPowerMin(), ipyData.GetRobotBaseHurt()))
         
     msgInfo = str(["Refresh", mapID, funcLineID, isClientRefresh, costMoneyList, calledPlayerIDDict])
     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "FBHelpBattle", msgInfo, len(msgInfo))
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_QueenRelics.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_QueenRelics.py
index d816e94..48022cf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_QueenRelics.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_QueenRelics.py
@@ -376,6 +376,10 @@
     FBCommon.NotifyFBHelp(curPlayer, lineID, fbHelpDict)
     return
 
+def DoFB_Npc_KillNPC(attacker, curNPC, tick):
+    __FBNPCOnKilled(curNPC, tick)
+    return
+
 ##玩家杀死NPC
 # @param curPlayer:玩家实例
 # @param curNPC:当前被杀死的NPC
@@ -383,6 +387,10 @@
 # @return 返回值无意义
 # @remarks 玩家主动离开副本.
 def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
+    __FBNPCOnKilled(curNPC, tick)
+    return
+
+def __FBNPCOnKilled(curNPC, tick):
     curNPCID = curNPC.GetNPCID()
     gameFB = GameWorld.GetGameFB()
     killNPCCount = gameFB.GetGameFBDictByKey(FBKey_KillNPCCount % curNPCID) + 1
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_20.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_20.py
index 546881c..35b6323 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_20.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_20.py
@@ -22,6 +22,11 @@
 import ChConfig
 import GameWorld
 import GameObj
+import BaseAttack
+import FBCommon
+import AICommon
+
+import random
 
 
 ## 初始化
@@ -38,8 +43,76 @@
 #  @return None
 #  @remarks 函数详细说明.
 def ProcessAI(curNPC, tick):
-    npcControl = NPCCommon.NPCControl(curNPC)
+    curHP = GameObj.GetHP(curNPC)
+    protectHP = GameObj.GetMaxHP(curNPC) / 2 # 保证血量不低于一半
+    if curHP <= protectHP:
+        GameObj.SetHP(curNPC, curHP + random.randint(protectHP / 3, protectHP))
+        GameWorld.DebugLog("机器人回血!objID=%s" % curNPC.GetID())
+        
+    fbPlayer = FBCommon.GetCurSingleFBPlayer()
+    if not fbPlayer:
+        # 副本中没有玩家则不处理
+        GameWorld.DebugLog("副本中没有玩家则不处理!objID=%s" % curNPC.GetID())
+        return
     
+    curTag = None
+    playerAtkObjID = fbPlayer.GetDictByKey(ChConfig.Def_PlayerKey_LastHurtNPCObjID)
+    if playerAtkObjID:
+        curTag = GameWorld.FindNPCByID(playerAtkObjID)
+        
+    npcControl = NPCCommon.NPCControl(curNPC)
+    # 没有玩家正在攻击的目标则取自身的仇恨列表
+    if not curTag:
+        #GameWorld.DebugLog("没有玩家正在攻击的目标,刷新自身仇恨目标!objID=%s,maxHP=%s" % (curNPC.GetID(), GameObj.GetMaxHP(curNPC)))
+        npcControl.RefreshAngryList(tick)
+        curNPCAngry = npcControl.GetMaxAngryTag()
+        if curNPCAngry:
+            curNPCAngryType = curNPCAngry.GetObjType()
+            curNPCAngryID = curNPCAngry.GetObjID()
+            curTag = GameWorld.GetObj(curNPCAngryID, curNPCAngryType)
+            
+    # 没有攻击目标则跟随玩家
+    if not curTag:
+        GameWorld.DebugLog("没有攻击目标,跟随玩家!objID=%s" % curNPC.GetID())
+        dist = GameWorld.GetDist(fbPlayer.GetPosX(), fbPlayer.GetPosY(), curNPC.GetPosX(), curNPC.GetPosY())
+        if dist > 12:
+            posX, posY = npcControl.GetMoveNearPos(fbPlayer.GetPosX(), fbPlayer.GetPosY(), 3)
+            curHP.ResetPos(posX, posY)
+        elif dist > 5:
+            npcControl.MoveToObj_Detel(fbPlayer, 5)
+        return
+    __NPCFight(npcControl, curNPC, curTag, tick)
+    return
+
+def __NPCFight(npcControl, curNPC, curTag, tick):
+    #设置进入战斗状态
+    NPCCommon.SetNPCInBattleState(curNPC)
+    #开始攻击
+    if curTag == None or GameObj.GetHP(curTag) <= 0:
+        return
+    tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())
+    GameWorld.DebugLog("    与目标距离: %s" % tagDist)
+    if tagDist > 12:
+        posX, posY = npcControl.GetMoveNearPos(curTag.GetPosX(), curTag.GetPosY(), 3)
+        curNPC.ResetPos(posX, posY)
+        tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())
+        
+    #---优先释放技能---
+    if AICommon.DoAutoUseSkill(curNPC, curTag, tagDist, tick):
+        return
+    #---释放普通攻击---
+    #超过攻击距离,移动过去
+    if tagDist > curNPC.GetAtkDist():
+        npcControl.MoveToObj_Detel(curTag)
+        return
+    if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():
+        #攻击间隔没有到, 返回
+        return
+    if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()):
+        #修正这个NPC的站立位置
+        return
+    #普通攻击
+    BaseAttack.Attack(curNPC, curTag, None, tick)
     return
 
 def OnCheckCanDie(atkObj, curNPC, skill, tick):
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 d38537a..0e6c4f0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -3654,7 +3654,10 @@
     #  @remarks 刷新NPC属性
     def RefreshNPCAttrState(self, canSyncClient=True, isReborn=False):
         curNPC = self.__Instance
-        curNPCMaxHP_Before = GameObj.GetMaxHP(curNPC)
+        if curNPC.GetType() == ChConfig.ntHelpBattleRobot:
+            # 助战机器人不处理
+            return
+        #curNPCMaxHP_Before = GameObj.GetMaxHP(curNPC)
         #清空NPC战斗属性
         curNPC.ClearBattleEffect()
         #--------------------------------------------
@@ -3691,6 +3694,28 @@
             
         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(baseHurt * fightPower / fbFightPower * hpCoefficient)
+        GameWorld.DebugLog("设置助战机器人属性: objID=%s,fightPower=%s,maxHP=%s" % (curNPC.GetID(), fightPower, maxHP))
+        GameObj.SetMaxHP(curNPC, maxHP)
+        GameObj.SetHP(curNPC, maxHP)
+        curNPC.Notify_HPEx()
+        curNPC.Notify_MaxHPEx()
+        return
     
     # NPC移动速度特殊处理,只处理百分比不能处理固定值 
     # 因为 ChConfig.TYPE_Calc_AttrSpeed 非服务端移动速度,偷懒处理法
@@ -3715,7 +3740,9 @@
     #  @remarks 刷新NPC行为属性
     def RefreshNPCActionState(self):
         curNPC = self.__Instance
-        
+        if curNPC.GetType() == ChConfig.ntHelpBattleRobot:
+            # 助战机器人不处理
+            return
         OperControlManager.ClearObjActionState(curNPC)
         
         #根据BUFF 加上状态

--
Gitblit v1.8.0