| | |
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import FamilyRobBoss
|
| | | #import EquipZhuXian
|
| | | import FBCommon
|
| | | import ChNPC
|
| | |
|
| | | import datetime
|
| | | import math
|
| | |
| | | #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
|
| | |
| | | if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:
|
| | | return
|
| | |
|
| | | crossNotifyList = []
|
| | | isCrossServer = GameWorld.IsCrossServer()
|
| | | atkServerGroupID = PlayerControl.GetPlayerServerGroupID(attacker)
|
| | | defServerGroupID = PlayerControl.GetPlayerServerGroupID(defender)
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | # 杀人玩家有帮会
|
| | | if attacker.GetFamilyID() > 0:
|
| | |
| | | notifyCode = 'PK_pan_318691'
|
| | | paramList = [defFamilyMemberLv, defName, defMapID, atkName,defPosX, defPosY, lineID]
|
| | |
|
| | | PlayerControl.FamilyNotify(defFamilyID, notifyCode, paramList)
|
| | |
|
| | | if isCrossServer:
|
| | | crossNotifyList.append(PlayerControl.GetCrossFamilyNotifyInfo(defFamilyID, notifyCode, paramList))
|
| | | else:
|
| | | PlayerControl.FamilyNotify(defFamilyID, notifyCode, paramList)
|
| | | |
| | | # 有职位被杀,全服广播
|
| | | if defFamilyMemberLv <= 0:
|
| | | return
|
| | | if defFamilyMemberLv > 0:
|
| | | defFamilyName = defender.GetFamilyName()
|
| | |
|
| | | defFamilyName = defender.GetFamilyName()
|
| | |
|
| | | killCnt = attacker.GetDictByKey(ChConfig.Def_PlayerKey_KillPlayerCnt % defender.GetPlayerID()) + 1
|
| | | attacker.SetDict(ChConfig.Def_PlayerKey_KillPlayerCnt % defender.GetPlayerID(), killCnt)
|
| | | #被杀重置击杀数
|
| | | defender.SetDict(ChConfig.Def_PlayerKey_KillPlayerCnt % attacker.GetPlayerID(), 0)
|
| | | |
| | | killPlayerNotifyDict = IpyGameDataPY.GetFuncEvalCfg('FamilyKilledNotify')
|
| | | |
| | | killKeys = sorted(killPlayerNotifyDict.keys())
|
| | | notifyKey = 0 |
| | | for killCntKey in killKeys:
|
| | | if killCnt < killCntKey:
|
| | | break
|
| | | notifyKey = killCntKey
|
| | | if notifyKey in killPlayerNotifyDict:
|
| | | notifyMark = killPlayerNotifyDict[notifyKey]
|
| | | PlayerControl.WorldNotify(0, notifyMark, [atkName, defMapID, defFamilyName, defFamilyMemberLv, defName])
|
| | | killCnt = attacker.GetDictByKey(ChConfig.Def_PlayerKey_KillPlayerCnt % defender.GetPlayerID()) + 1
|
| | | attacker.SetDict(ChConfig.Def_PlayerKey_KillPlayerCnt % defender.GetPlayerID(), killCnt)
|
| | | #被杀重置击杀数
|
| | | defender.SetDict(ChConfig.Def_PlayerKey_KillPlayerCnt % attacker.GetPlayerID(), 0)
|
| | | |
| | | killPlayerNotifyDict = IpyGameDataPY.GetFuncEvalCfg('FamilyKilledNotify')
|
| | | |
| | | killKeys = sorted(killPlayerNotifyDict.keys())
|
| | | notifyKey = 0 |
| | | for killCntKey in killKeys:
|
| | | if killCnt < killCntKey:
|
| | | break
|
| | | notifyKey = killCntKey
|
| | | if notifyKey in killPlayerNotifyDict:
|
| | | notifyMark = killPlayerNotifyDict[notifyKey]
|
| | | msgParamList = [atkName, defMapID, defFamilyName, defFamilyMemberLv, defName]
|
| | | if isCrossServer:
|
| | | crossNotifyList.append(PlayerControl.GetCrossWorldNotifyInfo(0, notifyMark, msgParamList))
|
| | | if atkServerGroupID != defServerGroupID:
|
| | | PlayerControl.NotifyCode(attacker, notifyMark, msgParamList)
|
| | | else:
|
| | | PlayerControl.WorldNotify(0, notifyMark, msgParamList)
|
| | | |
| | | if crossNotifyList:
|
| | | PlayerControl.CrossNotify([defServerGroupID], crossNotifyList)
|
| | |
|
| | | return
|
| | |
|
| | |
| | |
|
| | | return ChConfig.Def_BattleRelationType_PVE
|
| | |
|
| | | # 判断PK关系是否可攻击 Def_BattleRelationType_CommNoBoss也可攻击 只是攻击无效果
|
| | | def CheckBattleRelationType(skillBattleType, battleRelationType):
|
| | | if skillBattleType in [ChConfig.Def_BattleRelationType_Comm, ChConfig.Def_BattleRelationType_CommNoBoss]:
|
| | | return True
|
| | | |
| | | #if battleRelationType in [ChConfig.Def_BattleRelationType_Comm, ChConfig.Def_BattleRelationType_CommNoBoss]:
|
| | | # return True
|
| | | |
| | | if skillBattleType != battleRelationType:
|
| | | # PK模式的判定
|
| | | return False
|
| | | return True
|
| | |
|
| | | ## 获取攻击类型
|
| | | # @param attack 攻击方对象
|
| | |
| | | # Def_HurtType_SuperHit,
|
| | | # Def_HurtType_Miss,
|
| | | # ) = range(0, 3)
|
| | | # #类型: 0-普通 1-致命一击 2-躲闪
|
| | | # #类型: 0-普通 1-暴击 2-躲闪
|
| | | #===============================================================================
|
| | |
|
| | | ## 伤害结构体类
|
| | |
| | | def IsHappenStateByType(happenState, cmpType):
|
| | | return happenState & cmpType
|
| | |
|
| | | def CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState):
|
| | |
|
| | | # 表现形式 致命一击>(重击>暴击)>会心>格挡>境界压制
|
| | | # 重击定义:当触发重击时,则增加双倍暴击固定值伤害(重击与暴击互斥,优先判断重击,当重击触发时,暴击不触发)
|
| | | def CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState, curSkill):
|
| | | ''' 获取伤害类型结果
|
| | | 支持多种伤害类型同时触发, 飘字表现以最终表现伤害类型为主
|
| | | @return: 最终表现伤害类型, {伤害类型:[是否触发, 伤害计算值, 触发时防守方的伤害减免值], ...}
|
| | |
| | | ChConfig.Def_HurtType_LuckyHit:[False, 0, 0],
|
| | | 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]
|
| | | 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]
|
| | | # 暂时只计算玩家
|
| | |
| | | # 优先级列表, 互斥列表
|
| | | 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_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 = [] # 已经处理过的伤害类型列表
|
| | |
| | | for mutexHurtTypeList in mutexList:
|
| | | curMHHappen = False # 当前互斥列表是否有触发的
|
| | | for hType in mutexHurtTypeList:
|
| | | if hType not in calcTypeList:
|
| | | if hType not in calcTypeList or hType not in happenFunc:
|
| | | continue
|
| | | if hType in hadCheckList:
|
| | | continue
|
| | |
| | | if curMHHappen:
|
| | | # 只要其中一个已触发的则后面的均为默认不触发
|
| | | continue
|
| | | result = happenFunc[hType](atkObj, defObj, happenState)
|
| | | result = happenFunc[hType](atkObj, defObj, happenState, curSkill)
|
| | | if result: # 如果触发,更新相关数值
|
| | | hurtTypeResultDict[hType] = result
|
| | | curMHHappen = True
|
| | |
|
| | | # 再算优先级列表里
|
| | | for hType in priorityList:
|
| | | if hType not in calcTypeList:
|
| | | if hType not in calcTypeList or hType not in happenFunc:
|
| | | 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
|
| | |
|
| | |
| | | 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)
|
| | |
| | | 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)
|
| | |
| | | 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: 是否触发, 触发时伤害计算值, 触发时防守方的伤害减免值
|
| | | '''
|
| | |
| | | return True, 0, chanceDefPer
|
| | | return
|
| | |
|
| | | #def __HurtTypeHappen_Zhuxian(atkObj, defObj, happenState, curSkill):
|
| | | # """诛仙一击"""
|
| | | # rate = PlayerControl.GetZhuXianRate(atkObj)
|
| | | # if not rate:
|
| | | # return
|
| | | # |
| | | # 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):
|
| | | ## 改变技能伤害百分比
|
| | | |
| | | if not curSkill:
|
| | | return skillPer
|
| | | |
| | | if atkObj.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
| | | return skillPer
|
| | | |
| | | #skillTypeID = curSkill.GetSkillTypeID()
|
| | | |
| | | addPer = 0
|
| | | reducePer = 0
|
| | | #addPer += EquipZhuXian.GetZhuXianEquipSkillAddPer(atkObj.GetPlayerID(), skillTypeID)
|
| | | |
| | | if defObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
|
| | | #reducePer = EquipZhuXian.GetZhuXianEquipSkillReducePer(defObj.GetPlayerID(), skillTypeID)
|
| | | |
| | | #根据防守方职业 计算攻击方伤害加成
|
| | | if defObj.GetJob() in [ShareDefine.PlayerJob_Warrior, ShareDefine.PlayerJob_Knight]:
|
| | | addPer += PlayerControl.GetJobAHurtAddPer(atkObj)
|
| | | elif defObj.GetJob() in [ShareDefine.PlayerJob_Wizard, ShareDefine.PlayerJob_ForceUser]:
|
| | | addPer += PlayerControl.GetJobBHurtAddPer(atkObj)
|
| | | elif defObj.GetJob() in [ShareDefine.PlayerJob_Assassin, ShareDefine.PlayerJob_BowMaster]:
|
| | | addPer += PlayerControl.GetJobCHurtAddPer(atkObj)
|
| | | |
| | | #根据攻击方职业 计算防守方伤害减免
|
| | | if atkObj.GetJob() in [ShareDefine.PlayerJob_Warrior, ShareDefine.PlayerJob_Knight]:
|
| | | reducePer += PlayerControl.GetJobAAtkReducePer(defObj)
|
| | | elif atkObj.GetJob() in [ShareDefine.PlayerJob_Wizard, ShareDefine.PlayerJob_ForceUser]:
|
| | | reducePer += PlayerControl.GetJobBAtkReducePer(defObj)
|
| | | elif atkObj.GetJob() in [ShareDefine.PlayerJob_Assassin, ShareDefine.PlayerJob_BowMaster]:
|
| | | reducePer += PlayerControl.GetJobCAtkReducePer(defObj)
|
| | | |
| | | if addPer or reducePer:
|
| | | addSkillPer = (addPer - reducePer) / 10000.0
|
| | | skillPer = max(0, skillPer + addSkillPer)
|
| | | |
| | | return skillPer
|
| | |
|
| | | # 改变技能伤害(效果ID1010), 野外小怪1009替换1010伤害(2018-03-07增加精英怪)
|
| | | def ChangeSkillHurt(curPlayer, defObj, curSkill, skillPer, skillValue):
|
| | |
| | | if npcType == IPY_GameWorld.ntElf:
|
| | | # ntElf 定义为人物使用对地持续性技能,并且人物可以移动,则需要ntElf做依托物的情况
|
| | | # 那么ntElf执行人物的伤害计算和被动触发效果
|
| | | owner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, attacker)
|
| | | # 2018-11-16 Elf 支持主人为NPC
|
| | | # owner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, attacker)
|
| | | |
| | | owner = NPCCommon.GetSummonOwnerDetel(attacker)
|
| | | return attacker if not owner else owner
|
| | |
|
| | | return attacker
|
| | | |
| | | # 检查对象是否属于玩家,比如用于纯PVP验证
|
| | | def CheckIsPlayerOnwer(gameObj):
|
| | | if not gameObj:
|
| | | return False
|
| | |
|
| | | objType = gameObj.GetGameObjType()
|
| | | |
| | | if objType == IPY_GameWorld.gotPlayer:
|
| | | return True
|
| | | |
| | | objNPCType = gameObj.GetGameNPCObjType()
|
| | | if objNPCType == IPY_GameWorld.gnotNormal:
|
| | | return False
|
| | | |
| | | if objNPCType == IPY_GameWorld.gnotSummon:
|
| | | owner = NPCCommon.GetSummonOwnerDetel(gameObj)
|
| | | if not owner:
|
| | | return False
|
| | | if owner.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
| | | return False
|
| | | |
| | | return True
|
| | | |
| | | # 攻击时防守方神兵护盾的处理
|
| | | def CalcAtkProDef(atkObj, defObj, hurtValue, curSkill, tick):
|
| | | if defObj.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
| | | return hurtValue
|
| | | |
| | | if not CheckIsPlayerOnwer(atkObj):
|
| | | return hurtValue
|
| | |
|
| | | curProDef = PlayerControl.GetProDef(defObj)
|
| | | if not curProDef:
|
| | | return hurtValue
|
| | | |
| | | absortValue = min(PlayerControl.GetProDefAbsorb(defObj)*hurtValue/ChConfig.Def_MaxRateValue, curProDef)
|
| | | |
| | | PlayerControl.SetProDef(defObj, curProDef - absortValue)
|
| | | |
| | | # 被动技能触发
|
| | | defObj.SetDict(ChConfig.Def_PlayerKey_GodWeaponBeforeProDef, curProDef)
|
| | | 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 防御者
|
| | |
| | | # @param finalHurtPer 对最终计算出来的伤害影响效果(有正负,默认10000)
|
| | | # @return None or HurtType 伤害结构体类
|
| | | # @remarks 函数详细说明.
|
| | | def GetHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick):
|
| | | atkObj = ElfChangeAttacker(atkObj) # Elf灵为替身攻击,要取玩家的属性
|
| | | def GetHurtHP(attacker, defObj, curSkill, atkSkillValue, atkSkillPer, tick):
|
| | | atkObj = ElfChangeAttacker(attacker) # Elf灵为替身攻击,要取玩家的属性
|
| | | |
| | | #设置第一个防御者
|
| | | SetFirstDefender(atkObj, defObj, curSkill)
|
| | |
|
| | | resultHurtType = HurtType()
|
| | | atkObjType = attacker.GetGameObjType()
|
| | | defObjType = defObj.GetGameObjType()
|
| | | dHP = GameObj.GetHP(defObj) # 防守方当前血量
|
| | | dMaxHP = GameObj.GetMaxHP(defObj) # 防守方最大血量
|
| | |
| | | # 理论伤害一致, 多加点预算伤害避免计算误差
|
| | | #hurtValue = min(ShareDefine.Def_UpperLimit_DWord, hurtValue+10)
|
| | | #atkObj.SetDict(ChConfig.Def_PlayerKey_ClientMaxHurtValue, int(hurtValue*1.2))
|
| | | hurtValue = atkObj.GetMaxAtk()*atkSkillPer*10 + atkObj.GetSuperHit() # 加入被动计算不准确改成估算
|
| | | hurtValue = atkObj.GetMaxAtk()*atkSkillPer*40 # 加入被动计算不准确改成估算
|
| | |
|
| | | clientValue, hurtType = SkillShell.GetClientHurtByObj(defObj.GetID(), defObjType)
|
| | | if clientValue <= hurtValue:
|
| | | hurtValue = clientValue
|
| | | else:
|
| | | # 外挂最高伤害基本防范
|
| | | GameWorld.DebugAnswer(atkObj, "%s----客户端伤害 %s 服务端最高伤害 %s"%(atkObj.GetID(), [clientValue, hurtType], hurtValue))
|
| | | GameWorld.DebugLog(atkObj, "%s----客户端伤害 %s 服务端最高伤害 %s"%(atkObj.GetID(), [clientValue, hurtType], hurtValue))
|
| | | hurtValue = int(hurtValue*0.8)
|
| | | #GameWorld.DebugAnswer(atkObj, "客户端伤害 %s 服务端伤害 %s"%([defObj.GetID(), clientValue, hurtType], hurtValue))
|
| | |
|
| | | else:
|
| | | hurtValue, hurtType = CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick)
|
| | | hurtValue, hurtType = CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick, orgAtkObj=attacker)
|
| | |
|
| | | if defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShieldValue):
|
| | | # 麒麟护盾吸收伤害,将抵消的伤害存储
|
| | | absortValue = int(defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShieldValue)/float(ShareDefine.Def_MaxRateValue)*hurtValue) |
| | | hurtValue -= absortValue
|
| | | |
| | | # 吸收至指定血量比例值
|
| | | absorbHurt = defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShield)
|
| | | if absorbHurt <= defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShieldMax):
|
| | | maxValue = min(absorbHurt + absortValue, defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShieldMax))
|
| | | defObj.SetDict(ChConfig.Def_PlayerKey_AbsorbShield, maxValue) # 记录护盾吸收的伤害用于爆炸
|
| | | WriteHurtLog(attacker, defObj, curSkill, hurtValue, hurtType, "公式层")
|
| | |
|
| | | hurtValue = CalcHurtHPWithBuff(atkObj, defObj, hurtValue, curSkill, tick)
|
| | |
|
| | | # buff减少伤害百分比
|
| | | reducePer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, None, ChConfig.TriggerType_ReduceHurtHPPer)
|
| | | |
| | | # 被攻击被动技能特殊减免 受到单次伤害超过生命上限10%时候,减免50%伤害,CD10秒
|
| | | defObj.SetDict(ChConfig.Def_PlayerKey_curHurtValue, hurtValue)
|
| | | reducePer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, None, ChConfig.TriggerType_ReduceHurtHPPer)
|
| | | hurtValue = int(hurtValue*(max(ChConfig.Def_MaxRateValue - reducePer, 0))*1.0/ChConfig.Def_MaxRateValue)
|
| | |
|
| | |
|
| | | # 斩杀,濒死等情况的处理
|
| | | if PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackKill):
|
| | | # 终极斩杀新效果,必须和斩杀严格区分,会涉及到CD概率,已经触发其他技能等问题
|
| | | if PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_ZhongjiZhansha):
|
| | | # նɱ
|
| | | hurtType = ChConfig.Def_HurtType_ZhognjiZhansha
|
| | | hurtValue = GameObj.GetHP(defObj)
|
| | | #伤害结构体
|
| | | resultHurtType.HurtHP = hurtValue
|
| | | resultHurtType.HurtType = hurtType
|
| | | resultHurtType.RealHurtHP = hurtValue
|
| | | |
| | | remainHP = 0 # 剩余血量
|
| | |
|
| | | # 斩杀,濒死等情况的处理
|
| | | elif PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackKill):
|
| | | # նɱ
|
| | | hurtType = ChConfig.Def_HurtType_Zhansha
|
| | | hurtValue = GameObj.GetHP(defObj)
|
| | | #伤害结构体
|
| | | resultHurtType.HurtHP = hurtValue
|
| | |
| | |
|
| | | # 血盾
|
| | | hurtValue = CalcBloodShield(atkObj, defObj, hurtValue)
|
| | | |
| | | remainHP = min(dMaxHP, max(0, dHP - hurtValue)) # 剩余血量
|
| | |
|
| | | 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:
|
| | | if defObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:
|
| | |
| | | elif defObj.GetGameNPCObjType() == IPY_GameWorld.gnotTruck:
|
| | | remainHP = max(PlayerTruck.GetTruckDestroyMinHP(defObj), remainHP)
|
| | | GameObj.SetHP(defObj, remainHP)
|
| | | |
| | | 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,只扣其血
|
| | | GameObj.SetHP(defObj, remainHP)
|
| | | else:
|
| | | GameWorld.ErrLog('计算伤血值时,防守方类型错误:defObjType = %s' % (defObjType))
|
| | | return resultHurtType
|
| | |
|
| | | if GameObj.GetHP(defObj) > 0:
|
| | | # 被攻击者将部分伤害转化为血量, 返回转化的百分比(小数点)
|
| | | changePer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, None, ChConfig.TriggerType_ChangeHurtToHP)
|
| | | if changePer:
|
| | | SkillCommon.SkillAddHP(defObj, 0, int(changePer*hurtValue))
|
| | |
|
| | | lostValue = dHP - GameObj.GetHP(defObj) # 实际掉血量
|
| | | resultHurtType.LostHP = lostValue
|
| | | if defObjType == IPY_GameWorld.gotPlayer:
|
| | | FBLogic.OnFBLostHP(defObj, lostValue)
|
| | | |
| | | #攻击触发事件, 该代码应该放在DoAttack函数中处理逻辑比较清晰,也不会破坏GetHurtHP函数
|
| | | #因为DoAttack修改点比较多,暂不迁移,相关攻击事件逻辑,就往此函数中添加
|
| | | AttackEventTrigger(atkObj, defObj, resultHurtType, tick)
|
| | | #===========================================================================
|
| | | # if atkObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
|
| | | # GameWorld.DebugAnswer(atkObj, "--%s剩余血量 %s"%(defObj.GetID(), defObj.GetHP()))
|
| | | #===========================================================================
|
| | | |
| | | WriteHurtLog(attacker, defObj, curSkill, resultHurtType.LostHP, resultHurtType.HurtType, "最终扣血")
|
| | | |
| | | AttackEventTrigger(atkObj, defObj, curSkill, resultHurtType, tick)
|
| | |
|
| | | 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):
|
| | | # 优先处理神兵护盾
|
| | | hurtValue = CalcAtkProDef(atkObj, defObj, hurtValue, curSkill, tick)
|
| | |
|
| | | # 伤害吸收盾回血型
|
| | | buffManager = defObj.GetBuffState()
|
| | | curEffect, plusValue, skillID = BuffSkill.FindBuffEffectPlusByEffectID(buffManager, ChConfig.Def_Skill_Effect_AbsorbShieldXMZJ)
|
| | | if skillID:
|
| | | absortValue = hurtValue*curEffect.GetEffectValue(0)/ShareDefine.Def_MaxRateValue
|
| | | if absortValue:
|
| | | hurtValue -= absortValue
|
| | | findBuff = SkillCommon.FindBuffByID(defObj, skillID)[0]
|
| | | if findBuff:
|
| | | # 用于回血
|
| | | findBuff.SetValue(int(findBuff.GetValue() + absortValue))
|
| | |
|
| | | if defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbValue):
|
| | | defObj.SetDict(ChConfig.Def_PlayerKey_AbsorbValue, 0) #吸收的单次伤害,单次伤害必须清空
|
| | | if defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShieldValue):
|
| | | # 麒麟护盾吸收伤害,将抵消的伤害存储
|
| | | absortValue = int(defObj.GetDictByKey(ChConfig.Def_PlayerKey_AbsorbShieldValue)/float(ShareDefine.Def_MaxRateValue)*hurtValue) |
| | | hurtValue -= absortValue
|
| | | defObj.SetDict(ChConfig.Def_PlayerKey_AbsorbValue, absortValue) #吸收的单次伤害
|
| | | |
| | | # 天罡护法,将期间受到的伤害总值用于回血,不改变伤害
|
| | | curEffect, plusValue, skillID2 = BuffSkill.FindBuffEffectPlusByEffectID(buffManager, ChConfig.Def_Skill_Effect_StoreBlood)
|
| | | if skillID2:
|
| | | absortValue = hurtValue*curEffect.GetEffectValue(0)/ShareDefine.Def_MaxRateValue
|
| | | if absortValue:
|
| | | findBuff = SkillCommon.FindBuffByID(defObj, skillID2)[0]
|
| | | if findBuff:
|
| | | # 用于回血
|
| | | findBuff.SetValue(int(findBuff.GetValue() + absortValue))
|
| | | return hurtValue
|
| | |
|
| | |
|
| | |
|
| | | # GM 命令 HurtLog 查看战斗伤害日志
|
| | | def WriteHurtLog(attacker, defObj, curSkill, hurtValue, hurtType, msg):
|
| | | logLevel = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_HurtLog)
|
| | | if not logLevel:
|
| | | return
|
| | | |
| | | if logLevel == 1:
|
| | | # 只看玩家伤害
|
| | | if not attacker:
|
| | | return
|
| | | |
| | | if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
| | | return
|
| | | msg = "玩家" + msg
|
| | | |
| | | attackerID = attacker.GetID() if attacker else 0
|
| | | defenderID = defObj.GetID() if defObj else 0
|
| | | skillID = curSkill.GetSkillID() if curSkill else 0
|
| | | skillName = curSkill.GetSkillName() if curSkill else ""
|
| | | attackerName = attacker.GetName() if attacker else ""
|
| | | defenderName = defObj.GetName() if defObj else ""
|
| | | |
| | | if attacker and attacker.GetGameObjType() == IPY_GameWorld.gotPlayer:
|
| | | attackerName = attackerName.decode("utf8").encode('gbk')
|
| | | |
| | | if defObj and defObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
|
| | | defenderName = defenderName.decode("utf8").encode('gbk')
|
| | | |
| | | GameWorld.DebugLog("攻击伤害-%s:(%s %s)攻击(%s %s), 技能ID:(%s %s), 伤害值:%s, 伤害类型:%s "%(
|
| | | msg, attackerID, attackerName, defenderID, defenderName,
|
| | | skillID, skillName, hurtValue, hurtType))
|
| | |
|
| | | # 血盾支持多个同时存在
|
| | | def CalcBloodShield(atkObj, defObj, hurtValue):
|
| | |
| | |
|
| | | # 计算攻击伤害
|
| | | # maxHurt参数用于模拟计算最大伤害,防范客户端攻击伤害过高
|
| | | def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick, happenState=None, maxHurt=False):
|
| | | def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, tick, happenState=None, **atkwargs):
|
| | | # 翻滚闪避特殊处理
|
| | | if tick - defObj.GetDictByKey(ChConfig.Def_PlayerKey_SomersaultTime) < 500:
|
| | | return 0, ChConfig.Def_HurtType_Miss
|
| | |
|
| | | summonAtkPer = 1 # 召唤继承提高基础攻击力,取表
|
| | | if atkObj.GetGameObjType() == IPY_GameWorld.gotNPC and atkObj.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:
|
| | | summonAtkPerValue = atkObj.GetDictByKey(ChConfig.Def_GameObjKey_InheritOwner)
|
| | | summonAtkObj = atkwargs.get('orgAtkObj', None) if atkwargs.get('orgAtkObj', None) else atkObj
|
| | | if summonAtkObj.GetGameObjType() == IPY_GameWorld.gotNPC and summonAtkObj.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:
|
| | | summonAtkPerValue = summonAtkObj.GetDictByKey(ChConfig.Def_GameObjKey_InheritOwner)
|
| | | if summonAtkPerValue > 0:
|
| | | # 暴风雪类召唤兽转化为主人计算伤害
|
| | | atkObj = NPCCommon.GetSummonOwnerDetel(atkObj)
|
| | | if not atkObj:
|
| | | ownerAtkObj = NPCCommon.GetSummonOwnerDetel(summonAtkObj)
|
| | | if not ownerAtkObj:
|
| | | return 0, ChConfig.Def_HurtType_Miss
|
| | |
|
| | | summonAtkPer = summonAtkPerValue*1.0/ChConfig.Def_MaxRateValue
|
| | | #GameWorld.DebugLog("召唤兽取主人---------%s-%s-%s-%s"%(atkObj.GetID(), atkSkillPer, atkSkillValue, summonAtkPer))
|
| | | #GameWorld.DebugLog("召唤兽取主人---------%s-%s-%s-%s"%(ownerAtkObj.GetID(), atkSkillPer, atkSkillValue, summonAtkPer))
|
| | |
|
| | | 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)
|
| | |
| | | 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:
|
| | |
|
| | | 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):
|
| | |
| | | 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 maxHurt and not PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, |
| | | ChConfig.TriggerType_Buff_MustBeHit): # maxHurt用于模拟计算, 被动有必命中效果
|
| | | 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 \
|
| | | and SkillCommon.GetSkillBattleType(curSkill) == ChConfig.Def_BattleRelationType_CommNoBoss:
|
| | |
| | | and eval(hitFormula) < 0:
|
| | | return 0, ChConfig.Def_HurtType_Miss
|
| | |
|
| | | if maxHurt: # 用于模拟计算最大伤害
|
| | | rand = 1
|
| | | isLuckyHit, aLuckyHit, dLuckyHitReduce = True, atkObj.GetLuckyHitVal(), 0
|
| | | isSuperHit, aSuperHit, dSuperHitReduce = True, atkObj.GetSuperHit(), 0
|
| | | dDamChanceDef = 0
|
| | | hurtType = ChConfig.Def_HurtType_SuperHit
|
| | |
|
| | | 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_ThumpHit] |
| | | if not isSuperHit:
|
| | | isSuperHit, aSuperHit, dSuperHitReduce = hurtTypeResultDict[ChConfig.Def_HurtType_SuperHit] |
| | | else:
|
| | | hurtType, hurtTypeResultDict = CalcHurtTypeResult(atkObj, defObj, atkObjType, defObjType, happenState)
|
| | | #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] # 暴击
|
| | | dDamChanceDef = hurtTypeResultDict[ChConfig.Def_HurtType_Parry][2] # 抵御, 大于0代表触发抵御效果
|
| | | # 重击加成
|
| | | 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
|
| | |
|
| | | wReFightPower = 0
|
| | | worldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
|
| | | wLVIpyData = PlayerControl.GetPlayerLVIpyData(worldLV)
|
| | | wReFightPower = 0 if not wLVIpyData else wLVIpyData.GetReFightPower() # 当前世界等级参考战力
|
| | | if worldLV:
|
| | | wLVIpyData = PlayerControl.GetPlayerLVIpyData(worldLV)
|
| | | wReFightPower = 0 if not wLVIpyData else wLVIpyData.GetReFightPower() # 当前世界等级参考战力
|
| | |
|
| | | # 改变技能伤害
|
| | | 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)
|
| | |
| | |
|
| | | # 暴击增加技能伤害
|
| | | atkSkillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSkillPer)
|
| | | atkSkillPer += PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSkillPer)
|
| | | |
| | | # buff中暴击减层,无触发技能
|
| | | PassiveBuffEffMng.OnPassiveBuffTrigger(atkObj, defObj, curSkill, ChConfig.TriggerType_SuperHitSubLayer, tick)
|
| | |
|
| | |
|
| | | if isLuckyHit:
|
| | | # 会心一击时增加会心伤害百分比 |
| | | # 会心一击时增加会心伤害固定值 |
| | | aLuckyHit += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_LuckyHit)
|
| | |
|
| | | aLuckyHit -= PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_BeLuckyHitSubPer)
|
| | | aLuckyHit = max(aLuckyHit, 0)
|
| | | |
| | | #参与运算的数值
|
| | | rand = random.random() #种子数 0~1
|
| | |
|
| | |
| | | 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伤害加成
|
| | | aFinalHurtPer = PlayerControl.GetFinalHurtPer(atkObj) # 最外层伤害加成, 可能为负值
|
| | | aFinalHurtPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddFinalPer)
|
| | | |
| | | aFinalHurt = PlayerControl.GetFinalHurt(atkObj) # 最终固定伤害
|
| | | # 被动增加最终伤害
|
| | | aFinalHurt += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AttackAddFinalValue)
|
| | |
| | | aOnlyFinalHurt = PlayerControl.GetOnlyFinalHurt(atkObj) # 额外固定伤害
|
| | | aFightPower = atkObj.GetFightPower()
|
| | |
|
| | | |
| | | |
| | | else:
|
| | | aIgnoreDefRate = 0 # 无视防御比率
|
| | | aFinalHurtPer = GameObj.GetPetDamPer(atkObj) # 最外层伤害加成, 可能为负值
|
| | | aSkillAtkRate = NPCCommon.GetSkillAtkRate(atkObj) # 技能攻击力加成
|
| | | if atkObjType == IPY_GameWorld.gotNPC and atkObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:
|
| | | aSkillAtkRate += atkObj.GetSkillAtkRate()
|
| | | |
| | | aNPCHurtAddPer = 0 # PVE伤害加成
|
| | | aDamagePer = 0 # 外层伤害加成
|
| | | aDamagePerPVP = 0 # 外层PVP伤害加成
|
| | | aFinalHurtPer = 0 # 最外层伤害加成, 可能为负值
|
| | | aDamagePVP = 0 # PVP固定伤害
|
| | | aDamagePVE = 0 # PVE固定伤害
|
| | | aFinalHurt = NPCCommon.GetFinalHurt(atkObj) # 最终固定伤害
|
| | | aFightPower = NPCCommon.GetSuppressFightPower(atkObj)
|
| | |
|
| | |
| | | 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:
|
| | |
| | | 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)) |
| | | # 境界压制规则
|
| | | # 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"])))
|
| | |
|
| | | 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])))
|
| | | |
| | | # 骑宠争夺最终伤害衰减 |
| | | if defObjType == IPY_GameWorld.gotNPC and FamilyRobBoss.IsHorsePetRobBoss(defObj.GetNPCID()):
|
| | | ownerPlayer, npcObjType = GetAttackPlayer(atkObj)
|
| | |
|
| | | # 骑宠争夺最终伤害衰减 |
| | | if FamilyRobBoss.IsHorsePetRobBoss(defObj.GetNPCID()):
|
| | | findBuff = SkillCommon.FindBuffByID(atkObj, ChConfig.Def_SkillID_HorsePetRobBossKillCntBuff)[0]
|
| | | if ownerPlayer:
|
| | | findBuff = SkillCommon.FindBuffByID(ownerPlayer, ChConfig.Def_SkillID_HorsePetRobBossKillCntBuff)[0]
|
| | | if findBuff:
|
| | | reduceFinalHurtPer = findBuff.GetSkill().GetEffect(0).GetEffectValue(0)
|
| | | aFinalHurtPer -= reduceFinalHurtPer
|
| | |
| | | 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
|
| | | hurtFormula = hurtDist[hurtFormulaKey]
|
| | | hurtValue = int(eval(FormulaControl.GetCompileFormula(hurtFormulaKey, hurtFormula)))
|
| | | |
| | |
|
| | | if hurtType == ChConfig.Def_HurtType_Normal and SuppressValueRealmRate > 10000:
|
| | | # 存在压制
|
| | | return hurtValue, ChConfig.Def_HurtType_RealmSupress
|
| | |
| | | # 获取双方境界值
|
| | | 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代表不要压制
|
| | |
| | | ## 攻击时事件处理,反弹吸血或者额外触发技能等
|
| | | # @param resultHurtType 伤害结构体
|
| | | # @return
|
| | | def AttackEventTrigger(atkObj, defObj, resultHurtType, tick):
|
| | | def AttackEventTrigger(atkObj, defObj, curSkill, resultHurtType, tick):
|
| | |
|
| | | #反弹伤害
|
| | | CalcBounceHP(atkObj, defObj, resultHurtType.LostHP, resultHurtType.HurtType)
|
| | | #吸血
|
| | | CalcSuckBlood(atkObj, defObj, resultHurtType.RealHurtHP, tick)
|
| | | CalcSuckBlood(atkObj, defObj, curSkill, resultHurtType.RealHurtHP, tick)
|
| | |
|
| | | 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())
|
| | | else:
|
| | | defObj.SetDict(ChConfig.Def_PlayerKey_LastAttackerObjID, atkObj.GetID())
|
| | | return
|
| | |
|
| | |
|
| | |
| | | if objType == IPY_GameWorld.gotPlayer:
|
| | | return "P"
|
| | |
|
| | | if objType == IPY_GameWorld.gotNPC:
|
| | | if obj.GetType() == ChConfig.ntRobot:
|
| | | return "Robot"
|
| | | if obj.GetType() == ChConfig.ntHelpBattleRobot:
|
| | | return "HelpRobot"
|
| | | |
| | | objType = obj.GetGameNPCObjType()
|
| | | if objType == IPY_GameWorld.gnotPet:
|
| | | return "Pet"
|
| | |
| | | # @param atkObj 攻击者
|
| | | # @param defObj 防守者
|
| | | # @return None
|
| | | def CalcSuckBlood(atkObj, defObj, hurtValue, tick):
|
| | | def CalcSuckBlood(atkObj, defObj, curSkill, hurtValue, tick):
|
| | |
|
| | | if atkObj.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
| | | return
|
| | |
| | | #PVP 攻击回血
|
| | | atkBackHP += PlayerControl.GetPVPAtkBackHP(atkObj)
|
| | | # 百分比吸血
|
| | | atkBackHPPer = PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(atkObj, None, 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)
|
| | |
|
| | | |
| | | suckHP += atkBackHP
|
| | |
|
| | | if suckHP <= 0:
|
| | |
| | | 1 全体模式 IPY_GameWorld.amAll 对所有玩家都是敌对,家族区域同盟玩家除外
|
| | | 2 防卫模式 IPY_GameWorld.amCountry 本服玩家友好,他服玩家都是敌对
|
| | | 5 强制模式 IPY_GameWorld.amFamily 队友、仙盟成员、同阵营友好,其他玩家敌对
|
| | | 7 锁定单一目标模式 IPY_GameWorld.amContest 只对选中目标有伤害, 目前只用于部分BOSS争夺地图
|
| | |
|
| | | 场景区域
|
| | | 普通区域 IPY_GameWorld.gatNormal 可根据不同PK模式PK,击杀玩家有惩罚
|
| | |
| | |
|
| | | if GetIsNewGuy(tagPlayer):
|
| | | return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_NotAttackNewGuy
|
| | | |
| | | #攻守双方同一队伍,不可PK,可加增益buff
|
| | | #if curPlayerAreaType not in [ShareDefine.gatManor] and CanAlikeTeam(curPlayer, tagPlayer):
|
| | | # #副本队友特殊判断
|
| | | # if not PlayerCanAttackTeamerInFB(curPlayer, tagPlayer): |
| | | # return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_NotAttackTeam
|
| | |
|
| | | #恶意攻击的玩家默认都是敌人, 无论什么模式
|
| | | if IsMaliciousAttackPlayer(curPlayer, tagPlayer):
|
| | |
| | | # @param curObjDetel 对象实例
|
| | | # @return 返回值无意义
|
| | | # @remarks 理对象死亡逻辑
|
| | | def DoLogic_ObjDead(curObjDetel):
|
| | | def DoLogic_ObjDead(atkObj, curObjDetel, curSkill, tick):
|
| | | if GameObj.GetHP(curObjDetel) > 0:
|
| | | return
|
| | |
|
| | |
| | | return
|
| | |
|
| | | #---NPC处理---
|
| | | if not ChNPC.OnCheckCanDie(atkObj, curObjDetel, curSkill, tick):
|
| | | return
|
| | | |
| | | npcControl = NPCCommon.NPCControl(curObjDetel)
|
| | | npcControl.SetKilled()
|
| | | return
|