#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package Player.PlayerActCollectWords
|
#
|
# @todo:¼¯×ֻ
|
# @author hxp
|
# @date 2020-12-08
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: ¼¯×ֻ
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2020-12-08 19:00"""
|
#-------------------------------------------------------------------------------
|
import GameWorld
|
import PyGameData
|
import ShareDefine
|
import PlayerControl
|
import ChConfig
|
import IpyGameDataPY
|
import ChPyNetSendPack
|
import NetPackCommon
|
import ItemCommon
|
import ItemControler
|
import IPY_GameWorld
|
|
ActCollectWordsNameDict = {
|
1:ShareDefine.OperationActionName_CollectWords,
|
2:ShareDefine.OperationActionName_CollectWords2,
|
}
|
|
def OnPlayerLogin(curPlayer):
|
## Íæ¼ÒµÇ¼
|
|
for actNum, actName in ActCollectWordsNameDict.items():
|
|
isReset = __CheckPlayerCollectWordsAction(curPlayer, actNum)
|
if not isReset:
|
actInfo = PyGameData.g_operationActionDict.get(actName, {})
|
# »î¶¯ÖÐͬ²½»î¶¯ÐÅÏ¢
|
if actInfo.get(ShareDefine.ActKey_State):
|
SyncCollectWordsActionInfo(curPlayer, actNum)
|
SyncCollectWordsPlayerInfo(curPlayer, actNum)
|
|
return
|
|
def RefreshActCollectWordsInfo(actNum):
|
## ÊÕµ½GameServerͬ²½µÄ»î¶¯ÐÅÏ¢£¬Ë¢Ð»ÐÅÏ¢
|
playerManager = GameWorld.GetPlayerManager()
|
for index in xrange(playerManager.GetPlayerCount()):
|
curPlayer = playerManager.GetPlayerByIndex(index)
|
if curPlayer.GetID() == 0:
|
continue
|
__CheckPlayerCollectWordsAction(curPlayer, actNum)
|
|
return
|
|
def __CheckPlayerCollectWordsAction(curPlayer, actNum):
|
## ¼ì²éÍæ»î¶¯Êý¾ÝÐÅÏ¢
|
|
if actNum not in ActCollectWordsNameDict:
|
return
|
actName = ActCollectWordsNameDict[actNum]
|
|
playerID = curPlayer.GetPlayerID()
|
actInfo = PyGameData.g_operationActionDict.get(actName, {})
|
actID = actInfo.get(ShareDefine.ActKey_ID, 0)
|
state = actInfo.get(ShareDefine.ActKey_State, 0)
|
|
playerActID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollectWordsID % actNum) # Íæ¼ÒÉíÉϵĻID
|
|
# »î¶¯ID ÏàͬµÄ»°²»´¦Àí
|
if actID == playerActID:
|
GameWorld.DebugLog("¼¯×ֻID²»±ä£¬²»´¦Àí£¡actNum=%s,actID=%s" % (actNum, actID), curPlayer.GetPlayerID())
|
return
|
|
templateID = 0
|
cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
|
if cfgID:
|
actIpyData = IpyGameDataPY.GetIpyGameData(actName, cfgID)
|
templateID = 0 if not actIpyData else actIpyData.GetTemplateID()
|
exchangeList = IpyGameDataPY.GetIpyGameDataList("CollectWordsExchange", templateID)
|
if not exchangeList:
|
GameWorld.ErrLog("¼¯×Ö¶Ò»»ÕÒ²»µ½¶Ò»»Ä£°åÅäÖÃ!actNum=%s,cfgID=%s,templateID=%s" % (actNum, cfgID, templateID), playerID)
|
else:
|
for exchangeIpyData in exchangeList:
|
exchangeNum = exchangeIpyData.GetExchangeNum()
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollectWordsExchangeCount % (actNum, exchangeNum), 0)
|
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollectWordsID % actNum, actID)
|
GameWorld.DebugLog("¼¯×Ö»î¶¯ÖØÖÃ! actNum=%s,cfgID=%s,templateID=%s,actID=%s" % (actNum, cfgID, templateID, actID), playerID)
|
|
if state:
|
SyncCollectWordsActionInfo(curPlayer, actNum)
|
SyncCollectWordsPlayerInfo(curPlayer, actNum)
|
|
return True
|
|
def OnKillNPCDrop(curPlayer, curNPC):
|
## »÷ɱNPCµô×ÖÂß¼
|
|
if curNPC.GetType() in [ChConfig.ntPriWoodPilePVP]:
|
return
|
|
for actNum, actName in ActCollectWordsNameDict.items():
|
randList = __GetDropWordsItemRateList(curPlayer, actName, curNPC)
|
if not randList:
|
continue
|
dropItemID = GameWorld.GetResultByRandomList(randList)
|
if not dropItemID:
|
continue
|
GameWorld.DebugLog(" ¼¯×ֻµôÂäÎïÆ·! actNum=%s,actName=%s,npcID=%s,dropItemID=%s" % (actNum, actName, curNPC.GetNPCID(), dropItemID))
|
|
itemCount = 1 # ĬÈÏ1¸ö
|
isAuctionItem = 0 # ·ÇÅÄÆ·
|
ItemControler.GivePlayerItem(curPlayer, dropItemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])
|
|
return
|
|
def __GetDropWordsItemRateList(curPlayer, actName, npcData):
|
## »ñÈ¡µô×Ö±ýͼÁбí
|
|
actInfo = PyGameData.g_operationActionDict.get(actName, {})
|
if not actInfo:
|
return
|
|
if not actInfo.get(ShareDefine.ActKey_State):
|
return
|
|
cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
|
ipyData = IpyGameDataPY.GetIpyGameData(actName, cfgID)
|
if not ipyData:
|
return
|
|
isBoss = ChConfig.IsGameBoss(npcData)
|
playerLV = curPlayer.GetLV()
|
npcLV = npcData.GetLV()
|
limitLV = ipyData.GetLVLimit()
|
if not isBoss and limitLV and limitLV > playerLV:
|
#GameWorld.DebugLog(" ¼¯×Ö»î¶¯Íæ¼ÒµÈ¼¶²»×㣬ÎÞ·¨µôÂä! actName=%s,cfgID=%s,limitLV=%s" % (actName, cfgID, limitLV))
|
return
|
|
dropDiffLVLimit = ipyData.GetDropDiffLVLimit()
|
if not isBoss and dropDiffLVLimit and (playerLV - npcLV) > dropDiffLVLimit:
|
#GameWorld.DebugLog(" ¼¯×Ö»î¶¯Íæ¼ÒµÈ¼¶ÓëNPCµÈ¼¶²îÖµ¹ý´ó£¬ÎÞ·¨µôÂä! actName=%s,cfgID=%s,playerLV(%s) - npcLV(%s) > %s"
|
# % (actName, cfgID, playerLV, npcLV, dropDiffLVLimit))
|
return
|
|
lastDayOnlyExchange = ipyData.GetLastDayOnlyExchange()
|
if lastDayOnlyExchange:
|
openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
|
endDateStr = GameWorld.GetOperationActionDateStr(ipyData.GetEndDate(), openServerDay)
|
curDate = GameWorld.GetCurrentTime()
|
curDateStr = "%d-%s-%s" % (curDate.year, curDate.month, curDate.day)
|
if curDateStr == endDateStr:
|
#GameWorld.DebugLog(" ¼¯×ֻ×îºóÒ»Ìì²»µôÂä! actName=%s,cfgID=%s, %s" % (actName, cfgID, curDateStr))
|
return
|
|
if not isBoss:
|
return ipyData.GetDropItemRateList()
|
|
bossDropRateListInfo = ipyData.GetDropItemRateListBoss()
|
npcID = npcData.GetNPCID()
|
killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
|
limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
|
return bossDropRateListInfo.get(limitIndex, [])
|
|
def OnGetDropWordsItemDict(curPlayer, npcData, killCount):
|
## »ñÈ¡ÍÑ»úµôÂäÎïÆ·
|
|
dropItemCountDict = {}
|
for actNum, actName in ActCollectWordsNameDict.items():
|
|
dropRateList = __GetDropWordsItemRateList(curPlayer, actName, npcData)
|
if not dropRateList:
|
continue
|
|
preRate = 0
|
maxRate = dropRateList[-1][0]
|
for rateInfo in dropRateList:
|
rate, dropItemID = rateInfo
|
curRate = rate - preRate
|
if not curRate:
|
break
|
preRate = rate
|
if not dropItemID:
|
continue
|
totalRate = curRate * killCount # ×ܸÅÂÊ
|
dropCount = totalRate / maxRate # ¿ÉµôÂäÊý
|
rateEx = totalRate % maxRate # Ê£Óà¸ÅÂÊ
|
if GameWorld.CanHappen(rateEx, maxRate):
|
dropCount += 1
|
if not dropCount:
|
continue
|
|
dropItemCountDict[dropItemID] = dropItemCountDict.get(dropItemID, 0) + dropCount
|
GameWorld.DebugLog(" ÍÑ»ú¼¯×ֻµô×Ö: actNum=%s,actName=%s,dropItemID=%s,dropCount=%s" % (actNum, actName, dropItemID, dropCount))
|
|
return dropItemCountDict
|
|
#// AA 09 ¼¯×ֻ¶Ò»» #tagCMActCollectWordsExchange
|
#
|
#struct tagCMActCollectWordsExchange
|
#{
|
# tagHead Head;
|
# BYTE ActNum; //»î¶¯±àºÅ£¬1 »ò 2£¬Ï໥¶ÀÁ¢µÄ»î¶¯£¬¿Éͬʱ¿ªÆô
|
# BYTE ExchangeNum; //¶Ò»»±àºÅ
|
#};
|
def OnActCollectWordsExchange(index, clientData, tick):
|
actNum = clientData.ActNum
|
exchangeNum = clientData.ExchangeNum
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
|
GameWorld.DebugLog("¼¯×ֻ¶Ò»»£¡actNum=%s,exchangeNum=%s" % (actNum, exchangeNum))
|
|
if actNum not in ActCollectWordsNameDict:
|
return
|
actName = ActCollectWordsNameDict[actNum]
|
|
actInfo = PyGameData.g_operationActionDict.get(actName, {})
|
if not actInfo:
|
return
|
|
if not actInfo.get(ShareDefine.ActKey_State):
|
GameWorld.DebugLog("·Ç¼¯×ֻÖУ¬ÎÞ·¨¶Ò»»£¡actNum=%s" % actNum)
|
return
|
|
cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
|
ipyData = IpyGameDataPY.GetIpyGameData(actName, cfgID)
|
if not ipyData:
|
return
|
|
templateID = ipyData.GetTemplateID()
|
if not templateID:
|
return
|
|
exchangeList = IpyGameDataPY.GetIpyGameDataList("CollectWordsExchange", templateID)
|
if not exchangeList:
|
return
|
|
findIpyData = None
|
for exchangeIpyData in exchangeList:
|
if exchangeNum == exchangeIpyData.GetExchangeNum():
|
findIpyData = exchangeIpyData
|
break
|
|
if not findIpyData:
|
GameWorld.ErrLog("ÕÒ²»µ½¼¯×ֻ¶Ò»»ÅäÖÃÊý¾Ý£¡actNum=%s,cfgID=%s,templateID=%s,exchangeNum=%s"
|
% (actNum, cfgID, templateID, exchangeNum))
|
return
|
|
exchangeCountMax = findIpyData.GetExchangeCountMax()
|
curExchangeCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollectWordsExchangeCount % (actNum, exchangeNum))
|
if exchangeCountMax and curExchangeCount >= exchangeCountMax:
|
GameWorld.DebugLog("³¬¹ý×î´ó¼¯×Ö¶Ò»»´ÎÊý£¡templateID=%s,exchangeNum=%s,curExchangeCount=%s > %s"
|
% (templateID, exchangeNum, curExchangeCount, exchangeCountMax))
|
return
|
|
exchangeItemInfo = __GetExchangeItemInfo(findIpyData.GetExchangeItemInfo(), actInfo.get(ShareDefine.ActKey_WorldLV, 0))
|
if len(exchangeItemInfo) != 3:
|
return
|
exchangeItemID = exchangeItemInfo[0]
|
exchangeCount = exchangeItemInfo[1]
|
exchangeIsBind = exchangeItemInfo[2]
|
|
if not ItemControler.CheckPackSpaceEnough(curPlayer, [[exchangeItemID, exchangeCount, exchangeIsBind]]):
|
return
|
|
delItemList = []
|
needItemList = findIpyData.GetNeedItemList()
|
for needItemID, needCount, _ in needItemList:
|
costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, needItemID, needCount)
|
if bindCnt + unBindCnt < needCount:
|
GameWorld.DebugLog("¼¯×Ö¶Ò»»ËùÐèÎïÆ·²»×㣡exchangeItemID=%s,needItemID=%s,needCount=%s > %s"
|
% (exchangeItemID, needItemID, needCount, bindCnt + unBindCnt))
|
return
|
delItemList.append([costItemIndexList, bindCnt, unBindCnt, needCount])
|
|
if exchangeCountMax:
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollectWordsExchangeCount % (actNum, exchangeNum), curExchangeCount + 1)
|
SyncCollectWordsPlayerInfo(curPlayer, actNum, exchangeNum)
|
|
eventName = "CollectWordsExchange"
|
for costItemIndexList, bindCnt, unBindCnt, needCount in delItemList:
|
ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, needCount, eventName)
|
|
ItemControler.GivePlayerItem(curPlayer, exchangeItemID, exchangeCount, exchangeIsBind, [IPY_GameWorld.rptItem], event=[eventName, False, {}])
|
|
if findIpyData.GetNeedNotify():
|
PlayerControl.WorldNotify(0, "CollectWordsExchange", [curPlayer.GetPlayerName(), exchangeItemID])
|
|
return
|
|
def __GetExchangeItemInfo(cfgExchangeItemInfo, worldLV):
|
if isinstance(cfgExchangeItemInfo, dict):
|
return GameWorld.GetDictValueByRangeKey(cfgExchangeItemInfo, worldLV, [])
|
return cfgExchangeItemInfo
|
|
def SyncCollectWordsActionInfo(curPlayer, actNum):
|
## ͬ²½»î¶¯ÐÅÏ¢
|
|
if actNum not in ActCollectWordsNameDict:
|
return
|
actName = ActCollectWordsNameDict[actNum]
|
|
actInfo = PyGameData.g_operationActionDict.get(actName, {})
|
if not actInfo:
|
return
|
|
if not actInfo.get(ShareDefine.ActKey_State):
|
return
|
|
cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
|
ipyData = IpyGameDataPY.GetIpyGameData(actName, cfgID)
|
if not ipyData:
|
return
|
|
templateID = ipyData.GetTemplateID()
|
if not templateID:
|
return
|
|
openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
|
clientPack = ChPyNetSendPack.tagMCActCollectWordsInfo()
|
clientPack.ActNum = actNum
|
clientPack.StartDate = GameWorld.GetOperationActionDateStr(ipyData.GetStartDate(), openServerDay)
|
clientPack.EndtDate = GameWorld.GetOperationActionDateStr(ipyData.GetEndDate(), openServerDay)
|
clientPack.LimitLV = ipyData.GetLVLimit()
|
clientPack.LastDayOnlyExchange = ipyData.GetLastDayOnlyExchange()
|
clientPack.ExchangeItemList = []
|
|
exchangeList = IpyGameDataPY.GetIpyGameDataList("CollectWordsExchange", templateID)
|
if exchangeList:
|
for exchangeIpyData in exchangeList:
|
itemID, itemCount, isBind = __GetExchangeItemInfo(exchangeIpyData.GetExchangeItemInfo(), actInfo.get(ShareDefine.ActKey_WorldLV, 0))
|
needItemList = exchangeIpyData.GetNeedItemList()
|
|
exchangeItem = ChPyNetSendPack.tagMCActCollectWordsExchangeItem()
|
exchangeItem.ExchangeNum = exchangeIpyData.GetExchangeNum()
|
exchangeItem.ExchangeCountMax = exchangeIpyData.GetExchangeCountMax()
|
exchangeItem.ItemID = itemID
|
exchangeItem.ItemCount = itemCount
|
exchangeItem.IsBind = isBind
|
exchangeItem.NeedItemList = []
|
for needItemID, needCount, needIsBind in needItemList:
|
needItem = ChPyNetSendPack.tagMCActCollectWordsNeedItem()
|
needItem.ItemID = needItemID
|
needItem.ItemCount = needCount
|
needItem.IsBind = needIsBind
|
exchangeItem.NeedItemList.append(needItem)
|
exchangeItem.NeedItemCount = len(exchangeItem.NeedItemList)
|
|
clientPack.ExchangeItemList.append(exchangeItem)
|
|
clientPack.ExchangeCount = len(clientPack.ExchangeItemList)
|
NetPackCommon.SendFakePack(curPlayer, clientPack)
|
return
|
|
def SyncCollectWordsPlayerInfo(curPlayer, actNum, exchangeNum=0):
|
## ͬ²½»î¶¯Íæ¼ÒÊý¾Ý
|
|
if actNum not in ActCollectWordsNameDict:
|
return
|
actName = ActCollectWordsNameDict[actNum]
|
|
actInfo = PyGameData.g_operationActionDict.get(actName, {})
|
if not actInfo:
|
return
|
|
if not actInfo.get(ShareDefine.ActKey_State):
|
return
|
|
cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
|
ipyData = IpyGameDataPY.GetIpyGameData(actName, cfgID)
|
if not ipyData:
|
return
|
|
templateID = ipyData.GetTemplateID()
|
if not templateID:
|
return
|
|
exchangeList = IpyGameDataPY.GetIpyGameDataList("CollectWordsExchange", templateID)
|
if not exchangeList:
|
return
|
|
clientPack = ChPyNetSendPack.tagMCActCollectWordsPlayerInfo()
|
clientPack.ActNum = actNum
|
clientPack.ExchangeInfoList = []
|
for exchangeIpyData in exchangeList:
|
ipyExchangeNum = exchangeIpyData.GetExchangeNum()
|
if exchangeNum and exchangeNum != ipyExchangeNum:
|
continue
|
|
exchangeInfo = ChPyNetSendPack.tagMCActCollectWordsExchangeInfo()
|
exchangeInfo.ExchangeNum = ipyExchangeNum
|
exchangeInfo.ExchangeCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollectWordsExchangeCount % (actNum, ipyExchangeNum))
|
clientPack.ExchangeInfoList.append(exchangeInfo)
|
|
if exchangeNum:
|
break
|
|
clientPack.ExchangeCount = len(clientPack.ExchangeInfoList)
|
NetPackCommon.SendFakePack(curPlayer, clientPack)
|
return
|
|
|