#!/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 def GetActInfo(actNum): if ShareDefine.OperationActionName_CollectWords not in PyGameData.g_operationActionDict: return {} actNumDict = PyGameData.g_operationActionDict[ShareDefine.OperationActionName_CollectWords] if actNum not in actNumDict: return {} return actNumDict[actNum] def OnPlayerLogin(curPlayer): ## Íæ¼ÒµÇ¼ for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_CollectWords, {}).values(): actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0) isReset = __CheckPlayerCollectWordsAction(curPlayer, actNum) if not isReset: # »î¶¯ÖÐͬ²½»î¶¯ÐÅÏ¢ 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 not GameWorld.IsNormalPlayer(curPlayer): continue __CheckPlayerCollectWordsAction(curPlayer, actNum) return def __CheckPlayerCollectWordsAction(curPlayer, actNum): ## ¼ì²éÍæ»î¶¯Êý¾ÝÐÅÏ¢ playerID = curPlayer.GetPlayerID() actInfo = GetActInfo(actNum) 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("ActCollectWords", 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) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollectWordsGJSeconds % actNum, 0) 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 actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_CollectWords, {}).values(): actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0) randList = __GetDropWordsItemRateList(curPlayer, curNPC, actInfo) if not randList: continue if isinstance(randList, dict): for dropItemID, dropCountList in randList.items(): itemCount = GameWorld.GetResultByRandomList(dropCountList) if itemCount <= 0: continue GameWorld.DebugLog(" ¼¯×ֻµôÂäÎïÆ· dict! actNum=%s,npcID=%s,dropItemID=%s,itemCount=%s" % (actNum, curNPC.GetNPCID(), dropItemID, itemCount)) isAuctionItem = 0 # ·ÇÅÄÆ· ItemControler.GivePlayerItem(curPlayer, dropItemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]) continue dropItemID = GameWorld.GetResultByRandomList(randList) if not dropItemID: continue GameWorld.DebugLog(" ¼¯×ֻµôÂäÎïÆ·! actNum=%s,npcID=%s,dropItemID=%s" % (actNum, curNPC.GetNPCID(), dropItemID)) itemCount = 1 # ĬÈÏ1¸ö isAuctionItem = 0 # ·ÇÅÄÆ· ItemControler.GivePlayerItem(curPlayer, dropItemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]) return def __GetDropWordsItemRateList(curPlayer, npcData, actInfo): ## »ñÈ¡µô×Ö±ýͼÁбí if not actInfo.get(ShareDefine.ActKey_State): return cfgID = actInfo.get(ShareDefine.ActKey_CfgID) ipyData = IpyGameDataPY.GetIpyGameData("ActCollectWords", cfgID) if not ipyData: return isBoss = ChConfig.IsGameBoss(npcData) playerLV = curPlayer.GetLV() import NPCCommon npcLV = NPCCommon.GetNPCLV(npcData, curPlayer) 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: _, endDateStr = GameWorld.GetOperationActionDateStr(ipyData) 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 actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_CollectWords, {}).values(): actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0) dropRateList = __GetDropWordsItemRateList(curPlayer, npcData, actInfo) if not dropRateList: continue if not isinstance(dropRateList, list): 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,dropItemID=%s,dropCount=%s" % (actNum, dropItemID, dropCount)) return dropItemCountDict def OnGetGuajiAwardItemDict(curPlayer, awardSeconds, useUnsecond): ## »ñÈ¡¹Ò»úÊÕÒæ dropItemCountDict = {} for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_CollectWords, {}).values(): actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0) if not actInfo.get(ShareDefine.ActKey_State): continue cfgID = actInfo.get(ShareDefine.ActKey_CfgID) ipyData = IpyGameDataPY.GetIpyGameData("ActCollectWords", cfgID) if not ipyData: continue dropRateList = ipyData.GetDropItemRateList() if not dropRateList: continue guajiAwardSet = ipyData.GetGuajiAwardSet() # xÃëx´Î if not guajiAwardSet: continue doSeconds, doCount = guajiAwardSet if useUnsecond: unSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollectWordsGJSeconds % (actNum)) awardSeconds += unSeconds canDoCount = awardSeconds / doSeconds killCount = canDoCount * doCount updUnSeconds = awardSeconds % doSeconds PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollectWordsGJSeconds % (actNum), updUnSeconds) GameWorld.DebugLog(" ¹Ò»ú¼¯×ֻ: actNum=%s,awardSeconds=%s,canDoCount=%s,killCount=%s,unSeconds=%s,updUnSeconds=%s" % (actNum, awardSeconds, canDoCount, killCount, unSeconds, updUnSeconds)) else: canDoCount = awardSeconds / doSeconds killCount = canDoCount * doCount GameWorld.DebugLog(" ¹Ò»ú¼¯×ֻ: actNum=%s,awardSeconds=%s,canDoCount=%s,killCount=%s" % (actNum, awardSeconds, canDoCount, killCount)) if killCount <= 0: 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,dropItemID=%s,dropCount=%s,curRate=%s,totalRate=%s" % (actNum, dropItemID, dropCount, curRate, totalRate)) 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)) actInfo = GetActInfo(actNum) if not actInfo.get(ShareDefine.ActKey_State): GameWorld.DebugLog("·Ç¼¯×ֻÖУ¬ÎÞ·¨¶Ò»»£¡actNum=%s" % actNum) return cfgID = actInfo.get(ShareDefine.ActKey_CfgID) ipyData = IpyGameDataPY.GetIpyGameData("ActCollectWords", 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): ## ͬ²½»î¶¯ÐÅÏ¢ actInfo = GetActInfo(actNum) if not actInfo.get(ShareDefine.ActKey_State): return cfgID = actInfo.get(ShareDefine.ActKey_CfgID) ipyData = IpyGameDataPY.GetIpyGameData("ActCollectWords", cfgID) if not ipyData: return templateID = ipyData.GetTemplateID() if not templateID: return startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData) clientPack = ChPyNetSendPack.tagMCActCollectWordsInfo() clientPack.ActNum = actNum clientPack.StartDate = startDateStr clientPack.EndtDate = endDateStr 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): ## ͬ²½»î¶¯Íæ¼ÒÊý¾Ý actInfo = GetActInfo(actNum) if not actInfo: return if not actInfo.get(ShareDefine.ActKey_State): return cfgID = actInfo.get(ShareDefine.ActKey_CfgID) ipyData = IpyGameDataPY.GetIpyGameData("ActCollectWords", 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