ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -33,6 +33,7 @@
import ShareDefine
import GameObj
import PassiveBuffEffMng
import IpyGameDataPY
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -98,7 +99,19 @@
    curSkill.SetLastUseTick(tick)
    coolDownTime = curSkill.GetCoolDownTime()
    remainTime = coolDownTime
    skillTypeID = curSkill.GetSkillTypeID()
    if atkObj and skillTypeID in IpyGameDataPY.GetFuncEvalCfg("SkillCD", 1):
        reduceSkillCDPer += PlayerControl.GetTheFBSkillsCD(atkObj)
    if isPassiveSkill(curSkill):
        if curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_GiftSkill:
            # 天赋有减CD效果
            reduceSkillCDPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, None, curSkill, ChConfig.TriggerType_GiftReduceCD)
            # 减CD比率
            if reduceSkillCDPer > 0:
                remainTime = int(remainTime * max(0, ShareDefine.Def_MaxRateValue - reduceSkillCDPer) / ShareDefine.Def_MaxRateValue)
        # 被动技能的处理和主动技能区分
        curSkill.SetRemainTime(remainTime)
        return
@@ -213,11 +226,12 @@
def PlayerLoginMergeServerSkillLogic(curPlayer, tick):
    playerID = curPlayer.GetPlayerID()
    if not GameWorld.IsMergeServer():
    if not GameWorld.IsCrossServer():
        GameWorld.DebugLog("非跨服服务器上线不清除buff...", playerID)
        return
    
    ClearBuffSkillTypeIDList = ReadChConfig.GetEvalChConfig("ClearBuffSkillTypeID")
    #ClearBuffSkillTypeIDList = ReadChConfig.GetEvalChConfig("ClearBuffSkillTypeID")
    ClearBuffSkillTypeIDList = []
    # 跨服服务器上线清除增益/减益buff
    GameWorld.Log("跨服服务器上线清除buff...", playerID)
    clearBuffList = [] # 先汇总再清除,不然索引会变更
@@ -272,6 +286,15 @@
            curSkill.SetRemainTime(0)
            GameWorld.DebugLog("        SetRemainTime 0 skillName=%s,skillTypeID=%s" 
                               % (curSkill.GetSkillName(), curSkill.GetSkillTypeID()), playerID)
    return
def ResetAllSkillCD(curPlayer):
    skillManager = curPlayer.GetSkillManager()
    for i in xrange(skillManager.GetSkillCount()):
        skill = skillManager.GetSkillByIndex(i)
        if skill.GetRemainTime() != 0:
            skill.SetRemainTime(0)
            skill.Sync_Skill()
    return
## 刷新玩家所有技能的剩余时间(上线)
@@ -465,6 +488,8 @@
    
    return int(value)
   
## 玩家召唤NPC(当前玩家,召唤技能,召唤兽ID,召唤兽属性列表, 召唤兽离自己的距离, 当前时间)
#  @param curPlayer 当前玩家
#  @param curSkill 召唤技能
@@ -507,6 +532,8 @@
        summonPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), summonDist)
        summonNPC.Reborn(summonPos.GetPosX(), summonPos.GetPosY())
    summonNPC.SetBornTime(tick)
    # 继承技能等级
    SetSummonNPCSkillLV(summonNPC, curSkill)
    if curSkill:
        summonNPC.SetLastTime(curSkill.GetLastTime())
    #----设置为无敌,在AI中解除无敌
@@ -514,6 +541,38 @@
    summonNPC.SetCanAttack(False)
    
    return 
# 召唤兽技能继承,玩家释放技能的等级
def SetSummonNPCSkillLV(summonNPC, curSkill):
    if curSkill.GetEffect(0).GetEffectValue(1) == 0:
        return
    skillLV = curSkill.GetSkillLV() - 1
    if skillLV == 0:
        return
    skillManager = summonNPC.GetSkillManager()
    learnSkillIDList =[]
    for index in range(0, skillManager.GetSkillCount()):
        useSkill = skillManager.GetSkillByIndex(index)
        #已经到尾部了
        if not useSkill or useSkill.GetSkillTypeID() == 0:
            break
        useSkillTypeID = useSkill.GetSkillTypeID()
        # 找到可学习的技能
        learnSkillID = useSkillTypeID + skillLV
        findSkill = GameWorld.GetGameData().GetSkillBySkillID(learnSkillID)
        if not findSkill:
            continue
        if findSkill.GetSkillTypeID() != useSkillTypeID:
            # 不是同一个技能
            continue
        learnSkillIDList.append(learnSkillID)
    for skillID in learnSkillIDList:
        skillManager.LearnSkillByID(skillID, False)
    return
## 设置召唤兽属性
#  @param curPlayer 当前玩家
@@ -624,10 +683,10 @@
# @param curNPC NPC实例
# @param summonID 召唤兽的NPCID
# @return 召唤兽数量
def GetSummonCountByNPCID(curNPC, summonID):
def GetSummonCountByNPCID(gameObj, summonID):
    count = 0
    for i in range(0, curNPC.GetSummonCount()):
        summonNPC = curNPC.GetSummonNPCAt(i)
    for i in range(0, gameObj.GetSummonCount()):
        summonNPC = gameObj.GetSummonNPCAt(i)
        
        if not summonNPC:
            continue
@@ -1127,6 +1186,10 @@
    if curHP <= 0:
        return
    
    if PassiveBuffEffMng.GetValueByPassiveBuffTriggerType(curObj, None, None, ChConfig.TriggerType_ForbidenCure):
        # 禁止治疗
        return
    # 治疗加成
    curePer = PlayerControl.GetCurePer(curObj) if curObjType == IPY_GameWorld.gotPlayer else ChConfig.Def_MaxRateValue 
    addValue = int(addValue*curePer*1.0/ChConfig.Def_MaxRateValue)
@@ -1165,37 +1228,24 @@
            
    return
## 获取哥布林功能NPC类型掉血值
def GetGoblinLostHP(defender, hurtValue):
    if not defender:
        return hurtValue
    defObjType = defender.GetGameObjType()
    if defObjType == IPY_GameWorld.gotNPC:
        npcFuncType = defender.GetFunctionType()
        if npcFuncType == ChConfig.Def_NPCFuncType_Goblin:
            goblinHurtValue = int(ReadChConfig.GetEvalChConfig('GoblinHurtValue'))
            hurtValue = min(hurtValue, goblinHurtValue)
    return hurtValue
## 技能伤血
#  @param curObj 当前对象
#  @param skillTypeID 技能类型ID
#  @param buffOwner buff拥有者
#  @param lostValue 丢失值
#  @param tick 当前时间
#  @param view 是否广播
#  @param reduce 是否扣血
#  @return None
#  @remarks 函数详细说明.
def SkillLostHP(curObj, skillTypeID, buffOwner, lostValue, tick, view=True, reduceHP=True,
                isDoAttackResult=True, hurtType=ChConfig.Def_HurtType_Normal):
## 直接扣血不走公式
# view 是否广播客户端飘血
# isDoAttackResult 是否立即处理结果,为False必须外层有处理
# hurtType 飘血类型
# skillAffect 默认True 会被各种技能BUFF盾等影响伤血数值
#             False代表一些特殊处理纯固定伤害飘字(如采集固定掉1点血)
def SkillLostHP(curObj, skillTypeID, buffOwner, lostValue, tick, view=True,
                isDoAttackResult=True, hurtType=ChConfig.Def_HurtType_Normal,
                skillAffect=True):
    if lostValue <= 0:
        GameWorld.Log('###技能伤害血量异常,数值错误 = %s,技能类型ID = %s' % (lostValue, skillTypeID))
        return
    
    #lostValue = GetGoblinLostHP(curObj, lostValue)
    if not curObj.GetCanAttack():
        # 无敌不掉血
        ## 后续有其他情况也应考虑进来,如镖车是否某状态不掉血
        return
    curObjType = curObj.GetGameObjType()
    curSkill = GameWorld.GetGameData().FindSkillByType(skillTypeID, 1)
    
@@ -1206,44 +1256,49 @@
    
    notifyLostValue = lostValue
    curObjHP_BeforeAttack = GameObj.GetHP(curObj)
    if curObjHP_BeforeAttack == 0:
        # 没有血量不能再触发
        return
    
    if reduceHP :
        # 血盾
        lostValue = AttackCommon.CalcBloodShield(buffOwner, curObj, lostValue)
        #剩余血量
        remainHP = max(curObjHP_BeforeAttack - lostValue , 0)
        #NPC处理
        if curObjType == IPY_GameWorld.gotNPC:
            #宠物特殊处理
            if curObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:
                PetControl.SetPetHP(curObj, remainHP)
            else:
                GameObj.SetHP(curObj, remainHP)
                if not view :   # 已广播的不重复
                    curObj.Notify_HPEx()
        #其他对象逻辑处理
    if skillAffect:
        lostValue = AttackCommon.CalcHurtHPWithBuff(buffOwner, curObj, lostValue, curSkill, tick)
    #剩余血量
    remainHP = max(curObjHP_BeforeAttack - lostValue , 0)
    #NPC处理
    if curObjType == IPY_GameWorld.gotNPC:
        #宠物特殊处理
        if curObj.GetGameNPCObjType() == IPY_GameWorld.gnotPet:
            PetControl.SetPetHP(curObj, remainHP)
        else:
            # 已广播的不重复
            GameObj.SetHP(curObj, remainHP, not view)
            GameObj.SetHP(curObj, remainHP)
            if not view :   # 已广播的不重复
                curObj.Notify_HPEx()
    #其他对象逻辑处理
    else:
        # 已广播的不重复
        GameObj.SetHP(curObj, remainHP, not view)
    
    AttackCommon.WriteHurtLog(buffOwner, curObj, curSkill, lostValue, hurtType, "持续掉血")
    if view:
        #广播伤血类型
        AttackCommon.ChangeHPView(curObj, buffOwner, skillTypeID, notifyLostValue, hurtType)
        if buffOwner:
            PassiveBuffEffMng.OnPassiveSkillTrigger(buffOwner, curObj, curSkill, ChConfig.TriggerType_AttackOverPassive, tick)
        
    # 濒死状态触发技能
    if GameObj.GetHP(curObj) == 0:
        PassiveBuffEffMng.OnPassiveSkillTrigger(curObj, None, curSkill, ChConfig.TriggerType_WillDead, tick)
        PassiveBuffEffMng.OnPassiveBuffTrigger(curObj, None, curSkill, ChConfig.TriggerType_WillDead, tick)
    
    #无法找到Buff拥有者
    if not buffOwner:
        AttackCommon.DoLogic_ObjDead(curObj)
        AttackCommon.DoLogic_ObjDead(None, curObj, curSkill, tick)
        return
        
    #NPC需要手动添加伤血和仇恨, 因为无调用DoAttack
    if curObjType == IPY_GameWorld.gotNPC:
        
@@ -1620,11 +1675,13 @@
        return True
    
    buffSkill = curObjBuff.GetSkill()
    buffSkillLV = buffSkill.GetSkillLV()
    
    #已存在更强大的效果
    if buffSkillLV > curSkillLV:
        return
    #buff根据情况可以叠加低级,或者低级覆盖高级
#    buffSkillLV = buffSkill.GetSkillLV()
#
#    #已存在更强大的效果
#    if buffSkillLV > curSkillLV:
#        return
        
    if not buffSkill.GetLastTime():
        #GameWorld.DebugLog("无时间限制buff,只要存在buff,则无需重复添加")
@@ -1697,6 +1754,35 @@
    
    return returnInfo
def FindBuffByOwner(gameObj, skillTypeID, ownerID, ownerType):
    findSkill = GameWorld.GetGameData().GetSkillBySkillID(skillTypeID)
    buffType = GetBuffType(findSkill)
    buffTuple = GetBuffManagerByBuffType(gameObj, buffType)
    if buffTuple == ():
        return None
    buffManager = buffTuple[0]
    for i in range(0, buffManager.GetBuffCount()):
        curBuff = buffManager.GetBuff(i)
        if not curBuff:
            continue
        #判断是否拥有同一类型的技能
        if curBuff.GetSkill().GetSkillTypeID() != skillTypeID:
            continue
        #判断是否拥有同一类型的技能
        if curBuff.GetOwnerID() != ownerID:
            continue
        if curBuff.GetOwnerType() != ownerType:
            continue
        return curBuff
    return None
#---------------------------------------------------------------------
## 执行清空命令 参数:玩家, 保留技能类型列表
#  @param curPlayer 玩家
@@ -1905,6 +1991,10 @@
# @return 返回值, 伤害数量
# @remarks 获得区域技能伤害对象数量
def GetSkillArea_Atk_Count(attacker, curSkill):
    if attacker.GetGameObjType() ==  IPY_GameWorld.gotPlayer and attacker.GetAttackMode() == IPY_GameWorld.amContest:
        # 单一目标锁定模式
        return 1
    #默认攻击最大数
    hurtCount = 50