#!/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