#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package UseItem.Item_Chests
|
#
|
# @todo:±¦Ïä
|
# @author hxp
|
# @date 2018-02-05
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: Ipy±¦Ïä±íÎïÆ·
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2018-02-05 15:00"""
|
#-------------------------------------------------------------------------------
|
|
#µ¼Èë
|
import GameWorld
|
import ItemCommon
|
import PlayerControl
|
import IpyGameDataPY
|
import IPY_GameWorld
|
import ItemControler
|
import PlayerRune
|
import ChConfig
|
import ChItem
|
|
import math
|
#---------------------------------------------------------------------
|
|
def BatchUseItem(curPlayer, curRoleItem, tick, useCnt, exData):
|
##ÅúÁ¿Ê¹ÓÃÎïÆ·
|
|
chestsItemID = curRoleItem.GetItemTypeID()
|
chestsIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Chests", chestsItemID)
|
if not chestsIpyData:
|
return
|
|
showType = chestsIpyData.GetShowType() # ¹æ¶¨ÓпªÏä±íÏÖµÄĬÈÏÖ»ÄÜ¿ªÆô1¸ö
|
if showType:
|
useCnt = 1
|
|
isBind = int(chestsIpyData.GetIsBind()) # ½±ÀøÎïÆ·ÊÇ·ñ°ó¶¨
|
costItemID = chestsIpyData.GetCostItemID()
|
costItemCountTotal = chestsIpyData.GetCostItemCount() * useCnt
|
costGoldTotal = chestsIpyData.GetCostGold() * useCnt
|
auctionItemCanSell = chestsIpyData.GetAucionItemCanSell()
|
|
if costGoldTotal and not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal):
|
return
|
|
if costItemID:
|
costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID)
|
if bindCnt + unBindCnt < costItemCountTotal:
|
GameWorld.DebugLog("ËùÐèÏûºÄµÀ¾ß²»×㣬ÎÞ·¨´ò¿ª±¦Ïä!chestsItemID=%s,costItemID=%s,costItemCountTotal=%s,bindCnt=%s,unBindCnt=%s"
|
% (chestsItemID, costItemID, costItemCountTotal, bindCnt, unBindCnt))
|
return
|
|
GameWorld.DebugLog("UseChests: chestsItemID=%s,useCnt=%s,isBind=%s,costItemID=%s*%s,costGoldTotal=%s"
|
% (chestsItemID, useCnt, isBind, costItemID, costItemCountTotal, costGoldTotal))
|
# ²ú³öÔ¤´¦Àí
|
awardInfo = GetChestsAwardInfo(curPlayer, chestsItemID, useCnt, exData)
|
if not awardInfo:
|
return
|
needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount = awardInfo
|
GameWorld.DebugLog(" needSpaceDict=%s,jobAwardItemList=%s,moneyType=%s,moneyCount=%s,notifyItemList=%s,updOpenCount=%s,auctionItemCanSell=%s"
|
% (needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount, auctionItemCanSell))
|
|
for packType, needSpace in needSpaceDict.items():
|
packSpace = ItemCommon.GetItemPackSpace(curPlayer, packType, needSpace)
|
if packSpace < needSpace:
|
#PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [packType])
|
PlayerControl.NotifyCode(curPlayer, "OpenBoxItem", [packType, chestsItemID, needSpace - packSpace])
|
return
|
|
# ¿Û³ýÏûºÄ
|
if costItemID:
|
ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCountTotal, "Chests")
|
if costGoldTotal:
|
infoDict = {ChConfig.Def_Cost_Reason_SonKey:chestsItemID}
|
PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal, ChConfig.Def_Cost_UseItem, infoDict)
|
|
# ¸üпªÆô´ÎÊý
|
if updOpenCount:
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChestsOpenCount % chestsItemID, updOpenCount)
|
GameWorld.DebugLog(" ¸üб¦Ï俪Æô´ÎÊý: %s" % updOpenCount)
|
|
saveDataDict = {"AwardItem":jobAwardItemList}
|
ItemCommon.DelItem(curPlayer, curRoleItem, useCnt, True, ChConfig.ItemDel_Chests, saveDataDict)
|
|
# ¸ø½±Àø
|
syncItemList = []
|
for itemID, itemCount in jobAwardItemList:
|
isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", itemID) else 0
|
curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer)
|
if not curItem:
|
GameWorld.ErrLog("±¦Ïä´´½¨½±ÀøÎïÆ·Òì³£!chestsItemID=%s,useCnt=%s,itemID=%s,itemCount=%s,isBind=%s"
|
% (chestsItemID, useCnt, itemID, itemCount, isBind), curPlayer.GetPlayerID())
|
continue
|
|
if showType:
|
syncItemList.append(ItemCommon.GetJsonItem(curItem)) # ±ØÐëÔÚ¸øÎïÆ·Ö®Ç°ÏÈget
|
|
userData = curItem.GetUserData()
|
isOK = ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, event=[ChConfig.ItemGive_Chests, False, {"UseItemID":chestsItemID}])
|
if isOK and itemID in notifyItemList:
|
PlayerControl.WorldNotify(0, "ChooseMessage", [curPlayer.GetPlayerName(), chestsItemID, itemID, isBind, itemCount, userData])
|
|
# »õ±Ò
|
if moneyType:
|
addDataDict = {ChConfig.Def_Give_Reason_SonKey:chestsItemID}
|
if not PlayerControl.GiveMoney(curPlayer, moneyType, moneyCount, ChConfig.Def_GiveMoney_UseItem, addDataDict, False):
|
moneyType, moneyCount = 0, 0
|
|
# ֪ͨ
|
if syncItemList:
|
ChItem.SendUseItemGetItemResult(curPlayer, chestsItemID, useCnt, syncItemList, moneyType, moneyCount)
|
return True, useCnt
|
|
|
def GetChestsAwardInfo(curPlayer, chestsItemID, useCount, exData=0):
|
'''»ñÈ¡±¦Ï俪Æô½±Àø
|
@return: None - »ñÈ¡±¦Ïä½±ÀøÊ§°Ü
|
@return: needSpaceDict, jobAwardItemList [[itemID, itemCount], ...]
|
'''
|
|
awardIpyData = __GetChestsAwardIpyDataByLV(curPlayer, chestsItemID)
|
if not awardIpyData:
|
return
|
|
awardItemDict = {}
|
job = curPlayer.GetJob()
|
jobItemList = awardIpyData.GetJobItemList()
|
# Ñ¡ÔñÎïÆ·
|
if awardIpyData.GetSelectItemDict():
|
if not exData:
|
GameWorld.ErrLog("Ñ¡ÔñµÄÎïÆ·´íÎó, ÐèÒªÖ¸¶¨Ò»¸öÑ¡ÔñÎïÆ·ID!chestsItemID=%s,selectItemID=%s" % (chestsItemID, exData))
|
return
|
selectItemID = exData
|
|
isSelectOK = False
|
for cfgItemID, itemCount in awardIpyData.GetSelectItemDict().items():
|
# Ö§³Ö°´Ö°ÒµÑ¡Ôñ£¬Ç°¶ËÎÞÂÛ·¢Ö°Òµ¶ÔÓ¦ÎïÆ·ID»òÕßÅäÖõÄÎïÆ·ID¾ù¿É»ñµÃ
|
jobItemID = __GetChestsJobItem(chestsItemID, job, cfgItemID, jobItemList)
|
if not jobItemID:
|
return
|
if selectItemID == cfgItemID or selectItemID == jobItemID:
|
__AddAwardItem(awardItemDict, jobItemID, itemCount * useCount)
|
isSelectOK = True
|
break
|
|
if not isSelectOK:
|
GameWorld.ErrLog("Ñ¡ÔñµÄÎïÆ·´íÎó, ¸Ã±¦ÏäûÓиÃÎïÆ·!chestsItemID=%s,selectItemID=%s" % (chestsItemID, selectItemID))
|
return
|
|
# ¹Ì¶¨²ú³öÎïÆ·
|
if awardIpyData.GetFixedItemDict():
|
for itemID, itemCount in awardIpyData.GetFixedItemDict().items():
|
__AddAwardItem(awardItemDict, itemID, itemCount * useCount)
|
|
# Ëæ»úÎïÆ·¿â1
|
if awardIpyData.GetRandItemList1() and awardIpyData.GetRandTimeList1():
|
if not __AddChestsRandAwardItem(curPlayer, chestsItemID, useCount, awardItemDict, awardIpyData.GetRandItemList1(), awardIpyData.GetRandTimeList1()):
|
return
|
|
# ¸ù¾Ý±¦Ï俪Æô´ÎÊýÌØÊâ²ú³ö
|
updOpenCount = 0
|
randItemList2DoCount = useCount
|
randItemByUseCountDict = awardIpyData.GetRandItemByUseCount()
|
if randItemByUseCountDict:
|
maxOpenCount = max(randItemByUseCountDict)
|
hisOpenCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChestsOpenCount % chestsItemID)
|
if hisOpenCount < maxOpenCount:
|
updOpenCount = min(hisOpenCount + useCount, maxOpenCount)
|
for specUseCount, randItemList in randItemByUseCountDict.items():
|
if not (hisOpenCount < specUseCount <= updOpenCount):
|
GameWorld.DebugLog(" ²»Âú×ãÌØÊâ´ÎÊý²ú³ö: hisOpenCount=%s,specUseCount=%s,updOpenCount=%s"
|
% (hisOpenCount, specUseCount, updOpenCount))
|
continue
|
randItemList2DoCount -= 1
|
randItemInfo = GameWorld.GetResultByRandomList(randItemList)
|
GameWorld.DebugLog(" ¸ù¾Ý¿ªÆô´ÎÊýÌØÊâ²ú³ö: specUseCount=%s, %s, randItemList2DoCount=%s"
|
% (specUseCount, randItemInfo, randItemList2DoCount))
|
if not randItemInfo:
|
continue
|
if len(randItemInfo) != 2:
|
GameWorld.ErrLog("±¦Ï俪Æô´ÎÊýÌØÊâ²ú³öËæ»ú¿âÅäÖôíÎó!chestsItemID=%s" % chestsItemID)
|
return
|
itemID, itemCount = randItemInfo
|
if not itemID:
|
continue
|
__AddAwardItem(awardItemDict, itemID, itemCount)
|
|
if randItemList2DoCount != useCount:
|
GameWorld.DebugLog(" Ëæ»úÎïÆ·¿â2Ö´ÐдÎÊý: %s" % (randItemList2DoCount))
|
|
# Ëæ»úÎïÆ·¿â2
|
if awardIpyData.GetRandItemList2() and awardIpyData.GetRandTimeList2() and randItemList2DoCount:
|
if not __AddChestsRandAwardItem(curPlayer, chestsItemID, randItemList2DoCount, awardItemDict, awardIpyData.GetRandItemList2(), awardIpyData.GetRandTimeList2()):
|
return
|
|
# ²ú³öÌØÊâÎïÆ·¹ã²¥
|
needNotifyItemList = awardIpyData.GetNeedNotifyItemList()
|
|
needSpaceDict = {} # {packType:needSpace, ...}
|
notifyItemList = []
|
jobAwardItemList = []
|
for itemID, itemCount in awardItemDict.items():
|
if not itemCount:
|
continue
|
jobItemID = __GetChestsJobItem(chestsItemID, job, itemID, jobItemList)
|
if not jobItemID:
|
return
|
|
itemData = GameWorld.GetGameData().GetItemByTypeID(jobItemID)
|
if not itemData:
|
GameWorld.ErrLog("±¦Ïä½±ÀøÎïÆ·²»´æÔÚ! chestsItemID=%s,itemID=%s,jobItemID=%s" % (chestsItemID, itemID, jobItemID))
|
return
|
packType = ChConfig.GetItemPackType(itemData.GetType())
|
needSpace = int(math.ceil(itemCount / float(itemData.GetPackCount())))
|
needSpaceDict[packType] = needSpaceDict.get(packType, 0) + needSpace
|
|
# ×°±¸²ð¿ª¸ø£¬ÐèҪͬ²½Ã¿¼þ×°±¸µÄÊôÐÔ
|
if ItemCommon.GetIsEquip(itemData):
|
jobAwardItemList.extend([[jobItemID, 1]] * itemCount)
|
else:
|
jobAwardItemList.append([jobItemID, itemCount])
|
if itemID in needNotifyItemList or jobItemID in needNotifyItemList:
|
notifyItemList.append(jobItemID)
|
|
return needSpaceDict, jobAwardItemList, awardIpyData.GetMoneyType(), awardIpyData.GetMoneyCount() * useCount, notifyItemList, updOpenCount
|
|
def __GetMaxRandTime(randTimeList):
|
if len(randTimeList) == 1 and type(randTimeList[0]) == int:
|
return randTimeList[0]
|
return randTimeList[-1][1]
|
|
def __AddChestsRandAwardItem(curPlayer, chestsItemID, useCount, awardItemDict, randItemList, randTimeList):
|
|
# ¹ýÂËδ½âËøµÄÎïÆ·
|
resetRandItemList = [] # ÖØÉè¿É²ú³öµÄÎïÆ·±ýͼ¸ÅÂÊÁбí
|
for i, rateItemInfo in enumerate(randItemList):
|
if type(rateItemInfo) not in [list, tuple] or len(rateItemInfo) != 2:
|
GameWorld.ErrLog("±¦ÏäËæ»úÎïÆ·¿â±ýͼ¸ñʽ´íÎó!chestsItemID=%s,randItemList=%s" % (chestsItemID, randItemList))
|
return False
|
rate, itemInfo = rateItemInfo
|
if itemInfo and itemInfo[0]:
|
itemID = itemInfo[0] # ÓÐÅäÖÃÎïÆ·ID£¬ÐèÅжϸÃÎïÆ·IDÊÇ·ñºÏ·¨¿É¿ª³öµÈ£¬Ö§³ÖÅäÖÿÕÎïÆ·ID
|
itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
|
if not itemData:
|
return False
|
|
# ·ûÓ¡ÅжÏÊÇ·ñÒѾ½âËø
|
if itemData.GetType() == ChConfig.Def_ItemType_Rune:
|
if not PlayerRune.GetIsOpenByRuneID(curPlayer, itemID):
|
GameWorld.DebugLog("´Ë·ûӡδ½âËøÎÞ·¨¿ª³ö! chestsItemID=%s,itemID=%s" % (chestsItemID, itemID))
|
continue
|
|
curRate = rate if i == 0 else (rate - randItemList[i - 1][0])
|
preRate = 0 if not resetRandItemList else resetRandItemList[-1][0]
|
resetRandItemList.append([preRate + curRate, itemInfo]) # ÖØÉè±ýͼ¸ÅÂÊÁбí
|
|
for _ in xrange(useCount):
|
if len(randTimeList) == 1 and type(randTimeList[0]) == int:
|
randTimes = randTimeList[0]
|
else:
|
randTimes = GameWorld.GetResultByRandomList(randTimeList)
|
|
if randTimes == None:
|
GameWorld.ErrLog("±¦ÏäËæ»ú´ÎÊýÅäÖôíÎó!chestsItemID=%s" % chestsItemID)
|
return False
|
|
if not randTimes:
|
continue
|
|
for _ in xrange(randTimes):
|
randItemInfo = GameWorld.GetResultByRandomList(resetRandItemList)
|
if not randItemInfo:
|
#GameWorld.DebugLog("±¦ÏäËæ»ú¿âËæ»ú³öÎïÆ·0£¬randItemInfo=%s" % randItemInfo)
|
continue
|
if len(randItemInfo) != 2:
|
GameWorld.ErrLog("±¦ÏäËæ»ú¿âÅäÖôíÎó!chestsItemID=%s" % chestsItemID)
|
return False
|
|
itemID, itemCount = randItemInfo
|
if not itemID:
|
#GameWorld.DebugLog("±¦ÏäËæ»ú¿âËæ»ú³öÎïÆ·itemID=0£¬randItemInfo=%s" % randItemInfo)
|
continue
|
__AddAwardItem(awardItemDict, itemID, itemCount)
|
|
return True
|
|
def __GetChestsJobItem(chestsItemID, job, itemID, jobItemList):
|
## »ñÈ¡±¦ÏäÎïÆ·½±Àø¶ÔÓ¦µÄÖ°ÒµÎïÆ·£¬ Ö°Òµ´Ó1¿ªÊ¼
|
for jobItemIDList in jobItemList:
|
if type(jobItemIDList) not in [list, tuple]:
|
GameWorld.ErrLog("±¦ÏäÖ°ÒµÎïÆ·×é¸ñʽ´íÎó!chestsItemID=%s,jobItemList=%s" % (chestsItemID, jobItemList))
|
return 0
|
if itemID in jobItemIDList:
|
if job <= 0 or job > len(jobItemIDList):
|
GameWorld.ErrLog("±¦ÏäÖ°ÒµÎïÆ·ÅäÖôíÎó,ûÓиÃÖ°Òµ¶ÔÓ¦ÎïÆ·ID!chestsItemID=%s,job=%s,itemID=%s" % (chestsItemID, job, itemID))
|
return 0
|
return jobItemIDList[job - 1]
|
return itemID
|
|
def __AddAwardItem(awardItemDict, itemID, itemCount):
|
awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount
|
return
|
|
def __GetChestsAwardIpyDataByLV(curPlayer, chestsItemID):
|
## »ñÈ¡±¦Ï俪Æô½±Àø
|
awardIpyDataList = IpyGameDataPY.GetIpyGameDataList("ChestsAward", chestsItemID)
|
if not awardIpyDataList:
|
return
|
|
if len(awardIpyDataList) == 1:
|
return awardIpyDataList[0]
|
|
# ¶àÌõ²ú³ö¼Ç¼µÄ£¬°´µÈ¼¶À´
|
lvIpyDataList = []
|
for ipyData in awardIpyDataList:
|
lvIpyDataList.append([ipyData.GetAwardLV(), ipyData])
|
lvIpyDataList.sort() # ÉýÐòÅÅÐò
|
|
curLV = curPlayer.GetLV()
|
minLV = lvIpyDataList[0][0]
|
if curLV < minLV:
|
GameWorld.ErrLog("µ±Ç°µÈ¼¶ÎÞ·¨¿ªÆô¸Ã±¦Ïä!curLV=%s,minLV=%s,chestsItemID=%s" % (curLV, minLV, chestsItemID), curPlayer.GetPlayerID())
|
return
|
|
for i, lvIpyInfo in enumerate(lvIpyDataList[1:], 1):
|
awardLV, ipyData = lvIpyInfo
|
if curLV < awardLV:
|
awardLV, ipyData = lvIpyDataList[i - 1]
|
return ipyData
|
return awardIpyDataList[-1]
|
|