ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -34,6 +34,7 @@
import GameObj
import PassiveBuffEffMng
import IpyGameDataPY
import TurnAttack
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -520,38 +521,6 @@
        
    return summonNPCList, maxBornIndex
## 获得持续性技能的总量(技能类型 -> 12,13)
#  @param curPlayer 当前玩家
#  @param curSkill 当前技能
#  @param skillPlus ,技能增益
#  @return value
#  @remarks 函数详细说明.
def GetLastSkillMaxValue(curPlayer , curSkill , skillPlus=None):
    #根据约定,总量一定是第0个效果
    curEffect = curSkill.GetEffect(0)
    index = curEffect.GetEffectValue(0)
    skillPer = curEffect.GetEffectValue(1)
    effect = curEffect.GetEffectValue(2)
    maxValue = EffGetSet.GetValueByEffIndex(curPlayer, index)
    #GameWorld.Log("持续伤害总值设置curSkill = %s,maxValue = %s skillPer = %s,effect = %s"%(curSkill.GetSkillName(),maxValue,skillPer,effect))
    if maxValue == None:
        GameWorld.Log("计算附加技能总量错误,skillID = %s,index = %s" % (curSkill.GetSkillID(), index) , curPlayer.GetPlayerID())
        return effect
    #总值
    value = 0
    if skillPlus == None :
        value = (maxValue * skillPer / ChConfig.Def_MaxRateValue) + effect
        #GameWorld.Log("持续伤害总值设置 value = %s"%value)
    else:
        plus = 1 + skillPlus / float(ChConfig.Def_MaxRateValue)
        value = (maxValue * (skillPer * plus) / ChConfig.Def_MaxRateValue) + effect
        #GameWorld.Log("持续伤害总值设置 value = %s 技能附加 = %s"%(value,plus))
    return int(value)
## 玩家召唤NPC(当前玩家,召唤技能,召唤兽ID,召唤兽属性列表, 召唤兽离自己的距离, 当前时间)
#  @param curPlayer 当前玩家
#  @param curSkill 召唤技能
@@ -573,7 +542,7 @@
    lvSummonNPC = curPlayer.GetLV()
    summonNPC.SetLV(lvSummonNPC)
    summonNPC.SetCountry(curPlayer.GetCountry())
    summonNPC.SetDict(ChConfig.Def_NpcDictKey_CampType, curPlayer.GetFaction())
    GameObj.SetFaction(summonNPC, curPlayer.GetFaction())
    summonNPC.GetNPCAngry().Init(ChConfig.Def_SummonNPC_Angry_Count)
    #设置召唤兽属性
    SetSummonNPCProperty(curPlayer, summonNPC, curSkill)
@@ -647,21 +616,6 @@
    if curSkill:
        Calc_Summon_BaseEffectBySkillPer(curPlayer, summonNPC, curSkill)
        return
#    #同一个召唤兽有10个等级, 所以必须用GetFunctionType来决定召唤兽的类型
#    summonID = summonNPC.GetFunctionType()
#
#    summonList = None
#    if ChConfig.Def_SummonProperty.has_key(summonID):
#        summonList = ChConfig.Def_SummonProperty[summonID]
#
#    #设置玩家被动技能对召唤兽属性的影响
#    __PassiveSkill_AddSummonAttribute(curPlayer, summonNPC, summonID)
#
#    if summonList != None:
#        lvSummonNPC = summonNPC.GetLV()
#        #设置召唤兽战斗信息
#        __CalcSummonEffectValue(lvSummonNPC, summonNPC, summonList)
    
    #计算基础总值
    Calc_Summon_BaseEffect(summonNPC)
@@ -909,67 +863,6 @@
    #返回值,技能释放成功
    return summonNPC
## 召唤兽使用技能召唤
#  @param curNPC 当前NPC
#  @param curSkill 当前技能
#  @param maxSummonCount 最大召唤数量
#  @param maxAngryCount 最大怒值数量
#  @param posX 重生坐标X
#  @param posY 重生坐标Y
#  @param tick 当前时间
#  @return 召唤兽
#  @remarks 函数详细说明.
#def SummonNPC_UseSkill_SummonNPC(curNPC, curSkill , maxSummonCount , maxAngryCount , posX, posY, tick):
#    #获得召唤兽ID
#    summonNPCID = curSkill.GetEffect(0).GetEffectValue(0)
#
#    if not summonNPCID:
#        return
#
#    #第一次召唤的时候,需要初始化最大召唤个数
#    if not curNPC.GetSummonCount() :
#        curNPC.SetSummonCount(maxSummonCount, summonNPCID, maxAngryCount)
#
#    #召唤兽召唤补足
#    elif curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotSummon and maxSummonCount > curNPC.GetSummonCount():
#        curNPC.AddSummonCount(maxSummonCount - curNPC.GetSummonCount(), summonNPCID, maxAngryCount)
#
#    #寻找一个可以召唤的NPC
#    summonIsFull = True
#    summonNPC = None
#
#    for i in range(0, curNPC.GetSummonCount()):
#        summonNPC = curNPC.GetSummonNPCAt(i)
#        if GameObj.GetHP(summonNPC) > 0:
#            continue
#
#        summonIsFull = False
#        break
#
#    #已经没有可召唤兽的召唤兽,满了
#    if summonIsFull:
#        return
#
#    #设置这个NPC属性,并召唤出这个NPC
#    NPCCommon.InitNPC(summonNPC)
#
#    summonNPC.Reborn(posX , posY)
#    summonNPC.SetBornTime(tick)
#    summonNPC.SetLastTime(curSkill.GetLastTime())
#
#    #返回summonNPC,技能释放成功
#    return summonNPC
## 设置玩家被动技能对召唤兽属性的影响
#  @param curPlayer 当前玩家
#  @param summonNPC 当前召唤兽
#  @param summonID 召唤兽ID
#  @return None
#  @remarks 函数详细说明.
def __PassiveSkill_AddSummonAttribute(curPlayer, summonNPC, summonID):
    return
## 根据效果获得值
#  @param valueList 
#  @param curSkill 当前技能
@@ -984,21 +877,6 @@
        returnList.append(value)
        
    return returnList 
## 计算NPC属性效果
#  @param lvSummonNPC 玩家
#  @param summonNPC 效果
#  @param summonList NPC
#  @return True
#  @remarks 函数详细说明.
def __CalcSummonEffectValue(lvSummonNPC, summonNPC, summonList):
    for value in summonList:
        curValue = EffGetSet.GetValueByEffIndex(summonNPC, value[0])
        #GameWorld.Log("当期属性 = %s index = %s"%(curValue,value[0]))
        #GameWorld.Log("设置属性 = %s"%(curValue + value[1] * lvSummonNPC))
        EffGetSet.SetValueByEffIndex(summonNPC, value[0], curValue + value[1] * lvSummonNPC)
    return True
## 设置这个召唤兽的基础属性
#  @param summonNPC 召唤兽
@@ -1225,21 +1103,17 @@
#  @param addValue 添加值
#  @return None
#  @remarks 函数详细说明.
def SkillAddHP(curObj, skillTypeID, addValue, isNotify=True):
def SkillAddHP(curObj, skillID, addValue, isNotify=True, srcObj=None):
    if not srcObj:
        srcObj = curObj
    curObjType = curObj.GetGameObjType()
    
    #=======================================================================
    # if curObj.GetMapID() in ChConfig.CanNotRecoverMapIDList and skillTypeID not in ChConfig.ForceRecoverSkillList:
    #    GameWorld.DebugLog("该地图无法使用技能恢复血量!")
    #    return
    #=======================================================================
    if GameObj.GetPyPlayerState(curObj, ChConfig.Def_PlayerState_LimitAddHP):
        #GameWorld.DebugLog("当前禁疗状态下,无法恢复!")
        return
    
    if addValue <= 0:
        GameWorld.Log('###技能回复血量异常,数值错误 = %s,技能类型ID = %s' % (addValue , skillTypeID))
        GameWorld.Log('###技能回复血量异常,数值错误 = %s,技能ID = %s' % (addValue , skillID))
        return
    
    curHP = GameObj.GetHP(curObj)
@@ -1253,23 +1127,26 @@
        return
    
    # 治疗加成
    curePer = PlayerControl.GetCurePer(curObj) if curObjType == IPY_GameWorld.gotPlayer else ChConfig.Def_MaxRateValue
    addValue = int(addValue*curePer*1.0/ChConfig.Def_MaxRateValue)
    #curePer = PlayerControl.GetCurePer(curObj) if curObjType == IPY_GameWorld.gotPlayer else ChConfig.Def_MaxRateValue
    #addValue = int(addValue*curePer*1.0/ChConfig.Def_MaxRateValue)
    
    maxHP = GameObj.GetMaxHP(curObj)
    
    #血已最大值,不再恢复,跳出
    if curHP == maxHP:
    if curHP >= maxHP:
        GameWorld.DebugLog("满血不用回血,只通知回血表现!")
        #广播加血类型
        if isNotify:
            AttackCommon.ChangeHPView(curObj, curObj, skillTypeID, addValue, ChConfig.Def_HurtTYpe_Recovery)
        return
            AttackCommon.ChangeHPView(curObj, srcObj, skillID, addValue, ChConfig.Def_HurtTYpe_Recovery)
        return addValue
    
    remainHP = min(curHP + addValue, maxHP)
    cureHP = remainHP - curHP # 实际治疗量
    TurnAttack.AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID)
    
    #---玩家处理---
    if curObjType == IPY_GameWorld.gotPlayer:
        GameObj.SetHP(curObj, remainHP, not isNotify)
        GameObj.SetHP(curObj, remainHP, False) # 先不通知
        FBLogic.OnFBAddHP(curObj, addValue)
    
    #---NPC处理---
@@ -1279,15 +1156,12 @@
            PetControl.SetPetHP(curObj, remainHP)
        #普通NPC回血
        else:
            GameObj.SetHP(curObj, remainHP)
            if not isNotify:
                #已广播的不重复
                curObj.Notify_HP()
            GameObj.SetHP(curObj, remainHP, False) # 先不通知
    #广播加血类型
    if isNotify:
        AttackCommon.ChangeHPView(curObj, curObj, skillTypeID, addValue, ChConfig.Def_HurtTYpe_Recovery)
        AttackCommon.ChangeHPView(curObj, srcObj, skillID, addValue, ChConfig.Def_HurtTYpe_Recovery)
    return
## 直接扣血不走公式
@@ -1355,6 +1229,8 @@
    else:
        # 已广播的不重复
        GameObj.SetHP(curObj, remainHP, not view)
    lostHP = curObjHP_BeforeAttack - GameObj.GetHP(curObj) # 实际掉血量
    
    AttackCommon.WriteHurtLog(buffOwner, curObj, curSkill, lostValue, hurtType, "持续掉血")
    if view:
@@ -1408,10 +1284,14 @@
        elif curObjType == IPY_GameWorld.gotNPC:
            AttackCommon.NPCAddObjInHurtList(attackerOwner, curObj, curObjHP_BeforeAttack, lostValue)
            
    TurnAttack.AddTurnObjHurtValue(buffOwner, curObj, hurtType, lostValue, lostHP, curSkill)
    #统一调用攻击结束动作
    if isDoAttackResult:
        BaseAttack.DoLogic_AttackResult(buffOwner, curObj, None, tick)
    return
    TurnAttack.OnTurnfightAttackResult(buffOwner, curObj, curSkill)
    return lostHP
## 检查增加淬毒buff
#  @param skillTypeID 使用的技能typeID
@@ -1968,7 +1848,15 @@
    if not curSkill:
        return ChConfig.Def_BattleRelationType_Comm
    #0通哟  1 PVP类型  2PVE类型  
    return curSkill.GetHurtType()
    return curSkill.GetHurtType() % 10
def isAngerSkill(curSkill):
    ## 是否怒气技能
    return curSkill and curSkill.GetXP() > 0
def isTurnNormalSkill(curSkill):
    ## 是否回合普攻技能,区别与无技能的普通A一下,该普攻同样可以有各种技能效果,只是他属于普攻
    return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaSkill
## 检查技能是否为被动技能, 用于控制不可释放技能
def isPassiveSkill(curSkill):
@@ -2057,34 +1945,7 @@
#  @param useSkill 使用的技能
#  @return 基础治疗值
#  @remarks 函数详细说明.
def GetCureBaseValue(attacker, useSkill):
    return GetAttackerHurtValueByAtkType(attacker, AttackCommon.GetBattleType(attacker, useSkill))
## 获得基础伤害值(目前用于持续性技能的计算)
#  @param attacker 攻击者
#  @param useSkill 使用的技能
#  @return 基础伤害值
#  @remarks 获得基础伤害值
def GetHurtBaseValue(attacker, useSkill):
    return GetAttackerHurtValueByAtkType(attacker, AttackCommon.GetBattleType(attacker, useSkill))
#---------------------------------------------------------------------
## 通过攻击类型获得攻击方伤害值
#  @param attacker 攻击者
#  @param atkType 攻击类型(物理攻击、摩法攻击)
#  @return 攻击方伤害值
#  @remarks 通过攻击类型获得攻击方伤害值
def GetAttackerHurtValueByAtkType(attacker, atkType):
    return (attacker.GetMinAtk() + random.random() * (attacker.GetMaxAtk() - attacker.GetMinAtk()))
    #===========================================================================
    # if atkType == IPY_GameWorld.ghtPhy:
    #    #(最小攻击 + rand()*( 最大攻击伤害-最小攻击伤害 )
    #    return (attacker.GetMinAtk() + random.random() * (attacker.GetMaxAtk() - attacker.GetMinAtk()))
    #
    # #(最小剑气伤害 + rand()*( 最大剑气伤害-最小剑气伤害 )
    # return (attacker.GetMAtkMin() + random.random() * (attacker.GetMAtkMax() - attacker.GetMAtkMin()))
    #===========================================================================
def GetCureBaseValue(attacker, useSkill): return attacker.GetMaxAtk()
#---------------------------------------------------------------------
## 获得某技能管理器是否有特定技能
@@ -2202,19 +2063,6 @@
    curePercent = 1.0     #治疗加成值
    cureBaseValue = 0     #治疗基础值
    
    #passiveSkill = GetSkillFromOtherSkillByEffectID(userObj, curSkill, ChConfig.Def_Skill_Effect_PassiveSkillID)
    #该被动技能已学, 则处理被动影响的效果
    #===========================================================================
    # if passiveSkill != None and isPassiveSkill(passiveSkill):
    #    cureEffect = GetSkillEffectByEffectID(passiveSkill, ChConfig.Def_Skill_Effect_CureUpper)
    #
    #    #计算治疗加成,按几率触发
    #    if GameWorld.CanHappen(passiveSkill.GetHappenRate(), ChConfig.Def_MaxRateValue) \
    #    and cureEffect != None:
    #        curePercent += cureEffect.GetEffectValue(0) / float(ChConfig.Def_MaxRateValue)
    #===========================================================================
    #特殊技能的附加值
    addExValue = 0 
    
@@ -2233,27 +2081,46 @@
        cureBaseValue = GameObj.GetLastHurtValue(userObj)
    elif cureType == ChConfig.Def_Cure_TagMaxHP:
        cureBaseValue = 0 if not tagObj else GameObj.GetMaxHP(tagObj)
    #这边写死了效果1,基本已经定型
    #获得技能的计算参数值
    if cureType == ChConfig.Def_Cure_PHY:
        # 根据敏捷,力量差值及效果系数计算恢复比例
        skillPer = max(0, userObj.GetPHY() - userObj.GetSTR()) / float(curSkill.GetEffect(0).GetEffectValue(0))
        GameWorld.DebugLog("英勇复苏: 敏=%s,力=%s,skillPer=%s" % (userObj.GetPHY(), userObj.GetSTR(), skillPer))
    else:
        skillPer = curSkill.GetEffect(0).GetEffectValue(0) / float(ChConfig.Def_MaxRateValue)
    #技能附加
    #elif cureType == ChConfig.Def_Cure_TagAtk:
    #    cureBaseValue = 0 if not tagObj else GetCureBaseValue(tagObj, curSkill)
    #elif cureType == ChConfig.Def_Cure_LostHP:
    #    cureBaseValue = max(0, GameObj.GetMaxHP(userObj) - GameObj.GetHP(userObj))
    #elif cureType == ChConfig.Def_Cure_BeHurtValue:
    #    cureBaseValue = GameObj.GetLastBeHurtValue(userObj)
    skillPer = curSkill.GetEffect(0).GetEffectValue(0)
    #技能附加固定值
    skillValue = curSkill.GetEffect(0).GetEffectValue(1)
    
    skillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(userObj, None, curSkill, ChConfig.TriggerType_AddHP)/float(ChConfig.Def_MaxRateValue)
    skillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(userObj, None, curSkill, ChConfig.TriggerType_AddHP)
    skillPer /= float(ChConfig.Def_MaxRateValue)
    # 回合制
    curePer = 0 # 治疗加成
    cureDefPer = 0 # 敌方的弱化治疗
    angerOverflow = 0 # 怒气溢出值
    if userObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
        if isAngerSkill(curSkill):
            angerOverflow = max(GameObj.GetXP(userObj) - IpyGameDataPY.GetFuncCfg("AngerXP", 2), 0)
        #enemyObj = TurnAttack.GetEnemyObj(userObj)
        #curePer += GameObj.GetCurePer(userObj)
        #if enemyObj:
        #    cureDefPer += GameObj.GetCureDefPer(enemyObj)
    curePer /= float(ChConfig.Def_MaxRateValue)
    cureDefPer /= float(ChConfig.Def_MaxRateValue)
    baseValue = max(0, cureBaseValue) # 防止基值被弱化为负值,在恢复比例也是负值的情况下负负得正导致可以恢复血量
    #公式计算治疗值 
    cureHP = int((cureBaseValue * skillPer + skillValue + addExValue) * curePercent)
    cureHP = eval(IpyGameDataPY.GetFuncCompileCfg("CureFormula", 1))
    #cureHP = (cureHP + skillValue + addExValue) * curePercent # 策划没有要求,但是支持的,先屏蔽
    if not largeNum:
        cureHP = min(cureHP, ChConfig.Def_UpperLimit_DWord)
    cureHP = max(1, int(cureHP)) # 保底1点
    
    #GameWorld.DebugLog("获取治疗值(%s):cureType=%s,cureBaseValue=%s,skillPer=%s,skillValue=%s"
    #                   % (cureHP, cureType, cureBaseValue, skillPer, skillValue))
    GameWorld.DebugLog("获取治疗值(%s):skillID=%s,cureType=%s,baseValue=%s,skillPer=%s,curePer=%s,cureDefPer=%s,angerOverflow=%s"
                       % (cureHP, curSkill.GetSkillID(), cureType, baseValue, skillPer, curePer, cureDefPer, angerOverflow))
    return cureHP
@@ -2296,146 +2163,54 @@
#  @return 
def UpdateSkillCombo(attacker, skill, tick):
    return
    #===========================================================================
    # if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
    #    return
    #
    # SkillComboDict = ReadChConfig.GetEvalChConfig("SkillCombo")
    # jobType = ChConfig.JOB_TYPE_DICT[attacker.GetJob()]
    #
    # if jobType not in SkillComboDict:
    #    return
    #
    # jobSkillComboDict = SkillComboDict[jobType]
    #
    # curSkillTypeID = skill.GetSkillTypeID()
    #
    # isCombo = False
    # lastComboTick = attacker.GetDictByKey(ChConfig.Def_PlayerKey_LastSkillComboTick)
    # comboCnt = attacker.GetDictByKey(ChConfig.Def_PlayerKey_SkillComboCnt)
    # buffProcessState = attacker.GetDictByKey(ChConfig.Def_PlayerKey_ComboBuffProcessState)
    # # 持续性伤害buff已处理过不再处理
    # if curSkillTypeID in ChConfig.Ded_ComboBuffProcessSkillIDList and buffProcessState:
    #    #GameWorld.DebugLog("持续性伤害buff已处理过不再处理:%s" % curSkillTypeID)
    #    return
    #
    # for comboNum, comboInfo in jobSkillComboDict.items():
    #
    #    skillList = comboInfo[0]
    #    stateSkillReq = comboInfo[1]
    #    comboInterval = comboInfo[2]
    #    addHurtPerFormat = comboInfo[3]
    #    modulusPlusHappenRate = comboInfo[4]    # 伤害系数加成概率万分率
    #    modulusPlusFormat = comboInfo[5]    # 伤害系数公式
    #
    #    if curSkillTypeID not in skillList:
    #        continue
    #
    #    # 如果有姿态要求
    #    if stateSkillReq != 0:
    #        buffState = attacker.GetBuffState()
    #        if buffState.FindBuff(stateSkillReq) == None:
    #            #GameWorld.DebugLog("非对应职业姿态(%s),无法连击!" % stateSkillReq)
    #            continue
    #
    #    curComboCnt = skillList.index(curSkillTypeID) + 1 # 当前技能所在连击数
    #
    #    # 在规定时间内完成连击
    #    #GameWorld.DebugLog("skillList=%s, curSkillTypeID=%s,comboCnt=%s,curComboCnt=%s,tick=%s,lastComboTick=%s,(%s),comboInterval=%s"
    #    #                   % (skillList, curSkillTypeID, comboCnt, curComboCnt, tick, lastComboTick, tick - lastComboTick, comboInterval))
    #    if comboCnt > 0 and (comboCnt + 1) == curComboCnt and (tick - lastComboTick) <= comboInterval:
    #        isCombo = True
    #        #GameWorld.DebugLog("    连击成功!")
    #
    #    # 第一击
    #    elif curComboCnt == 1:
    #        GameWorld.DebugLog("    技能第一击!")
    #        comboCnt = 0
    #        isCombo = True
    #
    #    if isCombo:
    #        STR = attacker.GetSTR()
    #        PHY = attacker.GetPHY()
    #        modulus = 1 # 伤害系数
    #        if GameWorld.CanHappen(modulusPlusHappenRate):
    #            modulus = eval(modulusPlusFormat)
    #        addHurtPer = eval(addHurtPerFormat)
    #        attacker.SetDict(ChConfig.Def_PlayerKey_LastSkillComboTick, tick)
    #        attacker.SetDict(ChConfig.Def_PlayerKey_SkillComboCnt, curComboCnt)
    #        attacker.SetDict(ChConfig.Def_PlayerKey_ComboSkillTypeID, curSkillTypeID)
    #        attacker.SetDict(ChConfig.Def_PlayerKey_ComboAddHurtPer, addHurtPer)
    #        if curSkillTypeID in ChConfig.Ded_ComboBuffProcessSkillIDList:
    #            attacker.SetDict(ChConfig.Def_PlayerKey_ComboBuffProcessState, 1)
    #            #GameWorld.DebugLog("    持续性伤害buff连击!%s" % curSkillTypeID)
    #
    #
    #        # 通知客户端连击数
    #        skillComboPack = ChPyNetSendPack.tagMCSkillCombo()
    #        skillComboPack.Clear()
    #        skillComboPack.ComboNum = comboNum
    #        skillComboPack.ComboCnt = curComboCnt
    #        NetPackCommon.SendFakePack(attacker, skillComboPack)
    #        GameWorld.DebugLog("技能连击: num=%s,curCnt=%s,comboCnt=%s,力=%s,敏=%s,modulus=%s,addHurtPer=%s"
    #                           % (comboNum, curComboCnt, comboCnt, STR, PHY, modulus, addHurtPer))
    #        break
    #
    # # 没有连击成功, 重置连击信息
    # if not isCombo and comboCnt != 0:
    #    attacker.SetDict(ChConfig.Def_PlayerKey_LastSkillComboTick, 0)
    #    attacker.SetDict(ChConfig.Def_PlayerKey_SkillComboCnt, 0)
    #    attacker.SetDict(ChConfig.Def_PlayerKey_ComboSkillTypeID, 0)
    #    attacker.SetDict(ChConfig.Def_PlayerKey_ComboAddHurtPer, 0)
    #    attacker.SetDict(ChConfig.Def_PlayerKey_ComboBuffProcessState, 0)
    #    GameWorld.DebugLog("连击失败!curSkillTypeID=%s" % curSkillTypeID)
    #
    # return
    #===========================================================================
def GetSkillAddPerByID(curPlayer, skillTypeID):
    ## 获取技能伤害百分比提升值
    # @param skillTypeID: 技能TypeID
    SkillAddPerAttrIDDict = IpyGameDataPY.GetConfigEx("SkillAddPerAttrIDDict")
    if not SkillAddPerAttrIDDict:
        SkillAddPerAttrIDDict = {}
        skillPlusAttrIDDict = IpyGameDataPY.GetFuncEvalCfg("SkillPlusAttrID", 2, {})
        for attrIDStr, skillTypeIDList in skillPlusAttrIDDict.items():
            attrID = int(attrIDStr)
            if attrID not in ShareDefine.SkillAddPerAttrIDList:
                continue
            for cfgSkillTypeID in skillTypeIDList:
                SkillAddPerAttrIDDict[cfgSkillTypeID] = attrID
        IpyGameDataPY.SetConfigEx("SkillAddPerAttrIDDict", SkillAddPerAttrIDDict)
    if skillTypeID not in SkillAddPerAttrIDDict:
        return 0
    curAttrID = SkillAddPerAttrIDDict[skillTypeID]
    attrInfo = ChConfig.ItemEffect_AttrDict.get(curAttrID, [])
    if attrInfo == []:
        return 0
    effIndex = attrInfo[0][0]
    return EffGetSet.GetValueByEffIndex(curPlayer, effIndex)
    return 0
#    SkillAddPerAttrIDDict = IpyGameDataPY.GetConfigEx("SkillAddPerAttrIDDict")
#    if not SkillAddPerAttrIDDict:
#        SkillAddPerAttrIDDict = {}
#        skillPlusAttrIDDict = IpyGameDataPY.GetFuncEvalCfg("SkillPlusAttrID", 2, {})
#        for attrIDStr, skillTypeIDList in skillPlusAttrIDDict.items():
#            attrID = int(attrIDStr)
#            if attrID not in ShareDefine.SkillAddPerAttrIDList:
#                continue
#            for cfgSkillTypeID in skillTypeIDList:
#                SkillAddPerAttrIDDict[cfgSkillTypeID] = attrID
#        IpyGameDataPY.SetConfigEx("SkillAddPerAttrIDDict", SkillAddPerAttrIDDict)
#
#    if skillTypeID not in SkillAddPerAttrIDDict:
#        return 0
#    curAttrID = SkillAddPerAttrIDDict[skillTypeID]
#    attrInfo = ChConfig.ItemEffect_AttrDict.get(curAttrID, [])
#    if attrInfo == []:
#        return 0
#    effIndex = attrInfo[0][0]
#    return EffGetSet.GetValueByEffIndex(curPlayer, effIndex)
def GetSkillReducePerByID(curPlayer, skillTypeID):
    ## 获取技能伤害百分比减伤值
    # @param skillTypeID: 技能TypeID
    SkillReducePerAttrIDDict = IpyGameDataPY.GetConfigEx("SkillReducePerAttrIDDict")
    if not SkillReducePerAttrIDDict:
        SkillReducePerAttrIDDict = {}
        skillPlusAttrIDDict = IpyGameDataPY.GetFuncEvalCfg("SkillPlusAttrID", 2, {})
        for attrIDStr, skillTypeIDList in skillPlusAttrIDDict.items():
            attrID = int(attrIDStr)
            if attrID not in ShareDefine.SkillReducePerAttrIDList:
                continue
            for cfgSkillTypeID in skillTypeIDList:
                SkillReducePerAttrIDDict[cfgSkillTypeID] = attrID
        IpyGameDataPY.SetConfigEx("SkillReducePerAttrIDDict", SkillReducePerAttrIDDict)
    if skillTypeID not in SkillReducePerAttrIDDict:
        return 0
    curAttrID = SkillReducePerAttrIDDict[skillTypeID]
    attrInfo = ChConfig.ItemEffect_AttrDict.get(curAttrID, [])
    if attrInfo == []:
        return 0
    effIndex = attrInfo[0][0]
    return EffGetSet.GetValueByEffIndex(curPlayer, effIndex)
    return 0
#    SkillReducePerAttrIDDict = IpyGameDataPY.GetConfigEx("SkillReducePerAttrIDDict")
#    if not SkillReducePerAttrIDDict:
#        SkillReducePerAttrIDDict = {}
#        skillPlusAttrIDDict = IpyGameDataPY.GetFuncEvalCfg("SkillPlusAttrID", 2, {})
#        for attrIDStr, skillTypeIDList in skillPlusAttrIDDict.items():
#            attrID = int(attrIDStr)
#            if attrID not in ShareDefine.SkillReducePerAttrIDList:
#                continue
#            for cfgSkillTypeID in skillTypeIDList:
#                SkillReducePerAttrIDDict[cfgSkillTypeID] = attrID
#        IpyGameDataPY.SetConfigEx("SkillReducePerAttrIDDict", SkillReducePerAttrIDDict)
#
#    if skillTypeID not in SkillReducePerAttrIDDict:
#        return 0
#    curAttrID = SkillReducePerAttrIDDict[skillTypeID]
#    attrInfo = ChConfig.ItemEffect_AttrDict.get(curAttrID, [])
#    if attrInfo == []:
#        return 0
#    effIndex = attrInfo[0][0]
#    return EffGetSet.GetValueByEffIndex(curPlayer, effIndex)