From ec19547ca0985de3f1c4045411ee6c171204e535 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 21 十月 2025 19:00:45 +0800
Subject: [PATCH] 297 【常规】坊市系统-服务端(坊市、公会、将魂)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py | 1322 +++++++++++----------------------------------------------
1 files changed, 257 insertions(+), 1,065 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py
index 311a05b..a38043c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py
@@ -46,480 +46,98 @@
#---------------------------------------------------------------------
#"""Version = 2016-08-04 18:00"""
#---------------------------------------------------------------------
-import ChPyNetSendPack
-import NetPackCommon
-import GameWorld
-import IPY_GameWorld
-import ItemControler
+
import ChConfig
+import GameWorld
+import NetPackCommon
+import ItemControler
+import ChPyNetSendPack
import PlayerControl
-import ItemCommon
-import ShareDefine
-import PlayerFlashSale
-#import EventSrc
-import ChItem
import IpyGameDataPY
-import PlayerRune
-import GameFuncComm
-import PlayerSpringSale
-import PyGameData
+import ItemCommon
+import ObjPool
-import random
-import math
-import time
+# 重置类型
+ResetType_Day = 1
+ResetType_Week = 2
-g_mysticalShopDict = {} #神秘商店{等级范围:[等级段,{金钱类型:库}]}
-#---------------------------------------------------------------------
-##开始交易
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值真, 逻辑运行成功
-# @remarks 开始交易
-def StartTrade(curPlayer, tick):
+# 解锁类型
+UnlockType_FamilyLV = 1 # 公会等级
+UnlockType_RandRefresh = 2 # 随机刷新解锁
- curActionObj = curPlayer.GetActionObj()
- if curActionObj == None:
- return
-
- if curActionObj.GetGameObjType() != IPY_GameWorld.gotNPC:
- return
-
- curActionNPC = GameWorld.GetNPCManager().GetNPCByIndex(curActionObj.GetIndex())
- curActionNPCID = curActionNPC.GetNPCID()
-
- # 设置当前商店的npcid
- curPlayer.SetDict(ChConfig.Def_PlayerKey_TradeTagNPC, curActionNPCID)
-
- #设定为禁止整理背包
- curPlayer.SetForbiddenResetItem(1)
- curPlayer.BeginSpecialEvent(ShareDefine.TYPE_Event_Shop)
- return True
+# 部分商店类型
+ShopType_HeroSoul = 3 # 将魂
-#------------------------------------------------------------------------------
-## 获取远程商店的npc
-# @param curPlayer 玩家实例
-# @return 远程商店的npc
-def GetDirectNpcID():
- return 0
+RefreshShopTypeList = [ShopType_HeroSoul]
-#---------------------------------------------------------------------
-##请求商店物品列表
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值真, 逻辑运行成功
-def QueryNPCShopItem(playerIndex, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
-
- #时间间隔未到
- if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_QueryFuncData) \
- < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_QueryFuncData]:
- return
-
- curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_QueryFuncData, tick)
-
- #直接查询,存在该NPCID就发包
- tradeTagNPC = clientData.NPCShopID
- GameWorld.GetGameData().FilterShopItemByShopType(tradeTagNPC)
- shopItemCount = GameWorld.GetGameData().GetFilterShopItemCount()
- if shopItemCount <= 0:
- return
-
-# # 商店npcid与当前对话npc对应,0为远程商店
-# tradeTagNPC = clientData.NPCShopID
-# if tradeTagNPC != 0 and not CheckTradeTagNPC(curPlayer, tradeTagNPC):
-# return
-
- # 发送商品今日已购买次数
- #SyncShopItemTodayBuyCount(curPlayer)
-
- # 发送商店物品列表
- curPlayer.BeginShopEx(tradeTagNPC)
+def DoShopOpen(curPlayer):
+ for shopType in RefreshShopTypeList:
+ DoRandRefreshShopItem(curPlayer, shopType, sysRefresh=True)
return
-##同步商店NPC物品今日购买次数
-# @param curPlayer 玩家实例
-# @param npcID
-# @param itemIndex -1时同步该NPC所有物品
-# @return
-def SyncShopItemTodayBuyCount(curPlayer, itemIndexList=[], isReset=False):
- dayBuyCntInfo = ChPyNetSendPack.tagMCShopItemDayBuyCntInfo()
- dayBuyCntInfo.DayBuyCntList = []
- if itemIndexList:
- for itemIndex in itemIndexList:
- __AppendShopItemDayBuyCntInfo(curPlayer, itemIndex, dayBuyCntInfo.DayBuyCntList, isReset)
- else:
- ipyDataMgr = IpyGameDataPY.IPY_Data()
- for i in xrange(ipyDataMgr.GetStoreCount()):
- shopItem = ipyDataMgr.GetStoreByIndex(i)
- if not shopItem.GetLimitCnt():
- continue
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % shopItem.GetID()
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- if curDayBuyCnt <= 0:
- continue
- __AppendShopItemDayBuyCntInfo(curPlayer, shopItem.GetID(), dayBuyCntInfo.DayBuyCntList, isReset)
-
- dayBuyCntInfo.Count = len(dayBuyCntInfo.DayBuyCntList)
- NetPackCommon.SendFakePack(curPlayer, dayBuyCntInfo)
+def ShopItemOnLogin(curPlayer):
+ SyncShopItemBuyCntInfo(curPlayer)
+ for shopType in RefreshShopTypeList:
+ SyncShopRefreshItemInfo(curPlayer, shopType)
return
-##增加商店物品今日购买次数信息
-# @param curPlayer 玩家实例
-# @param npcID
-# @param itemIndex
-# @return
-def __AppendShopItemDayBuyCntInfo(curPlayer, itemIndex, dayBuyCntList, isReset):
- itemDayBuyCnt = ChPyNetSendPack.tagMCShopItemDayBuyCnt()
- itemDayBuyCnt.ItemIndex = itemIndex
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- itemDayBuyCnt.BuyCnt = curDayBuyCnt
- itemDayBuyCnt.IsReset = int(isReset)
- dayBuyCntList.append(itemDayBuyCnt)
- return
-
-## 登录
-def ShopItemOnLogin(curPlayer):
- SyncMysticalLimitShopInfo(curPlayer)
- SyncShopItemTodayBuyCount(curPlayer)
- if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MysticalShopGoods % 0):
- __DoMysticalShopRefresh(curPlayer, True, GameWorld.GetGameWorld().GetTick())
- SyncMysticalShopInfo(curPlayer)
- return
-
-##商店物品OnDay
-# @param curPlayer 玩家实例
-# @return
-def ShopItemOnDay(curPlayer, onEventType):
- if onEventType == ShareDefine.Def_OnEventType:
- OSSaleOpenMail(curPlayer)
- refreshType = [3]
- #神秘商店刷新次数重置
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MysticalShopRefreshCnt, 0)
- SyncMysticalShopInfo(curPlayer)
+def ShopItemOnDay(curPlayer):
+ for shopType in RefreshShopTypeList:
+ if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopRefreshCnt % shopType):
+ continue
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopRefreshCnt % shopType, 0)
+ SyncShopRefreshItemInfo(curPlayer, shopType)
- elif onEventType == ShareDefine.Def_OnEventTypeEx:
- refreshType = [4]
- openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay)
- isMixServer = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_IsMixServer)
- if isMixServer:
- mixServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_MixServerDay)
- if mixServerDay % 3 == 0:
- refreshType.append(7)
- elif openServerDay % 3 == 0:
- refreshType.append(7)
- else:
- return
- ResetShopItemBuyCount(curPlayer, refreshType)
+ ResetShopItemBuyCount(curPlayer, [ResetType_Day])
return
-##商店物品OnWeek
-# @param curPlayer 玩家实例
-# @return
-def ShopItemOnWeek(curPlayer, onEventType):
- if onEventType == ShareDefine.Def_OnEventType:
- refreshType = [1]
- elif onEventType == ShareDefine.Def_OnEventTypeEx:
- refreshType = [2]
- else:
- return
- ResetShopItemBuyCount(curPlayer, refreshType)
- return
-
-##商店物品OnMonth
-# @param curPlayer 玩家实例
-# @return
-def ShopItemOnMonth(curPlayer, onEventType):
- if onEventType == ShareDefine.Def_OnEventType:
- refreshType = 5
- elif onEventType == ShareDefine.Def_OnEventTypeEx:
- refreshType = 6
- else:
- return
- ResetShopItemBuyCount(curPlayer, [refreshType])
- return
-
-def ShopItemOnCrossPKSeasonChange(curPlayer):
- ## 按跨服PK赛季重置
- refreshType = 8
- ResetShopItemBuyCount(curPlayer, [refreshType])
+def ShopItemOnWeek(curPlayer):
+ ResetShopItemBuyCount(curPlayer, [ResetType_Week])
return
def ResetShopItemBuyCount(curPlayer, resetTypeList):
#@param resetTypeList: 需要重置的类型列表
- #重置商店物品购买次数 1:周一0点刷新 2:周一5点刷新 3:每日0点刷新 4:每日5点刷新 5每月0点 6每月5点 7每3天5点 8每赛季
if not resetTypeList:
# 暂定必须指定类型列表,防止终身限购的误被重置
return
-
- syncIndexList = []
+ syncIDList = []
ipyDataMgr = IpyGameDataPY.IPY_Data()
for i in xrange(ipyDataMgr.GetStoreCount()):
shopItem = ipyDataMgr.GetStoreByIndex(i)
if not shopItem.GetLimitCnt():
continue
- if shopItem.GetRefreshLimit():
+ if shopItem.GetResetType() not in resetTypeList:
continue
- if shopItem.GetRefreshType() not in resetTypeList:
+ shopID = shopItem.GetID()
+ curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ if curBuyCnt <= 0:
continue
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % shopItem.GetID()
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- if curDayBuyCnt <= 0:
- continue
- PlayerControl.NomalDictSetProperty(curPlayer, dayBuyCntKey, 0)
- syncIndexList.append(shopItem.GetID())
- if syncIndexList:
- SyncShopItemTodayBuyCount(curPlayer, syncIndexList, True)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, 0)
+ syncIDList.append(shopID)
+ if syncIDList:
+ SyncShopItemBuyCntInfo(curPlayer, syncIDList)
return
def ResetShopItemBuyCountByShopType(curPlayer, shopTypeList):
##根据商店类型重置商店限购物品次数
if not shopTypeList:
return
- syncIndexList = []
- ipyDataMgr = IpyGameDataPY.IPY_Data()
- for i in xrange(ipyDataMgr.GetStoreCount()):
- shopItem = ipyDataMgr.GetStoreByIndex(i)
- if not shopItem.GetLimitCnt():
+ syncIDList = []
+ for shopType in shopTypeList:
+ ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True)
+ if not ipyDataList:
continue
- if shopItem.GetRefreshLimit():
- continue
- if shopItem.GetShopType() not in shopTypeList:
- continue
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % shopItem.GetID()
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- if curDayBuyCnt <= 0:
- continue
- PlayerControl.NomalDictSetProperty(curPlayer, dayBuyCntKey, 0)
- syncIndexList.append(shopItem.GetID())
- if syncIndexList:
- SyncShopItemTodayBuyCount(curPlayer, syncIndexList, True)
- return
-
-def MysticalLimitShopOpen(curPlayer, befLV, aftLV):
- ##神秘限购开启
- ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition('Store', {'ShopType':16}, True)
- if not ipyDataList:
- return
- curTime = int(time.time())
- syncGoodsList = []
- for ipyData in ipyDataList:
- limitLV = ipyData.GetLimitLV()
- if befLV < limitLV and aftLV >= limitLV:
- goodsID = ipyData.GetID()
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopItemStartTime % goodsID, curTime)
- syncGoodsList.append(goodsID)
- GameWorld.DebugLog('神秘限购商品%s 开卖'%goodsID, curPlayer.GetID())
- if syncGoodsList:
- SyncMysticalLimitShopInfo(curPlayer)
- return
-
-def SyncMysticalLimitShopInfo(curPlayer):
- ##神秘限购通知
- packData = ChPyNetSendPack.tagMCMysticalShopTimeInfo()
- packData.ShopTimeList = []
- ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition('Store', {'ShopType':16}, True)
- curTime = int(time.time())
- for ipyData in ipyDataList:
- goodsID = ipyData.GetID()
- startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopItemStartTime % goodsID)
- if not startTime:
- continue
- if curTime - startTime >= ipyData.GetLimitValue():
- #超时的重置
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopItemStartTime % goodsID, 0)
- else:
- goodsTime = ChPyNetSendPack.tagMCMysticalShopTime()
- goodsTime.GoodsID = goodsID
- goodsTime.StartTime = startTime
- packData.ShopTimeList.append(goodsTime)
- if not packData.ShopTimeList:
- return
- packData.Count = len(packData.ShopTimeList)
- NetPackCommon.SendFakePack(curPlayer, packData)
- return
-
-def CheckMysticalShopRefresh(curPlayer, tick):
- ##神秘商店刷新
- createRoleTime = curPlayer.GetCreateRoleTime()
- if not createRoleTime:
- return
- diffTime = GameWorld.GetCurrentTime() - GameWorld.GetDateTimeByStr(createRoleTime, ChConfig.TYPE_Time_Format)
- pastSeconds = diffTime.days*24*60*60 + diffTime.seconds
- refreshTime = IpyGameDataPY.GetFuncCfg('MysteryShopRefresh', 4)
- if refreshTime and pastSeconds % refreshTime == 0:
- __DoMysticalShopRefresh(curPlayer, True, tick)
- return
-
-#// A2 32 神秘商店刷新 #tagCMRefreshMysticalShop
-#struct tagCMRefreshMysticalShop
-#{
-# tagHead Head;
-#};
-def OnMysticalShopRefresh(index, clientData, tick):
- curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- __DoMysticalShopRefresh(curPlayer, False, tick)
- return
-
-def __DoMysticalShopRefresh(curPlayer, isFree, tick):
- global g_mysticalShopDict #{等级范围:[等级段,{金钱类型:库}]}
- refreshTime = IpyGameDataPY.GetFuncCfg('MysteryShopRefresh', 4)
- if not refreshTime:
- return
-
- lastTime = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MysticalShopLastTime)
- if lastTime and tick - lastTime < 1000:
- #GameWorld.DebugLog('神秘商店刷新,过于频繁!')
- return
- curPlayer.SetDict(ChConfig.Def_PlayerKey_MysticalShopLastTime, tick)
- if not g_mysticalShopDict:
- ipyMgr= IpyGameDataPY.IPY_Data()
- for i in xrange(ipyMgr.GetMysteryShopCount()):
- ipyData = ipyMgr.GetMysteryShopByIndex(i)
- lvRange = ipyData.GetLVRange()
- goodsID = ipyData.GetGoodsID()
- goodsIpyData = IpyGameDataPY.GetIpyGameData('Store', goodsID)
- if not goodsIpyData:
+ for ipyData in ipyDataList:
+ if not ipyData.GetLimitCnt():
continue
- moneyType = goodsIpyData.GetMoneyType()
- weight = goodsIpyData.GetLimitValue()
- lvkey = tuple(lvRange)
- if lvkey not in g_mysticalShopDict:
- g_mysticalShopDict[lvkey] = [lvkey[0], {}]
- weightDict = {}
- if moneyType not in g_mysticalShopDict[lvkey][1]:
- g_mysticalShopDict[lvkey][1][moneyType] = []
- weightDict[moneyType] = weightDict.get(moneyType, 0) + weight
- g_mysticalShopDict[lvkey][1][moneyType].append([weightDict[moneyType], goodsID])
- if not g_mysticalShopDict:
- return
- playerLV = curPlayer.GetLV()
- curLVDan, shopDict = GameWorld.GetDictValueByRangeKey(g_mysticalShopDict, playerLV)
- if not shopDict:
- return
- maxCnt = IpyGameDataPY.GetFuncCfg('MysteryShopGoods', 1)
- goldGoodsCnt =GameWorld.GetResultByRandomList(IpyGameDataPY.GetFuncEvalCfg('MysteryShopGoods', 2))
- if not goldGoodsCnt:
- return
- specialGoodsID = 0 #必出的商品ID
- if not isFree:
- #优先道具,再仙玉
- itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
- costItemID = IpyGameDataPY.GetFuncCfg('MysteryShopRefresh', 1)
- costItemCntDict = IpyGameDataPY.GetFuncEvalCfg('MysteryShopRefresh', 2)
- curRefreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MysticalShopRefreshCnt)
- cntList = [int(cnt) for cnt in costItemCntDict.keys()]
- cntList.sort()
- costItemCnt = costItemCntDict[str(cntList[-1])]
- for cnt in cntList:
- if curRefreshCnt < cnt:
- costItemCnt = costItemCntDict[str(cnt)]
- break
- enough, indexList, hasBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(costItemID, itemPack, costItemCnt)
- costGold = 0
- if not enough:
- costGold = lackCnt * IpyGameDataPY.GetFuncCfg('MysteryShopRefresh', 3)
- if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold, ChConfig.Def_Cost_MysteryShopRefresh):
- return
- ItemCommon.ReduceItem(curPlayer, itemPack, indexList, costItemCnt, False, "MysteryShopRefresh")
- curLVRefreshData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MysticalShopLVRefreshCnt)
- curLVRefreshCnt, lvDan = curLVRefreshData / 10000, curLVRefreshData % 10000
- updLVRefreshCnt = 1 if curLVDan != lvDan else curLVRefreshCnt + 1 #等级段变更,重置该等级段的刷新次数
- updLVRefreshData = min(updLVRefreshCnt * 10000+curLVDan, ChConfig.Def_UpperLimit_DWord)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MysticalShopLVRefreshCnt, updLVRefreshData)
- specialRefreshCfg = IpyGameDataPY.GetFuncEvalCfg('MysteryShopRefresh', 5)
- if curLVDan in specialRefreshCfg and updLVRefreshCnt == specialRefreshCfg[curLVDan][0]:
- specialGoodsID = specialRefreshCfg[curLVDan][1]
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MysticalShopRefreshCnt, curRefreshCnt+1)
-
- goldGoodsCnt = min(goldGoodsCnt, maxCnt)
- sliverGoodsCnt = maxCnt - goldGoodsCnt
- goodsResultList = []
- if goldGoodsCnt:
- goodsResultList += GameWorld.GetResultByRandomListEx(shopDict.get(IPY_GameWorld.TYPE_Price_Gold_Money, []), goldGoodsCnt, [])
- if sliverGoodsCnt:
- goodsResultList += GameWorld.GetResultByRandomListEx(shopDict.get(IPY_GameWorld.TYPE_Price_Silver_Money, []), sliverGoodsCnt, [])
- if specialGoodsID and specialGoodsID not in goodsResultList:
- goodsResultList[0] = specialGoodsID
- GameWorld.DebugLog('神秘商店刷新特殊规则,等级段:%s,updLVRefreshCnt=%s,specialGoodsID=%s'%(curLVDan, updLVRefreshCnt, specialGoodsID))
-
- GameWorld.DebugLog('神秘商店刷新isFree=%s,goldGoodsCnt=%s,sliverGoodsCnt=%s,goodsResultList=%s'%(isFree, goldGoodsCnt, sliverGoodsCnt, goodsResultList))
- syncIndexList = []
- for i in xrange(maxCnt):
- goodsID = goodsResultList[i] if i < len(goodsResultList) else 0
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MysticalShopGoods % i, goodsID)
-
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % goodsID
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- if curDayBuyCnt:
- PlayerControl.NomalDictSetProperty(curPlayer, dayBuyCntKey, 0)
- syncIndexList.append(goodsID)
- if syncIndexList:
- SyncShopItemTodayBuyCount(curPlayer, syncIndexList, True)
- #通知
- SyncMysticalShopInfo(curPlayer)
- return
-
-def SyncMysticalShopInfo(curPlayer):
- ##神秘商店通知
- packData = ChPyNetSendPack.tagMCMysticalShopInfo()
- packData.RefreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MysticalShopRefreshCnt)
- packData.GoodsList = []
- maxCnt = IpyGameDataPY.GetFuncCfg('MysteryShopGoods', 1)
- for i in xrange(maxCnt):
- goodsID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MysticalShopGoods % i)
- goodsInfo = ChPyNetSendPack.tagMCMysticalShopGoods()
- goodsInfo.GoodsID = goodsID
- packData.GoodsList.append(goodsInfo)
- packData.Count = len(packData.GoodsList)
- NetPackCommon.SendFakePack(curPlayer, packData)
- return
-
-## 回购物品
-# @param None
-# @return None
-def BuyItemBack(curPlayer, clientPack, tick):
- index = clientPack.Index
-
- backPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptRecycle)
- if index >= backPack.GetCount():
- #假包退出
- return
-
- curItem = backPack.GetAt(index)
- if not curItem or curItem.IsEmpty():
- #没有物品退出
- return
-
- realPutCount = curItem.GetCount()
- itemControl = ItemControler.PlayerItemControler(curPlayer)
- if not itemControl.CanPutInItem(IPY_GameWorld.rptItem,
- curItem.GetItemTypeID(),
- realPutCount,
- curItem.GetIsBind()):
- #物品不能放入退出
- PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [IPY_GameWorld.rptItem])
- return
-
- itemPrice, priceType = __GetItemSellPrice(curPlayer, curItem)
- itemPrice = int(itemPrice) * realPutCount
- if not priceType or not itemPrice:
- return
-
- #付钱
- infoDict = {ChConfig.Def_Cost_Reason_SonKey:curItem.GetItemTypeID()}
- if not PlayerControl.PayMoney(curPlayer, priceType, itemPrice, ChConfig.Def_Cost_BuyItemBack, infoDict):
- return
-
- itemControl.PutInItem(IPY_GameWorld.rptItem, curItem, event=["BuyItemBack", False, {}])
-
- itemIndexs = str(curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DelPackIndex))
- itemIndexs = itemIndexs.replace(str(index + 1), '')
- if itemIndexs == '':
- #没有物品保留 0
- itemIndexs = '0'
-
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_DelPackIndex, int(itemIndexs))
+ shopID = ipyData.GetID()
+ curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ if curBuyCnt <= 0:
+ continue
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, 0)
+ syncIDList.append(shopID)
+ if syncIDList:
+ SyncShopItemBuyCntInfo(curPlayer, syncIDList)
return
def PayAutoBuyItem(curPlayer, lackItemDict, priceType, costType=ChConfig.Def_Cost_Unknown, infoDict={}, isCheck=False, shopItemIndexDict=None):
@@ -541,27 +159,26 @@
return
if shopItemIndexDict and itemID in shopItemIndexDict:
- itemIndex = shopItemIndexDict[itemID]
- ipyData = IpyGameDataPY.GetIpyGameData("Store", itemIndex)
+ shopID = shopItemIndexDict[itemID]
+ ipyData = IpyGameDataPY.GetIpyGameData("Store", shopID)
else:
ipyData = ItemCommon.GetShopItemPriceIpyData(itemID, priceType)
if not ipyData:
return
- itemIndex = ipyData.GetID()
+ shopID = ipyData.GetID()
shopType = ipyData.GetShopType()
priceType = ipyData.GetMoneyType()
itemMoney = ipyData.GetMoneyNum()
- limitCntList = ipyData.GetLimitCnt()
- if limitCntList:
- limitBuyCnt = limitCntList[0]
- curDayBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex)
- canBuyCnt = max(0, limitBuyCnt - curDayBuyCnt)
+ limitBuyCnt = ipyData.GetLimitCnt()
+ if limitBuyCnt:
+ curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ canBuyCnt = max(0, limitBuyCnt - curBuyCnt)
if canBuyCnt < lackCnt:
- GameWorld.Log("自动购买次数不足!shopType=%s,itemIndex=%s,itemID=%s,limitBuyCnt=%s,curDayBuyCnt=%s,canBuyCnt=%s < %s"
- % (shopType, itemIndex, itemID, limitBuyCnt, curDayBuyCnt, canBuyCnt, lackCnt), curPlayer.GetPlayerID())
+ GameWorld.Log("自动购买次数不足!shopType=%s,shopID=%s,itemID=%s,limitBuyCnt=%s,curBuyCnt=%s,canBuyCnt=%s < %s"
+ % (shopType, shopID, itemID, limitBuyCnt, curBuyCnt, canBuyCnt, lackCnt), curPlayer.GetPlayerID())
return
- addLimitCountInfo[itemIndex] = lackCnt
+ addLimitCountInfo[shopID] = lackCnt
totalMoney += (lackCnt * itemMoney)
@@ -578,679 +195,254 @@
return
if addLimitCountInfo:
- syncIndexList = []
- for itemIndex, lackCnt in addLimitCountInfo.items():
- curDayBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex, curDayBuyCnt + lackCnt)
- syncIndexList.append(itemIndex)
- SyncShopItemTodayBuyCount(curPlayer, syncIndexList)
+ syncIDList = []
+ for shopID, lackCnt in addLimitCountInfo.items():
+ curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, curBuyCnt + lackCnt)
+ syncIDList.append(shopID)
+ SyncShopItemBuyCntInfo(curPlayer, syncIDList)
return True
-#// A3 10 购买商城物品 #tagCMBuyItem
+#// A3 10 购买商城物品 #tagCSBuyItem
#
-#struct tagCMBuyItem
+#struct tagCSBuyItem
#{
# tagHead Head;
-# WORD BuyItemIndex; //购买的物品索引
-# DWORD BuyCount; //购买数量
+# DWORD ShopID; //商品ID
+# DWORD BuyCount; //购买数量
#};
def PyBuyItem(index, clientData, tick):
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- itemIndex = clientData.BuyItemIndex
+ shopID = clientData.ShopID
buyCount = clientData.BuyCount
- OnBuyItem(curPlayer, itemIndex, buyCount)
+ OnBuyItem(curPlayer, shopID, buyCount)
return
-##购买物品
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值真, 逻辑运行成功
-def BuyItem(curPlayer, tick):
- buyItemList = IPY_GameWorld.IPY_CBuyItemList()
- itemIndex = buyItemList.GetBuyItemIndex()
- clientBuyCount = buyItemList.GetBuyCount()
- OnBuyItem(curPlayer, itemIndex, clientBuyCount)
- return
-
-def OnBuyItem(curPlayer, itemIndex, clientBuyCount):
- GameWorld.DebugLog("购买商城物品: itemIndex=%s,clientBuyCount=%s" % (itemIndex, clientBuyCount), curPlayer.GetPlayerID())
+def OnBuyItem(curPlayer, shopID, clientBuyCount):
+ GameWorld.DebugLog("购买商城物品: shopID=%s,clientBuyCount=%s" % (shopID, clientBuyCount))
if GameWorld.IsCrossServer():
return
- if itemIndex < 0 or clientBuyCount <= 0:
+ if shopID <= 0 or clientBuyCount <= 0:
return
- ipyData = IpyGameDataPY.GetIpyGameData("Store", itemIndex)
+ ipyData = IpyGameDataPY.GetIpyGameData("Store", shopID)
if not ipyData:
return
shopType = ipyData.GetShopType()
- operationActionShopType = ipyData.GetOperationActionShop()
- if operationActionShopType == 1:
- if not PlayerSpringSale.IsSpringSaleShopType(shopType):
- return
- elif operationActionShopType == 2:
- if not PlayerFlashSale.IsFlashSaleShopType(shopType):
- return
-
- # 物品信息
- limitLV = ipyData.GetLimitLV()
- if limitLV and curPlayer.GetLV() < limitLV:
- return
- LimitVIPLVList = ipyData.GetLimitVIPLV()
- LimitCntList = ipyData.GetLimitCnt()
- limitBuyCnt = 0
- if LimitVIPLVList or LimitCntList:
- if not LimitVIPLVList:
- LimitVIPLVList = [0]
- if not LimitCntList:
- LimitCntList = [0]
-
- if len(LimitVIPLVList) != len(LimitCntList):
- GameWorld.Log(" 购买物品LimitVIPLV LimitCnt 长度不同")
- return
- curVIPlv = curPlayer.GetVIPLv()
- limitBuyCnt = -1
- for i, viplv in enumerate(LimitVIPLVList):
- if curVIPlv < viplv:
- break
- limitBuyCnt = LimitCntList[i]
- if limitBuyCnt == -1:
- GameWorld.DebugLog(" vip%s才能购买"%viplv)
- return
-
- curDayBuyCnt = 0
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex
+ limitBuyCnt = ipyData.GetLimitCnt()
if limitBuyCnt > 0:
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- canBuyCnt = max(0, limitBuyCnt - curDayBuyCnt)
+ curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ canBuyCnt = max(0, limitBuyCnt - curBuyCnt)
if canBuyCnt <= 0:
- GameWorld.DebugLog("BuyShopItem 今日购买次数已满!shopType=%s,itemIndex=%s" % (shopType, itemIndex))
+ GameWorld.DebugLog("商品限购次数已满 ! shopType=%s,shopID=%s,curBuyCnt=%s < %s" % (shopType, shopID, curBuyCnt, limitBuyCnt))
return
if clientBuyCount > canBuyCnt:
- GameWorld.DebugLog("BuyShopItem 修正购买次数!shopType=%s,itemIndex=%s,clientBuyCount=%s,canBuyCnt=%s"
- % (shopType, itemIndex, clientBuyCount, canBuyCnt))
clientBuyCount = canBuyCnt
- serverLimitCnt = ipyData.GetServerLimitCnt()
- if serverLimitCnt > 0:
- clientBuyCount = min(serverLimitCnt, clientBuyCount)
-
- itemID, itemCount, isBind = ipyData.GetItemID(), ipyData.GetItemCnt(), ipyData.GetIsBind()
+
+ itemID, itemCount, isBind = ipyData.GetItemID(), ipyData.GetItemCnt(), 0
itemListEx = ipyData.GetItemListEx()
- priceType, itemPrice = ipyData.GetMoneyType(), ipyData.GetMoneyNum()
-
- itemPrice *= clientBuyCount
- job = curPlayer.GetJob()
- jobItemList = ipyData.GetJobItem()
totalItemList = []
if itemID:
- jobItemID = GetShopJobItem(job, itemID, jobItemList)
- totalItemList.append([jobItemID, itemCount * clientBuyCount, isBind])
+ totalItemList.append([itemID, itemCount * clientBuyCount, isBind])
for itemIDEx, itemCountEx, isBindEx in itemListEx:
- jobItemID = GetShopJobItem(job, itemIDEx, jobItemList)
- totalItemList.append([jobItemID, itemCountEx * clientBuyCount, isBindEx])
- #允许价钱配置0,用来免费购买
+ totalItemList.append([itemIDEx, itemCountEx * clientBuyCount, isBindEx])
if not totalItemList:
- GameWorld.ErrLog("Store shop item error! shopType=%s,totalItemList=%s,itemPrice=%s" % (shopType, totalItemList, itemPrice))
+ GameWorld.ErrLog("Store shop item error! shopType=%s,shopID=%s" % (shopType, shopID), curPlayer.GetPlayerID())
+ return
+ mainItemID = totalItemList[0][0]
+ GameWorld.DebugLog("shopType=%s,shopID=%s,totalItemList=%s" % (shopType, shopID, totalItemList))
+
+ # 检查是否解锁商品购买
+ if not CheckBuyItemUnlock(curPlayer, shopType, shopID, mainItemID, ipyData):
+ GameWorld.Log("Store shop item lock! shopID=%s,shopID=%s" % (shopType, shopID), curPlayer.GetPlayerID())
return
- mainItemID = 0
- needPackSpaceDict = {}
- for i, itemInfo in enumerate(totalItemList):
- itemID = itemInfo[0]
- itemCnt = itemInfo[1]
- curItem = GameWorld.GetGameData().GetItemByTypeID(itemID)
- if not curItem:
- GameWorld.ErrLog("Store shop item error! shopType=%s,itemID=%s" % (shopType, itemID))
- return
- packType = ChConfig.GetItemPackType(curItem)
- needSpace = ItemControler.GetItemNeedPackCount(packType, curItem, itemCnt)
- needPackSpaceDict[packType] = needPackSpaceDict.get(packType, 0) + needSpace
-
- if i == 0:
- mainItemID = itemID
-
- if not mainItemID:
- return
-
- GameWorld.DebugLog("购买物品: shopType=%s,itemIndex=%s,clientBuyCount=%s,totalItemList=%s,mainItemID=%s,needPackSpaceDict=%s"
- % (shopType, itemIndex, clientBuyCount, totalItemList, mainItemID, needPackSpaceDict), curPlayer.GetPlayerID())
- mailKey = ipyData.GetMailKey()
- isLackPack = False #是否背包不足
- for packType, needSpace in needPackSpaceDict.items():
- if needSpace > ItemCommon.GetItemPackSpace(curPlayer, packType, needSpace):
- isLackPack = True
- if mailKey:
- break
- else:
- curPlayer.ShopResult(itemIndex, IPY_GameWorld.tsrNoPlace)
- PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [packType])
- return
- sendMailKey = mailKey if isLackPack and mailKey else '' #背包不足且配置了mailKey的才发邮件
-
- # 购买限制条件扩展
- if CheckBuyItemLimitEx(curPlayer, shopType, itemIndex, mainItemID, ipyData.GetLimitValue(), clientBuyCount):
- GameWorld.Log("Store shop item buy limit! shopType=%s,itemIndex=%s,limitValue=%s"
- % (shopType, itemIndex, ipyData.GetLimitValue()), curPlayer.GetPlayerID())
- return
- if not PlayerControl.HaveMoney(curPlayer, priceType, itemPrice):
- curPlayer.ShopResult(itemIndex, IPY_GameWorld.tsrNoMoney)
- return
-
- if serverLimitCnt > 0: #全服限购判断放到最后面,GameServer直接加次数
- if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_StoreQueryState) == 1:
- #已经在查询中, 不重复查询
- GameWorld.DebugLog("全服购买次数已经在查询中, 不重复查询 itemIndex=%s" % itemIndex)
- return
- cmdStr = '%s' % ([itemIndex, serverLimitCnt, clientBuyCount, totalItemList, mainItemID, limitBuyCnt, sendMailKey])
- GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0,
- "GetStoreServerBuyCnt", cmdStr, len(cmdStr))
- #设置状态查询中
- curPlayer.SetDict(ChConfig.Def_PlayerKey_StoreQueryState, 1)
- return
- #-------------------------开始购买物品-----------------------------
- DoBuyStoreItem(curPlayer, itemIndex, clientBuyCount, totalItemList, mainItemID, limitBuyCnt, sendMailKey, ipyData)
-
- return
-
-def DoBuyStoreItem(curPlayer, itemIndex, clientBuyCount, totalItemList, mainItemID, limitBuyCnt, sendMailKey, ipyData=None):
- if not ipyData:
- ipyData = IpyGameDataPY.GetIpyGameData("Store", itemIndex)
priceType, itemPrice = ipyData.GetMoneyType(), ipyData.GetMoneyNum()
itemPrice *= clientBuyCount
- shopType = ipyData.GetShopType()
+ #if not PlayerControl.HaveMoney(curPlayer, priceType, itemPrice):
+ # return
- beforeMoney = PlayerControl.GetMoney(curPlayer, priceType)
infoDict = {"TotalItemList":totalItemList, "ClientBuyCount":clientBuyCount, "ShopType":shopType,
- "ShopItemIndex":itemIndex, ChConfig.Def_Cost_Reason_SonKey:mainItemID}
- if not PlayerControl.PayMoney(curPlayer, priceType, itemPrice, ChConfig.Def_Cost_BuyStoreItem, infoDict, clientBuyCount):
- GameWorld.ErrLog("购买商城物品实际扣除货币时失败: itemIndex=%s,clientBuyCount=%s,priceType=%s,itemPrice=%s"
- % (itemIndex, clientBuyCount, priceType, itemPrice))
+ "ShopID":shopID, ChConfig.Def_Cost_Reason_SonKey:mainItemID}
+ if priceType and itemPrice and not PlayerControl.PayMoney(curPlayer, priceType, itemPrice, ChConfig.Def_Cost_BuyStoreItem, infoDict, clientBuyCount):
return
-
- afterMoney = PlayerControl.GetMoney(curPlayer, priceType)
# 今日购买次数+1
if limitBuyCnt > 0:
- dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex
- curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
- updDayBuyCnt = min(curDayBuyCnt + clientBuyCount, ChConfig.Def_UpperLimit_DWord)
- PlayerControl.NomalDictSetProperty(curPlayer, dayBuyCntKey, updDayBuyCnt)
- GameWorld.DebugLog("更新商城物品限购次数: itemIndex=%s,curDayBuyCnt=%s,clientBuyCount=%s,updDayBuyCnt=%s/%s"
- % (itemIndex, curDayBuyCnt, clientBuyCount, updDayBuyCnt, limitBuyCnt), curPlayer.GetPlayerID())
- SyncShopItemTodayBuyCount(curPlayer, [itemIndex])
+ updBuyCnt = min(curBuyCnt + clientBuyCount, ChConfig.Def_UpperLimit_DWord)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, updBuyCnt)
+ GameWorld.DebugLog("更新商城物品限购次数: shopID=%s,curBuyCnt=%s,clientBuyCount=%s,updBuyCnt=%s/%s"
+ % (shopID, curBuyCnt, clientBuyCount, updBuyCnt, limitBuyCnt))
+ SyncShopItemBuyCntInfo(curPlayer, [shopID])
- dataDict = {"ShopType":shopType, "ShopItemIndex":itemIndex, "ClientBuyCount":clientBuyCount,
- "ItemPrice":itemPrice, "MoneyType":priceType,
- "BeforeMoney":beforeMoney, "AfterMoney":afterMoney}
- isForceEvent = priceType not in [IPY_GameWorld.TYPE_Price_Silver_Money]
+ ItemControler.GivePlayerItemOrMail(curPlayer, totalItemList, event=["BuyItem", False, {}], notifyDataEx=shopID)
+ return
+
+def CheckBuyItemUnlock(curPlayer, shopType, shopID, mainItemID, ipyData):
+ ## 检查是否解锁商品购买
+ # @return: 是否已解锁购买
- for itemID, itemCount, isBind in totalItemList:
- curItemObj = ItemControler.GetOutPutItemObj(itemID, itemCount, False, curPlayer=curPlayer)
- if not curItemObj:
- continue
- userData = curItemObj.GetUserData()
- curItemObj.Clear()
- if not sendMailKey:
- if not ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isBind, event=[ChConfig.ItemGive_BuyItem, isForceEvent, dataDict]):
- GameWorld.ErrLog("购买商城物品放入背包失败! itemID=%s, itemCount=%s" % (itemID, itemCount), curPlayer.GetPlayerID())
-
- if ipyData.GetNotifyMark() and itemID == mainItemID:
- PlayerControl.WorldNotify(0, ipyData.GetNotifyMark(), [curPlayer.GetName(), mainItemID, userData])
-
- # 购买永久守护时删除限时守护
- if itemID == 4101:
- delGuardItem = ItemCommon.FindItemInPackByItemID(curPlayer, 4105, IPY_GameWorld.rptItem)
- if delGuardItem:
- ItemCommon.DelItem(curPlayer, delGuardItem, 1)
-
- if sendMailKey:
- PlayerControl.SendMailByKey(sendMailKey, [curPlayer.GetID()], totalItemList, detail=dataDict)
- else:
- ItemControler.NotifyGiveAwardInfo(curPlayer, totalItemList, ChConfig.ItemGive_BuyItem, dataEx=shopType)
- SyncShoppingResult(curPlayer, itemIndex, clientBuyCount)
- return
-
-def GetShopJobItem(job, itemID, jobItemList):
- ## 获取商城物品对应的职业物品, 职业从1开始
- for jobItemIDList in jobItemList:
- if type(jobItemIDList) not in [list, tuple]:
- GameWorld.ErrLog("商城职业物品组格式错误!shopItemID=%s,jobItemList=%s" % (itemID, jobItemList))
- return itemID
- if itemID in jobItemIDList:
- if job <= 0 or job > len(jobItemIDList):
- GameWorld.ErrLog("商城职业物品配置错误,没有该职业对应物品ID!shopItemID=%s,job=%s" % (itemID, job))
- return itemID
- return jobItemIDList[job - 1]
- return itemID
-
-def SyncShoppingResult(curPlayer, itemIndex, itemCnt):
- #通知购买结果
- resultInfo = ChPyNetSendPack.tagMCShoppingResult()
- resultInfo.ItemIndex = itemIndex
- resultInfo.ItemCnt = itemCnt
- NetPackCommon.SendFakePack(curPlayer, resultInfo)
- return
-
-## 商店购买物品限制条件扩展
-# @param curPlayer 玩家实例
-# @return
-def CheckBuyItemLimitEx(curPlayer, shopNPCID, itemIndex, curItemID, limitValue, clientBuyCount):
- if shopNPCID == 7: #符印商店
- return not PlayerRune.GetIsOpenByRuneID(curPlayer, curItemID)
- if shopNPCID in [8, 9, 10]: #仙盟商店
- if curPlayer.GetFamilyID() == 0:
- #无家族
- return True
+ unlockType = ipyData.GetUnlockType()
+ unlockValue = ipyData.GetUnlockValue()
+
+ # 公会等级解锁
+ if unlockType == UnlockType_FamilyLV:
+ if not curPlayer.GetFamilyID():
+ GameWorld.DebugLog("无公会无法购买! shopID=%s" % shopID)
+ return
curFamilyLV = curPlayer.GetFamilyLV()
if curFamilyLV <= 0:
curFamilyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyLV)
- return curFamilyLV < limitValue
- if shopNPCID in [15]: # 开服特惠商店
- #playerCreateRoleDays = GameWorld.GetCreateRoleDays(curPlayer)
- openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay)+1
- return openServerDay != limitValue
-
- if shopNPCID == 16:#神秘限购
- startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopItemStartTime % itemIndex)
- curTime = int(time.time())
- return not startTime or curTime - startTime >= limitValue
+ if curFamilyLV < unlockValue:
+ GameWorld.DebugLog("公会等级不足无法购买! shopID=%s,curFamilyLV=%s < %s" % (shopID, curFamilyLV, unlockValue))
+ return
-#
-# limitPlusDict = {shopItem.GetLimitPlusType1():shopItem.GetLimitPlusValue1(),
-# shopItem.GetLimitPlusType2():shopItem.GetLimitPlusValue2(),
-# shopItem.GetLimitPlusType3():shopItem.GetLimitPlusValue3(),
-# }
-#
-# for limitType, limitValue in limitPlusDict.items():
-# if limitType <= 0:
-# continue
-#
-# # 优先判断NPC独有的
-# callFunc = GameWorld.GetExecFunc(EventSrc, "FunctionNPCShopBuyCheck.CheckByNPC_%s_%s"
-# % (shopNPCID, limitType))
-#
-# if callFunc:
-# return callFunc(curPlayer, shopItem.GetItemID(), limitValue)
-#
-# # 公共限制条件判断
-# callFunc = GameWorld.GetExecFunc(EventSrc, "FunctionNPCShopBuyCheck.CheckPublic_%s" % limitType)
-#
-# if callFunc:
-# return callFunc(curPlayer, shopItem.GetItemID(), limitValue)
-
- # 默认不限制
- return False
-
-def OSSaleOpenMail(curPlayer):
- #开服特惠开启邮件
- if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_OSSail):
- return
- openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay)+1
- if openServerDay not in IpyGameDataPY.GetFuncEvalCfg('OSSaleOpenMail'):
- return
- addItemList = IpyGameDataPY.GetFuncEvalCfg('OSSaleOpenMail', 2)
- PlayerControl.SendMailByKey('SellMail1', [curPlayer.GetID()], addItemList)
- return
-
-
-## 商店npcid
-# @param curPlayer 玩家实例
-# @return
-def GetCurTradeTagNPC(curPlayer):
- curActionNPCID = -1
-
- # 当前商店的npcid
- tradeTagNPC = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TradeTagNPC)
- # 远程商店
- if not tradeTagNPC:
- return GetDirectNpcID()
-
- # 商店npcid与当前对话npc对应
- elif CheckTradeTagNPC(curPlayer, tradeTagNPC):
- return tradeTagNPC
-
- else:
- GameWorld.ErrLog("GetCurStoreItemList:trade tag NPC not match:%s"%tradeTagNPC,
- curPlayer.GetPlayerID())
-
- return curActionNPCID
-
-## 判断记录的商店npcid是否正确
-# @param curPlayer 玩家实例
-# @param tradeTagNPC
-# @return
-def CheckTradeTagNPC(curPlayer, tradeTagNPC):
-
- curActionObj = curPlayer.GetActionObj()
- if not curActionObj:
- return False
-
- if curActionObj.GetGameObjType() != IPY_GameWorld.gotNPC:
- return False
-
- curActionNPC = GameWorld.GetNPCManager().GetNPCByIndex(curActionObj.GetIndex())
- if curActionNPC.GetNPCID() != tradeTagNPC:
- return False
-
+ # 随机刷新解锁
+ elif unlockType == UnlockType_RandRefresh:
+ if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID):
+ GameWorld.DebugLog("该商品没有随机解锁无法购买! shopID=%s" % shopID)
+ return
+
return True
-#--------------------出售物品
-##出售物品
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值真, 逻辑运行成功
-# @remarks 出售物品
-def SellItem(curPlayer, tick):
- #1检查事件发生的顺序
- sendData = IPY_GameWorld.IPY_CPlayerSellItem()
- packType = sendData.GetPackType()
- itemIndex = sendData.GetItemIndex()
- shopType = ChConfig.Def_ShopType_NpcShop
-
- return SellPackItem(curPlayer, packType, [itemIndex], shopType)
-
-#// A3 11 批量出售物品 #tagCMSellItem
+#// A2 32 刷新商店 #tagCSRefreshShop
#
-#struct tagCMSellItem
+#struct tagCSRefreshShop
#{
# tagHead Head;
-# BYTE PackType; //背包类型
-# BYTE Count; //索引数量
-# BYTE ItemIndex[Count]; //物品索引
+# WORD ShopType;
#};
-def OnSellManyItem(index, clientData, tick):
+def OnRefreshShop(index, clientData, tick):
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
- packType = clientData.PackType
- ItemIndexList = clientData.ItemIndex
- if not ItemIndexList:
- return
- shopType = ChConfig.Def_ShopType_NpcShop
- isOk = SellPackItem(curPlayer, packType, ItemIndexList, shopType)
- if isOk:
- curPlayer.Sync_MakeItemAnswer(ShareDefine.Def_mitKeySell, 1)
-
- return
-#---------------------------------------------------------------------
-##出售指定背包物品
-# @param curPlayer 玩家实例
-# @param packType 背包类型
-# @param itemIndex 物品索引
-# @param shopType 商店类型,1NPC商店,2远程贩售
-# @return 返回值真, 检查通过
-# @remarks 出售指定背包物品
-def SellPackItem(curPlayer, packType, itemIndexList, shopType):
- backPack = curPlayer.GetItemManager().GetPack(packType)
- if backPack == None:
- return False
+ shopType = clientData.ShopType
+ DoRandRefreshShopItem(curPlayer, shopType)
+ return
+
+def DoRandRefreshShopItem(curPlayer, shopType, randCnt=0, sysRefresh=False):
+ ## 随机刷新商店物品,ID不重复
+ # @param randCnt: 指定要随机解锁的个数
- totalSellPriceDict = {}
- hasSellOK = False
- notForceRecordEquipTypeList = range(ChConfig.Def_ItemType_retWeapon, ChConfig.Def_ItemType_retNeck)
- for itemIndex in itemIndexList:
- curItem = backPack.GetAt(itemIndex)
-
- if not __CheckItemSell(curPlayer, curItem):
+ ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True)
+ if not ipyDataList:
+ return
+
+ shopIDWeightDict = {}
+ randWeightList = []
+ for ipyData in ipyDataList:
+ if ipyData.GetUnlockType() != UnlockType_RandRefresh:
continue
- hasSellOK = True
- #当前物品数量
- curItemCount = curItem.GetCount()
- #itemName = curItem.GetName()
- #获得单个物品销售价格
- curItemSellPrice, curItemSellType = __GetItemSellPrice(curPlayer, curItem)
- #获得整组销售价格
- curAllItemSellPrice = int(curItemSellPrice) * curItemCount
- totalSellPriceDict[curItemSellType] = totalSellPriceDict.get(curItemSellType, 0) + curAllItemSellPrice
- #GameWorld.Log('curItemSellPrice=%s,curAllItemSellPrice=%s,curItemCount=%s'%(curItemSellPrice,curAllItemSellPrice,curItemCount))
+ shopID = ipyData.GetID()
+ randWeight = ipyData.GetUnlockValue()
+ randWeightList.append([randWeight, shopID])
+ shopIDWeightDict[shopID] = randWeight
- #===========================================================================================
- # #因日记记录过大, 添加记录筛选条件
- # if ItemControler.ItemNeedRecord(curItem):
- # #详细记录装备信息
- # DataRecordPack.DR_GetMoneyBySellPackItem(curPlayer, curItemSellType, curAllItemSellPrice)
- #===========================================================================================
+ if not randWeightList:
+ GameWorld.ErrLog("该商店没有可随机刷新解锁的商品! shopType=%s" % shopType)
+ return
+
+ refreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopRefreshCnt % shopType)
+ moneyType, moneyValue = 0, 0
+ if shopType == ShopType_HeroSoul:
+ randCnt = IpyGameDataPY.GetFuncCfg("StoreHeroSoul", 1)
+ freeCnt = IpyGameDataPY.GetFuncCfg("StoreHeroSoul", 3)
+ if not sysRefresh and refreshCnt >= freeCnt:
+ moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("StoreHeroSoul", 2)
+
+ GameWorld.DebugLog("随机刷新商店商品: shopType=%s,randCnt=%s/%s,refreshCnt=%s,moneyType=%s,moneyValue=%s,sysRefresh=%s"
+ % (shopType, randCnt, len(randWeightList), refreshCnt, moneyType, moneyValue, sysRefresh))
+
+ if randCnt <= 0:
+ return
+
+ if moneyType and moneyValue and not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "RefreshShopItem"):
+ return
+
+ doCnt = randCnt * 10
+ randShopIDList = []
+ syncBuyCntIDList = []
+ while randWeightList and len(randShopIDList) < randCnt and doCnt > 0:
+ doCnt -= 1
+ shopID = GameWorld.GetResultByWeightList(randWeightList)
+ if not shopID:
+ continue
+ randShopIDList.append(shopID)
+ randWeight = shopIDWeightDict.get(shopID, 0)
+ if [randWeight, shopID] in randWeightList:
+ randWeightList.remove([randWeight, shopID])
+
+ GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID, 1)
+ if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID):
+ syncBuyCntIDList.append(shopID)
+
+ GameWorld.DebugLog("随机刷新商品数: %s,%s" % (len(randShopIDList), randShopIDList))
+ GameWorld.DebugLog("剩余锁定商品数: %s,%s" % (len(randWeightList), randWeightList))
+
+ # 其他的设置未解锁
+ for _, shopID in randWeightList:
+ GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID, 0)
+ if not sysRefresh:
+ refreshCnt += 1
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopRefreshCnt % shopType, refreshCnt)
+ GameWorld.DebugLog("更新刷新商店次数=%s" % refreshCnt)
- isForceDR = curItem.GetType() not in notForceRecordEquipTypeList and not ItemControler.ItemNotNeedRecord(curItem)
- #物品消失
- ItemCommon.DelItem(curPlayer, curItem, curItemCount, False, ChConfig.ItemDel_SellPackItem, isForceDR=isForceDR)
- #PutItemInBuyBackPack(curPlayer, curItem)
- if not hasSellOK:
- return False
- for priceType, priceMoney in totalSellPriceDict.items():
- #玩家钱增加
- addDataDict = {}
- PlayerControl.GiveMoney(curPlayer, priceType, priceMoney, ChConfig.Def_GiveMoney_SellPackItem, addDataDict, False)
- PlayerControl.NotifyCode(curPlayer, "GetMoney01", [priceType, priceMoney])
- return True
-
-
-## 售卖物品回购背包的处理, 放入空位不叠加(本项目没有回购,先屏蔽)
-# @param None
-# @return None
-def PutItemInBuyBackPack(curPlayer, curItem):
+ if syncBuyCntIDList:
+ SyncShopItemBuyCntInfo(curPlayer, syncBuyCntIDList)
+ SyncShopRefreshItemInfo(curPlayer, shopType, randShopIDList)
return
- itemIndexs = str(curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DelPackIndex))
- backPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptRecycle)
- emptyIndex = ItemCommon.GetEmptyIndexInPack(curPlayer, IPY_GameWorld.rptRecycle)
- if emptyIndex == -1:
- #清除旧物品
- emptyIndex = int(itemIndexs[0]) - 1
- item = backPack.GetAt(emptyIndex)
- item.Clear()
- itemIndexs = itemIndexs[1:]
+
+def SyncShopRefreshItemInfo(curPlayer, shopType, syncIDList=[]):
+ ##同步刷新解锁的商品信息
+ if not syncIDList:
+ syncIDList = []
+ ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True)
+ if not ipyDataList:
+ return
+ for ipyData in ipyDataList:
+ shopID = ipyData.GetID()
+ if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID):
+ continue
+ syncIDList.append(shopID)
+ if not syncIDList:
+ return
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCShopRefreshItemInfo)
+ clientPack.ShopType = shopType
+ clientPack.RefreshCnt = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopRefreshCnt % shopType), 250)
+ clientPack.ShopIDList = syncIDList
+ clientPack.Count = len(clientPack.ShopIDList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
+def SyncShopItemBuyCntInfo(curPlayer, syncIDList=[]):
+ ##同步商品购买次数
+
+ objPool = ObjPool.GetPoolMgr()
+ buyCntList = []
+ if syncIDList:
+ for shopID in syncIDList:
+ buyInfo = objPool.acquire(ChPyNetSendPack.tagSCShopItemBuyCnt)
+ buyInfo.ShopID = shopID
+ buyInfo.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ buyCntList.append(buyInfo)
else:
- # 清空空格位防范, 防止异常情况物品消失而没有重置标记位导致数值越界
- itemIndexs = itemIndexs.replace(str(emptyIndex + 1), '')
- item = backPack.GetAt(emptyIndex)
-
- itemIndexs = "%s%s"%(itemIndexs, emptyIndex + 1)
+ ipyDataMgr = IpyGameDataPY.IPY_Data()
+ for i in xrange(ipyDataMgr.GetStoreCount()):
+ shopItem = ipyDataMgr.GetStoreByIndex(i)
+ if not shopItem.GetLimitCnt():
+ continue
+ shopID = shopItem.GetID()
+ buyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID)
+ if buyCnt <= 0:
+ continue
+ buyInfo = objPool.acquire(ChPyNetSendPack.tagSCShopItemBuyCnt)
+ buyInfo.ShopID = shopID
+ buyInfo.BuyCnt = buyCnt
+ buyCntList.append(buyInfo)
+
+ if not buyCntList:
+ return
- #放入新物品
- item.PutIn(curItem)
- PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_DelPackIndex, int(itemIndexs))
+ clientPack = objPool.acquire(ChPyNetSendPack.tagSCShopItemBuyCntInfo)
+ clientPack.BuyCntList = buyCntList
+ clientPack.Count = len(clientPack.BuyCntList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
return
-
-
-##检查物品是否可以出售
-# @param curPlayer 玩家实例
-# @param curItem 物品实例
-# @return 返回值真, 检查通过
-# @remarks 检查物品是否可以出售
-def __CheckItemSell(curPlayer, curItem) :
- if not ItemCommon.CheckItemCanUse(curItem):# or ItemControler.GetIsAuctionItem(curItem):
- PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_644055")
- return
-
- #if ItemControler.IsEventItem(curItem):
- # PlayerControl.NotifyCode(curPlayer, "itemuse_chenxin_31379")
- # return
-
- if curItem.GetCanSell() == 0:
- #不能出售的物品,无法出售
- PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_272921")
- return
-
- #获得单个物品销售价格
- itemPrice , priceType = __GetItemSellPrice(curPlayer, curItem)
- itemPrice = int(itemPrice) * curItem.GetCount()
-
- if not itemPrice or not priceType:
- PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_272921")
- return
-
- if not PlayerControl.CanGiveMoney(curPlayer, priceType, itemPrice):
- # 对不起,您携带的金钱已经达上限,操作无效
- #PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_609765")
- return
-
- return True
-
-#---------------------------------------------------------------------
-##获得物品的出售价格
-# @param curPlayer 玩家实例
-# @param curItem 物品实例
-# @return 返回值, 物品的出售价格
-# @remarks 获得物品的出售价格
-def __GetItemSellPrice(curPlayer, curItem):
- #为配合客户端,进行以下逻辑(向上取整)
- #2012-03-26 jiang 耐久这里不进行除ChConfig.Def_EndureRepairParameter的转换该有公式自己计算
- #curItemEndure = curItem.GetCurDurg()
- #curItemMaxEndure = curItem.GetMaxEndure()
-
- # 修改此函数请同时修改 脱机挂出售
- #当前物品价格 原价出售
- priceType = curItem.GetGoldPaperPrice()
- if not priceType:
- priceType = IPY_GameWorld.TYPE_Price_Silver_Money
- curItemPrice = curItem.GetSilverPrice()
- return curItemPrice, priceType
-
-##检查玩家可否开始NPC事件
-# @param curPlayer 玩家实例
-# @return 返回值真, 检查通过
-# @remarks 检查玩家可否开始NPC事件
-def CheckPlayerCanStateEvent(curPlayer):
- if curPlayer.GetPlayerAction() not in ChConfig.Def_Player_DoEvent_State :
- #CannotDoing 对不起,您当前状态无法进行此操作,操作无效
- PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_740826")
- return False
-
- return True
-
-#---------------------------------------------------------------------
-##检查物品是否可以放入合成背包.
-# @param curItem 物品实例
-# @return 布尔值
-# @remarks 检查物品是否可以放入合成背包
-def __CheckItemCanPutInComposePack(curItem):
- return curItem.GetType() in ChConfig.Def_Compose_Can_Put_List
-
-#---------------------------------------------------------------------
-##通用背包放入操作
-# @param curPlayer 玩家实例
-# @param srcBackpack 起点背包
-# @param desBackPack 目标背包
-# @param srcIndex 起点索引
-# @param destIndex 目标索引
-# @param putItemCount 放入数量
-# @param tick 时间戳
-# @return 返回值无意义
-# @remarks 通用背包放入操作
-def BackpackOperate(curPlayer, srcBackpack, desBackPack, srcIndex, destIndex, putItemCount, tick):
- #获得需要操作的物品的物品
- scrItem = __GetBackPackOperateItem(curPlayer, srcBackpack, desBackPack, srcIndex)
-
- if scrItem == None:
- return
-
- itemControl = ItemControler.PlayerItemControler(curPlayer)
-
- if not itemControl.CanPutInItem(desBackPack, scrItem.GetItemTypeID(), putItemCount, scrItem.GetIsBind()):
- PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [desBackPack])
- return
-
- #拖拽物品
- ItemControler.DragItem(curPlayer, srcBackpack, srcIndex, desBackPack, destIndex, putItemCount)
- return
-#---------------------------------------------------------------------
-##通用背包操作检查
-# @param scrItem 放入物品
-# @param desBackPack 目标背包
-# @return 布尔值
-# @remarks 通用背包操作检查
-def __CheckBackPackOperate(scrItem, desBackPack):
- #特殊检查
- if desBackPack in ChConfig.Def_ComposePack_List:
- if not __CheckItemCanPutInComposePack(scrItem):
- GameWorld.ErrLog('BackpackOperate ItemErr = %s, ItemType = %s'%(scrItem.GetItemTypeID(), scrItem.GetType()))
- return False
-
- return True
-#---------------------------------------------------------------------
-##获得背包当前操作的物品
-# @param curPlayer 玩家实例
-# @param srcBackpack 起始背包
-# @param desBackPack 目的背包
-# @param srcIndex 起始物品索引
-# @return 操作物品实例或者None
-# @remarks 获得背包当前操作的物品
-def __GetBackPackOperateItem(curPlayer, srcBackpack, desBackPack, srcIndex):
- #操作背包检查
- if srcBackpack not in ChConfig.Def_BackpackOperate_List or desBackPack not in ChConfig.Def_BackpackOperate_List:
- GameWorld.ErrLog('PackItemExchange packErr, srcBackpack = %s, \
- desBackPack = %s'%(srcBackpack, desBackPack), curPlayer.GetID())
- return
-
- #获得放入的物品
- scrItem = curPlayer.GetItemManager().GetPack(srcBackpack).GetAt(srcIndex)
-
- #---物品检查---
- if not ItemCommon.CheckItemCanUse(scrItem):
- return
-
- #特殊检查
- if not __CheckBackPackOperate(scrItem, desBackPack):
- return
-
- return scrItem
-#---------------------------------------------------------------------
-##通用背包交换操作
-# @param curPlayer 玩家实例
-# @param srcBackpack 起点背包
-# @param destBackPack 目标背包
-# @param srcIndex 起点索引
-# @param destIndex 目标索引
-# @param tick 时间戳
-# @return 返回值无意义
-# @remarks 通用背包交换操作
-def PackItemExchange(curPlayer, srcBackpack, destBackPack, srcIndex, destIndex, tick):
- #获得需要操作的物品的物品
- scrItem = __GetBackPackOperateItem(curPlayer, srcBackpack, destBackPack, srcIndex)
-
- if scrItem == None:
- return
-
- #---验证目标背包格子--
- destItem = curPlayer.GetItemManager().GetPack(destBackPack).GetAt(destIndex)
- #目标格子只验证锁定, 可以允许空位
- if destItem == None or destItem.GetIsLocked():
- return
-
- ItemCommon.DoLogicSwitchItem(curPlayer, scrItem, destItem, destBackPack)
- return
-
-
-## 获得金钱付费字典
-# @param moneyList 金钱列表 [金钱类型, 金钱数量,。。。]
-# @param payMoneyDict 金钱累加字典
-# @return 金钱累加字典
-# @remarks 获得金钱付费字典
-def GetPayMoneyDict(moneyList, payMoneyDict={}):
- length = len(moneyList)
-
- for index in range(0, length, 2):
- moneyType = moneyList[index]
- money = moneyList[index + 1]
-
- payMoney = payMoneyDict.get(moneyType)
- if payMoney == None:
- payMoneyDict[moneyType] = money
- else:
- payMoneyDict[moneyType] += money
-
- return payMoneyDict
-
-
-## 检查金钱
-# @param curPlayer 玩家
-# @param payMoneyDict 付钱字典
-# @return BOOL是否足够
-# @remarks 检查金钱
-def CheckPayMoney(curPlayer, payMoneyDict):
-
- for moneyType, money in payMoneyDict.items():
-
- #验证手续费
- if not PlayerControl.HaveMoney(curPlayer, moneyType, money):
- return False
-
- return True
-
--
Gitblit v1.8.0