From 2e0dbebc2b1e2dbfea405ac4674c7c50bd92b73d Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期五, 08 十一月 2024 13:56:48 +0800 Subject: [PATCH] 10289 【越南】【英语】【砍树】【tqxbqy】运势-服务端 --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py | 258 +++++++++++++++++++++++++++++++++------------------ 1 files changed, 167 insertions(+), 91 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py index e0bbb05..4220e01 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py @@ -30,6 +30,7 @@ import PlayerFeastTravel import PlayerFairyCeremony import PlayerNewFairyCeremony +import PlayerActYunshi import PlayerActTask import ItemCommon import ChConfig @@ -37,6 +38,7 @@ import random import time +# 寻宝类型: >=100的为策划自行配置的自定义寻宝类型,<100的用于指定系统寻宝功能 TreasureTypeList = ( TreasureType_Jipin, # 极品寻宝 1 TreasureType_Rune, # 符印寻宝 2 @@ -70,6 +72,34 @@ Sync_TreasureInfo(curPlayer, syncTypeList) return +def ResetTreasureType(curPlayer, treasureTypeList): + ## 重置寻宝类型数 + for treasureType in treasureTypeList: + setIpyData = IpyGameDataPY.GetIpyGameData("TreasureSet", treasureType) + if not setIpyData: + continue + recycleItemMail = setIpyData.GetRecycleItemMail() + costItemID = setIpyData.GetCostItemID() + if recycleItemMail and costItemID: + ItemControler.RecycleItem(curPlayer, costItemID, recycleItemMail) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureFreeCount % (treasureType), 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureCount % (treasureType), 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureLuck % (treasureType), 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureCntAward % (treasureType), 0) + + gridNumMaxLimitInfo = setIpyData.GetGridNumMaxLimitInfo() + for gridNumStr in gridNumMaxLimitInfo.keys(): + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureGridCnt % (treasureType, int(gridNumStr)), 0) + + Sync_TreasureInfo(curPlayer, treasureTypeList) + return + +def IsActTreasureType(curPlayer, treasureType): + ## 是否活动中的寻宝类型 + if PlayerActYunshi.IsActTreasureType(curPlayer, treasureType): + return True + return False + #// A5 68 请求寻宝 #tagCMRequestTreasure # #struct tagCMRequestTreasure @@ -93,6 +123,10 @@ setIpyData = IpyGameDataPY.GetIpyGameData("TreasureSet", treasureType) if not setIpyData: return + if setIpyData.GetIsActType(): + if not IsActTreasureType(curPlayer, treasureType): + GameWorld.ErrLog("该寻宝类型非活动中,无法寻宝! treasureType=%s" % (treasureType), playerID) + return treasureCountList = setIpyData.GetTreasureCountList() # 寻宝获得个数列表 if not treasureCountList: GameWorld.DebugLog("没有寻宝次数列表配置!", playerID) @@ -106,7 +140,7 @@ return packType = setIpyData.GetPackType() - if treasureType not in [TreasureType_GatherTheSoul, TreasureType_Gubao]: + if setIpyData.GetCheckPack(): if not ItemCommon.CheckPackHasSpace(curPlayer, packType, True): GameWorld.DebugLog("对应寻宝背包没有空格子!packType=%s" % packType, playerID) return @@ -177,113 +211,87 @@ luckyGridNumList = [setIpyData.GetLuckyGridNum()] GameWorld.DebugLog("luckyGridNumList=%s, %s" % (luckyGridNumList, luckyItemRateList), playerID) luckFormula = setIpyData.GetLuckyRateFormat() # 幸运物品概率公式 - addLuck = setIpyData.GetOnceLucky() * treasureCount # 增加幸运值 + addLuck = setIpyData.GetOnceLucky() # 增加幸运值 maxLuck = setIpyData.GetFullLucky() # 满幸运值 curLuck = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureLuck % (treasureType)) # 当前幸运值 - updLuck = curLuck + addLuck - - commItemRateList = GetUpdLuckyItemRateList(ipyData, luckyGridNumList, curLuck, luckFormula, costType) # 常规产出物品格子饼图,幸运物品概率已变更 + updLuck = curLuck curTreasureCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureCount % (treasureType)) # 当前已寻宝次数 - updTreasureCount = curTreasureCount + treasureCount - GameWorld.DebugLog("已经寻宝次数=%s,当前幸运=%s,commItemRateList=%s" % (curTreasureCount, curLuck, commItemRateList), playerID) + updTreasureCount = curTreasureCount beSureCountDict = ipyData.GetGridItemRateList3() # 第x次必出产出格子编号饼图 ensureCount = setIpyData.GetEnsureCount() # 每多少次触发保底产出库 ensureRateList = ipyData.GetGridItemRateList2() + GameWorld.DebugLog("beSureCountDict=%s" % beSureCountDict, playerID) + GameWorld.DebugLog("ensureCount=%s, %s" % (ensureCount, ensureRateList), playerID) notifyGridNumList = setIpyData.GetNotifyGridNumList() # 额外需要广播的格子,幸运必出、次数必出可不配置 + gridNumMaxLimitInfo = setIpyData.GetGridNumMaxLimitInfo() # {"格子":最大可产出次数, ...} + gridNumCountInfo = {} # 有限制产出次数的格子已经产出数 + for gridNumStr in gridNumMaxLimitInfo.keys(): + gridNumCountInfo[int(gridNumStr)] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureGridCnt % (treasureType, gridNumStr)) + GameWorld.DebugLog("gridNumMaxLimitInfo=%s,gridNumCountInfo=%s" % (gridNumMaxLimitInfo, gridNumCountInfo), playerID) # 单抽产出优先级: 幸运物品 > 必出 > 保底 > 普通 # 连抽没有优先级限制,只要满足条件即可产出 getGridResult = [] - - # 1.满幸运必出 - if updLuck >= maxLuck and luckyGridNumList: - if luckyItemRateList: - luckyGridNum = GameWorld.GetResultByRandomList(luckyItemRateList) - else: - luckyGridNum = luckyGridNumList[0] - getGridResult.append(luckyGridNum) - GameWorld.DebugLog("满幸运必出幸运物品: luckyGridNum=%s" % luckyGridNum, playerID) + for tIndex in range(treasureCount): + updLuck = min(updLuck + addLuck, maxLuck) + updTreasureCount += 1 + GameWorld.DebugLog("%s,累计次数=%s,幸运=%s" % (tIndex + 1, updTreasureCount, updLuck), playerID) + if gridNumMaxLimitInfo: + GameWorld.DebugLog(" gridNumMaxLimitInfo=%s,gridNumCountInfo=%s" % (gridNumMaxLimitInfo, gridNumCountInfo), playerID) + baseRateList, commItemRateList = GetUpdLuckyItemRateList(ipyData, luckyGridNumList, updLuck, luckFormula, costType) # 常规产出物品格子饼图,幸运物品概率已变更 + commItemRateList = GetRemoveLimitGridRateList(commItemRateList, gridNumCountInfo, gridNumMaxLimitInfo) + GameWorld.DebugLog(" 基础饼图=%s" % baseRateList, playerID) + GameWorld.DebugLog(" 常规饼图=%s" % commItemRateList, playerID) - # 单抽 - if treasureCount == 1: - if not getGridResult: - if updTreasureCount in beSureCountDict: - gridNumRateList = beSureCountDict[updTreasureCount] - gridNum = GameWorld.GetResultByRandomList(gridNumRateList) - GameWorld.DebugLog("到达次数必出,updTreasureCount=%s,gridNumRateList=%s,gridNum=%s" % (updTreasureCount, gridNumRateList, gridNum), playerID) - elif ensureCount and updTreasureCount % ensureCount == 0 and ensureRateList: - gridNumRateList = ensureRateList - gridNum = GameWorld.GetResultByRandomList(gridNumRateList) - GameWorld.DebugLog("满次数保底出,updTreasureCount=%s,gridNumRateList=%s,gridNum=%s" % (updTreasureCount, gridNumRateList, gridNum), playerID) + curRateList = [] # 可能会改变饼图,每次抽奖使用新的饼图对象,不要改变配置的饼图概率 + + # 满幸运必出 + if updLuck >= maxLuck and luckyGridNumList: + if luckyItemRateList: + curRateList = GetRemoveLimitGridRateList(luckyItemRateList, gridNumCountInfo, gridNumMaxLimitInfo) else: - gridNumRateList = commItemRateList - gridNum = GameWorld.GetResultByRandomList(gridNumRateList) - GameWorld.DebugLog("常规产出,updTreasureCount=%s,gridNum=%s" % (updTreasureCount, gridNum), playerID) - getGridResult.append(gridNum) + curRateList = GetRemoveLimitGridRateList([(10000, luckyGridNumList[0])], gridNumCountInfo, gridNumMaxLimitInfo) + GameWorld.DebugLog(" 【满幸运饼图】: %s" % curRateList) - # 连抽 - elif treasureCount > 1: - # 2. 次数必出 - besureGridNumList = [] - for count, gridNumRateList in beSureCountDict.items(): - if curTreasureCount < count and updTreasureCount >= count: - for gridInfo in gridNumRateList: - besureGridNumList.append(gridInfo[1]) - gridNum = GameWorld.GetResultByRandomList(gridNumRateList) - getGridResult.append(gridNum) - GameWorld.DebugLog("到达次数必出,count=%s,updTreasureCount=%s,gridNumRateList=%s,gridNum=%s" % (count, updTreasureCount, gridNumRateList, gridNum), playerID) + # 次数必出 + if not curRateList and updTreasureCount in beSureCountDict: + besureGridRateList = beSureCountDict[updTreasureCount] + curRateList = GetRemoveLimitGridRateList(besureGridRateList, gridNumCountInfo, gridNumMaxLimitInfo) + GameWorld.DebugLog(" 【第%s次数必出饼图】: %s" % (updTreasureCount, curRateList)) + + # 满次数必出 + if not curRateList and ensureCount and updTreasureCount % ensureCount == 0 and ensureRateList: + curRateList = GetRemoveLimitGridRateList(ensureRateList, gridNumCountInfo, gridNumMaxLimitInfo) + GameWorld.DebugLog(" 【满%s次数必出饼图】: %s" % (ensureCount, curRateList)) + + doCount = 0 + while doCount <= 50: # 限制最大次数 + doCount += 1 + if doCount > 1 or not curRateList: # 重新随机的默认使用常规饼图 + curRateList = commItemRateList - # 3. 次数保底 - ensureGridNumList = [] - if ensureCount and updTreasureCount / ensureCount > curTreasureCount / ensureCount and ensureRateList: - for gridInfo in ensureRateList: - ensureGridNumList.append(gridInfo[1]) - gridNum = GameWorld.GetResultByRandomList(ensureRateList) - getGridResult.append(gridNum) - GameWorld.DebugLog("满次数保底出,updTreasureCount=%s,gridNumRateList=%s,gridNum=%s" % (updTreasureCount, ensureRateList, gridNum), playerID) - - # 4. 常规产出 - doCount = 200 - needCount = max(0, treasureCount - len(getGridResult)) - while needCount and doCount: - doCount -= 1 - gridNum = GameWorld.GetResultByRandomList(commItemRateList) - + gridNum = GameWorld.GetResultByRandomList(curRateList) if gridNum in luckyGridNumList and gridNum in getGridResult: - GameWorld.DebugLog("幸运物品已经出过,不再重复产出!") + GameWorld.DebugLog(" 幸运物品已经出过,不再重复产出! gridNum=%s in %s" % (gridNum, getGridResult)) continue - if gridNum in besureGridNumList: - canGive = True - for besureGridNum in besureGridNumList: - if besureGridNum in getGridResult: - canGive = False - GameWorld.DebugLog("次数必出物品已经出过,不再重复产出!gridNum=%s,besureGridNum=%s,besureGridNumList=%s" - % (gridNum, besureGridNum, besureGridNumList), playerID) - break - if not canGive: - continue - - if gridNum in ensureGridNumList: - canGive = True - for ensureGridNum in ensureGridNumList: - if ensureGridNum in getGridResult: - canGive = False - GameWorld.DebugLog("满次数保底物品已经出过,不再重复产出!gridNum=%s,ensureGridNum=%s,ensureGridNumList=%s" - % (gridNum, ensureGridNum, ensureGridNumList), playerID) - break - if not canGive: - continue - - needCount -= 1 - getGridResult.append(gridNum) - GameWorld.DebugLog("常规产出: gridNum=%s" % (gridNum), playerID) + # 其他产出限制... - else: - return - + if not gridNum: + continue + + getGridResult.append(gridNum) + GameWorld.DebugLog(" 本次产出: gridNum=%s, %s" % (gridNum, getGridResult), playerID) + if gridNum in luckyGridNumList: + updLuck = 0 + GameWorld.DebugLog(" 【产出幸运格子】: gridNum=%s" % (gridNum), playerID) + if gridNum in gridNumCountInfo: + gridNumCountInfo[gridNum] = gridNumCountInfo[gridNum] + 1 + GameWorld.DebugLog(" 【更新产出次数】: gridNum=%s, %s" % (gridNum, gridNumCountInfo), playerID) + break + GameWorld.DebugLog("寻宝格子结果: getGridResult=%s" % getGridResult, playerID) if len(getGridResult) != treasureCount: GameWorld.ErrLog("寻宝异常,实际获得数量与寻宝请求数不同!treasureType=%s,treasureIndex=%s" % (treasureType, treasureIndex), playerID) @@ -367,7 +375,9 @@ updLuck = 0 break PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureLuck % (treasureType), updLuck) - + for gridNum, updCount in gridNumCountInfo.items(): + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureGridCnt % (treasureType, gridNum), updCount) + addScoreType = setIpyData.GetAwardMoneyType() # 额外奖励货币类型 addScore = setIpyData.GetAwardMoneyValue() # 单次奖励货币数 if addScoreType and addScore: @@ -407,8 +417,8 @@ if mailItemList: PlayerControl.SendMailByKey("HappyXBUnEnough", [playerID], mailItemList) - GameWorld.DebugLog("寻宝成功: treasureType=%s,updTreasureCount=%s,updLuck=%s,addLuck=%s,addScoreType=%s,addScore=%s" - % (treasureType, updTreasureCount, updLuck, addLuck, addScoreType, addScore), playerID) + GameWorld.DebugLog("寻宝成功: treasureType=%s,updTreasureCount=%s,updLuck=%s,addScoreType=%s,addScore=%s,gridNumCountInfo=%s" + % (treasureType, updTreasureCount, updLuck, addScoreType, addScore, gridNumCountInfo), playerID) GameWorld.DebugLog(" treasureResult=%s" % (treasureResult), playerID) GameWorld.DebugLog(" mailItemList=%s" % (mailItemList), playerID) @@ -424,6 +434,26 @@ Sync_TreasureInfo(curPlayer, [treasureType]) return + +def GetRemoveLimitGridRateList(srcGridNumRateList, gridNumCountInfo, gridNumMaxLimitInfo): + ## 获取移除限制产出的格子后的饼图列表 + # @param srcGridNumRateList: 原始概率 [(概率, 格子编号), ...] + # @param gridNumCountInfo: 有限制产出数的格子已经产出数量信息 {gridNum:count, ...} + # @param gridNumMaxLimitInfo: 有限制产出数的格子最大产出数量信息 {"gridNum":countLimit, ...} + newRateList = [] + if not gridNumMaxLimitInfo: + return newRateList + srcGridNumRateList # 不使用原配置饼图,不然可能导致修改掉原始配置饼图导致bug + for i, rateInfo in enumerate(srcGridNumRateList): + rate, gridNum = rateInfo + if str(gridNum) in gridNumMaxLimitInfo: + limitCount = gridNumMaxLimitInfo[str(gridNum)] + if limitCount and gridNumCountInfo.get(gridNum, 0) >= limitCount: + # 已达到限制产出数,不再产出 + continue + srcRate = rate if i == 0 else (rate - srcGridNumRateList[i - 1][0]) # 原概率 + newRate = srcRate if not newRateList else (newRateList[-1][0] + srcRate) + newRateList.append((newRate, gridNum)) + return newRateList def GetUpdLuckyItemRateList(ipyData, luckyGridNumList, curLuck, luckFormula, costType): # 获取幸运物品提升概率后的饼图 @@ -445,7 +475,7 @@ specRate = newRate if not updRateList else (updRateList[-1][0] + newRate) # 提升后对应饼图概率 updRateList.append((specRate, gridNum)) - return updRateList + return srcPieList, updRateList def GetJobItem(job, itemID, jobItemList): ## 获取宝箱物品奖励对应的职业物品, 职业从1开始 @@ -460,6 +490,37 @@ return jobItemIDList[job - 1] return itemID +def GetTreasureCntAward(curPlayer, treasureType, needTreasureCnt): + ## 领取天道树奖励 + needTreasureCnt = GameWorld.ToIntDef(needTreasureCnt, 0) + playerID = curPlayer.GetPlayerID() + ipyData = IpyGameDataPY.GetIpyGameData("TreasureCntAward", treasureType, needTreasureCnt) + if not ipyData: + return + awardIndex = ipyData.GetAwardIndex() + awardItemList = ipyData.GetAwardItemList() + + awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureCntAward % (treasureType)) + if awardState&pow(2, awardIndex): + GameWorld.DebugLog("该寻宝次数奖励已领奖! treasureType=%s,needTreasureCnt=%s,awardIndex=%s" + % (treasureType, needTreasureCnt, awardIndex), playerID) + return + + treasureCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureCount % (treasureType)) + if treasureCount < needTreasureCnt: + GameWorld.DebugLog("该寻宝次数不足,无法领奖! treasureType=%s,treasureCount=%s < %s" + % (treasureType, treasureCount, needTreasureCnt), playerID) + return + + updState = awardState|pow(2, awardIndex) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureCntAward % (treasureType), updState) + GameWorld.DebugLog("领取寻宝次数奖励! treasureType=%s,needTreasureCnt=%s,awardIndex=%s,awardState=%s,updState=%s" + % (treasureType, needTreasureCnt, awardIndex, awardState, updState), playerID) + + ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList) + Sync_TreasureInfo(curPlayer, [treasureType]) + return + def Sync_TreasureInfo(curPlayer, syncTypeList=None): if syncTypeList == None: syncTypeList = [] @@ -472,12 +533,27 @@ treasureInfoPack.Clear() treasureInfoPack.TreasuerInfoList = [] for tType in syncTypeList: + setIpyData = IpyGameDataPY.GetIpyGameData("TreasureSet", tType) + if not setIpyData: + continue + if setIpyData.GetIsActType(): + if not IsActTreasureType(curPlayer, tType): + continue + gridNumMaxLimitInfo = setIpyData.GetGridNumMaxLimitInfo() tTypeInfo = ChPyNetSendPack.tagMCTreasureTypeInfo() tTypeInfo.Clear() tTypeInfo.TreasureType = tType tTypeInfo.LuckValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureLuck % (tType)) tTypeInfo.TreasureCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureCount % (tType)) tTypeInfo.FreeCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureFreeCount % (tType)) + tTypeInfo.TreasureCntAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureCntAward % (tType)) + for gridNumStr in gridNumMaxLimitInfo.keys(): + gridNum = int(gridNumStr) + gridLimit = ChPyNetSendPack.tagMCTreasureGridLimit() + gridLimit.GridNum = gridNum + gridLimit.GridCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreasureGridCnt % (tType, gridNum)) + tTypeInfo.GridLimitCntList.append(gridLimit) + tTypeInfo.GridLimitCnt = len(tTypeInfo.GridLimitCntList) treasureInfoPack.TreasuerInfoList.append(tTypeInfo) treasureInfoPack.InfoCount = len(treasureInfoPack.TreasuerInfoList) NetPackCommon.SendFakePack(curPlayer, treasureInfoPack) -- Gitblit v1.8.0