4999 【后端】【1.3.100】血量百分比不管有没被超过,哪怕一击秒杀也会强制触发,pvp强制触发

1. 持续掉血如毒不处理
2. 无敌下,不会再因为毒而掉血
3. 宠物类当主人血量达到多少触发技能,逻辑从AI拔除,直接在被攻击触发
4. 宠物AI逻辑改为3秒触发一次,AI目前只剩buff刷新,降低频率
8个文件已修改
3个文件已添加
374 ■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/ChNPC.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_105.py 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuff/PassiveSkill_2102.py 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuff/PassiveSkill_2104.py 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuff/PassiveSkill_4068.py 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuffEffMng.py 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -1627,6 +1627,19 @@
    
    remainHP = int(remainHP)    #防范
    if defObjType == IPY_GameWorld.gotPlayer:
        curHP = GameObj.GetHP(defObj)
        GameObj.SetHP(defObj, remainHP, False)
        lockHPPer = PassiveBuffEffMng.OnObjsPassiveSkillLockHP(defObj, atkObj, curSkill, ChConfig.TriggerType_LockHP, tick)
        if lockHPPer:
            # 锁血情况
            lockHP = GameObj.GetMaxHP(defObj)*lockHPPer/ChConfig.Def_MaxRateValue
            if lockHP < curHP and remainHP < lockHP:
                remainHP = lockHP
            elif lockHP >= curHP:
                remainHP = curHP
            #锁血纠正血量
        GameObj.SetHP(defObj, remainHP, False)
            
    elif defObjType == IPY_GameWorld.gotNPC:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
@@ -1809,8 +1809,13 @@
    # 暂且只有玩家被攻击触发
    if not curSkill or curSkill.GetSkillType() in ChConfig.Def_CanAttackSkill_List:
        # 优先触发,如无敌可以抵挡后续的被动伤害技能
        PassiveBuffEffMng.DelayUsePassiveTriggerSkill(curPlayer, curSkill, attacker, tick)
        PassiveBuffEffMng.OnPassiveSkillTrigger(curPlayer, attacker, None, ChConfig.TriggerType_BeAttackOver, tick)
        PassiveBuffEffMng.OnPassiveBuffTrigger(curPlayer, attacker, None, ChConfig.TriggerType_BeAttackOver, tick)
        # 由主人条件触发宠物被动技能
        PassiveBuffEffMng.OnPetPassiveSkillTrigger(curPlayer, attacker, None, ChConfig.TriggerType_BeAttackOver, tick)
    return
## NPC被攻击(当前NPC,技能,当前时间)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -2252,6 +2252,7 @@
TYPE_Map_Tick_ProcessMinute = 10                #每分钟触发事件
TYPE_Map_Tick_ProcessFiveMinute = 11            #五分钟触发事件
TYPE_Map_Tick_BossAITick = 12                   #BOSSAI间隔,此处不包含召唤兽,外层控制
TYPE_Map_Tick_PetAITick = 13                   #宠物AI间隔特殊处理
TYPE_Map_Tick_Time = [
                      1000 * 60 * 3 ,           #0 回报当前地图活跃人数(3分钟一次)
@@ -2266,7 +2267,8 @@
                      1000 * 10     ,           #9 战盟战10秒刷新排行榜
                      1000 * 60     ,           #10 每分钟触发事件
                      1000 * 60 * 5 ,           #11 五分钟触发事件
                      800,                     #12 BOSS 宠物 镖车的AI间隔
                      800,                      #12 BOSS 镖车的AI间隔
                      3000,                     #13 宠物AI特殊处理间隔
                      ]
TYPE_Map_Tick_Count = len( TYPE_Map_Tick_Time ) 
@@ -2992,6 +2994,7 @@
#---SetDict 玩家字典KEY,不存于数据库---
# key的长度不能超过29个字节
Def_PlayerKey_LockHPSkillID = "LockHPSkillID"   # 锁血功能的技能
Def_PlayerKey_GodWeaponBeforeProDef = "GWBPD"   # 神兵护盾被攻击前的值
Def_PlayerKey_curHurtValue = "curHurtValue"     # 计算中的临时伤害值,技能特殊用
Def_PlayerKey_DefenderObjID = "DefenderObjID"     # 后续触发技能需要用到的对象ID,暂用于玩家
@@ -4405,7 +4408,8 @@
TriggerType_SummonDie,   #自身召唤兽死亡触发技能 60
TriggerType_GiftReduceCD, # 天赋用的减CD 61
TriggerType_ProDefValue, # 神兵护盾值下降时 62
) = range(1, 63)
TriggerType_LockHP, # 锁血触发技能 63
) = range(1, 64)
# NPC功能类型定义
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/ChNPC.py
@@ -358,7 +358,19 @@
    for curNPC in gameTruck_List:
        ProcessNPCAI(curNPC, tick)
    
    # 宠物AI
    ProcessPetAI(gameWorld, gameNPC, tick)
# 宠物AI需求减弱特殊处理, 减少性能消耗
def ProcessPetAI(gameWorld, gameNPC, tick):
    #---处理宠物的AI---
    #未到刷新间隔
    if tick - gameWorld.GetTickByType(ChConfig.TYPE_Map_Tick_PetAITick) < \
                ChConfig.TYPE_Map_Tick_Time[ChConfig.TYPE_Map_Tick_PetAITick]:
        return
    gameWorld.SetTickByType(ChConfig.TYPE_Map_Tick_PetAITick, tick)
    gamePet_List = []
    
    for index in range(0, gameNPC.GetPetCount()):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
@@ -333,18 +333,21 @@
        useSkill = changeSkill
        #GameWorld.DebugLog("----随机技能 %s"%useSkill.GetSkillID())
      
    if PetControl.IsPet(curNPC):
        petOwner = PetControl.GetPetOwner(curNPC)
        if petOwner == None:
            GameWorld.ErrLog("宠物(%s)找不到主人"%curNPC.GetRolePet().PetID)
            return False
        #血量条件判定
        effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_HPPerLimit)
        if effect:
            if GameObj.GetHP(petOwner)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(petOwner) >= effect.GetEffectValue(0):
                return False
    #===========================================================================
    # 改成被动触发
    # if PetControl.IsPet(curNPC):
    #    petOwner = PetControl.GetPetOwner(curNPC)
    #
    #    if petOwner == None:
    #        GameWorld.ErrLog("宠物(%s)找不到主人"%curNPC.GetRolePet().PetID)
    #        return False
    #
    #    #血量条件判定
    #    effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_HPPerLimit)
    #    if effect:
    #        if GameObj.GetHP(petOwner)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(petOwner) >= effect.GetEffectValue(0):
    #            return False
    #===========================================================================
    
    skillTag = SkillShell.GetSkillAffectTag(useSkill)
    skillAim = SkillShell.GetSkillFireAim(useSkill)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_105.py
@@ -36,11 +36,13 @@
#  @return None
#  @remarks 执行AI
def ProcessAI(rolePet, tick):
    ## 执行频率, 根据人数降低---------------------------
    if tick - rolePet.GetDictByKey(Def_LastAI1ProTick) < 1500:
        return
    rolePet.SetDict(Def_LastAI1ProTick, tick)
    #-------------------------------------------------------
    #===========================================================================
    # ## 执行频率, 根据人数降低---------------------------
    # if tick - rolePet.GetDictByKey(Def_LastAI1ProTick) < 3000:
    #    return
    # rolePet.SetDict(Def_LastAI1ProTick, tick)
    # #-------------------------------------------------------
    #===========================================================================
    
    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, rolePet)
@@ -58,24 +60,26 @@
        posX, posY = petControl.GetMoveNearPos(curPlayer.GetPosX(), curPlayer.GetPosY(), 1)
        rolePet.ResetPos(posX, posY)
    
    skillManager = rolePet.GetSkillManager()
    for index in range(0, skillManager.GetSkillCount()):
        useSkill = skillManager.GetSkillByIndex(index)
        #已经到尾部了
        if not useSkill or useSkill.GetSkillTypeID() == 0:
            break
        if SkillCommon.isPassiveSkill(useSkill):
            #GameWorld.Log('被动技能不释放不释放 = %s'%(useSkill.GetSkillName()))
            continue
        effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_HPPerLimit)
        if not effect:
            continue
        if GameObj.GetHP(curPlayer)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(curPlayer) >= effect.GetEffectValue(0):
            continue
        AICommon.DoNPCUseSkill(rolePet, curPlayer, useSkill, 0, tick)
    #===========================================================================
    # skillManager = rolePet.GetSkillManager()
    # for index in range(0, skillManager.GetSkillCount()):
    #    useSkill = skillManager.GetSkillByIndex(index)
    #    #已经到尾部了
    #    if not useSkill or useSkill.GetSkillTypeID() == 0:
    #        break
    #
    #    if SkillCommon.isPassiveSkill(useSkill):
    #        #GameWorld.Log('被动技能不释放不释放 = %s'%(useSkill.GetSkillName()))
    #        continue
    #
    #    effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_HPPerLimit)
    #    if not effect:
    #        continue
    #
    #    if GameObj.GetHP(curPlayer)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(curPlayer) >= effect.GetEffectValue(0):
    #        continue
    #
    #    AICommon.DoNPCUseSkill(rolePet, curPlayer, useSkill, 0, tick)
    #===========================================================================
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -1206,6 +1206,11 @@
        GameWorld.Log('###技能伤害血量异常,数值错误 = %s,技能类型ID = %s' % (lostValue, skillTypeID))
        return
    
    if not curObj.GetCanAttack():
        # 无敌不掉血
        ## 后续有其他情况也应考虑进来,如镖车是否某状态不掉血
        return
    #lostValue = GetGoblinLostHP(curObj, lostValue)
    curObjType = curObj.GetGameObjType()
    curSkill = GameWorld.GetGameData().FindSkillByType(skillTypeID, 1)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuff/PassiveSkill_2102.py
New file
@@ -0,0 +1,34 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
# @todo: 宠物主人被攻击后触发被动技能, 血量低于XX百分比
#
# @author: Alee
# @date 2018-1-9 下午09:39:37
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
import ChConfig
import GameWorld
import GameObj
import PlayerControl
import PetControl
def CheckCanHappen(attacker, defender, effect, curSkill):
    # 未配置不验证血量百分比
    if not effect.GetEffectValue(0):
        return False
    petOwner = PetControl.GetPetOwner(attacker)
    if petOwner == None:
        return False
    #血量条件判定
    if GameObj.GetHP(petOwner)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(petOwner) >= effect.GetEffectValue(0):
        return False
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuff/PassiveSkill_2104.py
New file
@@ -0,0 +1,34 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
# @todo: 宠物主人被攻击后触发被动技能, 血量低于XX百分比,有锁血功能
#
# @author: Alee
# @date 2018-1-9 下午09:39:37
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
import ChConfig
import GameWorld
import GameObj
import PlayerControl
import PetControl
def CheckCanHappen(attacker, defender, effect, curSkill):
    # 未配置不验证血量百分比
    if not effect.GetEffectValue(0):
        return False
    petOwner = PetControl.GetPetOwner(attacker)
    if petOwner == None:
        return False
    #血量条件判定
    if GameObj.GetHP(petOwner)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(petOwner) >= effect.GetEffectValue(0):
        return False
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuff/PassiveSkill_4068.py
New file
@@ -0,0 +1,31 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package
#
# @todo: 锁血技能
#
# @author: Alee
# @date 2018-12-4 下午02:24:09
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
import ChConfig
import GameWorld
import GameObj
def CheckCanHappen(attacker, defender, effect, curSkill):
    # 未配置不验证血量百分比
    if not effect.GetEffectValue(0):
        return False
    if GameObj.GetHP(attacker)*ChConfig.Def_MaxRateValue/GameObj.GetMaxHP(attacker) >= effect.GetEffectValue(0):
        return False
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveBuffEffMng.py
@@ -276,6 +276,9 @@
def GetTriggerTypeByEffectID(effectID):
    # 临时配置
    tdict = {
             2102:ChConfig.TriggerType_BeAttackOver,   # 被攻击后触发 20
             2104:ChConfig.TriggerType_LockHP, # 锁血触发技能 63
             4000:ChConfig.TriggerType_BuffState,   # 进入4012的某个状态触发技能 2
             4001:ChConfig.TriggerType_TagBuffState,   # 目标进入4012的某个状态触发技能 2
             4002:ChConfig.TriggerType_AddDamagePer,   # 提高增加伤害属性值,计算时 3
@@ -343,6 +346,7 @@
             4065:ChConfig.TriggerType_DamageReducePVP,   # PVP减少伤害
             4066:ChConfig.TriggerType_AddDamagePer,   # 提高增加伤害属性值,计算时 3
             4067:ChConfig.TriggerType_ProDefValue, # 神兵护盾值下降时 62
             4068:ChConfig.TriggerType_LockHP, # 锁血触发技能 63
             }
    return tdict.get(effectID, -1) 
    #===========================================================================
@@ -773,6 +777,155 @@
    return GameWorld.GetObj(curHurt.GetObjID(), curHurt.GetObjType())
        
# 多种被动技能优先触发释放一个,如被动 血量40%触发无敌技能,血量一定是停留在40%
# 先锁血,后触发技能 同 DelayUsePassiveTriggerSkill 使用
def OnPassiveSkillLockHP(attacker, defender, connSkill, triggerType, tick, isEnhanceSkill=False):
    attacker = FindRealAttacker(attacker)
    if not attacker:
        return 0, 0
    stopPassiveSkill = False   # 被动技能不能再触发被动技能,但可以触发天赋技能
    if connSkill:
        if not connSkill.GetFuncType():
            # 非功能类技能,避免死循环
            return 0, 0
        if SkillCommon.isPassiveSkill(connSkill):
            stopPassiveSkill = True
    if SkillCommon.GetUsingPassiveSkill(attacker) and triggerType != ChConfig.TriggerType_BuffState:
        # 防范被动技能触发的 非被动技能
        stopPassiveSkill = True
    passiveEff = GetPassiveEffManager().GetPassiveEff(attacker)
    if not passiveEff:
        return 0, 0
    connSkillID = connSkill.GetSkillTypeID() if connSkill else 0
    skills = passiveEff.GetPassiveSkillsByTriggerType(triggerType, connSkillID)
    if not skills:
        return 0, 0
    defender = GetPassiveDefender(attacker, defender)
    # 当前战斗关系 pvp pve
    battleRelationType = AttackCommon.GetBattleRelationType(attacker, defender)
    #GameWorld.DebugLog("OnPriorityPassiveSkillTrigger-----------%s-%s"%(skills, battleRelationType))
    lockHPPerMax = 0  ## 取有效的最高血量
    lockHPSkillID = 0
    for skillTypeID, effectID in skills:
        if connSkillID == skillTypeID:
            continue
        curSkill = attacker.GetSkillManager().FindSkillBySkillTypeID(skillTypeID)
        if not curSkill:
            continue
        if stopPassiveSkill and curSkill.GetFuncType() != ChConfig.Def_SkillFuncType_GiftSkill:
            # 只有天赋才可以再次被触发
            continue
        effect = SkillCommon.GetSkillEffectByEffectID(curSkill, effectID)
        if not effect:
            continue
        if SkillCommon.RefreshSkillRemainTime(curSkill, tick):
            continue
        skillBattleType = SkillCommon.GetSkillBattleType(curSkill)
        if not AttackCommon.CheckBattleRelationType(skillBattleType, battleRelationType):
            # PK模式的判定
            continue
        pyName = "PassiveSkill_%s" % effectID
        callFunc = GameWorld.GetExecFunc(PassiveBuff, "%s.%s" % (pyName, "CheckCanHappen"))
        if not callFunc:
            continue
        if not callFunc(attacker, defender, effect, curSkill):
            continue
        # 最终取最高值来决定当前生命值,卡血设定
        if effect.GetEffectValue(0) > lockHPPerMax:
            lockHPPerMax = effect.GetEffectValue(0)
            lockHPSkillID = skillTypeID
    return lockHPSkillID, lockHPPerMax
# 锁血功能的技能 含人物和宠物
def OnObjsPassiveSkillLockHP(attacker, defender, connSkill, triggerType, tick,):
    if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
        return 0
    lockHPSkillID, lockHPPerMax = OnPassiveSkillLockHP(attacker, defender, connSkill, triggerType, tick)
    rolePet = attacker.GetPetMgr().GetFightPet()
    if rolePet:
        lockHPSkillIDPet, lockHPPerMaxPet = OnPassiveSkillLockHP(rolePet, defender, connSkill, triggerType, tick)
        if lockHPPerMax + lockHPPerMaxPet == 0:
            # 无触发
            return 0
        # 触发宠物技能标志
        if lockHPPerMaxPet > lockHPPerMax:
            rolePet.SetDict(ChConfig.Def_PlayerKey_LockHPSkillID, lockHPSkillIDPet)
            return lockHPPerMaxPet
    if lockHPPerMax == 0:
        return 0
    # 触发人物技能标志
    attacker.SetDict(ChConfig.Def_PlayerKey_LockHPSkillID, lockHPSkillID)
    return lockHPPerMax
# 从伤血延后到技能结束触发被动技能
def DelayUsePassiveTriggerSkill(attacker, curSkill, defender, tick):
    if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
        return
    # 检查是宠物还是人物技能
    skillTypeID = attacker.GetDictByKey(ChConfig.Def_PlayerKey_LockHPSkillID)
    if not skillTypeID:
        rolePet = attacker.GetPetMgr().GetFightPet()
        if not rolePet:
            return
        skillTypeID = rolePet.GetDictByKey(ChConfig.Def_PlayerKey_LockHPSkillID)
        if not skillTypeID:
            return
        attacker = rolePet
        GameWorld.DebugLog("DelayUsePassiveTriggerSkill-----pet")
    # 一定要清标志
    attacker.SetDict(ChConfig.Def_PlayerKey_LockHPSkillID, 0)
    curSkill = attacker.GetSkillManager().FindSkillBySkillTypeID(skillTypeID)
    if not curSkill:
        return
    GameWorld.DebugLog("DelayUsePassiveTriggerSkill-----skillTypeID-%s"%skillTypeID)
    # 设置标志避免被动技能触发被动技能, 被动当中可能会触发多种类型技能,故不用isPassiveSkill做屏蔽
    SkillCommon.SetUsingPassiveSkill(attacker, 1)
    if not SkillShell.UsePassiveTriggerSkill(attacker, curSkill, defender, tick):
        # 不管技能是否是否成功都必须进入CD
        SkillCommon.SetSkillRemainTime(curSkill, PlayerControl.GetReduceSkillCDPer(attacker), tick, attacker)
    SkillCommon.SetUsingPassiveSkill(attacker, 0)
    return
# 灵宠部分技能需要通过主人触发,灵宠自己触发的逻辑依然走 OnPassiveSkillTrigger
def OnPetPassiveSkillTrigger(attacker, defender, connSkill, triggerType, tick):
    if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
        return
    rolePet = attacker.GetPetMgr().GetFightPet()
    #无出战宠物
    if rolePet == None:
        return
    OnPassiveSkillTrigger(rolePet, defender, connSkill, triggerType, tick)
# 被动技能触发释放
def OnPassiveSkillTrigger(attacker, defender, connSkill, triggerType, tick, isEnhanceSkill=False, skillIDSet=None):
    attacker = FindRealAttacker(attacker)