#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#
|
#
|
##@package PlayerEquipDecompose.py
|
#
|
# @todo:×°±¸·Ö½â
|
#
|
# @author xdh
|
# @date 2016-08-05
|
# @version 1.0
|
# @note:
|
#------------------------------------------------------------------------------
|
#"""Version = 2017-05-24 14:51"""
|
#------------------------------------------------------------------------------
|
import IpyGameDataPY
|
import IPY_GameWorld
|
import GameWorld
|
import ItemCommon
|
import ChPyNetSendPack
|
import ShareDefine
|
import NetPackCommon
|
import PlayerControl
|
import ChConfig
|
import FormulaControl
|
import DataRecordPack
|
import PlayerSuccess
|
import GameFuncComm
|
import PlayerVip
|
import ItemControler
|
import random
|
import json
|
|
import math
|
#---------------------------------------------------------------------
|
|
|
##µÇ¼´¦Àí
|
# @param curPlayer Íæ¼Ò
|
# @return None
|
def PlayerLogin(curPlayer):
|
Sync_EDLVInfo(curPlayer)
|
return
|
|
def DoEquipDecomposeOpen(curPlayer):
|
#¹¦ÄÜ¿ªÆô
|
RefreshEDAttr(curPlayer) # ÊôÐÔË¢ÐÂ
|
return
|
|
#//A3 2C ×°±¸·Ö½â #tagCMEquipDecompose
|
#
|
#struct tagCMEquipDecompose
|
#{
|
# tagHead Head;
|
# BYTE Count; //²ÄÁÏËùÔÚ±³°üË÷ÒýµÄÊýÁ¿
|
# WORD IndexList[Count]; //²ÄÁÏËùÔÚ±³°üË÷ÒýÁбí
|
# DWORD ItemIDList[Count]; //²ÄÁÏËùÔÚ±³°üÎïÆ·IDÁбí
|
# BYTE IsAuto; //ÊÇ·ñ×Ô¶¯·Ö½â
|
#};
|
## Íæ¼Ò·Ö½â×°±¸·â°ü A5 08
|
# @param playerIndex Íæ¼ÒË÷Òý
|
# @param clientData ¿Í»§¶Ë·â°ü
|
# @param tick ʱ¼ä
|
# @return None
|
def OnDoEquipDecompose(index, clientData, tick):
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
if not clientData.Count:
|
return
|
eatIndexList = clientData.IndexList
|
eatItemIDList = clientData.ItemIDList
|
isAuto = clientData.IsAuto
|
EatItems(curPlayer, eatIndexList, eatItemIDList, isAuto)
|
return
|
|
# ÍÌÊÉÎïÆ·, ·µ»Ø±»ÍÌÊýÁ¿
|
def EatItems(curPlayer, eatIndexList, eatItemIDList, isAuto=False):
|
if len(eatIndexList) != len(eatItemIDList):
|
return 0, 0
|
drDelItemList, totalAddExp, delAllCnt, giveItemIDDict = __GetCanEatItemInfo(curPlayer, eatIndexList, eatItemIDList)
|
if not totalAddExp:
|
GameWorld.DebugLog(" ×°±¸ÎüÊÕ Ã»ÓпÉÍÌÊÉÎïÆ·£¡")
|
return 0, 0
|
LV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeLV)
|
Exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeExp)
|
reduceTotalExp, updLV, updExp = __GetEatItemResult(curPlayer, LV, Exp, totalAddExp)
|
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipDecomposeExp, updExp)
|
if LV != updLV:
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipDecomposeLV, updLV)
|
|
#Ë¢ÊôÐÔ
|
RefreshEDAttr(curPlayer) # ÊôÐÔË¢ÐÂ
|
PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
|
#¸øÁ¶µ¤²ÄÁÏ
|
curDecomposeCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeCnt)
|
updDecomposeCnt = curDecomposeCnt + delAllCnt
|
perDecomposeCnt = IpyGameDataPY.GetFuncCfg('EquipDecomposeAward')
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipDecomposeCnt, updDecomposeCnt%perDecomposeCnt)
|
jsonItemList = []
|
giveCnt = 0
|
if perDecomposeCnt and updDecomposeCnt >= perDecomposeCnt:
|
awardRateList = IpyGameDataPY.GetFuncEvalCfg('EquipDecomposeAward', 2)
|
resetItemIDList = IpyGameDataPY.GetFuncEvalCfg('EquipDecomposeAward', 3)
|
giveCnt = updDecomposeCnt/perDecomposeCnt
|
minCnt, minItemID = 0, 0
|
for itemid in resetItemIDList:
|
cnt = ItemControler.FindPlayerItemCountByItemID(curPlayer, IPY_GameWorld.rptItem, itemid)
|
cnt += ItemControler.FindPlayerItemCountByItemID(curPlayer, IPY_GameWorld.rptWarehouse, itemid)
|
if not minItemID or cnt < minCnt:
|
minCnt = cnt
|
minItemID = itemid
|
|
#giveItemIDDict = {}
|
for _ in xrange(giveCnt):
|
itmeID = GameWorld.GetResultByRandomList(awardRateList)
|
if not itmeID:
|
continue
|
if itmeID in resetItemIDList and minItemID: #¸øÍæ¼ÒÓµÓÐ×îÉٵIJÄÁÏ
|
itmeID = minItemID
|
|
giveItemIDDict[itmeID] = giveItemIDDict.get(itmeID, 0) + 1
|
|
if giveItemIDDict:
|
for giveItemID, itemCnt in giveItemIDDict.items():
|
jsonItemList.append(ItemCommon.GetJsonItem([giveItemID,itemCnt,1]))
|
needSpace = len(giveItemIDDict)
|
packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
|
if packSpace < needSpace:
|
prizeItemList = [[giveItemID, itemCnt, 1] for giveItemID, itemCnt in giveItemIDDict.items()]
|
PlayerControl.SendMailByKey("DefaultLackSpace", [curPlayer.GetPlayerID()], prizeItemList)
|
else:
|
for giveItemID, itemCnt in giveItemIDDict.items():
|
ItemControler.GivePlayerItem(curPlayer, giveItemID, itemCnt, 0, [IPY_GameWorld.rptItem])
|
|
#ͬ²½¿Í»§¶Ë
|
Sync_EDLVInfo(curPlayer, jsonItemList)
|
# Á÷Ïò
|
#saveDataDict = {"ExpBefore":Exp, "AddTotalExp":reduceTotalExp, "ExpAfter":updExp,
|
# "DelItemList(ItemID,delCnt,baseExp,addExp)":drDelItemList, 'isAuto':isAuto}
|
#DataRecordPack.DR_ClassUpSystem(curPlayer, "EquipDecomposeUp", updLV, saveDataDict)
|
|
#EventReport.WriteEvent__lv(curPlayer, LV, updLV, Exp, updExp)
|
# ÕûÀí±³°ü
|
tick = GameWorld.GetGameWorld().GetTick()
|
ItemControler.ResetItem(curPlayer, IPY_GameWorld.rptItem, 0, 0, tick)
|
return len(drDelItemList), giveCnt
|
|
##»ñÈ¡¿ÉÒÔÍÌÊɵÄÎïÆ·ÐÅÏ¢
|
# @param curPlayer: Íæ¼ÒʵÀý
|
# @return [¿ÉÍÌÊɵÄÎïÆ·Áбí], ×î´ó¿ÉÌṩµÄ¾Ñé
|
def __GetCanEatItemInfo(curPlayer, expIndexList, eatItemIDList):
|
eatItemList = []
|
totalAddExp = 0
|
allitemCnt = 0
|
awardItemDict = {}
|
eatEquipAwardExDict = IpyGameDataPY.GetFuncEvalCfg("EquipDecomposeAward2", 1, {})
|
eatEquipAwardItemID = IpyGameDataPY.GetFuncCfg("EquipDecomposeAward", 4)
|
petEatItemAddExpPer = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_EatItem)
|
itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
|
for i, index in enumerate(expIndexList):
|
eatItem = itemPack.GetAt(index)
|
|
if not eatItem or eatItem.IsEmpty():
|
continue
|
|
eatItemID = eatItem.GetItemTypeID()
|
if eatItemIDList[i] != eatItemID:
|
GameWorld.ErrLog(' ×°±¸·Ö½â¿Í»§¶Ë·¢µÄÎïÆ·Ë÷ÒýÓëʵ¼ÊÎïÆ·ID²»¶ÔÓ¦ index=%s,eatItemID=%s,wantEatItemID=%s'%(index, eatItemID, eatItemIDList[i]))
|
continue
|
if eatItem.GetType() == ChConfig.Def_ItemType_EquipDecomposeExp:
|
curEff = eatItem.GetEffectByIndex(0)
|
baseExp = curEff.GetEffectValue(0)
|
elif ItemCommon.CheckItemIsEquip(eatItem):
|
itemColor = eatItem.GetItemColor()
|
itemClass = eatItem.GetLV()
|
isSuite = 1 if eatItem.GetSuiteID() else 0
|
ipyData = IpyGameDataPY.GetIpyGameData("PetEatEquip", itemColor, itemClass)
|
if not ipyData:
|
GameWorld.DebugLog(" tagPetEatEquip.txt,δÅäÖøÃÎïÆ·£¡ eatItemID=%s, EquipColor=%s,EquipClass=%s" % (eatItemID, itemColor, itemClass))
|
continue
|
baseExp = ipyData.GetExp()
|
|
if itemColor >= ChConfig.Def_Quality_Orange:
|
awardCount = eval(IpyGameDataPY.GetFuncCompileCfg("EquipDecomposeAward", 5))
|
awardItemDict[eatEquipAwardItemID] = awardItemDict.get(eatEquipAwardItemID, 0) + awardCount
|
GameWorld.DebugLog("·Ö½â³È×°ÒÔÉ϶îÍâ½±Àø: eatEquip=%s,itemClass=%s,itemColor=%s,isSuite=%s,awardCount=%s total:%s"
|
% (eatItem.GetItemTypeID(), itemClass, itemColor, isSuite, awardCount, awardItemDict))
|
|
# ¸ßÆ·ÖʶîÍâ½±Àø
|
for exAwardColor, exAwardInfo in eatEquipAwardExDict.items():
|
if itemColor < int(exAwardColor):
|
continue
|
exItemID, exItemCountFormat = exAwardInfo
|
exAwardCount = eval(FormulaControl.GetCompileFormula("EquipDecomposeAwardEx%s" % exAwardColor, exItemCountFormat))
|
if not exItemID or exAwardCount <= 0:
|
continue
|
awardItemDict[exItemID] = awardItemDict.get(exItemID, 0) + exAwardCount
|
GameWorld.DebugLog("·Ö½â¸ß¼¶Æ·ÖʶîÍâ½±Àø: eatEquip=%s,itemClass=%s,itemColor=%s,isSuite=%s,exAwardColor=%s,exItemID=%s,exAwardCount=%s total:%s"
|
% (eatItem.GetItemTypeID(), itemClass, itemColor, isSuite, exAwardColor, exItemID, exAwardCount, awardItemDict))
|
|
else:
|
GameWorld.ErrLog(' ²»¿É·Ö½âµÄµÀ¾ßindex=%s eatItemID=%s'%(index, eatItemID))
|
continue
|
itemCnt = eatItem.GetCount() # ×°±¸Ò»°ãĬÈÏ1£¬ÈçÊǾÑéµÀ¾ßÔòÒ»°ã¿Éµþ¼Ó
|
addExp = baseExp * itemCnt
|
|
totalAddExp += addExp
|
allitemCnt += itemCnt
|
ItemCommon.DelItem(curPlayer, eatItem, itemCnt, True, ChConfig.ItemDel_EquipDecompose)
|
|
|
GameWorld.DebugLog(" ÎüÊÕ É¾³ýÎïÆ· i=%s,baseExp=%s,itemCnt=%s,addExp=%s,totalAddExp=%s"
|
% (index, baseExp, itemCnt, addExp, totalAddExp))
|
# ÏȼìË÷¿É³ÔÁÐ±í£¬·ÀÖ¹Éý¼¶¹ý³ÌÖгԵôÔÀ´²»¿É³ÔµÄ[index, ÎïÆ·ÊµÀý, »ù´¡¾Ñé]
|
eatItemList.append([eatItemID, itemCnt, baseExp, addExp])
|
if petEatItemAddExpPer:
|
totalAddExp += totalAddExp * petEatItemAddExpPer / ChConfig.Def_MaxRateValue
|
|
PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_DecomposeEquip, allitemCnt)
|
return eatItemList, totalAddExp, allitemCnt, awardItemDict
|
|
|
##»ñÈ¡ÍÌÊɽá¹û
|
# @param curPlayer: Íæ¼ÒʵÀý
|
# @return ʵ¼ÊÐèÒª¿Û³ýµÄ¾Ñé, ×îÖÕÄ¿±êÎïÆ·, ×îÖÕ¾ÑéÖµ
|
def __GetEatItemResult(curPlayer, LV, Exp, totalAddExp):
|
remainExp = totalAddExp # Ê£Óà¿ÉÓþÑé
|
reduceTotalExp = 0 # ÕæÕýÐèÒª¿Û³ýµÄ¾Ñé
|
ipyMgr = IpyGameDataPY.IPY_Data()
|
maxLV = ipyMgr.GetEquipDecomposeByIndex(ipyMgr.GetEquipDecomposeCount()-1).GetLV()
|
# ¾Ñé¼ì²é
|
while remainExp > 0:
|
if LV +1 >= maxLV:
|
break
|
maxExp = __GetLvUpNeedExp(LV)
|
|
if not maxExp:
|
break
|
|
needExp = max(0, maxExp - Exp)
|
if remainExp >= needExp:
|
Exp = 0
|
reduceTotalExp += needExp
|
remainExp -= needExp
|
LV += 1
|
else:
|
Exp += remainExp
|
reduceTotalExp += remainExp
|
remainExp = 0
|
|
#µÈ¼¶ÂúºóÒ²¿ÉÒÔ·Ö½â¼Ó¾Ñ飬¹ÊËùÓÐ×°±¸¶¼·Ö½â
|
Exp += remainExp
|
reduceTotalExp = totalAddExp
|
GameWorld.DebugLog("×ܿɼӾÑé=%s,ʵ¼Ê×ܿ۳ý¾Ñé=%s,newLV=%s,×îÖÕ¾Ñé=%s" %
|
(totalAddExp, reduceTotalExp, LV, Exp))
|
return reduceTotalExp, LV, Exp
|
|
|
|
def __GetLvUpNeedExp(lv):
|
"""»ñȡװ±¸·Ö½âÉý¼¶ÐèÒª¾Ñé"""
|
#ÅäÖõĵȼ¶´Ó1¿ªÊ¼
|
ipyData = IpyGameDataPY.GetIpyGameData("EquipDecompose", lv+1)
|
if not ipyData:
|
return 0
|
return ipyData.GetUpNeedExp()
|
|
|
## Ë¢ÊôÐÔ
|
def RefreshEDAttr(curPlayer):
|
if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_EquipDecompose):
|
return
|
allAttrList = [{} for _ in range(4)]
|
curLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeLV)
|
ipyData = IpyGameDataPY.GetIpyGameData('EquipDecompose', curLV+1)
|
if not ipyData:
|
return
|
for attrID, attrValue in ipyData.GetAttr().items():
|
PlayerControl.CalcAttrDict_Type(int(attrID), attrValue, allAttrList)
|
|
|
# ±£´æ¼ÆËãÖµ
|
PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_EquipDecompose, allAttrList)
|
return
|
|
|
|
#// A3 2D ×°±¸·Ö½âÉèÖà #tagCMDecomposeSeting
|
#
|
#struct tagCMDecomposeSeting
|
#{
|
# tagHead Head;
|
# DWORD Seting;
|
#};
|
def OnDecomposeSetingSave(index, clientData, tick):
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipDecomposeSeting, clientData.Seting)
|
return
|
|
## ·Ö½âµÈ¼¶Ïà¹ØÐÅÏ¢
|
def Sync_EDLVInfo(curPlayer, getItemInfo=[]):
|
getItemInfo = json.dumps(getItemInfo, ensure_ascii=False)
|
PackData = ChPyNetSendPack.tagMCEquipDecomposeInfo()
|
PackData.Clear()
|
PackData.LV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeLV)
|
PackData.Exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeExp)
|
PackData.Seting = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeSeting)
|
PackData.DecomposeCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_EquipDecomposeCnt)
|
PackData.GetItemData = str(getItemInfo)
|
PackData.GetItemLen = len(PackData.GetItemData)
|
NetPackCommon.SendFakePack(curPlayer, PackData)
|
return
|