提交 | 用户 | age
9f30bc 1 #!/usr/bin/python
H 2 # -*- coding: GBK -*-
3 #-------------------------------------------------------------------------------
4 #
5 ##@package Player.PlayerActLunhuidian
6 #
7 # @todo:轮回殿
8 # @author hxp
9 # @date 2024-11-11
10 # @version 1.0
11 #
12 # 详细描述: 轮回殿
13 #
14 #-------------------------------------------------------------------------------
15 #"""Version = 2024-11-11 18:00"""
16 #-------------------------------------------------------------------------------
17
18 import PyGameData
19 import ShareDefine
20 import PlayerControl
21 import IpyGameDataPY
22 import ChPyNetSendPack
8a0a84 23 import FunctionNPCCommon
9f30bc 24 import NetPackCommon
H 25 import ItemControler
8a0a84 26 import PlayerCoin
9f30bc 27 import GameWorld
H 28 import ChConfig
29
30 # 轮回设定配置索引
31 RoundSetIndex = (
32 RoundSetIndex_AwardType, # 0 奖励类型
33 RoundSetIndex_AwardTypeValue, # 1 奖励类型对应值
34 RoundSetIndex_RoundMax, # 2 最大轮回次数
35 ) = range(3)
36
37 # 轮回奖励类型
bbaf5b 38 AwardTypeList = (
H 39 AwardType_PayMoney, # 1 消耗货币
40 AwardType_Treasure, # 2 寻宝
41 AwardType_UseItem, # 3 消耗物品
42 ) = range(1, 1 + 3)
9f30bc 43
H 44 def OnPlayerLogin(curPlayer):
45     
46     for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_Lunhuidian, {}).values():
47         actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0)
48         isReset = __CheckPlayerActLunhuidianAction(curPlayer, actNum)
49         # 活动中同步活动信息
50         if not isReset and actInfo.get(ShareDefine.ActKey_State):
51             Sync_ActLunhuidianActionInfo(curPlayer, actNum)
52             cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
53             ipyData = IpyGameDataPY.GetIpyGameData("ActLunhuidian", cfgID)
54             if ipyData:
55                 roundSetDict = ipyData.GetRoundSetInfo()
56                 for roundType in roundSetDict.keys():
57                     Sync_ActLunhuidianPlayerInfo(curPlayer, actNum, roundType)
58     return
59
60 def RefreshActLunhuidianActionInfo(actNum):
61     ## 收到GameServer同步的活动信息,刷新活动信息
62     playerManager = GameWorld.GetPlayerManager()
63     for index in xrange(playerManager.GetPlayerCount()):
64         curPlayer = playerManager.GetPlayerByIndex(index)
65         if not GameWorld.IsNormalPlayer(curPlayer):
66             continue
67         __CheckPlayerActLunhuidianAction(curPlayer, actNum)
68     return
69
70 def __CheckPlayerActLunhuidianAction(curPlayer, actNum):
71     ## 检查玩活动数据信息
72     
73     playerID = curPlayer.GetPlayerID()
74     
75     actInfo = GameWorld.GetActInfo(ShareDefine.OperationActionName_Lunhuidian, actNum)
76     actID = actInfo.get(ShareDefine.ActKey_ID, 0)
77     state = actInfo.get(ShareDefine.ActKey_State, 0)
78     cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
79     
80     playerActID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianID % actNum) # 玩家身上的活动ID
81     
82     # 活动ID 相同的话不处理
83     if actID == playerActID:
84         GameWorld.DebugLog("轮回殿活动ID不变,不处理! actNum=%s,cfgID=%s,actID=%s" % (actNum, cfgID, actID), playerID)
85         return
86     GameWorld.DebugLog("轮回殿活动重置! actNum=%s,cfgID=%s,actID=%s,playerActID=%s,state=%s" 
87                        % (actNum, cfgID, actID, playerActID, state), playerID)
bdbcaa 88     OnGiveUngetAward(curPlayer, actNum)
9f30bc 89     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianID % actNum, actID)
H 90     
91     if state:
92         Sync_ActLunhuidianActionInfo(curPlayer, actNum)
93         ipyData = IpyGameDataPY.GetIpyGameData("ActLunhuidian", cfgID)
94         if ipyData:
95             roundSetDict = ipyData.GetRoundSetInfo()
8a0a84 96             ctgIDDict = ipyData.GetRoundCTGIDInfo()
H 97             shopTypeDict = ipyData.GetRoundShopTypeInfo()
98             resetCTGIDList, resetShopTypeList = [], []
bdbcaa 99             for roundType, roundSet in roundSetDict.items():
H 100                 SaveActRoundSet(curPlayer, actNum, roundType, roundSet)
9f30bc 101                 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType), 0)
H 102                 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianRound % (actNum, roundType), 1) # 从第1轮开始
103                 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianAward % (actNum, roundType), 0)
104                 Sync_ActLunhuidianPlayerInfo(curPlayer, actNum, roundType)
8a0a84 105                 resetCTGIDList += ctgIDDict.get(roundType, [])
H 106                 shopType = shopTypeDict.get(roundType, 0)
107                 if shopType and shopType not in resetShopTypeList:
108                     resetShopTypeList.append(shopType)
109                     
110             PlayerCoin.DoResetCTGCountByIDList(curPlayer, "ActLunhuidian", resetCTGIDList)
111             FunctionNPCCommon.ResetShopItemBuyCountByShopType(curPlayer, resetShopTypeList)
112             
9f30bc 113     return True
H 114
bdbcaa 115 def SaveActRoundSet(curPlayer, actNum, roundType, roundSet):
H 116     ## 保存参与的活动轮回设定,用于活动结束邮件补发奖励
117     # 单次actNum活动最多支持同时开x个轮回类型,一般同个时间的轮回活动最多同时开2个或3个最多了
118     for num in range(20):
119         if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianSet % (actNum, num)):
120             continue
121         roundMax = GetRoundSetValue(roundSet, RoundSetIndex_RoundMax)
122         setValue = roundType * 100 + roundMax
123         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianSet % (actNum, num), setValue)
124         GameWorld.DebugLog("    保存轮回殿参与值! actNum=%s,roundType=%s,roundMax=%s,setValue=%s" 
125                            % (actNum, roundType, roundMax, setValue), curPlayer.GetPlayerID())
126         break
127     return
128
129 def OnGiveUngetAward(curPlayer, actNum):
130     ## 补发未领取奖励
131     for num in range(20):
132         setValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianSet % (actNum, num))
133         if not setValue:
134             continue
135         __DoGiveUngetAwardByMail(curPlayer, actNum, setValue)
136         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianSet % (actNum, num), 0)                            
137     return
138
139 def __DoGiveUngetAwardByMail(curPlayer, actNum, setValue):
140     playerID = curPlayer.GetPlayerID()
141     roundType = setValue / 100
142     roundMax = setValue % 100
143     curRound = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianRound % (actNum, roundType))
144     curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType))
145     awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianAward % (actNum, roundType))
146     awardIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLunhuidianAward", roundType)
147     if not awardIpyDataList:
148         return
149     
150     mailItemList = []
151     doRound = curRound
152     doValue = curValue
153     doAwardState = awardState
154     while doValue > 0 and doRound <= roundMax:
155         GameWorld.DebugLog("处理补发轮回奖励: doRound=%s,doValue=%s,doAwardState=%s" % (doRound, doValue, doAwardState), playerID)
156         roundValueMax = 0
157         for awardIpyData in awardIpyDataList:
158             needV = awardIpyData.GetNeedValue()
159             aIndex = awardIpyData.GetAwardIndex()
160             awardItemList = awardIpyData.GetAwardItemList()
161             roundValueMax = max(roundValueMax, needV)
162             if doAwardState&pow(2, aIndex):
163                 GameWorld.DebugLog("    已领取该奖励: doRound=%s,aIndex=%s,needV=%s" % (doRound, aIndex, needV), playerID)
164                 continue
165             if doValue < needV:
166                 GameWorld.DebugLog("    所需值不达标: doRound=%s,aIndex=%s,needV=%s > %s" % (doRound, aIndex, needV, doValue), playerID)
167                 continue
168             mailItemList += awardItemList
169             GameWorld.DebugLog("    未领取补发奖: doRound=%s,aIndex=%s,needV=%s,%s" % (doRound, aIndex, needV, awardItemList), playerID)
170             
171         doRound += 1
172         doValue -= roundValueMax
173         doAwardState = 0
174         
175     if not mailItemList:
176         return
177     GameWorld.Log("处理补发轮回奖励完毕: actNum=%s,roundType=%s,roundMax=%s,curRound=%s,curValue=%s,awardState=%s,mailItemList=%s" 
178                        % (actNum, roundType, roundMax, curRound, curValue, awardState, mailItemList), playerID)
179     PlayerControl.SendMailByKey("LunhuidianUnget", [playerID], mailItemList)
180     return
181
9f30bc 182 def GetRoundSetValue(roundSet, setIndex): return roundSet[setIndex] if len(roundSet) > setIndex else 0
H 183
184 def AddLunhuidianValue(curPlayer, awardType, awardTypeValue, addValue):
185     ## 增加轮回殿进度值
186     playerID = curPlayer.GetPlayerID()
187     for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_Lunhuidian, {}).values():
188         if not actInfo.get(ShareDefine.ActKey_State):
189             continue
190         cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
191         actNum = actInfo.get(ShareDefine.ActKey_ActNum, 0)
192         ipyData = IpyGameDataPY.GetIpyGameData("ActLunhuidian", cfgID)
193         if not ipyData:
194             continue
195         roundSetDict = ipyData.GetRoundSetInfo()
196         for roundType, roundSet in roundSetDict.items():
197             if awardType != GetRoundSetValue(roundSet, RoundSetIndex_AwardType):
198                 continue
199             if awardTypeValue != GetRoundSetValue(roundSet, RoundSetIndex_AwardTypeValue):
200                 continue
201             
202             curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType))
203             updValue = min(curValue + addValue, ChConfig.Def_UpperLimit_DWord)
204             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType), updValue)
205             GameWorld.DebugLog("更新轮回殿累计值: actNum=%s,cfgID=%s,roundType=%s,awardType=%s,awardTypeValue=%s,addValue=%s,curValue=%s,updValue=%s" 
206                                % (actNum, cfgID, roundType, awardType, awardTypeValue, addValue, curValue, updValue), playerID)
207             Sync_ActLunhuidianPlayerInfo(curPlayer, actNum, roundType)
208             
209     return
210
211 def GetLunhuidianAward(curPlayer, dataEx, dataExStr):
212     ## 领取奖励
213     # @param awardInfo: 要领取的奖励信息 roundType|needValue
214     actNum = dataEx
215     awardSplitList = dataExStr.split("|")
216     if len(awardSplitList) != 2:
217         GameWorld.DebugLog("发送领取格式错误: dataExStr=%s" % dataExStr)
218         return
219     roundType = GameWorld.ToIntDef(awardSplitList[0], 0)
220     needValue = GameWorld.ToIntDef(awardSplitList[1], 0)
221     
222     playerID = curPlayer.GetPlayerID()
223     actInfo = GameWorld.GetActInfo(ShareDefine.OperationActionName_Lunhuidian, actNum)
224     if not actInfo or not actInfo.get(ShareDefine.ActKey_State):
225         GameWorld.DebugLog("该轮回殿非活动中: actNum=%s" % actNum)
226         return
227     cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
228     ipyData = IpyGameDataPY.GetIpyGameData("ActLunhuidian", cfgID)
229     if not ipyData:
230         return
231     roundSetDict = ipyData.GetRoundSetInfo()
232     if roundType not in roundSetDict:
233         GameWorld.DebugLog("该轮回殿类型不在本次活动中: actNum=%s,roundType=%s not in %s" % (actNum, roundType, roundSetDict))
234         return
235     roundSet = roundSetDict[roundType]
236     roundMax = GetRoundSetValue(roundSet, RoundSetIndex_RoundMax)
237     
238     awardIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLunhuidianAward", roundType)
239     if not awardIpyDataList:
240         return
241     
242     curRound = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianRound % (actNum, roundType))
243     curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType))
244     awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianAward % (actNum, roundType))
245     
246     roundValueMax = 0
247     unGetIndexList = []
248     awardIndex, awardItemList = None, []
249     for awardIpyData in awardIpyDataList:
250         needV = awardIpyData.GetNeedValue()
251         roundValueMax = max(roundValueMax, needV)
252         aIndex = awardIpyData.GetAwardIndex()
253         if needValue == needV:
254             awardIndex = aIndex
255             awardItemList = awardIpyData.GetAwardItemList()
256         else:
257             if not awardState&pow(2, aIndex):
258                 unGetIndexList.append(aIndex)
259                 
260     if awardIndex == None:
261         GameWorld.DebugLog("轮回殿没有该奖励! actNum=%s,roundType=%s,needValue=%s" % (actNum, roundType, needValue), playerID)
262         return
263     
264     if awardState&pow(2, awardIndex):
265         GameWorld.DebugLog("轮回殿奖励已领奖! actNum=%s,roundType=%s,needValue=%s,awardIndex=%s" 
266                            % (actNum, roundType, needValue, awardIndex), playerID)
267         return
268     
269     if curValue < needValue:
270         GameWorld.DebugLog("轮回殿当前值不足,无法领奖! actNum=%s,roundType=%s,curRound=%s,curValue=%s < %s" 
271                            % (actNum, roundType, curRound, curValue, needValue), playerID)
272         return
273     
274     updState = awardState|pow(2, awardIndex)
275     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianAward % (actNum, roundType), updState)
276     GameWorld.DebugLog("领取轮回殿奖励! actNum=%s,roundType=%s,needValue=%s,awardIndex=%s,awardState=%s,updState=%s,curRound=%s" 
277                        % (actNum, roundType, needValue, awardIndex, awardState, updState, curRound), playerID)
61f8b7 278     ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Lunhuidian", False, {}])
9f30bc 279     
H 280     GameWorld.DebugLog("    curRound=%s/%s,unGetIndexList=%s,curValue=%s,roundValueMax=%s" 
281                        % (curRound, roundMax, unGetIndexList, curValue, roundValueMax), playerID)
282     if not unGetIndexList and curRound < roundMax:
283         updRound = curRound + 1
284         updValue = max(0, curValue - roundValueMax)
285         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianRound % (actNum, roundType), updRound)
286         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType), updValue)
287         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActLunhuidianAward % (actNum, roundType), 0)
288         GameWorld.DebugLog("    本轮次所有奖励已经领取完毕,进入下一轮! updRound=%s,updValue=%s" % (updRound, updValue), playerID)
289         
290     Sync_ActLunhuidianPlayerInfo(curPlayer, actNum, roundType)
291     return
292
293 def Sync_ActLunhuidianPlayerInfo(curPlayer, actNum, roundType):
294     clientPack = ChPyNetSendPack.tagMCActLunhuidianPlayerInfo()
295     clientPack.ActNum = actNum
296     clientPack.RoundType = roundType
297     clientPack.CurRound = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianRound % (actNum, roundType))
298     clientPack.CurValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianValue % (actNum, roundType))
299     clientPack.AwardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActLunhuidianAward % (actNum, roundType))
300     NetPackCommon.SendFakePack(curPlayer, clientPack)
301     return
302
303 def Sync_ActLunhuidianActionInfo(curPlayer, actNum, roundType=0):
304     ## 通知活动信息
305     actInfo = GameWorld.GetActInfo(ShareDefine.OperationActionName_Lunhuidian, actNum)
306     if not actInfo:
307         return
308     if not actInfo.get(ShareDefine.ActKey_State):
309         return
310     cfgID = actInfo.get(ShareDefine.ActKey_CfgID)
311     ipyData = IpyGameDataPY.GetIpyGameData("ActLunhuidian", cfgID)
312     if not ipyData:
313         return
314     
315     startDateStr, endDateStr = GameWorld.GetOperationActionDateStr(ipyData)
316     clientPack = ChPyNetSendPack.tagMCActLunhuidianInfo()
317     clientPack.Clear()
318     clientPack.ActNum = actNum
319     clientPack.StartDate = startDateStr
320     clientPack.EndtDate = endDateStr
321     clientPack.ResetType = ipyData.GetResetType()
322     clientPack.LimitLV = ipyData.GetLVLimit()
323     
324     roundSetDict = ipyData.GetRoundSetInfo()
8a0a84 325     ctgIDDict = ipyData.GetRoundCTGIDInfo()
H 326     shopTypeDict = ipyData.GetRoundShopTypeInfo()
9f30bc 327     for roundType, roundSet in roundSetDict.items():
H 328         roundInfo = ChPyNetSendPack.tagMCActLunhuidianRound()
329         roundInfo.RoundType = roundType
330         roundInfo.AwardType = GetRoundSetValue(roundSet, RoundSetIndex_AwardType)
331         roundInfo.AwardTypeValue = GetRoundSetValue(roundSet, RoundSetIndex_AwardTypeValue)
332         roundInfo.RoundMax = GetRoundSetValue(roundSet, RoundSetIndex_RoundMax)
333         roundInfo.AwardList = []
334         
335         awardIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLunhuidianAward", roundType)
336         if awardIpyDataList:
337             for awardIpyData in awardIpyDataList:
338                 award = ChPyNetSendPack.tagMCActLunhuidianAward()
339                 award.AwardIndex = awardIpyData.GetAwardIndex()
340                 award.NeedValue = awardIpyData.GetNeedValue()
341                 for itemID, itemCount, isAuctionItem in awardIpyData.GetAwardItemList():
342                     item = ChPyNetSendPack.tagMCActLunhuidianItem()
343                     item.ItemID = itemID
344                     item.ItemCount = itemCount
345                     item.IsBind = isAuctionItem
346                     award.AwardItemList.append(item)
347                 award.Count = len(award.AwardItemList)
348                 
349                 roundInfo.AwardList.append(award)
350         roundInfo.AwardCount = len(roundInfo.AwardList)
8a0a84 351         roundInfo.CTGIDList = ctgIDDict.get(roundType, [])
H 352         roundInfo.CTGIDCount = len(roundInfo.CTGIDList)
353         roundInfo.ShopType = shopTypeDict.get(roundType, 0)
9f30bc 354         
H 355         clientPack.RoundList.append(roundInfo)
356     clientPack.RoundCount = len(clientPack.RoundList)
357     NetPackCommon.SendFakePack(curPlayer, clientPack)
358     return