#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package Player.PlayerChangeJob  
 | 
#  
 | 
# @todo:תְҵ  
 | 
# @author hxp  
 | 
# @date 2022-10-14  
 | 
# @version 1.0  
 | 
#  
 | 
# ÏêϸÃèÊö: ×ªÖ°Òµ  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#"""Version = 2022-10-14 19:00"""  
 | 
#-------------------------------------------------------------------------------  
 | 
  
 | 
import GameWorld  
 | 
import ShareDefine  
 | 
import IpyGameDataPY  
 | 
import IPY_GameWorld  
 | 
import PlayerBillboard  
 | 
import Item_ResetAttrPoint  
 | 
import DataRecordPack  
 | 
import PlayerControl  
 | 
import ItemControler  
 | 
import ItemCommon  
 | 
import ChConfig  
 | 
  
 | 
  
 | 
def DoChangeJob(curPlayer, curJob, tagJob, isFree=False):  
 | 
    ''' ×ª»»Ö°Òµ£¬Îª·Àֹתְҵ¹ý³Ìʧ°Ü£¬¸Ãº¯Êý¿ÉÖØ¸´Ö´Ðе÷Óã¬Èç¹ûÍæ¼Òתְ³öÏÖÒì³££¬¿Éͨ¹ýºǫ́GMÖ±½ÓÖ´ÐÐÃüÁîÖØ¸´²Ù×÷תְ  
 | 
    '''  
 | 
      
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    GameWorld.Log("Íæ¼Òתְҵ: playerJob=%s,curJob=%s,tagJob=%s,isFree=%s"   
 | 
                  % (curPlayer.GetJob(), curJob, tagJob, isFree), playerID)  
 | 
    if curJob == tagJob:  
 | 
        return  
 | 
    jobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)  
 | 
    if curJob not in jobList or tagJob not in jobList:  
 | 
        return  
 | 
      
 | 
    if not isFree:  
 | 
        costItemInfo = IpyGameDataPY.GetFuncEvalCfg("ChangeJob", 1) # ËùÐèÎïÆ·ID|¸öÊý  
 | 
        costItemID, costItemCount = costItemInfo  
 | 
          
 | 
        costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)  
 | 
        lackCnt = costItemCount - bindCnt - unBindCnt  
 | 
        if lackCnt > 0:  
 | 
            GameWorld.DebugLog("תְҵËùÐèµÀ¾ß²»×ã! costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s"   
 | 
                               % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt), playerID)  
 | 
            return  
 | 
          
 | 
    ipyDataMgr = IpyGameDataPY.IPY_Data()  
 | 
      
 | 
    # 1.¼¼ÄÜ£¨ÈË×å·¨±¦¼¼ÄÜ£¬ÆÕ¹¥¼¼ÄÜ£¬Ô¦Áé¾í¼¼ÄÜ£¬·¹ö¼¼ÄÜ£¬¾³½ç¼¼ÄÜ£¬×¨¾«£©  
 | 
    # ÎåÐÐר¾« Ö±½ÓÖØÖà  
 | 
    delSkillIDList = [] # ÐèҪɾ³ýµÄ¼¼ÄÜIDÁÐ±í  
 | 
    replaceSkillDict = {} # ÐèÒªÌæ»»µÄ¼¼ÄÜÐÅÏ¢ {skillID:Ìæ»»¼¼ÄÜID, ...}  
 | 
    skillManager = curPlayer.GetSkillManager()  
 | 
    for i in range(skillManager.GetSkillCount()):  
 | 
        curSkill = skillManager.GetSkillByIndex(i)  
 | 
        if not curSkill:  
 | 
            continue  
 | 
          
 | 
        skillUseType = curSkill.GetUseType()  
 | 
        if skillUseType == 0:  
 | 
            # ÎÞÖ°ÒµÏÞÖÆ  
 | 
            continue  
 | 
        if not skillUseType & pow(2, curJob):  
 | 
            continue  
 | 
          
 | 
        funcType = curSkill.GetFuncType()  
 | 
        skillID = curSkill.GetSkillID()  
 | 
        skillTypeID = curSkill.GetSkillTypeID()  
 | 
        if funcType in [ChConfig.Def_SkillFuncType_FbSPSkill]:  
 | 
            delSkillIDList.append(skillID)  
 | 
        else:  
 | 
            replaceSkillDict[skillTypeID] = [skillID, curSkill.GetSkillLV(), 0]  
 | 
              
 | 
    # 1.1 ÆÕ¹¥  
 | 
    curJobCommAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("JobFitterSkill", curJob)  
 | 
    tagJobCommAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("JobFitterSkill", tagJob)  
 | 
    if len(curJobCommAtkSkillIDList) != len(tagJobCommAtkSkillIDList):  
 | 
        GameWorld.ErrLog("תְҵÆÕ¹¥¶ÔÓ¦¼¼ÄÜÅäÖôíÎó! curJob=%s,tagJob=%s" % (curJob, tagJob), playerID)  
 | 
        return  
 | 
    for i, skillTypeID in enumerate(curJobCommAtkSkillIDList):  
 | 
        if skillTypeID in replaceSkillDict:  
 | 
            replaceSkillDict[skillTypeID][-1] = tagJobCommAtkSkillIDList[i]  
 | 
              
 | 
    # 1.2 ·¨±¦ - Ö÷¶¯¼¼ÄÜ  
 | 
    for index in range(ipyDataMgr.GetTreasureUpCount()):  
 | 
        ipyData = ipyDataMgr.GetTreasureUpByIndex(index)  
 | 
        UnLockSkillList = ipyData.GetUnLockSkill()  
 | 
        for skillTypeID in UnLockSkillList:  
 | 
            if skillTypeID not in replaceSkillDict:  
 | 
                continue  
 | 
            if tagJob > len(UnLockSkillList):  
 | 
                GameWorld.ErrLog("·¨±¦Éý¼¶±íδÅäÖÃתְҵ¶ÔÓ¦¼¼ÄÜ! skillTypeID=%s,tagJob=%s" % (skillTypeID, tagJob), playerID)  
 | 
                return  
 | 
            replaceSkillDict[skillTypeID][-1] = UnLockSkillList[tagJob - 1]  
 | 
            break  
 | 
          
 | 
    # 1.3 ¾³½ç - ±»¶¯¼¼ÄÜ  
 | 
    for index in range(ipyDataMgr.GetRealmCount()):  
 | 
        ipyData = ipyDataMgr.GetRealmByIndex(index)  
 | 
        LearnSkillIDInfo = ipyData.GetLearnSkillIDInfo()  
 | 
        if str(curJob) not in LearnSkillIDInfo:  
 | 
            continue  
 | 
        curJobLearnSkillIDList = LearnSkillIDInfo[str(curJob)]  
 | 
        tagJobLearnSkillIDList = LearnSkillIDInfo.get(str(tagJob), [])  
 | 
        for i, skillTypeID in enumerate(curJobLearnSkillIDList):  
 | 
            if skillTypeID not in replaceSkillDict:  
 | 
                continue  
 | 
            if i >= len(tagJobLearnSkillIDList):  
 | 
                GameWorld.ErrLog("¾³½ç±íδÅäÖÃתְҵ¶ÔÓ¦¼¼ÄÜ! skillTypeID=%s,tagJob=%s" % (skillTypeID, tagJob), playerID)  
 | 
                return  
 | 
            replaceSkillDict[skillTypeID][-1] = tagJobLearnSkillIDList[i]  
 | 
            break  
 | 
          
 | 
    for skillTypeID, repInfo in replaceSkillDict.items():  
 | 
        skillID, skillLV, repSkillTypeID = repInfo  
 | 
        if not repSkillTypeID or not GameWorld.GetGameData().GetSkillBySkillID(repSkillTypeID):  
 | 
            GameWorld.ErrLog("Íæ¼ÒתְҵʱÕÒ²»µ½¿ÉÌæ»»µÄÄ¿±êÖ°Òµ¼¼ÄÜÊý¾Ý! skillTypeID=%s,skillID=%s,skillLV=%s,repSkillTypeID=%s,tagJob=%s"   
 | 
                             % (skillTypeID, skillID, skillLV, repSkillTypeID, tagJob), playerID)  
 | 
            return  
 | 
          
 | 
    # 2. ÎïÆ·£º Ö°Òµ×°±¸¡¢³á°ò¡¢Ê±×°  
 | 
    itemColorMin = IpyGameDataPY.GetFuncCfg("ChangeJob", 2) # ±³°üÖÐÐèҪת»»µÄ×îµÍ×°±¸ÑÕɫƷÖÊ  
 | 
    auctionItemNeed = IpyGameDataPY.GetFuncCfg("ChangeJob", 3) # ±³°üÖÐÅÄÆ·ÊÇ·ñת»»  
 | 
    jobWingIDListInfo = IpyGameDataPY.GetFuncEvalCfg("ChangeJob", 4, {}) # Ö°Òµ¶ÔÓ¦³á°òIDÍ»ÆÆË³ÐòÁбí {Ö°Òµ:[³á°òÎïÆ·ID, ...], ...}  
 | 
    costItemIDList = [] # Ê±×°×°±¸ÎïÆ·ID×éÁбí [[Ö°Òµ1ʱװID, Ö°Òµ2ʱװID, ...], ...]  
 | 
    for index in range(ipyDataMgr.GetCoatCount()):  
 | 
        ipyData = ipyDataMgr.GetCoatByIndex(index)  
 | 
        costItemIDList.append(ipyData.GetEquipItemID())  
 | 
          
 | 
    replaceItemList = []  
 | 
    for packType in [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse, IPY_GameWorld.rptEquip]:  
 | 
        equipPack = curPlayer.GetItemManager().GetPack(packType)  
 | 
        for index in range(equipPack.GetCount()):  
 | 
            curItem = equipPack.GetAt(index)  
 | 
            if not curItem or curItem.IsEmpty():  
 | 
                continue  
 | 
              
 | 
            itemID = curItem.GetItemTypeID()  
 | 
            itemPlace = curItem.GetEquipPlace()  
 | 
            itemColor = curItem.GetItemColor()  
 | 
              
 | 
            # ±³°ü¡¢²Ö¿â ¶îÍâÌõ¼þ  
 | 
            if packType in [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse]:  
 | 
                if ItemCommon.CheckItemIsEquip(curItem) and itemPlace != ShareDefine.retWing:  
 | 
                    if itemColor < itemColorMin:  
 | 
                        continue  
 | 
                    if not auctionItemNeed and ItemControler.GetIsAuctionItem(curItem):  
 | 
                        continue  
 | 
                      
 | 
            itemJobLimit = curItem.GetJobLimit()  
 | 
            if not itemJobLimit:  
 | 
                continue  
 | 
              
 | 
            if itemJobLimit != curJob:  
 | 
                # ·ÇÐèҪת»»µÄÖ°ÒµÎïÆ·²»´¦Àí  
 | 
                continue  
 | 
              
 | 
            # »ù´¡²¿Î», Ö±½Ó°´×°±¸ÎïÆ·IDÊ×λΪ¶ÔÓ¦Ö°Òµ½øÐÐÌæ»»  
 | 
            if itemPlace in ChConfig.EquipPlace_Base:  
 | 
                tagJobItemID = GameWorld.ToIntDef("%s%s" % (tagJob, str(itemID)[1:]))  
 | 
                replaceItemList.append([packType, curItem, tagJobItemID])  
 | 
                  
 | 
            # Ê±×°  
 | 
            elif itemPlace in [ShareDefine.retWeaponSkin, ShareDefine.retClothesSkin, ShareDefine.retWeapon2Skin]:  
 | 
                tagJobItemID = 0  
 | 
                for costJobItemIDList in costItemIDList:  
 | 
                    if itemID not in costJobItemIDList:  
 | 
                        continue  
 | 
                    if tagJob > len(costJobItemIDList):  
 | 
                        GameWorld.ErrLog("ʱװ±íδÅäÖÃתְҵ¶ÔӦʱװ! itemID=%s,tagJob=%s" % (itemID, tagJob), playerID)  
 | 
                        return  
 | 
                    tagJobItemID = costJobItemIDList[tagJob - 1]  
 | 
                    break  
 | 
                replaceItemList.append([packType, curItem, tagJobItemID])  
 | 
                  
 | 
            # ³á°ò  
 | 
            elif itemPlace == ShareDefine.retWing:  
 | 
                curJobWingIDList = jobWingIDListInfo.get(curJob, [])  
 | 
                tagJobWingIDList = jobWingIDListInfo.get(tagJob, [])  
 | 
                if len(curJobWingIDList) != len(tagJobWingIDList):  
 | 
                    GameWorld.ErrLog("¹¦ÄÜÅäÖñíתְҵ¶ÔÓ¦³á°òID³¤¶ÈÅäÖò»Ò»ÖÂ! curJob=%s,tagJob=%s" % (curJob, tagJob), playerID)  
 | 
                    return  
 | 
                if itemID in curJobWingIDList:  
 | 
                    tagJobItemID = tagJobWingIDList[curJobWingIDList.index(itemID)]  
 | 
                    replaceItemList.append([packType, curItem, tagJobItemID])  
 | 
                      
 | 
            else:  
 | 
                GameWorld.ErrLog("תְҵδ֪ת»»Âß¼µÄÎïÆ·ID! itemID=%s,tagJob=%s" % (itemID, tagJob), playerID)  
 | 
                  
 | 
    assignItemList = []  
 | 
    for packType, curItem, tagJobItemID in replaceItemList:  
 | 
        tagItem = ItemControler.GetOutPutItemObj(tagJobItemID, curItem.GetCount(), curPlayer=curPlayer)  
 | 
        if not tagItem:  
 | 
            GameWorld.ErrLog("תְҵʱ´´½¨ÎïÆ·Òì³£! tagJobItemID=%s,tagJob=%s" % (tagJobItemID, tagJob), playerID)  
 | 
            return  
 | 
        assignItemList.append([packType, curItem, tagItem])  
 | 
          
 | 
    ## -------- ÒÔÉÏΪÑéÖ¤¶¼Ã»ÓÐÈκÎÎÊÌâºó£¬¿ªÊ¼Ö´ÐÐ×ªÖ°ÒµÌæ»» ----------  
 | 
    DR_ChangeJob(curPlayer, {"curJob":curJob, "tagJob":tagJob})  
 | 
    delSkillIDList.sort()  
 | 
    DR_ChangeJob(curPlayer, {"delSkillIDList":delSkillIDList, "replaceSkillDict":replaceSkillDict, "assignItemCount":len(assignItemList)})  
 | 
    # ´¦Àí¼¼ÄÜ  
 | 
    GameWorld.Log("ɾ³ý¼¼ÄÜ: ¸öÊý=%s,delSkillIDList=%s" % (len(delSkillIDList), delSkillIDList), playerID)  
 | 
    for num, delSkillID in enumerate(delSkillIDList, 1):  
 | 
        skillData = GameWorld.GetGameData().GetSkillBySkillID(delSkillID)  
 | 
        skillName = skillData.GetSkillName() if skillData else ""  
 | 
        skillManager.DeleteSkillBySkillID(delSkillID, False)  
 | 
        GameWorld.Log("    É¾³ý¼¼ÄÜ %s: delSkillID=%s(%s)" % (num, delSkillID, skillName), playerID)  
 | 
        DR_ChangeJob(curPlayer, {"delSkillID":delSkillID, "skillName":skillName})  
 | 
          
 | 
    repSkillTypeIDList = replaceSkillDict.keys()  
 | 
    repSkillTypeIDList.sort()  
 | 
    GameWorld.Log("Ìæ»»¼¼ÄÜ: ¸öÊý=%s,repSkillTypeIDList=%s" % (len(repSkillTypeIDList), repSkillTypeIDList), playerID)  
 | 
    for num, skillTypeID in enumerate(repSkillTypeIDList, 1):  
 | 
        skillID, skillLV, repSkillTypeID = replaceSkillDict[skillTypeID]  
 | 
        skillManager.DeleteSkillBySkillID(skillID, False)  
 | 
        for _ in range(skillLV):  
 | 
            skillManager.LVUpSkillBySkillTypeID(repSkillTypeID)  
 | 
        repSkill = skillManager.FindSkillBySkillTypeID(repSkillTypeID)  
 | 
        repSkillID = repSkill.GetSkillID() if repSkill else 0  
 | 
        skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)  
 | 
        skillName = skillData.GetSkillName() if skillData else ""  
 | 
        repSkillData = GameWorld.GetGameData().GetSkillBySkillID(repSkillID)  
 | 
        repSkillName = repSkillData.GetSkillName() if repSkillData else ""  
 | 
        GameWorld.Log("    Ìæ»»¼¼ÄÜ %s: skillTypeID=%s,skillID=%s(%s),skillLV=%s,tagJob=%s,repSkillTypeID=%s,repSkillID=%s(%s)"   
 | 
                      % (num, skillTypeID, skillID, skillName, skillLV, tagJob, repSkillTypeID, repSkillID, repSkillName), playerID)  
 | 
        DR_ChangeJob(curPlayer, {"skillTypeID":skillTypeID, "skillID":skillID, "skillLV":skillLV, "skillName":skillName,  
 | 
                                 "repSkillTypeID":repSkillTypeID, "repSkillID":repSkillID, "repSkillName":repSkillName})  
 | 
          
 | 
    GameWorld.Log("ɾ³ýר¾«Ïà¹Ø×Öµä¼Ç¼Êý¾Ý", playerID)  
 | 
    for index in range(ipyDataMgr.GetSkillElementCount()):  
 | 
        ipyData = ipyDataMgr.GetSkillElementByIndex(index)  
 | 
        elementSkillID = ipyData.GetElementSkillID()  
 | 
        mainSkillID = ipyData.GetMainSkillID()  
 | 
        selectElementSkillID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_SkillElementID % mainSkillID)  
 | 
        if selectElementSkillID:  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_SkillElementID % mainSkillID, 0)  
 | 
            mainSkillData = GameWorld.GetGameData().GetSkillBySkillID(mainSkillID)  
 | 
            mainSkillName = mainSkillData.GetSkillName() if mainSkillData else ""  
 | 
            selSkillData = GameWorld.GetGameData().GetSkillBySkillID(selectElementSkillID)  
 | 
            selSkillName = selSkillData.GetSkillName() if selSkillData else ""  
 | 
            GameWorld.Log("    È¡ÏûʹÓÃÖеÄר¾«: mainSkillID=%s(%s),selectElementSkillID=%s(%s)"   
 | 
                          % (mainSkillID, mainSkillName, selectElementSkillID, selSkillName), playerID)  
 | 
              
 | 
        elementSkillIDLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_SkillElementLV % elementSkillID)  
 | 
        if elementSkillIDLV:  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_SkillElementLV % elementSkillID, 0)              
 | 
            elmSkillData = GameWorld.GetGameData().GetSkillBySkillID(elementSkillID)  
 | 
            elmSkillName = elmSkillData.GetSkillName() if elmSkillData else ""  
 | 
            GameWorld.Log("    ÖØÖÃר¾«¼Ç¼µÈ¼¶: elementSkillID=%s(%s),elementSkillIDLV=%s" % (elementSkillID, elmSkillName, elementSkillIDLV), playerID)  
 | 
              
 | 
    Item_ResetAttrPoint.DoResetAttrPoint(curPlayer, 0, 0)  
 | 
      
 | 
    # ´¦ÀíÎïÆ·  
 | 
    GameWorld.Log("Ìæ»»ÎïÆ·: ¸öÊý=%s" % len(assignItemList), playerID)  
 | 
    for num, itemInfo in enumerate(assignItemList, 1):  
 | 
        packType, curItem, tagItem = itemInfo  
 | 
        curItemID = curItem.GetItemTypeID()  
 | 
        curItemName = curItem.GetName()  
 | 
        curUserData = curItem.GetUserData()  
 | 
        curAuctionItem = ItemControler.GetIsAuctionItem(curItem)  
 | 
        curItemScore = ItemCommon.GetEquipGearScore(curItem)  
 | 
          
 | 
        tagItemID = tagItem.GetItemTypeID()  
 | 
        tagItemName = tagItem.GetName()          
 | 
        tagUserData = tagItem.GetUserData()  
 | 
        tagAuctionItem = ItemControler.GetIsAuctionItem(tagItem)  
 | 
          
 | 
        if curAuctionItem != tagAuctionItem:  
 | 
            ItemControler.SetIsAuctionItem(tagItem, curAuctionItem, curPlayer)  
 | 
        tagItem.SetUserData(curUserData, len(curUserData)) # ¼Ì³ÐÎïÆ·×Ô¶¨ÒåÊý¾Ý  
 | 
        ItemCommon.MakeEquipGS(tagItem)  
 | 
        tagItemScore = ItemCommon.GetEquipGearScore(tagItem)  
 | 
          
 | 
        GameWorld.Log("    Ìæ»»ÎïÆ· %s: packType=%s,curItemID=%s(%s),curAuctionItem=%s,curItemScore=%s,tagJob=%s,tagItemID=%s(%s),tagItemScore=%s,curUserData=%s,tagUserData=%s"   
 | 
                      % (num, packType, curItemID, curItemName, curAuctionItem, curItemScore, tagJob, tagItemID, tagItemName, tagItemScore, curUserData, tagUserData), playerID)  
 | 
          
 | 
        curItemDRDict = ItemCommon.GetItemNoteDict(curItem, curItem.GetCount())  
 | 
        curItemDRDict.update({"ItemScore":curItemScore})  
 | 
        tagItemDRDict = ItemCommon.GetItemNoteDict(tagItem, tagItem.GetCount())  
 | 
        tagItemDRDict.update({"ItemScore":tagItemScore})  
 | 
        DR_ChangeJob(curPlayer, {"packType":packType, "curItem":curItemDRDict, "tagItem":tagItemDRDict})  
 | 
        curItem.AssignItem(tagItem)  
 | 
          
 | 
    # ¿Û³ýÏûºÄ  
 | 
    if not isFree and costItemCount:  
 | 
        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCount, "ChangeJob")  
 | 
          
 | 
    curPlayer.SetJob(tagJob)  
 | 
    GameWorld.Log("=== ×ªÖ°ÒµÍê±Ï: SetJob=%s ===" % tagJob, playerID)  
 | 
    DR_ChangeJob(curPlayer, {"SetJob":tagJob})  
 | 
      
 | 
    PlayerControl.PlayerControl(curPlayer).ReCalcAllState()  
 | 
    PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=True)  
 | 
      
 | 
    # ÌßÏÂÏß  
 | 
    curPlayer.Kick(IPY_GameWorld.disMapServerClose)  
 | 
    return  
 | 
  
 | 
def DR_ChangeJob(curPlayer, dataDict):  
 | 
    dataDict.update({"PlayerID":curPlayer.GetPlayerID(), "AccID":curPlayer.GetAccID()})  
 | 
    DataRecordPack.SendEventPack("ChangeJob", dataDict, curPlayer)  
 | 
    return  
 | 
  
 | 
  
 |