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