|  |  | 
 |  |  | #---------------------------------------------------------------------
 | 
 |  |  | g_skillHurtList = IPY_GameWorld.IPY_HurtList()
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # 特殊处理搜索范围,一般用于副本
 | 
 |  |  | Def_SearchMap_NPC = 200 # 本线全图搜索NPC
 | 
 |  |  | Def_SearchMap_Player = 201 # 本线全图搜索玩家
 | 
 |  |  | 
 | 
 |  |  | #伤害结构体
 | 
 |  |  | #hurtTypeIndance = None
 | 
 |  |  | #---------------------------------------------------------------------
 | 
 |  |  | 
 |  |  |     
 | 
 |  |  |     return None
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  |      | 
 |  |  | # 触发型技能根据伤血类型触发被动技能,群攻只触发一次,放在伤血列表被清之前
 | 
 |  |  | # 只处理 isEnhanceSkill的情况,对应 OnHurtTypeTriggerSkill
 | 
 |  |  | def OnHurtTypeTriggerPassiveSkill(attacker, target, curSkill, tick):
 | 
 |  |  |      | 
 |  |  |     skillHurtLists = [] # 内部触发清除g_skillHurtList
 | 
 |  |  |     for i in xrange(g_skillHurtList.GetHurtCount()):
 | 
 |  |  |         hurtObj = g_skillHurtList.GetHurtAt(i)
 | 
 |  |  |         if not hurtObj:
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         skillHurtLists.append([hurtObj.GetObjID(), hurtObj.GetObjType(), hurtObj.GetAttackType()])
 | 
 |  |  |      | 
 |  |  |     for hurtList in skillHurtLists:
 | 
 |  |  |         defender = GameWorld.GetObj(hurtList[0], hurtList[1])
 | 
 |  |  |         if not defender:
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         if GameObj.GetHP(defender) > 0:
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         if hurtList[1] == IPY_GameWorld.gotPlayer:
 | 
 |  |  |             if hurtList[2] == ChConfig.Def_HurtType_Zhansha:
 | 
 |  |  |                 defender.SetDict(ChConfig.Def_PlayerKey_Zhansha, 1)
 | 
 |  |  |             elif hurtList[2] == ChConfig.Def_HurtType_ZhognjiZhansha:
 | 
 |  |  |                 defender.SetDict(ChConfig.Def_PlayerKey_Zhansha, 2)
 | 
 |  |  |                  | 
 |  |  |             # 濒死状态触发技能, 不能在GetHurtHP内部触发技能,否则会导致原技能的伤血列表异常
 | 
 |  |  |             PassiveBuffEffMng.OnPassiveSkillTrigger(defender, attacker, None, ChConfig.TriggerType_WillDead, tick)
 | 
 |  |  |             PassiveBuffEffMng.OnPassiveBuffTrigger(defender, attacker, None, ChConfig.TriggerType_WillDead, tick)
 | 
 |  |  |             if hurtList[2] in [ChConfig.Def_HurtType_Zhansha, ChConfig.Def_HurtType_ZhognjiZhansha]:
 | 
 |  |  |                 defender.SetDict(ChConfig.Def_PlayerKey_Zhansha, 0)
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | #---------------------------------------------------------------------
 | 
 |  |  | ## 攻击通用函数
 | 
 |  |  | #  @param attacker 攻击Obj
 | 
 |  |  | 
 |  |  |         __AttackSuccess(attacker, attackerHP, defender, useSkill, tick)
 | 
 |  |  |         #调用触发附加技能
 | 
 |  |  |         SkillShell.DoLogic_UseEnhanceSkill(attacker, defender, useSkill, tick, destX, destY)
 | 
 |  |  |     else:
 | 
 |  |  |         OnHurtTypeTriggerPassiveSkill(attacker, defender, useSkill, tick)
 | 
 |  |  |         
 | 
 |  |  |     #因攻击结束动作中,法宝攻击将导致目标死亡。要判定后在次调用,避免2次->AttackResult
 | 
 |  |  |     if AttackCommon.GetIsDead(defender):
 | 
 |  |  | 
 |  |  |         #关系
 | 
 |  |  |         relation = GetTagRelation(attacker, defender, curSkill, tick)
 | 
 |  |  |         return relation[0] == ChConfig.Type_Relation_Friend
 | 
 |  |  |     elif curSkillUseTag == ChConfig.Def_UseSkillTag_AppointNPC:
 | 
 |  |  |         if defender and GameObj.GetHP(defender) > 0 :
 | 
 |  |  |             return True
 | 
 |  |  |         return False
 | 
 |  |  |     
 | 
 |  |  |     return __CheckCanAttack(attacker , defender , curSkill , tick)
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  |     # 防守者自己通知
 | 
 |  |  |     __Sync_AttackResult(defender, defender, curSkill)
 | 
 |  |  |     
 | 
 |  |  | 
 | 
 |  |  |     OnHurtTypeTriggerPassiveSkill(attacker, defender, curSkill, tick)
 | 
 |  |  |     DoLogic_AttackResult(attacker, defender, curSkill, tick)
 | 
 |  |  |     
 | 
 |  |  |     return True
 | 
 |  |  | 
 |  |  |     return True
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # 按仙盟成员均摊伤害
 | 
 |  |  | def AttackerSkillAttackAreaByFamily(attacker, defender, srcPosX, srcPosY, curSkill,
 | 
 |  |  |                             skillPercent, skillEnhance, tick, isExSkill = False):
 | 
 |  |  |     #清空伤血列表
 | 
 |  |  |     global g_skillHurtList
 | 
 |  |  |     g_skillHurtList.Clear()
 | 
 |  |  |      | 
 |  |  |     #攻击方原有血量,用来通知反弹
 | 
 |  |  |     attackerHP = GameObj.GetHP(attacker)
 | 
 |  |  |     resultList = __GetAreaAtackObj(attacker, curSkill, srcPosX, srcPosY, tick, __CheckCanAttack)
 | 
 |  |  |              | 
 |  |  |     #有目标类技能,查找指定的攻击目标是否在列表中,不在添加
 | 
 |  |  |     resultList = __AddObj_In_resultList(resultList, attacker, defender, curSkill, tick)
 | 
 |  |  | 
 | 
 |  |  |     # 计算仙盟成员数量, 按人头均摊伤害
 | 
 |  |  |     resultDict = {}
 | 
 |  |  |     for obj in resultList:
 | 
 |  |  |         if obj.GetGameObjType() != IPY_GameWorld.gotPlayer:
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         familyID = obj.GetFamilyID()
 | 
 |  |  |         if familyID not in resultDict:
 | 
 |  |  |             resultDict[familyID] = []
 | 
 |  |  | 
 | 
 |  |  |         resultDict[familyID].append(obj)
 | 
 |  |  |          | 
 |  |  |     skillEffect = SkillCommon.GetSkillEffectByEffectID(curSkill, ChConfig.Def_Skill_Effect_AvgHurtFMCnt)
 | 
 |  |  |     minSkillPer = 0.01   # 如果未配置默认最低值
 | 
 |  |  |     if skillEffect:
 | 
 |  |  |         minSkillPer = skillEffect.GetEffectValue(0)
 | 
 |  |  |          | 
 |  |  |     attackList = []
 | 
 |  |  |     for familyID in resultDict:
 | 
 |  |  |         cnt = len(resultDict[familyID]) if familyID != 0 else 1 # 无仙盟承受100%伤害
 | 
 |  |  |          | 
 |  |  |         skillPercent = max(skillPercent/cnt, minSkillPer)
 | 
 |  |  |         attackList.extend(__DoAreaAttack(attacker, curSkill, skillEnhance/cnt, skillPercent, resultDict[familyID],
 | 
 |  |  |                                      [], g_skillHurtList, tick))
 | 
 |  |  | 
 | 
 |  |  |      | 
 |  |  |     __DoAreaAttackResult(attacker, defender, curSkill, attackList, attackerHP, tick, isExSkill)
 | 
 |  |  |      | 
 |  |  |     return True
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # 触发技能的类型为 单体攻击,或者单体buff并且非对自己释放的技能,可以对伤害目标一一执行触发技能逻辑
 | 
 |  |  | # 否则只触发一次技能 # 群体BUFF的请参考IsPlayerUseSkill 客户端决定对象,一样可以实现同样效果
 | 
 |  |  | # 返回真表示可以对每个伤害目标触发,返回假则为单体
 | 
 |  |  | 
 |  |  |                     SkillShell.SkillTrigSkill(attacker, defObj, curSkill, enhanceSkillID, tick)
 | 
 |  |  |             else:
 | 
 |  |  |                 SkillShell.SkillTrigSkill(attacker, defender, curSkill, enhanceSkillID, tick)
 | 
 |  |  | 
 | 
 |  |  |     else:
 | 
 |  |  |         OnHurtTypeTriggerPassiveSkill(attacker, defender, curSkill, tick)
 | 
 |  |  |          | 
 |  |  |     for defObj in attackList:
 | 
 |  |  |             
 | 
 |  |  |         #因攻击结束动作中,法宝攻击将导致目标死亡。要判定后在次调用,避免2次->AttackResult
 | 
 |  |  | 
 |  |  |                    powerList, g_skillHurtList, tick):
 | 
 |  |  |     attackList = []   #被攻击对象列表
 | 
 |  |  | 
 | 
 |  |  |     checkComboOK = False
 | 
 |  |  |     #checkComboOK = False
 | 
 |  |  | 
 | 
 |  |  |     #执行攻击结果
 | 
 |  |  |     for obj in resultList:
 | 
 |  |  | 
 |  |  |         if powerList != []:
 | 
 |  |  |             skillPercent, skillEnhance = powerList.pop(0)
 | 
 |  |  | 
 | 
 |  |  |         if not checkComboOK:
 | 
 |  |  |         #if not checkComboOK:
 | 
 |  |  |             #攻击前连击检查
 | 
 |  |  |             SkillCommon.UpdateSkillCombo(attacker, curSkill, tick)
 | 
 |  |  |             checkComboOK = True
 | 
 |  |  |         #    SkillCommon.UpdateSkillCombo(attacker, curSkill, tick)
 | 
 |  |  |         #    checkComboOK = True
 | 
 |  |  |             
 | 
 |  |  |         callFunc(attacker, obj, curSkill, skillEnhance, skillPercent, g_skillHurtList, tick)
 | 
 |  |  |         
 | 
 |  |  | 
 |  |  |         GameWorld.ErrLog("Def_Dict_UseSkillTag_ObjType 没有对应项 %s" % curSkillUseTag)
 | 
 |  |  |         return resultList
 | 
 |  |  |     
 | 
 |  |  |     gameMap = GameWorld.GetMap()
 | 
 |  |  |     | 
 |  |  |     if skillMatrix == None:
 | 
 |  |  |         #作用范围 作用矩阵
 | 
 |  |  |         attackDis = curSkill.GetAtkRadius()
 | 
 |  |  |         skillMatrix = ChConfig.MatrixDict.get(attackDis)
 | 
 |  |  |         if skillMatrix == None:
 | 
 |  |  |         skillMatrix = ChConfig.MatrixDict.get(attackDis, None)
 | 
 |  |  |         if skillMatrix == None and attackDis not in [Def_SearchMap_Player, Def_SearchMap_NPC]:
 | 
 |  |  |             GameWorld.ErrLog("CheckAreaObj skillId=%s, attakDis=%s not in matrixDict=%s" 
 | 
 |  |  |                              % (curSkill.GetSkillID(), attackDis, ChConfig.MatrixDict))
 | 
 |  |  |             return resultList
 | 
 |  |  | 
 |  |  |     #技能攻击最大数量
 | 
 |  |  |     hurtCount = SkillCommon.GetSkillArea_Atk_Count(attacker, curSkill)
 | 
 |  |  |     
 | 
 |  |  |     ownerTag = None
 | 
 |  |  |     ownerPlayerID = 0
 | 
 |  |  |     isSummonNPCAtker = attacker.GetGameObjType() == IPY_GameWorld.gotNPC and NPCCommon.IsSummonNPC(attacker)
 | 
 |  |  |     if isSummonNPCAtker:
 | 
 |  |  | 
 |  |  |     if attackAim:
 | 
 |  |  |         hurtCount -= 1
 | 
 |  |  |         resultList.append(attackAim)
 | 
 |  |  |             | 
 |  |  |          | 
 |  |  |     if skillMatrix:
 | 
 |  |  |         # 按范围搜索
 | 
 |  |  |         resultList = ServerByPos(attacker, curSkill, tick, skillMatrix, hurtCount,  | 
 |  |  |                 srcPosX, srcPosY, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                 ownerPlayerID, isSummonNPCAtker, resultList)
 | 
 |  |  |     elif attackDis == Def_SearchMap_Player:
 | 
 |  |  |         # 搜索本地图当前线路玩家
 | 
 |  |  |         ServerByMapPlayer(attacker, curSkill, tick, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                       ownerPlayerID, isSummonNPCAtker, resultList, hurtCount)
 | 
 |  |  |     elif attackDis == Def_SearchMap_NPC:
 | 
 |  |  |         # 搜索本地图当前线路NPC
 | 
 |  |  |         ServerByMapNPC(attacker, curSkill, tick, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                                          ownerPlayerID, isSummonNPCAtker, resultList, hurtCount)
 | 
 |  |  |     return resultList
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # 按范围搜索目标对象
 | 
 |  |  | def ServerByPos(attacker, curSkill, tick, skillMatrix, hurtCount,  | 
 |  |  |                 srcPosX, srcPosY, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                 ownerPlayerID, isSummonNPCAtker, resultList):
 | 
 |  |  |     ownerTag = None
 | 
 |  |  |     gameMap = GameWorld.GetMap()
 | 
 |  |  |     for curPos in skillMatrix:
 | 
 |  |  |         #伤害次数到了
 | 
 |  |  |         if hurtCount <= 0:
 | 
 |  |  | 
 |  |  |                 break
 | 
 |  |  |         
 | 
 |  |  |             curObj = mapObj.GetObjByIndex(i)
 | 
 |  |  |             curObjType = curObj.GetGameObjType()
 | 
 |  |  |              | 
 |  |  |             #不在影响对象列表中
 | 
 |  |  |             if curObjType not in hurtTypeList:
 | 
 |  |  |                 continue
 | 
 |  |  |              | 
 |  |  |             #攻击对象
 | 
 |  |  |             curTag = GameWorld.GetObj(curObj.GetID(), curObjType)
 | 
 |  |  |             curTag, ownerTag = __SearchCheck(attacker, curSkill, tick, curObj, hurtTypeList, attackAim, curSkillUseTag,  | 
 |  |  |                                              CheckFunc, ownerPlayerID, isSummonNPCAtker, resultList)
 | 
 |  |  |             if not curTag:
 | 
 |  |  |                 if ownerTag:
 | 
 |  |  |                     hurtCount -= 1
 | 
 |  |  |                 continue
 | 
 |  |  |             
 | 
 |  |  |             if attackAim and attackAim.GetID() == curTag.GetID():
 | 
 |  |  |                 # 不在攻击主目标
 | 
 |  |  |                 continue
 | 
 |  |  |              | 
 |  |  |             #群攻技能不能对镖车释放, 永恒版本屏蔽此限制
 | 
 |  |  |             #if curObjType == IPY_GameWorld.gotNPC and curTag.GetGameNPCObjType() == IPY_GameWorld.gnotTruck:
 | 
 |  |  |             #    continue
 | 
 |  |  |              | 
 |  |  |             if curSkillUseTag == ChConfig.Def_UseSkillTag_CanAttackNPC:
 | 
 |  |  |                 if NPCCommon.GetNpcObjOwnerIsPlayer(curTag):
 | 
 |  |  |                     #npc主人是玩家不能攻击
 | 
 |  |  |                     continue
 | 
 |  |  |              | 
 |  |  |             if CheckFunc != None:
 | 
 |  |  |                 #检查是否受影响
 | 
 |  |  |                 if not CheckFunc(attacker, curTag, curSkill, tick):
 | 
 |  |  |                     continue
 | 
 |  |  |              | 
 |  |  |             # 如果攻击者是召唤兽 且 攻击的是主人玩家,则把主人放在最后面一个处理伤害目标,防止先处理后如果主人死亡将导致后续的逻辑异常
 | 
 |  |  |             if ownerPlayerID > 0 and curObjType == IPY_GameWorld.gotPlayer and isSummonNPCAtker and ownerPlayerID == curObj.GetID():
 | 
 |  |  |                 ownerTag = curTag
 | 
 |  |  |                 continue
 | 
 |  |  |             hurtCount -= 1
 | 
 |  |  |             resultList.append(curTag)
 | 
 |  |  |              | 
 |  |  |     if ownerTag:
 | 
 |  |  |         resultList.append(ownerTag)
 | 
 |  |  |     return resultList
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | def __SearchCheck(attacker, curSkill, tick, curObj, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                 ownerPlayerID, isSummonNPCAtker, resultList, curTag=None):
 | 
 |  |  |     curObjType = curObj.GetGameObjType()
 | 
 |  |  |      | 
 |  |  |     #不在影响对象列表中
 | 
 |  |  |     if curObjType not in hurtTypeList:
 | 
 |  |  |         return None, None
 | 
 |  |  |      | 
 |  |  |     #攻击对象
 | 
 |  |  |     if not curTag:
 | 
 |  |  |         curTag = GameWorld.GetObj(curObj.GetID(), curObjType)
 | 
 |  |  |     if not curTag:
 | 
 |  |  |         return None, None
 | 
 |  |  |      | 
 |  |  |     if attackAim and attackAim.GetID() == curTag.GetID():
 | 
 |  |  |         # 不在攻击主目标
 | 
 |  |  |         return None, None
 | 
 |  |  |      | 
 |  |  |     if curSkillUseTag == ChConfig.Def_UseSkillTag_CanAttackNPC:
 | 
 |  |  |         if NPCCommon.GetNpcObjOwnerIsPlayer(curTag):
 | 
 |  |  |             #npc主人是玩家不能攻击
 | 
 |  |  |             return None, None
 | 
 |  |  |      | 
 |  |  |     if CheckFunc != None:
 | 
 |  |  |         #检查是否受影响
 | 
 |  |  |         if not CheckFunc(attacker, curTag, curSkill, tick):
 | 
 |  |  |             return None, None
 | 
 |  |  |      | 
 |  |  |     # 如果攻击者是召唤兽 且 攻击的是主人玩家,则把主人放在最后面一个处理伤害目标,防止先处理后如果主人死亡将导致后续的逻辑异常
 | 
 |  |  |     if ownerPlayerID > 0 and curObjType == IPY_GameWorld.gotPlayer and isSummonNPCAtker and ownerPlayerID == curObj.GetID():
 | 
 |  |  |         ownerTag = curTag
 | 
 |  |  |         return None, ownerTag
 | 
 |  |  |     return curTag, None
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # 搜索本地图当前线路NPC
 | 
 |  |  | def ServerByMapNPC(attacker, curSkill, tick, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                                          ownerPlayerID, isSummonNPCAtker, resultList, hurtCount):
 | 
 |  |  |     gameNPCManager = GameWorld.GetNPCManager()
 | 
 |  |  |     for index in xrange(gameNPCManager.GetNPCCount()):
 | 
 |  |  |         curNPC = gameNPCManager.GetNPCByIndex(index)
 | 
 |  |  |         if curNPC == None or curNPC.GetID() == 0:
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         curTag, ownerTag = __SearchCheck(attacker, curSkill, tick, curNPC, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                                          ownerPlayerID, isSummonNPCAtker, resultList, curTag=curNPC)
 | 
 |  |  |         if not curTag:
 | 
 |  |  |             if ownerTag:
 | 
 |  |  |                 hurtCount -= 1
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         hurtCount -= 1
 | 
 |  |  |         resultList.append(curTag)
 | 
 |  |  |              | 
 |  |  |     if ownerTag:
 | 
 |  |  |         resultList.append(ownerTag)
 | 
 |  |  |          | 
 |  |  |     return resultList
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # 搜索本地图当前线路玩家
 | 
 |  |  | def ServerByMapPlayer(attacker, curSkill, tick, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                       ownerPlayerID, isSummonNPCAtker, resultList, hurtCount):
 | 
 |  |  |     copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
 | 
 |  |  |     for i in range(copyMapPlayerManager.GetPlayerCount()):
 | 
 |  |  |         curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)
 | 
 |  |  |          | 
 |  |  |         if curPlayer == None or curPlayer.IsEmpty():
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         curTag, ownerTag = __SearchCheck(attacker, curSkill, tick, curPlayer, hurtTypeList, attackAim, curSkillUseTag, CheckFunc,
 | 
 |  |  |                                          ownerPlayerID, isSummonNPCAtker, resultList, curTag=curPlayer)
 | 
 |  |  |         if not curTag:
 | 
 |  |  |             if ownerTag:
 | 
 |  |  |                 hurtCount -= 1
 | 
 |  |  |             continue
 | 
 |  |  |          | 
 |  |  |         hurtCount -= 1
 | 
 |  |  |         resultList.append(curTag)
 | 
 |  |  |             
 | 
 |  |  |     if ownerTag:
 | 
 |  |  |         resultList.append(ownerTag)
 | 
 |  |  | 
 |  |  |         PYView_UseSkillPos(attacker, skillID, battleType, useSkillPosX, useSkillPosY, g_skillHurtList, False)
 | 
 |  |  |     
 | 
 |  |  |     return
 | 
 |  |  | 
 | 
 |  |  | # 通知客户端表现封包 无其他作用
 | 
 |  |  | def Sync_AttackResult(attacker, curSkill):
 | 
 |  |  |     global g_skillHurtList
 | 
 |  |  |     g_skillHurtList.Clear()
 | 
 |  |  |      | 
 |  |  |     defender = None
 | 
 |  |  |     if SkillShell.GetSkillFireAim(curSkill) == ChConfig.Def_UseSkillAim_Obj:
 | 
 |  |  |         useSkillTagID = attacker.GetUseSkillTagID()
 | 
 |  |  |         useSkillTagType = attacker.GetUseSkillTagType()
 | 
 |  |  |         defender = GameWorld.GetObj(useSkillTagID, useSkillTagType)
 | 
 |  |  |      | 
 |  |  |     __Sync_AttackResult(attacker, defender, curSkill)
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | ##############################主动攻击成功#############################
 | 
 |  |  | ## 玩家攻击成功
 | 
 |  |  | #  @param curPlayer 攻击Obj
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  |         if curPlayerSkill:
 | 
 |  |  |             SkillCommon.SetSkillRemainTime(curPlayerSkill, PlayerControl.GetReduceSkillCDPer(curPlayer), tick, curPlayer)
 | 
 |  |  |          | 
 |  |  |         if curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_GiftSkill:
 | 
 |  |  |             UseSkillOver(curPlayer, target, curSkill, tick)
 | 
 |  |  |         else:
 | 
 |  |  |             OnHurtTypeTriggerPassiveSkill(curPlayer, target, curSkill, tick)
 | 
 |  |  |         return True
 | 
 |  |  |     
 | 
 |  |  |     #玩家进入战斗状态
 | 
 |  |  | 
 |  |  |     
 | 
 |  |  | # 根据伤血类型触发技能,群攻只触发一次,放在伤血列表被清之前
 | 
 |  |  | def OnHurtTypeTriggerSkill(attacker, target, curSkill, tick):
 | 
 |  |  |      | 
 |  |  |     isSuperHit = False
 | 
 |  |  |     usePassiveSkillResult = True    # 第一次判断不能调用,即代表都不可用无需循环
 | 
 |  |  |     usePassiveSkillResultOnSuperHit = True    # 暴击对象1V1触发,第一次判断不能调用,即代表都不可用无需循环
 | 
 |  |  | 
 |  |  |             continue
 | 
 |  |  |         
 | 
 |  |  |         skillHurtLists.append([hurtObj.GetObjID(), hurtObj.GetObjType(), hurtObj.GetAttackType()])
 | 
 |  |  |      | 
 |  |  |     
 | 
 |  |  |     skillIDSet = set()
 | 
 |  |  |     for hurtList in skillHurtLists:
 | 
 |  |  | 
 |  |  |         
 | 
 |  |  |         if GameObj.GetHP(defender) <= 0:
 | 
 |  |  |             if hurtList[1] == IPY_GameWorld.gotPlayer:
 | 
 |  |  |                 if hurtList[2] == ChConfig.Def_HurtType_Zhansha:
 | 
 |  |  |                     defender.SetDict(ChConfig.Def_PlayerKey_Zhansha, 1)
 | 
 |  |  |                 elif hurtList[2] == ChConfig.Def_HurtType_ZhognjiZhansha:
 | 
 |  |  |                     defender.SetDict(ChConfig.Def_PlayerKey_Zhansha, 2)
 | 
 |  |  |                 # 濒死状态触发技能, 不能在GetHurtHP内部触发技能,否则会导致原技能的伤血列表异常
 | 
 |  |  |                 PassiveBuffEffMng.OnPassiveSkillTrigger(defender, attacker, None, ChConfig.TriggerType_WillDead, tick)
 | 
 |  |  |                 PassiveBuffEffMng.OnPassiveBuffTrigger(defender, attacker, None, ChConfig.TriggerType_WillDead, tick)
 | 
 |  |  |                 if hurtList[2] in [ChConfig.Def_HurtType_Zhansha, ChConfig.Def_HurtType_ZhognjiZhansha]:
 | 
 |  |  |                     defender.SetDict(ChConfig.Def_PlayerKey_Zhansha, 0)
 | 
 |  |  |             continue
 | 
 |  |  |         
 | 
 |  |  |         if usePassiveSkillResult:
 | 
 |  |  | 
 |  |  |         if hurtList[2] == ChConfig.Def_HurtType_SuperHit:
 | 
 |  |  |             #被暴击触发技能
 | 
 |  |  |             PassiveBuffEffMng.OnPassiveSkillTrigger(defender, attacker, None, ChConfig.TriggerType_BeSuperHit, tick)
 | 
 |  |  |             PassiveBuffEffMng.OnPetPassiveSkillTrigger(defender, attacker, None, ChConfig.TriggerType_BeSuperHit, tick)
 | 
 |  |  |         elif hurtList[2] == ChConfig.Def_HurtType_Miss:
 | 
 |  |  |             PassiveBuffEffMng.OnPassiveSkillTrigger(defender, attacker, None, ChConfig.TriggerType_MissSkill, tick)
 | 
 |  |  |          | 
 |  |  | 
 | 
 |  |  |         elif hurtList[2] == ChConfig.Def_HurtType_LuckyHit:
 | 
 |  |  |             PassiveBuffEffMng.OnPetPassiveSkillTrigger(defender, attacker, None, ChConfig.TriggerType_BeLuckyHit, tick)
 | 
 |  |  |              | 
 |  |  |         if hurtList[2] in ChConfig.Def_RealAttack_Type:
 | 
 |  |  |             # 被攻击处理层级
 | 
 |  |  |             PassiveBuffEffMng.OnPassiveBuffTrigger(defender, attacker, None, ChConfig.TriggerType_Buff_BeAttackSubLayer, tick)
 | 
 |  |  | 
 |  |  | # 灵为玩家的替身需要走此逻辑
 | 
 |  |  | # 技能使用结束,在处理技能逻辑和通知封包之后调用
 | 
 |  |  | def UseSkillOver(attacker, defender, curSkill, tick):
 | 
 |  |  |      | 
 |  |  |     # 根据伤血类型触发技能,群攻只触发一次,放在伤血列表被清之前
 | 
 |  |  |     OnHurtTypeTriggerSkill(attacker, defender, curSkill, tick)
 | 
 |  |  |     
 | 
 |  |  | 
 |  |  |                                                     ChConfig.Def_SkillFuncType_NormalAttack]):
 | 
 |  |  |         # 攻击减层级 优先处理,因为同个技能触发buff后,会再处理层级,导致立即减层级
 | 
 |  |  |         PassiveBuffEffMng.OnPassiveBuffTrigger(attacker, defender, curSkill, ChConfig.TriggerType_Buff_AttackSubLayer, tick)
 | 
 |  |  |          | 
 |  |  |      | 
 |  |  |     # 普攻和对敌技能
 | 
 |  |  |     if not curSkill or curSkill.GetSkillType() in ChConfig.Def_CanAttackSkill_List:
 | 
 |  |  |          | 
 |  |  |         PassiveBuffEffMng.OnPassiveSkillTrigger(attacker, defender, curSkill, ChConfig.TriggerType_AttackOver, tick)
 | 
 |  |  |         PassiveBuffEffMng.OnPassiveBuffTrigger(attacker, defender, curSkill, ChConfig.TriggerType_AttackOver, tick)
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  |     tagFaintRate = PlayerControl.GetFaintDefRate(defender) if defender.GetGameObjType() == IPY_GameWorld.gotPlayer else 0
 | 
 |  |  | 
 | 
 |  |  |     rate = max(PlayerControl.GetFaintRate(attacker) - tagFaintRate, 0)
 | 
 |  |  |     # 添加最高60%击晕效果
 | 
 |  |  |     rate = min(max(PlayerControl.GetFaintRate(attacker) - tagFaintRate, 0), 6000)
 | 
 |  |  |     if not GameWorld.CanHappen(rate):
 | 
 |  |  |         return
 | 
 |  |  | 
 | 
 |  |  | 
 |  |  | #  @return None
 | 
 |  |  | #  @remarks 设置玩家属性消耗,如魔法,XP点,HP
 | 
 |  |  | def SetSkillLostAttr(curPlayer, curSkill, tick):
 | 
 |  |  |     #-----------扣魔法
 | 
 |  |  |     lostMPValue = curSkill.GetMP()
 | 
 |  |  |     curPlayerMP = curPlayer.GetMP()
 | 
 |  |  |      | 
 |  |  |     if curPlayerMP < lostMPValue:
 | 
 |  |  |         GameWorld.ErrLog('释放技能 = %s异常, 魔法 = %s不足 = %s' % (
 | 
 |  |  |                             curSkill.GetSkillTypeID(), curPlayerMP, lostMPValue))
 | 
 |  |  |      | 
 |  |  |     if lostMPValue > 0:
 | 
 |  |  |         curPlayer.SetMP(curPlayer.GetMP() - lostMPValue)
 | 
 |  |  |         #自动回魔
 | 
 |  |  |         PlayerControl.PlayerAutoRestoreMP(curPlayer, tick)
 | 
 |  |  |      | 
 |  |  |     #----------扣XP点
 | 
 |  |  |     lostXPValue = curSkill.GetXP()
 | 
 |  |  |     curPlayerXP = curPlayer.GetXP()
 | 
 |  |  |      | 
 |  |  |     if curPlayerXP < lostXPValue:
 | 
 |  |  |         GameWorld.ErrLog('释放技能 = %s异常, XP点 = %s不足 = %s' % (
 | 
 |  |  |                             curSkill.GetSkillTypeID(), curPlayerXP, lostXPValue))
 | 
 |  |  |      | 
 |  |  |     if lostXPValue > 0:
 | 
 |  |  |         remain = curPlayer.GetXP() - lostXPValue
 | 
 |  |  |         remain = max(0, remain)
 | 
 |  |  |         curPlayer.SetDict(ChConfig.Def_PlayerKey_RecordXPValue, remain)
 | 
 |  |  |         curPlayer.SetXP(remain)
 | 
 |  |  |     #===========================================================================
 | 
 |  |  |     # #-----------扣魔法
 | 
 |  |  |     # lostMPValue = curSkill.GetMP()
 | 
 |  |  |     # curPlayerMP = curPlayer.GetMP()
 | 
 |  |  |     #  | 
 |  |  |     # if curPlayerMP < lostMPValue:
 | 
 |  |  |     #    GameWorld.ErrLog('释放技能 = %s异常, 魔法 = %s不足 = %s' % (
 | 
 |  |  |     #                        curSkill.GetSkillTypeID(), curPlayerMP, lostMPValue))
 | 
 |  |  |     #  | 
 |  |  |     # if lostMPValue > 0:
 | 
 |  |  |     #    curPlayer.SetMP(curPlayer.GetMP() - lostMPValue)
 | 
 |  |  |     #    #自动回魔
 | 
 |  |  |     #    PlayerControl.PlayerAutoRestoreMP(curPlayer, tick)
 | 
 |  |  |     #  | 
 |  |  |     # #----------扣XP点
 | 
 |  |  |     # lostXPValue = curSkill.GetXP()
 | 
 |  |  |     # curPlayerXP = curPlayer.GetXP()
 | 
 |  |  |     #  | 
 |  |  |     # if curPlayerXP < lostXPValue:
 | 
 |  |  |     #    GameWorld.ErrLog('释放技能 = %s异常, XP点 = %s不足 = %s' % (
 | 
 |  |  |     #                        curSkill.GetSkillTypeID(), curPlayerXP, lostXPValue))
 | 
 |  |  |     #  | 
 |  |  |     # if lostXPValue > 0:
 | 
 |  |  |     #    remain = curPlayer.GetXP() - lostXPValue
 | 
 |  |  |     #    remain = max(0, remain)
 | 
 |  |  |     #    curPlayer.SetDict(ChConfig.Def_PlayerKey_RecordXPValue, remain)
 | 
 |  |  |     #    curPlayer.SetXP(remain)
 | 
 |  |  |     #===========================================================================
 | 
 |  |  | 
 | 
 |  |  |     #----------扣HP点
 | 
 |  |  |     lostHPValue = curSkill.GetHP()
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  |     # 暂且只有玩家被攻击触发
 | 
 |  |  |     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,技能,当前时间)
 | 
 |  |  | 
 |  |  |     #===========================================================================
 | 
 |  |  |     Sync_SkillHurtList(attacker, curSkill.GetSkillID(), srcPosX, srcPosY, g_skillHurtList)
 | 
 |  |  |         
 | 
 |  |  |     OnHurtTypeTriggerPassiveSkill(attacker, None, curSkill, tick)
 | 
 |  |  |     skillIDSet = set()
 | 
 |  |  |     #攻击结果 不处理触发逻辑
 | 
 |  |  |     for defObj in attackList:
 | 
 |  |  | 
 |  |  |             continue
 | 
 |  |  |         
 | 
 |  |  |         #放在函数中可多次触发 如SP 触发减速或者伤害,但不能放在攻击计算中,因为伤害型技能会影响伤血列表
 | 
 |  |  |         PassiveBuffEffMng.OnPassiveSkillTrigger(attacker, defObj, curSkill, ChConfig.TriggerType_AttackPlayer, tick,
 | 
 |  |  |         PassiveBuffEffMng.OnPassiveSkillTrigger(attacker, defObj, curSkill, ChConfig.TriggerType_StormAttackOneByOne, tick,
 | 
 |  |  |                                                 isEnhanceSkill=False, skillIDSet=skillIDSet)
 | 
 |  |  |         
 | 
 |  |  |         DoLogic_AttackResult(attacker, defObj, curSkill, tick)
 | 
 |  |  | 
 |  |  |             continue
 | 
 |  |  |         SkillCommon.SetSkillRemainTime(curSkill, 0, tick, attacker)
 | 
 |  |  |     
 | 
 |  |  |     if attackList:
 | 
 |  |  |         PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(attacker, attackList[0], curSkill, ChConfig.TriggerType_StormAttackReduceCD)
 | 
 |  |  |         PassiveBuffEffMng.OnPassiveSkillTrigger(attacker, attackList[0], curSkill, ChConfig.TriggerType_StormAttackOver, tick)
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | ## 清空伤血列表
 | 
 |  |  | #  @param 无
 | 
 |  |  | #  @return 无
 | 
 |  |  | 
 |  |  |         
 | 
 |  |  |     sendPack.HurtCount = len(sendPack.HurtList)
 | 
 |  |  | 
 | 
 |  |  |     PlayerControl.PyNotifyAll(curPlayer, sendPack, notifySelf=True, notifyCnt=0)
 | 
 |  |  |     PlayerControl.PyNotifyAll(curPlayer, sendPack, notifySelf=True, notifyCnt=-1)
 | 
 |  |  | 
 | 
 |  |  | 
 | 
 |  |  | # py重现View_UseSkillPos效果,对地通知,只用于玩家
 |