hxp
2018-11-25 ae8e857873ba53e55392ab06237cd7b16426d93e
4762 【后端】助战机器人AI及伤血;
6个文件已修改
149 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_QueenRelics.py 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_20.py 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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 \
@@ -1899,6 +1915,10 @@
        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
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" # 最终伤害百分比
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))
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
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):
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 加上状态