hxp
2019-04-27 835c5fad7ad4e723c34be7f5fc073eeb7104e3f4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -288,6 +288,8 @@
    #if FBLogic.DoFBOnKill_Player_ValuePrize(curPlayer, defender, tick):
    __GiveKill_Player_ValuePrize(curPlayer, defender, tick)
    
    NPCCommon.OnPlayerKillNPCPlayer(curPlayer, defender, tick)
    #执行副本杀人逻辑
    if FBLogic.DoFBOnKill_Player(curPlayer, defender, tick):
        return
@@ -1262,7 +1264,7 @@
# Def_HurtType_SuperHit, 
# Def_HurtType_Miss, 
# ) = range(0, 3)
# #类型: 0-普通 1-致命一击 2-躲闪
# #类型: 0-普通 1-暴击 2-躲闪
#===============================================================================
## 伤害结构体类
@@ -1291,7 +1293,10 @@
def IsHappenStateByType(happenState, cmpType):
    return happenState & cmpType
def CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState):
# 表现形式 致命一击>(重击>暴击)>会心>格挡>境界压制
# 重击定义:当触发重击时,则增加双倍暴击固定值伤害(重击与暴击互斥,优先判断重击,当重击触发时,暴击不触发)
def CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState, curSkill):
    ''' 获取伤害类型结果 
    支持多种伤害类型同时触发, 飘字表现以最终表现伤害类型为主
    @return: 最终表现伤害类型, {伤害类型:[是否触发, 伤害计算值, 触发时防守方的伤害减免值], ...}
@@ -1303,11 +1308,15 @@
                          ChConfig.Def_HurtType_SuperHit:[False, 0, 0],
                          ChConfig.Def_HurtType_Parry:[False, 0, 0],
                          ChConfig.Def_HurtType_Zhuxian:[False, 0, 0],
                          ChConfig.Def_HurtType_DeadlyHit:[False, 0, 0],
                          ChConfig.Def_HurtType_ThumpHit:[False, 0, 0],
                          }
    
    calcTypeList =  []
    if atkObjType == IPY_GameWorld.gotPlayer:
        calcTypeList += [ChConfig.Def_HurtType_LuckyHit, ChConfig.Def_HurtType_SuperHit, ChConfig.Def_HurtType_Zhuxian]
        calcTypeList += [ChConfig.Def_HurtType_LuckyHit, ChConfig.Def_HurtType_SuperHit,
                         ChConfig.Def_HurtType_Zhuxian, ChConfig.Def_HurtType_DeadlyHit,
                         ChConfig.Def_HurtType_ThumpHit]
    if defObjType == IPY_GameWorld.gotPlayer:
        calcTypeList += [ChConfig.Def_HurtType_Parry]
    # 暂时只计算玩家
@@ -1317,10 +1326,12 @@
    # 优先级列表, 互斥列表
    priorityList, mutexList = ReadChConfig.GetEvalChConfig("CalcHurtTypeInfo")
    happenFunc = {
                  ChConfig.Def_HurtType_LuckyHit:lambda aObj, dObj, hState:__HurtTypeHappen_LuckyHit(aObj, dObj, hState),
                  ChConfig.Def_HurtType_SuperHit:lambda aObj, dObj, hState:__HurtTypeHappen_SuperHit(aObj, dObj, hState),
                  ChConfig.Def_HurtType_Parry:lambda aObj, dObj, hState:__HurtTypeHappen_Parry(aObj, dObj, hState),
                  #ChConfig.Def_HurtType_Zhuxian:lambda aObj, dObj, hState:__HurtTypeHappen_Zhuxian(aObj, dObj, hState),
                  ChConfig.Def_HurtType_LuckyHit:__HurtTypeHappen_LuckyHit,
                  ChConfig.Def_HurtType_SuperHit:__HurtTypeHappen_SuperHit,
                  ChConfig.Def_HurtType_Parry:__HurtTypeHappen_Parry,
                  #ChConfig.Def_HurtType_Zhuxian:__HurtTypeHappen_Zhuxian,
                  ChConfig.Def_HurtType_DeadlyHit:__HurtTypeHappen_Deadly,
                  ChConfig.Def_HurtType_ThumpHit:__HurtTypeHappen_ThumpHit,
                  }
    
    hadCheckList = [] # 已经处理过的伤害类型列表
@@ -1337,7 +1348,7 @@
            if curMHHappen:
                # 只要其中一个已触发的则后面的均为默认不触发
                continue
            result = happenFunc[hType](atkObj, defObj, happenState)
            result = happenFunc[hType](atkObj, defObj, happenState, curSkill)
            if result: # 如果触发,更新相关数值
                hurtTypeResultDict[hType] = result
                curMHHappen = True
@@ -1348,7 +1359,7 @@
            continue
        if hType not in hadCheckList:
            hadCheckList.append(hType)
            result = happenFunc[hType](atkObj, defObj, happenState)
            result = happenFunc[hType](atkObj, defObj, happenState, curSkill)
            if result: # 如果触发,更新相关数值
                hurtTypeResultDict[hType] = result
                
@@ -1359,12 +1370,12 @@
    return hurtType, hurtTypeResultDict
def __HurtTypeHappen_LuckyHit(atkObj, defObj, happenState):
    ''' 判断伤害类型是否发生 - 幸运一击
    @return: 是否触发, 触发时伤害计算值, 触发时防守方的伤害减免值
def __HurtTypeHappen_LuckyHit(atkObj, defObj, happenState, curSkill):
    ''' 判断伤害类型是否发生 - 会心一击
    @return: 是否触发, 触发时伤害计算固定值, 触发时防守方的伤害减免固定值
    '''
    if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_LuckyHit):
        return True, atkObj.GetLuckyHitVal(), PlayerControl.GetLuckyHitReducePer(defObj)
        return True, atkObj.GetLuckyHitVal(), PlayerControl.GetLuckyHitReduce(defObj)
    
    aLuckyHitRate = atkObj.GetLuckyHitRate()
    dLuckyHitRateReduce = PlayerControl.GetLuckyHitRateReduce(defObj)
@@ -1374,16 +1385,16 @@
    if atkLuckyHitRate <= 0:
        return
    if GameWorld.CanHappen(atkLuckyHitRate):
        return True, atkObj.GetLuckyHitVal(), PlayerControl.GetLuckyHitReducePer(defObj)
        return True, atkObj.GetLuckyHitVal(), PlayerControl.GetLuckyHitReduce(defObj)
    return
def __HurtTypeHappen_SuperHit(atkObj, defObj, happenState):
def __HurtTypeHappen_SuperHit(atkObj, defObj, happenState, curSkill):
    ''' 判断伤害类型是否发生 - 暴击
    @return: 是否触发, 触发时伤害计算值, 触发时防守方的伤害减免值
    @return: 是否触发, 触发时伤害计算固定值, 触发时防守方的伤害减免固定值
    '''
    
    if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_SuperHit):
        return True, atkObj.GetSuperHit(), PlayerControl.GetSuperHitReducePer(defObj)
        return True, atkObj.GetSuperHit(), PlayerControl.GetSuperHitReduce(defObj)
    
    aSuperHitRate = atkObj.GetSuperHitRate()
    dSuperHitRateReduce = PlayerControl.GetSuperHitRateReduce(defObj)
@@ -1393,10 +1404,10 @@
    if superHitRate <= 0:
        return
    if GameWorld.CanHappen(superHitRate):
        return True, atkObj.GetSuperHit(), PlayerControl.GetSuperHitReducePer(defObj)
        return True, atkObj.GetSuperHit(), PlayerControl.GetSuperHitReduce(defObj)
    return
def __HurtTypeHappen_Parry(atkObj, defObj, happenState):
def __HurtTypeHappen_Parry(atkObj, defObj, happenState, curSkill):
    ''' 判断伤害类型是否发生 - 防守方抵御
    @return: 是否触发, 触发时伤害计算值, 触发时防守方的伤害减免值
    '''
@@ -1407,7 +1418,7 @@
        return True, 0, chanceDefPer
    return
#def __HurtTypeHappen_Zhuxian(atkObj, defObj, happenState):
#def __HurtTypeHappen_Zhuxian(atkObj, defObj, happenState, curSkill):
#    """诛仙一击"""
#    rate = PlayerControl.GetZhuXianRate(atkObj)
#    if not rate:
@@ -1416,6 +1427,29 @@
#    if GameWorld.CanHappen(rate):
#        return True, PlayerControl.GetZhuXianHurtPer(atkObj), 0
#    return
# 致命一击
def __HurtTypeHappen_Deadly(atkObj, defObj, happenState, curSkill):
    if PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, None, ChConfig.TriggerType_IsDealy):
        return True, 0, 0
    return
#重击定义:当触发重击时,则增加双倍暴击固定值伤害(重击与暴击互斥,优先判断重击,当重击触发时,暴击不触发)
def __HurtTypeHappen_ThumpHit(atkObj, defObj, happenState, curSkill):
    if IsHappenStateByType(happenState, ChConfig.Def_Skill_HappenState_ThumpHit):
        return True, atkObj.GetSuperHit()*2, PlayerControl.GetSuperHitReduce(defObj)
    thumpHitRate = 0
    thumpHitRate += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill,
                                                                       ChConfig.TriggerType_AddThumpHitRate)
    thumpHitRate += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill,
                                                                       ChConfig.TriggerType_AddThumpHitRate)
    if thumpHitRate <= 0:
        return
    if GameWorld.CanHappen(thumpHitRate):
        return True, atkObj.GetSuperHit()*2, PlayerControl.GetSuperHitReduce(defObj)
    return
def ChangeSkillHurtPer(atkObj, defObj, curSkill, skillPer):
@@ -1590,6 +1624,36 @@
    PassiveBuffEffMng.OnPassiveSkillTrigger(defObj, atkObj, None, ChConfig.TriggerType_ProDefValue, tick)
    return hurtValue - absortValue
# 设置玩家一次主动型攻击中的第一个防御者
def SetFirstDefender(attacker, defObj, curSkill):
    if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
        return
    if curSkill and curSkill.GetFuncType() not in [ChConfig.Def_SkillFuncType_FbSkill,
                                          ChConfig.Def_SkillFuncType_NormalAttack]:
        return
    if attacker.GetDictByKey(ChConfig.Def_PlayerKey_FirstDefender):
        return
    attacker.SetDict(ChConfig.Def_PlayerKey_FirstDefender, defObj.GetID())
    return
# 清除第一目标
def ClearFirstDefender(attacker):
    if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
        return
    attacker.SetDict(ChConfig.Def_PlayerKey_FirstDefender, 0)
    return
def GetFirstDefenderID(attacker):
    return attacker.GetDictByKey(ChConfig.Def_PlayerKey_FirstDefender)
## 计算伤血值
#  @param atkObj 攻击者
#  @param defObj 防御者
@@ -1603,6 +1667,9 @@
#  @remarks 函数详细说明.
def GetHurtHP(attacker, defObj, curSkill, atkSkillValue, atkSkillPer, tick):
    atkObj = ElfChangeAttacker(attacker)  # Elf灵为替身攻击,要取玩家的属性
    #设置第一个防御者
    SetFirstDefender(atkObj, defObj, curSkill)
    
    resultHurtType = HurtType()
    atkObjType = attacker.GetGameObjType()
@@ -1713,6 +1780,9 @@
        elif defObj.GetType() == ChConfig.ntHelpBattleRobot:
            remainHP = min(dHP, max(GameObj.GetMaxHP(defObj)/2, remainHP)) # 助战机器人剩余血量不能少于一半
            GameObj.SetHP(defObj, remainHP)
        elif defObj.GetType() == ChConfig.ntMonsterTime:
            UpdateTimeMonsterHP(defObj, tick)
            
        else:
            #防守方是怪物NPC,只扣其血
@@ -1734,15 +1804,66 @@
    
    WriteHurtLog(attacker, defObj, curSkill, resultHurtType.LostHP, resultHurtType.HurtType, "最终扣血")
    
    #攻击触发事件, 该代码应该放在DoAttack函数中处理逻辑比较清晰,也不会破坏GetHurtHP函数
    #因为DoAttack修改点比较多,暂不迁移,相关攻击事件逻辑,就往此函数中添加
    AttackEventTrigger(atkObj, defObj, curSkill, resultHurtType, tick)
    #===========================================================================
    # if atkObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
    #    GameWorld.DebugAnswer(atkObj, "--%s剩余血量 %s"%(defObj.GetID(), defObj.GetHP()))
    #===========================================================================
    
    return resultHurtType
def UpdateTimeMonsterHP(curNPC, tick):
    '''
    NPC总血量 = 单人每秒掉血量*理论击杀所需时间
         掉血值 = 单人每秒掉血量+min(当前人数, 最大人数)*附加掉血量
    '''
    npcID = curNPC.GetNPCID()
    ipyData = IpyGameDataPY.GetIpyGameData("NPCTimeLostHP", npcID)
    if not ipyData:
        return
    lastLostHPTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPTick)
    curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPTick, tick)
    if not lastLostHPTick or tick - lastLostHPTick >= 2000:
        passTick = 1000
    else:
        passTick = tick - lastLostHPTick
    if passTick <= 0:
        return
    lostHPPerSecond = ipyData.GetLostHPPerSecond()
    maxPlayerCount = ipyData.GetMaxPlayerCount()
    lostHPPerSecondEx = ipyData.GetLostHPPerSecondEx()
    effPlayerCount = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCount)
    refreshPlayerCountTick = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCountTick)
    if not refreshPlayerCountTick or tick - refreshPlayerCountTick >= 3000:
        curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCountTick, tick)
        effPlayerCount = 0
        for i in xrange(curNPC.GetInSightObjCount()):
            seeObj = curNPC.GetInSightObjByIndex(i)
            if seeObj == None :
                continue
            if not seeObj.GetVisible():
                continue
            seeObjType = seeObj.GetGameObjType()
            if seeObjType == IPY_GameWorld.gotPlayer:
                effPlayerCount += 1
                if maxPlayerCount and effPlayerCount >= maxPlayerCount:
                    effPlayerCount = maxPlayerCount
                    break
        curNPC.SetDict(ChConfig.Def_NPC_Dict_TimeLostHPPlayerCount, effPlayerCount)
        #GameWorld.DebugLog("刷新影响人数: effPlayerCount=%s" % effPlayerCount)
    if effPlayerCount > 1:
        hurtValuePerSecond = lostHPPerSecond + (effPlayerCount - 1) * lostHPPerSecondEx
    else:
        hurtValuePerSecond = lostHPPerSecond
    lostHPTotal = int(hurtValuePerSecond * passTick / 1000.0)
    remainHP = min(GameObj.GetMaxHP(curNPC), max(0, GameObj.GetHP(curNPC) - lostHPTotal))
    GameObj.SetHP(curNPC, remainHP, isByTime=True)
    #GameWorld.DebugLog("怪物按时间掉血: npcID=%s,effPlayerCount=%s,hurtValuePerSecond=%s,passTick=%s,lostHPTotal=%s"
    #                   % (npcID, effPlayerCount, hurtValuePerSecond, passTick, lostHPTotal))
    return
# 计算伤害后,因各种buff和状态的影响处理
def CalcHurtHPWithBuff(atkObj, defObj, hurtValue, curSkill, tick):
@@ -1847,7 +1968,15 @@
    atkObjType = atkObj.GetGameObjType()
    defObjType = defObj.GetGameObjType()
    aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType) # 获取境界
    if defObjType == IPY_GameWorld.gotNPC and ChConfig.IsGameBoss(defObj) and dRealmLV > aRealmLV:
        if atkObjType == IPY_GameWorld.gotPlayer:
            GameWorld.DebugLog("BossRealmHint%s-%s"%(dRealmLV, aRealmLV))
            PlayerControl.NotifyCode(atkObj, 'BossRealmHint', [dRealmLV])
        # 攻击高境界的BOSS 伤害固定为1
        return 1, ChConfig.Def_HurtType_Normal
    atkType = GetBattleType(atkObj, curSkill)
    happenState = happenState if happenState else SkillShell.GetHappenState(curSkill)
    happenState += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_HappenState)
@@ -1874,11 +2003,13 @@
    #当攻击方为NPC,防守方为玩家时,计算压制等级 及 压制战力
    if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer:
        
        if curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_RealmSuppress:
            # 境界压制技能不对高等级境界玩家产生攻击
            aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType)
            if aRealmLV <= dRealmLV:
                return 0, ChConfig.Def_HurtType_Immune   # 免疫
        #=======================================================================
        # if curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_RealmSuppress:
        #    # 境界压制技能不对高等级境界玩家产生攻击
        #    aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType)
        #    if aRealmLV <= dRealmLV:
        #        return 0, ChConfig.Def_HurtType_Immune   # 免疫
        #=======================================================================
        
        atkIsBoss = 1 if ChConfig.IsGameBoss(atkObj) else 0
        if NPCCommon.GetIsLVSuppress(atkObj):
@@ -1926,13 +2057,25 @@
            return 0, ChConfig.Def_HurtType_Miss
    
    hurtType, hurtTypeResultDict = CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState)
    hurtType, hurtTypeResultDict = CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState, curSkill)
    #GameWorld.DebugLog("GetHurtHP hurtType=%s, hurtTypeResultDict=%s" % (hurtType, hurtTypeResultDict))
    isLuckyHit, aLuckyHit, dLuckyHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_LuckyHit] # 幸运一击
    isSuperHit, aSuperHit, dSuperHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_SuperHit] # 暴击
    # 重击和暴击互斥,并且使用同一个参数
    isSuperHit, aSuperHit, dSuperHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_ThumpHit]
    if not isSuperHit:
        isSuperHit, aSuperHit, dSuperHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_SuperHit]
    else:
        # 重击加成
        thumpPer = 0
        thumpPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddThumpHitPer)
        thumpPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddThumpHitPer)
        aSuperHit = aSuperHit*(thumpPer + 10000)/10000
    dDamChanceDef = hurtTypeResultDict[ChConfig.Def_HurtType_Parry][2] # 抵御, 大于0代表触发抵御效果
    isZhuxianHit, aZhuxianHurtPer, dZhuxianReducePer = hurtTypeResultDict[ChConfig.Def_HurtType_Zhuxian] # 诛仙一击
    isDeadlyHit = hurtTypeResultDict[ChConfig.Def_HurtType_DeadlyHit][0] # 致命一击
    if PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_OneDamage):
        return 1, hurtType
    
@@ -1944,19 +2087,21 @@
    
    # 改变技能伤害
    atkSkillPer, atkSkillValue = ChangeSkillHurt(atkObj, defObj, curSkill, atkSkillPer, atkSkillValue)
    atkSkillPer = ChangeSkillHurtPer(atkObj, defObj, curSkill, atkSkillPer)
    
    # --- 新增普通攻击的数值和技能攻击的数值,根据类型各自计算
    if atkObjType == IPY_GameWorld.gotPlayer:
        if not curSkill or curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:
            atkSkillPer += float(PlayerControl.GetNormalHurtPer(atkObj))/ChConfig.Def_MaxRateValue
            atkSkillValue += PlayerControl.GetNormalHurt(atkObj)
        elif curSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_FbSkill, ChConfig.Def_SkillFuncType_FbPassiveSkill]:
            atkSkillPer += float(PlayerControl.GetFabaoHurtPer(atkObj))/ChConfig.Def_MaxRateValue
            atkSkillValue += PlayerControl.GetFabaoHurt(atkObj)
    #  atkSkillPer 包含普攻,所以不是用技能增强处理
    atkSkillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddSkillPer)
    
    atkSkillPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddSkillPer)
    aIceAtkSuperHit = 1 # 元素真伤倍值,暂时默认为1,之后扩展
    aIceAtkSuperHit += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddIceAtkPer)
    aIceAtkSuperHit += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddIceAtkPer)
    
    if isSuperHit:
        addASuperHit = PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitValue)
@@ -1971,7 +2116,7 @@
    if isLuckyHit:
        # 会心一击时增加会心伤害百分比
        # 会心一击时增加会心伤害固定值
        aLuckyHit += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_LuckyHit)
        aLuckyHit -= PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_BeLuckyHitSubPer)
        aLuckyHit = max(aLuckyHit, 0)
@@ -1997,10 +2142,12 @@
    if atkObjType == IPY_GameWorld.gotPlayer:
        aIgnoreDefRate = atkObj.GetIgnoreDefRate()  # 无视防御比率
        aSkillAtkRate = atkObj.GetSkillAtkRate()    # 技能攻击力加成
        aDamagePer = PlayerControl.GetDamagePer(atkObj)     # 外层伤害加成
        aDamagePVP = PlayerControl.GetDamagePVP(atkObj)     # PVP固定伤害
        aDamagePVE = PlayerControl.GetDamagePVE(atkObj)     # PVE固定伤害
        # 被动技能增加伤害
        aDamagePer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddDamagePer)
        aDamagePer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddDamagePer)
        #aDamagePVP += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddDamagePer)
        #aDamagePVP += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddDamagePer)
        
        aNPCHurtAddPer = PlayerControl.GetNPCHurtAddPer(atkObj)     # PVE伤害加成
        aDamagePerPVP = PlayerControl.GetDamagePerPVP(atkObj)     # 外层PVP伤害加成
@@ -2015,6 +2162,8 @@
        aOnlyFinalHurt = PlayerControl.GetOnlyFinalHurt(atkObj) # 额外固定伤害
        aFightPower = atkObj.GetFightPower()
        
    else:
        aIgnoreDefRate = 0  # 无视防御比率
        aFinalHurtPer = GameObj.GetPetDamPer(atkObj) # 最外层伤害加成, 可能为负值
@@ -2023,8 +2172,9 @@
            aSkillAtkRate += atkObj.GetSkillAtkRate()
            
        aNPCHurtAddPer = 0  # PVE伤害加成
        aDamagePer = 0      # 外层伤害加成
        aDamagePerPVP = 0   # 外层PVP伤害加成
        aDamagePVP = 0      # PVP固定伤害
        aDamagePVE = 0      # PVE固定伤害
        aFinalHurt = NPCCommon.GetFinalHurt(atkObj) # 最终固定伤害
        aFightPower = NPCCommon.GetSuppressFightPower(atkObj)
        
@@ -2032,25 +2182,29 @@
    if defObjType == IPY_GameWorld.gotPlayer:
        dIgnoreDefRateReduce = PlayerControl.GetIgnoreDefRateReduce(defObj)  # 无视防御比率抗性
        dSkillAtkRateReduce = PlayerControl.GetSkillAtkRateReduce(defObj) # 技能攻击力减少
        dDamReduce = defObj.GetDamageReduceRate() # 外层减伤
        dDamReduce += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_DamageReduce)
        dDamagePVPReduce = PlayerControl.GetDamagePVPReduce(defObj) # PVP固定减伤
        #dDamReduce += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_DamageReduce)
        dDamagePerPVPReduce = PlayerControl.GetDamagePerPVPReduce(defObj) # 外层PVP减伤
        dDamagePerPVPReduce += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_DamageReducePVP)
        dFinalHurtReduce = PlayerControl.GetFinalHurtReduce(defObj) # 最终固定伤害减少
        dBeHurtPer = PlayerControl.GetBeHurtPer(defObj)      # 加深受到伤害百分比
        dFightPower = defObj.GetFightPower()
        dFinalHurtReducePer = PlayerControl.GetFinalHurtReducePer(defObj)
        dFinalHurtReducePer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_dFinalHurtReducePer)
    else:
        dIgnoreDefRateReduce = 0    # 无视防御比率抗性
        dSkillAtkRateReduce = 0     # 技能攻击力减少
        dDamReduce = 0              # 外层减伤
        dDamagePVPReduce = 0        # PVP固定减伤
        dDamagePerPVPReduce = 0     # 外层PVP减伤
        dFinalHurtReduce = 0        # 最终固定伤害减少
        dBeHurtPer = 0
        dFightPower = NPCCommon.GetSuppressFightPower(defObj)
        dFinalHurtReducePer = 0             # 最终伤害减少百分比 默认0
        
    #攻击字典 { 攻击类型 : '公式' }
    hurtDist = ReadChConfig.GetEvalChConfig('CalcAttackValue')
    if suppressLV:
        suppressFormulaKeyLV = "SuppressValueLV_%s" % (atkIsBoss)
        if suppressFormulaKeyLV in hurtDist:
@@ -2063,59 +2217,20 @@
            suppressFPFormula = hurtDist[suppressFormulaKeyFP]
            suppressValueFP = eval(FormulaControl.GetCompileFormula(suppressFormulaKeyFP, suppressFPFormula))
    
    # 境界压制百分比
    SuppressValueRealmRate = 10000 # 默认值
    suppressRealm = 0
    if atkObjType == IPY_GameWorld.gotPlayer and defObjType == IPY_GameWorld.gotPlayer:
        RealmGroupList = IpyGameDataPY.GetFuncEvalCfg("RealmGroup", 1)
        aRealmLV, dRealmLV = atkObj.GetOfficialRank(), defObj.GetOfficialRank()
        aRealmGroup, dRealmGroup = 0, 0
        for g, gMaxRealmLV in enumerate(RealmGroupList, 1):
            if aRealmLV and aRealmLV <= gMaxRealmLV and not aRealmGroup:
                aRealmGroup = g
            if dRealmLV and dRealmLV <= gMaxRealmLV and not dRealmGroup:
                dRealmGroup = g
        suppressRealm = aRealmGroup - dRealmGroup
        suppressFormulaKeyRealm = "PVPSuppressValueRealm"
        if suppressFormulaKeyRealm in hurtDist:
            SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula(suppressFormulaKeyRealm, hurtDist[suppressFormulaKeyRealm])))
        #GameWorld.DebugLog("境界压制:aRealmLV=%s,dRealmLV=%s,aRealmGroup=%s,dRealmGroup=%s,SuppressValueRealmRate=%s"
        #                   % (aRealmLV, dRealmLV, aRealmGroup, dRealmGroup, SuppressValueRealmRate))
    elif atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer:
        # EVP 境界压制
        aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType)
        if aRealmLV + dRealmLV != 0:
            #有压制
            suppressRealm = aRealmLV - dRealmLV # 存在负数
            suppressRealmHurtPer = GetRealmHurtPer(aRealmLV, dRealmLV, 2) # 境界压制加成百分比,存在负数
            suppressFormulaKeyRealm = "EVPSuppressValueRealm"
            if suppressFormulaKeyRealm in hurtDist:
                SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula(suppressFormulaKeyRealm, hurtDist[suppressFormulaKeyRealm])))
    elif atkObjType == IPY_GameWorld.gotPlayer and defObjType == IPY_GameWorld.gotNPC:
        # PVE 境界压制
        aRealmLV, dRealmLV = GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType)
        if aRealmLV + dRealmLV != 0:
            #有压制
            suppressRealm = aRealmLV - dRealmLV # 存在负数
            suppressRealmHurtPer = GetRealmHurtPer(aRealmLV, dRealmLV, 3) # 境界压制加成百分比,存在负数
            suppressFormulaKeyRealm = "PVESuppressValueRealm"
            if suppressFormulaKeyRealm in hurtDist:
                SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula(suppressFormulaKeyRealm, hurtDist[suppressFormulaKeyRealm])))
    # 境界压制规则
    # 1. 其中一方无境界等级则无效, 如普通NPC
    # 2. 宠物和召唤兽(如水元素)有效, 取主人
    # 3. 玩家地境界低于BOSS则伤害固定为1 (在函数入口处已处理)
    # 4. 其他情况统一境界压制 境界差*2%
    if aRealmLV == 0 or dRealmLV == 0:
        SuppressValueRealmRate = 10000
    else:
        SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula("SuppressValueRealm", hurtDist["SuppressValueRealm"])))
        
        
    # 骑宠争夺最终伤害衰减           
    if defObjType == IPY_GameWorld.gotNPC and FamilyRobBoss.IsHorsePetRobBoss(defObj.GetNPCID()):
        ownerPlayer = None
        # 召唤兽和宠物需要从人物获取状态
        if atkObj.GetGameObjType() == IPY_GameWorld.gotNPC:
            if atkObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:
                ownerPlayer = PetControl.GetPetOwner(atkObj)
            elif atkObj.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:
                ownerPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, atkObj)
        else:
            ownerPlayer = atkObj
        ownerPlayer, npcObjType = GetAttackPlayer(atkObj)
            
        if ownerPlayer:
            findBuff = SkillCommon.FindBuffByID(ownerPlayer, ChConfig.Def_SkillID_HorsePetRobBossKillCntBuff)[0]
@@ -2180,14 +2295,20 @@
# 获取双方境界值
def GetPVERealmLVs(atkObj, defObj, atkObjType, defObjType):
    if atkObjType == IPY_GameWorld.gotNPC:
        aRealmLV = NPCCommon.GetRealmLV(atkObj)
        if aRealmLV == 0:
            # 0代表不要压制
            return 0, 0
        ownerPlayer, npcObjType = GetAttackPlayer(atkObj)
        if ownerPlayer:
            # 召唤兽和宠物取主人境界,可以是攻击方需提取
            aRealmLV = ownerPlayer.GetOfficialRank()
        else:
            aRealmLV = NPCCommon.GetRealmLV(atkObj)
            if aRealmLV == 0:
                # 0代表不要压制
                return 0, 0
    else:
        aRealmLV = atkObj.GetOfficialRank()
        
    if defObjType == IPY_GameWorld.gotNPC:
        # 召唤兽和宠物取主人境界,但是宠物和人物召唤兽不可被攻击,故不需要
        dRealmLV = NPCCommon.GetRealmLV(defObj)
        if dRealmLV == 0:
            # 0代表不要压制
@@ -2363,7 +2484,7 @@
        #PVP 攻击回血
        atkBackHP += PlayerControl.GetPVPAtkBackHP(atkObj)
        # 百分比吸血
        atkBackHPPer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, None, ChConfig.TriggerType_Buff_SuckBloodPer)
        atkBackHPPer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_Buff_SuckBloodPer)
        atkBackHPPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_Buff_SuckBloodPer)
        
        atkBackHP += int(hurtValue * atkBackHPPer*1.0 / ChConfig.Def_MaxRateValue)
@@ -2514,6 +2635,7 @@
        1    全体模式    IPY_GameWorld.amAll              对所有玩家都是敌对,家族区域同盟玩家除外  
        2    防卫模式    IPY_GameWorld.amCountry          本服玩家友好,他服玩家都是敌对
        5    强制模式    IPY_GameWorld.amFamily           队友、仙盟成员、同阵营友好,其他玩家敌对
        7    锁定单一目标模式 IPY_GameWorld.amContest       只对选中目标有伤害, 目前只用于部分BOSS争夺地图
        
    场景区域
        普通区域    IPY_GameWorld.gatNormal    可根据不同PK模式PK,击杀玩家有惩罚