#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package Player.PlayerGubao
|
#
|
# @todo:¹Å±¦
|
# @author hxp
|
# @date 2025-10-11
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: ¹Å±¦
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-10-11 21:00"""
|
#-------------------------------------------------------------------------------
|
|
import GameWorld
|
import ItemCommon
|
import PlayerControl
|
import IpyGameDataPY
|
import ChPyNetSendPack
|
import NetPackCommon
|
import IPY_GameWorld
|
import ItemControler
|
import PlayerOnline
|
import ChConfig
|
import ObjPool
|
|
GubaoEffType_GoldRush = 1 # ²ÎÓëÌÔ½ð
|
GubaoEffType_Arena = 2 # ²ÎÓëÑÝÎ䳡
|
|
def GetGubaoInfo(curPlayer, gubaoID):
|
info = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GubaoInfo % gubaoID)
|
layer = info / 100000
|
lv = info % 100000 / 100
|
star = info % 100
|
return lv, star, layer
|
def SetGubaoInfo(curPlayer, gubaoID, lv, star, layer):
|
## ÌØÊâЧ¹û²ã*100000 + µÈ¼¶*100 + ÐǼ¶
|
info = min(layer, 99) * 100000 + min(lv, 999) * 100 + min(star, 99)
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GubaoInfo % gubaoID, info)
|
return
|
|
def OnPlayerLogin(curPlayer):
|
Sync_GubaoInfo(curPlayer)
|
return
|
|
def IsGubaoActivated(curPlayer, gubaoID):
|
## ¼ì²é¹Å±¦ÊÇ·ñÒѼ¤»î
|
lv, star, _ = GetGubaoInfo(curPlayer, gubaoID)
|
if lv or star:
|
return True
|
return False
|
|
#// B2 16 ¹Å±¦¼¤»î #tagCMGubaoActivate
|
#
|
#struct tagCMGubaoActivate
|
#{
|
# tagHead Head;
|
# WORD GubaoID;
|
#};
|
def OnGubaoActivate(index, curPackData, tick):
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
playerID = curPlayer.GetPlayerID()
|
gubaoID = curPackData.GubaoID
|
|
if IsGubaoActivated(curPlayer, gubaoID):
|
GameWorld.DebugLog("¹Å±¦ÒѾ¼¤»î¹ý£¡ gubaoID=%s" % gubaoID, playerID)
|
return
|
|
ipyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
|
if not ipyData:
|
return
|
needItemID = ipyData.GetUnlockItemID()
|
needItemCnt = ipyData.GetUnlockItemCnt()
|
if not needItemID or not needItemCnt:
|
return
|
|
itemCount = ItemControler.GetItemCountByID(curPlayer, needItemID)
|
if itemCount < needItemCnt:
|
GameWorld.DebugLog("¼¤»î¹Å±¦Ë鯬²»×ã! gubaoID=%s,needItemID=%s,itemCount=%s < %s" % (gubaoID, needItemID, itemCount, needItemCnt), playerID)
|
return
|
ItemControler.DelItemCountByID(curPlayer, needItemID, needItemCnt)
|
|
lv, star, layer = 1, 0, 0
|
SetGubaoInfo(curPlayer, gubaoID, lv, star, layer)
|
GameWorld.DebugLog("¹Å±¦¼¤»î³É¹¦£¡ gubaoID=%s" % gubaoID, playerID)
|
|
RefreshGubaoAttr(curPlayer)
|
Sync_GubaoInfo(curPlayer, [gubaoID])
|
return
|
|
#// B2 17 ¹Å±¦ÉýÐÇ #tagCMGubaoStarUp
|
#
|
#struct tagCMGubaoStarUp
|
#{
|
# tagHead Head;
|
# WORD GubaoID;
|
#};
|
def OnGubaoStarUp(index, curPackData, tick):
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
playerID = curPlayer.GetPlayerID()
|
gubaoID = curPackData.GubaoID
|
|
if not IsGubaoActivated(curPlayer, gubaoID):
|
GameWorld.DebugLog("¹Å±¦Î´¼¤»î£¬ÎÞ·¨ÉýÐÇ£¡ gubaoID=%s" % gubaoID, playerID)
|
return
|
|
gubaoIpyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
|
if not gubaoIpyData:
|
return
|
quality = gubaoIpyData.GetGubaoQuality()
|
selfItemID = gubaoIpyData.GetUnlockItemID()
|
|
lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
|
nextStar = star + 1
|
|
ipyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoStar", quality)
|
if not ipyDataList:
|
return
|
nextIpyData = None
|
for ipyData in ipyDataList:
|
if ipyData.GetGubaoStar() == nextStar:
|
nextIpyData = ipyData
|
break
|
if not nextIpyData:
|
GameWorld.DebugLog("¹Å±¦ÒÑÂúÐÇ£¡ gubaoID=%s,quality=%s,star=%s" % (gubaoID, quality, star), playerID)
|
return
|
needSelfCnt = nextIpyData.GetStarUPNeedSelfCnt()
|
needItemList = nextIpyData.GetStarUPNeedItemList()
|
|
if needItemList:
|
itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
|
lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
|
if lackItemDict:
|
GameWorld.DebugLog("¹Å±¦ÉýÐÇËùÐèÎïÆ·²»×㣡 quality=%s,nextStar=%s,needItemList=%s,lackItemDict=%s" % (quality, nextStar, needItemList, lackItemDict), playerID)
|
return
|
|
if needSelfCnt:
|
if not ItemControler.CheckItemEnoughByID(curPlayer, selfItemID, needSelfCnt):
|
return
|
|
#¿ÛÏûºÄ
|
if selfItemID and needSelfCnt:
|
ItemControler.DelItemCountByID(curPlayer, selfItemID, needSelfCnt)
|
if needItemList:
|
ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
|
|
updStar = nextStar
|
SetGubaoInfo(curPlayer, gubaoID, lv, updStar, layer)
|
GameWorld.DebugLog("¹Å±¦ÉýÐÇ: gubaoID=%s,updStar=%s,needSelfCnt=%s,needItemList=%s" % (gubaoID, updStar, needSelfCnt, needItemList), playerID)
|
|
RefreshGubaoAttr(curPlayer)
|
Sync_GubaoInfo(curPlayer, [gubaoID])
|
return
|
|
#// B2 18 ¹Å±¦Éý¼¶ #tagCMGubaoLVUp
|
#
|
#struct tagCMGubaoLVUp
|
#{
|
# tagHead Head;
|
# WORD GubaoID;
|
#};
|
def OnGubaoLVUp(index, curPackData, tick):
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
playerID = curPlayer.GetPlayerID()
|
gubaoID = curPackData.GubaoID
|
|
if not IsGubaoActivated(curPlayer, gubaoID):
|
GameWorld.DebugLog("¹Å±¦Î´¼¤»î£¬ÎÞ·¨Éý¼¶£¡ gubaoID=%s" % gubaoID, playerID)
|
return
|
|
gubaoIpyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
|
if not gubaoIpyData:
|
return
|
quality = gubaoIpyData.GetGubaoQuality()
|
|
ipyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoLV", quality)
|
if not ipyDataList:
|
return
|
|
lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
|
nextLV = lv + 1
|
nextIpyData = None
|
for ipyData in ipyDataList:
|
if nextLV <= ipyData.GetLessEqualLV():
|
nextIpyData = ipyData
|
break
|
|
if not nextIpyData:
|
GameWorld.DebugLog("¹Å±¦ÒÑÂú¼¶£¡ gubaoID=%s,quality=%s,lv=%s" % (gubaoID, quality, lv), playerID)
|
return
|
|
needItemList = nextIpyData.GetLVUPNeedItemInfo()
|
if needItemList:
|
itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
|
lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)
|
if lackItemDict:
|
GameWorld.DebugLog("¹Å±¦Éý¼¶ËùÐèÎïÆ·²»×㣡 quality=%s,nextLV=%s,needItemList=%s,lackItemDict=%s"
|
% (quality, nextLV, needItemList, lackItemDict), playerID)
|
return
|
|
if needItemList:
|
ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "Gubao")
|
|
updLV = nextLV
|
SetGubaoInfo(curPlayer, gubaoID, updLV, star, layer)
|
GameWorld.DebugLog("¹Å±¦Éý¼¶: gubaoID=%s,quality=%s,updLV=%s,needItemList=%s" % (gubaoID, quality, updLV, needItemList), playerID)
|
|
RefreshGubaoAttr(curPlayer)
|
Sync_GubaoInfo(curPlayer, [gubaoID])
|
return
|
|
def GetGubaoTotalLVStar(curPlayer):
|
## »ñÈ¡¹Å±¦×ܵȼ¶£¬ÐÇÊý
|
totalLV, totalStar = 0, 0
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for index in xrange(ipyDataMgr.GetGubaoCount()):
|
ipyData = ipyDataMgr.GetGubaoByIndex(index)
|
gubaoID = ipyData.GetGubaoID()
|
lv, star, _ = GetGubaoInfo(curPlayer, gubaoID)
|
totalLV += lv
|
totalStar += star
|
return totalLV, totalStar
|
|
def GetGubaoTotalCnt(curPlayer, checkCnt=0):
|
## »ñÈ¡¹Å±¦¼¤»î×ÜÊý
|
# @param checkCnt: ¿ÉÖ¸¶¨ÐèÒªÑéÖ¤µÄËùÐè¸öÊý£¬µ±´ïµ½¸Ã¸öÊýʱֱ½Ó·µ»Ø¸Ã¸öÊý
|
totalCount = 0
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for index in xrange(ipyDataMgr.GetGubaoCount()):
|
ipyData = ipyDataMgr.GetGubaoByIndex(index)
|
gubaoID = ipyData.GetGubaoID()
|
if not IsGubaoActivated(curPlayer, gubaoID):
|
continue
|
totalCount += 1
|
if checkCnt and totalCount >= checkCnt:
|
break
|
return totalCount
|
|
def RefreshGubaoAttr(curPlayer):
|
CalcGubaoAttr(curPlayer)
|
PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
|
return
|
|
def CalcGubaoAttr(curPlayer):
|
|
playerID = curPlayer.GetPlayerID()
|
attrDict = {}
|
|
gubaoStarDict = {}
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for index in xrange(ipyDataMgr.GetGubaoCount()):
|
ipyData = ipyDataMgr.GetGubaoByIndex(index)
|
gubaoID = ipyData.GetGubaoID()
|
|
if not IsGubaoActivated(curPlayer, gubaoID):
|
continue
|
|
lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
|
gubaoStarDict[gubaoID] = star
|
|
# »ù´¡ÊôÐÔ
|
BaseAttrIDList = ipyData.GetBaseAttrIDList()
|
BaseAttrValueList = ipyData.GetBaseAttrValueList()
|
BaseAttrPerStarAddList = ipyData.GetBaseAttrPerStarAddList()
|
for bIndex, attrID in enumerate(BaseAttrIDList):
|
baseValue = BaseAttrValueList[bIndex]
|
perStarAdd = BaseAttrPerStarAddList[bIndex]
|
attrValue = baseValue + perStarAdd * star
|
attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
|
GameWorld.DebugLog("¹Å±¦»ù´¡ÊôÐÔ! gubaoID=%s,star=%s,addAttr=%s,v:%s,perStar:%s,%s"
|
% (gubaoID, star, BaseAttrIDList, BaseAttrValueList, BaseAttrPerStarAddList, attrDict), playerID)
|
|
# ÌØÊâÊôÐÔ
|
attrID = ipyData.GetSpecAttrID()
|
effType = ipyData.GetSpecEffType()
|
SpecAttrValue = ipyData.GetSpecAttrValue()
|
SpecAttrPerLVAdd = ipyData.GetSpecAttrPerLVAdd()
|
SpecAttrPerStarAdd = ipyData.GetSpecAttrPerStarAdd()
|
attrValue = SpecAttrValue + SpecAttrPerLVAdd * max(lv - 1, 0) + SpecAttrPerStarAdd * star
|
if effType: # ÓÐÌØÊâЧ¹ûÀàÐ͵Ä
|
attrValue *= layer
|
attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
|
GameWorld.DebugLog("¹Å±¦ÌØÊâÊôÐÔ! gubaoID=%s,lv=%s,star=%s,effType=%s,layer=%s,attrID=%s,v=%s,perLV=%s,perStar=%s,attrValue=%s,%s"
|
% (gubaoID, lv, star, effType, layer, attrID, SpecAttrValue, SpecAttrPerLVAdd, SpecAttrPerStarAdd, attrValue, attrDict), playerID)
|
|
# ¹²Ãù
|
for index in range(ipyDataMgr.GetGubaoResonanceCount()):
|
ipyData = ipyDataMgr.GetGubaoResonanceByIndex(index)
|
resonanceID = ipyData.GetResonanceID()
|
gubaoIDList = ipyData.GetGubaoIDList()
|
if not gubaoIDList:
|
continue
|
starList = [gubaoStarDict.get(gubaoID, 0) for gubaoID in gubaoIDList]
|
minStar = min(starList) # ¹²ÃùÐǼ¶£¬È¡×éºÏÖÐ×îµÍ¹Å±¦ÐǼ¶
|
|
attrIpyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoResonanceAttr", resonanceID)
|
if not attrIpyDataList:
|
continue
|
|
resonanceAttrIpyData = None
|
for attrIpyData in attrIpyDataList:
|
resonanceStar = attrIpyData.GetResonanceStar()
|
if resonanceStar > minStar:
|
break
|
resonanceAttrIpyData = attrIpyData
|
|
if not resonanceAttrIpyData:
|
GameWorld.DebugLog("ûÓйű¦¹²ÃùÊôÐÔ! resonanceID=%s,minStar=%s,starList=%s" % (resonanceID, minStar, starList), playerID)
|
continue
|
|
resonanceAttrIDList = resonanceAttrIpyData.GetResonanceAttrIDList()
|
resonanceAttrValueList = resonanceAttrIpyData.GetResonanceAttrValueList()
|
for i, attrID in enumerate(resonanceAttrIDList):
|
attrValue = resonanceAttrValueList[i]
|
attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
|
GameWorld.DebugLog("¹Å±¦¹²Ãù: resonanceID=%s,resonanceStar=%s,starList=%s,addAttr=%s,%s,%s"
|
% (resonanceID, resonanceAttrIpyData.GetResonanceStar(), starList,
|
resonanceAttrIDList, resonanceAttrValueList, attrDict), playerID)
|
|
# ±£´æ¼ÆËãÖµ
|
GameWorld.DebugLog("¹Å±¦ÊôÐÔ: %s" % attrDict, playerID)
|
PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_Gubao, attrDict)
|
return
|
|
def AddGubaoSpecEffLayer(curPlayer, effType, addLayer):
|
## Ôö¼Ó¹Å±¦ÌØÊâЧ¹ûÊôÐԲ㼶
|
gubaoIDList = []
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for index in xrange(ipyDataMgr.GetGubaoCount()):
|
ipyData = ipyDataMgr.GetGubaoByIndex(index)
|
gubaoID = ipyData.GetGubaoID()
|
if not IsGubaoActivated(curPlayer, gubaoID):
|
continue
|
if effType != ipyData.GetSpecEffType():
|
continue
|
layerMax = ipyData.GetSpecEffLayerMax()
|
if not layerMax:
|
continue
|
|
lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
|
if layer >= layerMax:
|
continue
|
layer = min(layerMax, layer + addLayer)
|
SetGubaoInfo(curPlayer, gubaoID, lv, star, layer)
|
gubaoIDList.append(gubaoID)
|
|
if not gubaoIDList:
|
return
|
Sync_GubaoInfo(curPlayer, gubaoIDList)
|
RefreshGubaoAttr(curPlayer)
|
return
|
|
def GetItemGubaoIDDict():
|
## »ñÈ¡ÎïÆ·Ë鯬¶ÔÓ¦µÄ¹Å±¦ID×Öµä
|
ItemGubaoIDDict = IpyGameDataPY.GetConfigEx("ItemGubaoIDDict")
|
if not ItemGubaoIDDict:
|
ItemGubaoIDDict = {}
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for index in range(ipyDataMgr.GetGubaoCount()):
|
ipyData = ipyDataMgr.GetGubaoByIndex(index)
|
gubaoID = ipyData.GetGubaoID()
|
itemID = ipyData.GetUnlockItemID()
|
ItemGubaoIDDict[itemID] = gubaoID
|
IpyGameDataPY.SetConfigEx("ItemGubaoIDDict", ItemGubaoIDDict)
|
return ItemGubaoIDDict
|
|
def AutoTransGubaoPiece(curPlayer, itemID):
|
## ×Ô¶¯×ª»¯Òç³öµÄ¹Å±¦Ë鯬
|
ItemGubaoIDDict = GetItemGubaoIDDict()
|
if itemID not in ItemGubaoIDDict:
|
return
|
gubaoID = ItemGubaoIDDict[itemID]
|
if not IsGubaoActivated(curPlayer, gubaoID):
|
return
|
gubaoIpyData = IpyGameDataPY.GetIpyGameData("Gubao", gubaoID)
|
if not gubaoIpyData:
|
return
|
if gubaoIpyData.GetUnlockItemID() != itemID:
|
return
|
quality = gubaoIpyData.GetGubaoQuality()
|
|
starIpyDataList = IpyGameDataPY.GetIpyGameDataList("GubaoStar", quality)
|
if not starIpyDataList:
|
return
|
|
itemCount = ItemControler.GetItemCountByID(curPlayer, itemID)
|
if itemCount <= 0:
|
return
|
|
_, star, _ = GetGubaoInfo(curPlayer, gubaoID)
|
needPieceTotal = 0 # »¹ÐèË鯬¸öÊý
|
for ipyData in starIpyDataList:
|
if star >= ipyData.GetGubaoStar():
|
continue
|
needSelfCnt = ipyData.GetStarUPNeedSelfCnt() # ÉýÐÇËùÐè
|
if not needSelfCnt:
|
continue
|
needPieceTotal += needSelfCnt
|
if itemCount <= needPieceTotal:
|
return
|
|
transPieceCnt = itemCount - needPieceTotal # Òç³öÊýÁ¿
|
if transPieceCnt <= 0:
|
return
|
|
qualityTransDict = IpyGameDataPY.GetFuncEvalCfg("Gubao", 1, {})
|
if str(quality) not in qualityTransDict:
|
return
|
transItemID, transCount = qualityTransDict[str(quality)]
|
transCountTotal = transCount * transPieceCnt
|
GameWorld.DebugLog("×Ô¶¯×ª»¯¹Å±¦Òç³öË鯬! gubaoID=%s,itemID=%s,itemCount=%s,star=%s,needPieceTotal=%s,transPieceCnt=%s,transItemID=%s,transCountTotal=%s"
|
% (gubaoID, itemID, itemCount, star, needPieceTotal, transPieceCnt, transItemID, transCountTotal))
|
ItemControler.GivePlayerItemOrMail(curPlayer, [[transItemID, transCountTotal]], isNotifyAward=False)
|
ItemControler.SetItemCountByID(curPlayer, itemID, needPieceTotal)
|
return transPieceCnt
|
|
def Sync_GubaoInfo(curPlayer, gubaoIDList=None):
|
if gubaoIDList == None:
|
syncIDList = []
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for index in range(ipyDataMgr.GetGubaoCount()):
|
ipyData = ipyDataMgr.GetGubaoByIndex(index)
|
syncIDList.append(ipyData.GetGubaoID())
|
else:
|
syncIDList = gubaoIDList
|
|
gubaoInfoList = []
|
for gubaoID in syncIDList:
|
if gubaoIDList == None and not IsGubaoActivated(curPlayer, gubaoID):
|
# ûÓÐÖ¸¶¨Ê±Ö»Í¬²½¼¤»îµÄ
|
continue
|
lv, star, layer = GetGubaoInfo(curPlayer, gubaoID)
|
gubao = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCGubao)
|
gubao.GubaoID = gubaoID
|
gubao.GubaoLV = lv
|
gubao.GubaoStar = star
|
gubao.EffLayer = layer
|
gubaoInfoList.append(gubao)
|
|
if not gubaoInfoList:
|
return
|
|
clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCGubaoInfo)
|
clientPack.GubaoInfoList = gubaoInfoList
|
clientPack.Count = len(clientPack.GubaoInfoList)
|
NetPackCommon.SendFakePack(curPlayer, clientPack)
|
return
|