10019 【砍树】回合战斗(灵宠通用;技能通用;玩家镜像支持)
1. 灵宠修改为通用模式,玩家及NPC均可召唤灵宠,NPC对应召唤的灵宠NPC与玩家的灵宠NPCID区分;
2. 技能全部为通用技能,玩家、玩家镜像、NPC均通用;支持玩家镜像赋予玩家技能进行攻击;
3. 技能释放方式8(单体恢复:增加方式6-按目标攻击力恢复血量)
4. 修改玩家技能缓存格式
5. 修复玩家灵宠技能升级bug
8个文件已修改
172 ■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -2101,6 +2101,7 @@
            suppressFightPower = max(0, suppressNPCFightPower - PlayerControl.GetFightPower(defObj))
            
    mustHit = False
    petNPCOwner = None
    helpBattleFormatKey = ""
    if atkObjType == IPY_GameWorld.gotNPC and atkObj.GetType() == ChConfig.ntHelpBattleRobot:
        mustHit = True
@@ -2116,6 +2117,7 @@
        helpBattleFormatKey = "HelpRobot_Def"
    if atkObjType == IPY_GameWorld.gotNPC and PetControl.IsPetNPC(atkObj):
        mustHit = True
        petNPCOwner = PetControl.GetPetNPCOwner(atkObj)
        
    #命中公式 攻击方类型不同,公式不同
    hitFormula = ReadChConfig.GetChConfig('CalcCanHit')
@@ -2218,7 +2220,12 @@
    #------- 攻击方
    aMinAtk = atkObj.GetMinAtk() * summonAtkPer        # 攻击方最小攻击
    aMaxAtk = atkObj.GetMaxAtk() * summonAtkPer       # 攻击方最大攻击
    if petNPCOwner:
        #主人攻击力可能会变化,所以在这里用到时直接取
        aMinAtk = petNPCOwner.GetMinAtk() * summonAtkPer        # 攻击方最小攻击
        aMaxAtk = petNPCOwner.GetMaxAtk() * summonAtkPer       # 攻击方最大攻击
        #GameWorld.DebugLog("灵宠攻击,直接取主人攻击力: %s ~ %s,  自己: %s ~ %s" % (aMinAtk, aMaxAtk, atkObj.GetMinAtk(), atkObj.GetMaxAtk()))
    aIceAtk = atkObj.GetIceAtk()        # 冰攻, 元素真伤, 玩家及NPC通用
    aIceAtk += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(atkObj, defObj, curSkill, ChConfig.TriggerType_AddIceAtk)
    #------- 防守方
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -41,6 +41,9 @@
def GetObjName(gameObj):
    objName = gameObj.GetName()
    mirrorPlayerID = gameObj.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID)
    if mirrorPlayerID:
        objName = "%s[%s]" % (objName, mirrorPlayerID)
    faction = GameObj.GetFaction(gameObj)
    fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum)
    return "%s%s %s" % ("A" if faction == 1 else "B", fightPlaceNum, objName)
@@ -89,7 +92,7 @@
    tagObj = None
    if tagPlayerID:
        npcID = ChConfig.Def_NPCID_PVP
        tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID, pvpPlayerID=tagPlayerID)
        tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID, mirrorPlayerID=tagPlayerID)
        if not tagObj:
            return
        PlusData = PlayerViewCacheTube.GetPlayerPropPlusDictByID(playerID)[1] # 从缓存中获取
@@ -343,6 +346,8 @@
    tagID = tagObj.GetID()
    if curObj.GetGameObjType() == IPY_GameWorld.gotPlayer: 
        atkOK = PlayerAttack(curObj, tagObj, tick)
    elif curObj.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID):
        atkOK = PlayerMirrorAttack(curObj, tagObj, tick)
    else:
        atkOK = NPCAttack(curObj, tagObj, tick)
        
@@ -468,14 +473,49 @@
        GameWorld.DebugLog("        %s 技能攻击: curID=%s,tagID=%s,atkOK=%s" % (objName, curObj.GetID(), tagObj.GetID(), atkOK))
    return atkOK
def PlayerMirrorAttack(playerNPC, tagObj, tick):
    ## 玩家镜像攻击
    playerID = playerNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID)
    objName = "● %s" % GetObjName(playerNPC)
    tagObjID = tagObj.GetID()
    autoUseSkillTypeIDList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 2, {})
    tagDist = 0
    skillManager = playerNPC.GetSkillManager()
    for skillTypeID in autoUseSkillTypeIDList:
        curSkill = skillManager.FindSkillBySkillTypeID(skillTypeID)
        if not curSkill:
            continue
        skillID = curSkill.GetSkillID()
        #被动技能无法使用
        if SkillCommon.isPassiveSkill(curSkill):
            continue
        #还在冷却时间内无法释放
        if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0:
            continue
        if not AICommon.DoNPCUseSkill(playerNPC, tagObj, curSkill, tagDist, tick):
            GameWorld.DebugLog("        %s 技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (objName, playerID, tagObjID, skillID))
            continue
        GameWorld.DebugLog("        %s 技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (objName, playerID, tagObjID, skillID))
        return skillID
    #普通攻击
    atkOK = BaseAttack.Attack(playerNPC, tagObj, None, tick)
    if atkOK:
        GameWorld.DebugLog("        %s 普通攻击: curID=%s,tagID=%s,atkOK=%s" % (objName, playerID, tagObjID, atkOK))
    else:
        GameWorld.DebugLog("        %s 攻击失败: curID=%s,tagID=%s,atkOK=%s" % (objName, playerID, tagObjID, atkOK))
    return atkOK
def PlayerAttack(curPlayer, tagObj, tick):
    ## 玩家攻击, 参考技能使用 #def UseSkillEx(index, clientData, tick):
    playerID = curPlayer.GetPlayerID()
    job = curPlayer.GetJob()
    jobAutoUseSkillDict = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 2, {})
    if job not in jobAutoUseSkillDict:
        return
    skillList = jobAutoUseSkillDict[job]
    autoUseSkillTypeIDList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 2, {})
    
    posX, posY = tagPosX, tagPosY = curPlayer.GetPosX(), curPlayer.GetPosY()
    tagObjType, tagObjID = tagObj.GetGameObjType(), tagObj.GetID()
@@ -493,10 +533,11 @@
    
    useSkillResult = False
    skillMgr = curPlayer.GetSkillManager()
    for skillID in skillList:
        curSkill = skillMgr.FindSkillBySkillID(skillID)
    for skillTypeID in autoUseSkillTypeIDList:
        curSkill = skillMgr.FindSkillBySkillTypeID(skillTypeID)
        if not curSkill:
            continue
        skillID = curSkill.GetSkillID()
        
        #CheckSkillCondition
        #被动技能无法使用
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1195,7 +1195,8 @@
Def_Cure_PHY, # 敏捷 3
Def_Cure_HurtValue, # 伤害值 4
Def_Cure_TagMaxHP, # 目标最大生命值 5
) = range(6)
Def_Cure_TagAtk, # 目标攻击力 6
) = range(7)
#回魔类型(影响公式参数)
Def_RestoreTypeList = (
@@ -3093,7 +3094,7 @@
Def_NPC_Dict_SummonMapNPCPlayerID = 'SummonMapNPCPlayerID'
Def_NPC_Dict_SummonRefreshID = 'SummonRefreshID'
Def_NPC_Dict_PriWoodPilePlayerID = 'PriWoodPilePlayerID'
Def_NPC_Dict_PVPPlayerID = 'PVPPlayerID'
Def_NPC_Dict_MirrorPlayerID = 'MirrorPlayerID' # 镜像玩家ID
#NPC技能已使用次数
Def_NPC_Dict_SkillUseCnt = 'NPCSkillUseCnt_%s' # 参数skillTypeID
#不死的boss
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -2268,7 +2268,7 @@
# @param aiType: AI类型
# @return 如果召唤失败返回None 否则返回召唤的NPC的实例
# @remarks 在地图里召唤NPC 根据NPCID 出生点 AI类型 和TICK
def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0, sightLevel=0, refreshID=0, pvpPlayerID=0):
def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0, sightLevel=0, refreshID=0, mirrorPlayerID=0):
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcId)
    if not npcData:
        GameWorld.ErrLog("找不到该NPCID: %s" % npcId)
@@ -2300,8 +2300,8 @@
    if curSummon.GetType() == ChConfig.ntRobot:
        __OnFBRobotReborn(curSummon, curSummon.GetLV())
        
    if curSummon.GetType() == ChConfig.ntPVP and pvpPlayerID:
        curSummon.SetDict(ChConfig.Def_NPC_Dict_PVPPlayerID, pvpPlayerID)
    if mirrorPlayerID:
        curSummon.SetDict(ChConfig.Def_NPC_Dict_MirrorPlayerID, mirrorPlayerID)
        
    curSummon.Reborn(rebornX, rebornY, False)
    NPCControl(curSummon).DoNPCRebornCommLogic(tick)
@@ -2506,8 +2506,8 @@
    if summonPlayerID > 0:
        curNPC.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, 0)
        
    if curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PVPPlayerID):
        curNPC.SetDict(ChConfig.Def_NPC_Dict_PVPPlayerID, 0)
    if curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID):
        curNPC.SetDict(ChConfig.Def_NPC_Dict_MirrorPlayerID, 0)
        
    refreshObj = NPCRealmRefresh.GetTagNPCRefresh(curNPC)
    if refreshObj:
@@ -4125,9 +4125,9 @@
        if PetControl.RefurbishPetAttr(curNPC):
            return
        
        pvpPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PVPPlayerID)
        if pvpPlayerID:
            self.SetPVPNPCPlayerAttr(pvpPlayerID)
        mirrorPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID)
        if mirrorPlayerID:
            self.SetMirrorPlayerNPCAttr(mirrorPlayerID, isReborn)
        else:
            DoNPCAttrStrengthen(curNPC, isReborn)
            
@@ -4142,8 +4142,9 @@
            
        return
    
    def SetPVPNPCPlayerAttr(self, pvpPlayerID):
        PropDict, PlusDict = PlayerViewCacheTube.GetPlayerPropPlusDictByID(pvpPlayerID)
    def SetMirrorPlayerNPCAttr(self, mirrorPlayerID, isReborn):
        ## 设置镜像玩家NPC属性
        PropDict, PlusDict = PlayerViewCacheTube.GetPlayerPropPlusDictByID(mirrorPlayerID)
        if not PropDict:
            return
        curNPC = self.__Instance
@@ -4166,18 +4167,26 @@
        GameObj.SetAtkBackDefRate(curNPC, PropDict.get("AtkBackDefRate", 0))
        GameObj.SetSuckHPPer(curNPC, PropDict.get("SuckHPPer", 0))
        GameObj.SetSuckHPDefPer(curNPC, PropDict.get("SuckHPDefPer", 0))
        if not isReborn:
            return
        skillManager = curNPC.GetSkillManager()
        SkillInfo = PlusDict.get("SkillInfo", {})
        for _, skillLVDict in SkillInfo.items():
            for skillID, _ in skillLVDict.items():
                skillID = GameWorld.ToIntDef(skillID)
                skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
                if not skillData:
                    continue
                skillManager.LearnSkillByID(skillID)
                
        GameWorld.DebugLog("SetPVPNPCPlayerAttr: objID=%s,NPCID=%s,pvpPlayerID=%s,maxHP=%s,SkillInfo=%s"
                           % (curNPC.GetID(), curNPC.GetNPCID(), pvpPlayerID, GameObj.GetMaxHP(curNPC), SkillInfo))
        learnSkillIDList = []
        for index in range(0, skillManager.GetSkillCount()):
            useSkill = skillManager.GetSkillByIndex(index)
            GameWorld.DebugLog("    NPC SkillID=%s" % useSkill.GetSkillID())
            learnSkillIDList.append(useSkill.GetSkillID())
        GameWorld.DebugLog("设置镜像玩家: objID=%s,NPCID=%s,mirrorPlayerID=%s,maxHP=%s,learnSkillIDList=%s"
                           % (curNPC.GetID(), curNPC.GetNPCID(), mirrorPlayerID, GameObj.GetMaxHP(curNPC), learnSkillIDList))
        return
    
    def SetHelpBattleRobotRebornAttr(self, fightPower):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -549,31 +549,39 @@
    playerName = curPlayer.GetName()
    petNPCID = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
    classLV = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV) + 1
    alreadyLearnSkillInfo = {}
    for i in xrange(petDataItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)):
    itemSkillList = []
    itemSkillCount = petDataItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)
    for i in xrange(itemSkillCount):
        skillID = petDataItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i)
        skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
        if not skillData:
            continue
        skillTypeID = skillData.GetSkillTypeID()
        alreadyLearnSkillInfo[skillTypeID] = [skillID, i]
    #GameWorld.DebugLog("开始更新灵宠技能: petNPCID=%s,classLV=%s,alreadyLearnSkillInfo=%s" % (petNPCID, classLV, alreadyLearnSkillInfo))
        itemSkillList.append([skillTypeID, skillID])
    #GameWorld.DebugLog("开始更新灵宠技能: petNPCID=%s,classLV=%s,itemSkillList=%s" % (petNPCID, classLV, itemSkillList))
    
    petIpyData = GetPetIpydata(petNPCID)
    petSkillList = petIpyData.GetSkillID()
    petSkillUnLockList = petIpyData.GetSkillUnLock()
    sysMarkList = petIpyData.GetSkillUnLockSys()
    learnSkillList = []
    skillChange = False
    for i, skillID in enumerate(petSkillList):
        limitPetClassLV = petSkillUnLockList[i] # 学习此技能所需宠物阶级
        if classLV < limitPetClassLV:
            #GameWorld.DebugLog("    未满足学习阶级: i=%s,skillID=%s,limitPetClassLV=%s" % (i, skillID, limitPetClassLV))
            GameWorld.DebugLog("    未满足学习阶级: i=%s,skillID=%s,limitPetClassLV=%s" % (i, skillID, limitPetClassLV))
            break
        skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
        if not skillData:
            continue
        skillTypeID = skillData.GetSkillTypeID()
        alreadyLearnSkillID, skillIndex = alreadyLearnSkillInfo.get(skillTypeID, [0, -1])
        alreadyLearnSkillID, alreadyLearnIndex = 0, -1
        for skillIndex, skillInfo in enumerate(itemSkillList):
            itemSkillTypeID, itemSkillID = skillInfo
            if itemSkillTypeID == skillTypeID:
                alreadyLearnSkillID = itemSkillID
                alreadyLearnIndex = skillIndex
                break
        if skillID <= alreadyLearnSkillID:
            #GameWorld.DebugLog("    技能已经学习过: i=%s,skillID=%s <= alreadyLearnSkillID=%s" % (i, skillID, alreadyLearnSkillID))
            continue
@@ -581,12 +589,11 @@
            #GameWorld.DebugLog("    主人学习技能: i=%s,skillID=%s" % (i, skillID))
            SkillCommon.GivePlayerSkillByJobSkill(curPlayer, [skillID])
            continue
        skillChange = True
        if not alreadyLearnSkillID:
            #GameWorld.DebugLog("    学习新的技能: i=%s,skillID=%s" % (i, skillID))
            petDataItem.AddUserAttr(ShareDefine.Def_IudetPet_Skill, skillID)
            itemSkillList.append([skillTypeID, skillID])
        else:
            #GameWorld.DebugLog("    学习升级技能: i=%s,skillID=%s,skillIndex=%s" % (i, skillID, skillIndex))
            petDataItem.UpdataUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, skillIndex, skillID)
            itemSkillList[alreadyLearnIndex] = [skillTypeID, skillID]
        if not SkillCommon.isPassiveAttr(skillData):
            #被动技能不学
            learnSkillList.append(skillID)
@@ -597,6 +604,20 @@
        #增加升级活跃点效果
        PlayerActivity.AddActivityByLVOnLearnSkill(curPlayer, skillID)
        
    if not skillChange:
        return learnSkillList
    for skillIndex, skillInfo in enumerate(itemSkillList):
        skillID = skillInfo[1]
        if skillIndex < itemSkillCount:
            itemSkillID = petDataItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, skillIndex)
            if itemSkillID != skillID:
                #GameWorld.DebugLog("    学习升级技能: itemSkillID=%s -> skillID=%s,skillIndex=%s" % (itemSkillID, skillID, skillIndex))
                petDataItem.UpdataUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, skillIndex, skillID)
        else:
            #GameWorld.DebugLog("    学习新的技能: skillID=%s,skillIndex=%s" % (skillID, skillIndex))
            petDataItem.AddUserAttr(ShareDefine.Def_IudetPet_Skill, skillID)
    nowSkillIDList = []
    for i in xrange(petDataItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)):
        nowSkillIDList.append(petDataItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i))
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
@@ -250,9 +250,9 @@
    curPlayerPlusDict["TotalStoneLV"] = Operate_EquipStone.GetTotalStoneLV(curPlayer)
    curPlayerPlusDict["TotalEquipWashLV"] = Operate_EquipWash.GetTotalEquipWashLV(curPlayer)
    #主动技能总等级
    skillInfo = SkillShell.GetAllSkillInfo(curPlayer, [ChConfig.Def_SkillFuncType_FbSkill, ChConfig.Def_SkillFuncType_NormalAttack])
    skillInfo = SkillShell.GetAllSkillCacheInfo(curPlayer, [ChConfig.Def_SkillFuncType_FbSkill, ChConfig.Def_SkillFuncType_NormalAttack])
    curPlayerPlusDict["SkillInfo"] = skillInfo
    curPlayerPlusDict["TotalSkillLV"] = sum(skillInfo.get(ChConfig.Def_SkillFuncType_FbSkill, {}).values())
    curPlayerPlusDict["TotalSkillLV"] = sum(skillInfo.get("%s"%ChConfig.Def_SkillFuncType_FbSkill, {}).values())
    
    #灵宠数据
    curPlayerPlusDict["Pet"] = PlayerPet.GetPetCacheInfo(curPlayer)
@@ -425,7 +425,7 @@
        return dataDict
    PyGameData.g_viewCacheCallback[playerID] = [callFunc, callData]
    
    #发送到GameServer去查询
    #GameWorld.DebugLog("发送到GameServer查询玩家缓存! playerID=%s,findPlayerID=%s" % (playerID, findPlayerID), playerID)
    sendPack = ChMapToGamePyPack.tagMGQueryPlayerCache()
    sendPack.PlayerID = playerID
    sendPack.FindPlayerID = findPlayerID
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -2225,6 +2225,8 @@
        cureBaseValue = GameObj.GetLastHurtValue(userObj)
    elif cureType == ChConfig.Def_Cure_TagMaxHP:
        cureBaseValue = 0 if not tagObj else GameObj.GetMaxHP(tagObj)
    elif cureType == ChConfig.Def_Cure_TagAtk:
        cureBaseValue = 0 if not tagObj else GetCureBaseValue(tagObj, curSkill)
        
        
    #这边写死了效果1,基本已经定型
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
@@ -3895,10 +3895,8 @@
        
    return allSkillCnt
## 获取技能总等级
#  @param curPlayer
#  @return allSkillLV:总技能等级
def GetAllSkillInfo(curPlayer, funcTypeList):
def GetAllSkillCacheInfo(curPlayer, funcTypeList):
    ## 获取技能缓存信息
    # @return: {funcType:{skillID:skillLV, ...}, ...}
    skillDict = {}
    skillManager = curPlayer.GetSkillManager()
@@ -3909,8 +3907,9 @@
        funcType = curPlayerSkill.GetFuncType()
        if funcType not in funcTypeList:
            continue
        if funcType not in skillDict:
            skillDict[funcType] = {}
        skillLVDict = skillDict[funcType]
        skillLVDict[curPlayerSkill.GetSkillID()] = curPlayerSkill.GetSkillLV()
        funcTypeKey = str(funcType)
        if funcTypeKey not in skillDict:
            skillDict[funcTypeKey] = {}
        skillLVDict = skillDict[funcTypeKey]
        skillLVDict["%s" % curPlayerSkill.GetSkillID()] = curPlayerSkill.GetSkillLV()
    return skillDict