| | |
| | | import PlayerFeastTravel
|
| | | import PlayerFairyCeremony
|
| | | import PlayerNewFairyCeremony
|
| | | import PlayerActYunshi
|
| | | import PlayerActTask
|
| | | import ItemCommon
|
| | | import ChConfig
|
| | |
| | | import random
|
| | | import time
|
| | |
|
| | | # 寻宝类型: >=100的为策划自行配置的自定义寻宝类型,<100的用于指定系统寻宝功能
|
| | | TreasureTypeList = (
|
| | | TreasureType_Jipin, # 极品寻宝 1
|
| | | TreasureType_Rune, # 符印寻宝 2
|
| | |
| | | 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
|
| | |
| | | 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)
|
| | |
| | | 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
|
| | |
| | | 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)
|
| | |
| | | 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:
|
| | |
| | | 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)
|
| | |
|
| | |
| | |
|
| | | 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):
|
| | | # 获取幸运物品提升概率后的饼图
|
| | |
| | | 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开始
|
| | |
| | | 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 = []
|
| | |
| | | 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)
|