From 8c3d4da0efd8345892ac9822297b93644e03be3a Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 07 三月 2019 18:56:24 +0800 Subject: [PATCH] 6332 【后端】【2.0】主要是拍品相关规则调整及背包优化(拍品堆叠逻辑修改) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py | 227 +++++++++++++++++++++----------------------------------- 1 files changed, 86 insertions(+), 141 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py index 75cc076..61958a6 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py @@ -37,15 +37,6 @@ import math #--------------------------------------------------------------------- -## 放不下主角背包放入万能背包的逻辑, curGiveItem 要先 SetCount -# @param curPlayer 当前玩家 -# @param curGiveItem 要先 SetCount -# @return None or True -# @remarks 函数详细说明. -def DoLogic_PutItemInPack(curPlayer, curGiveItem, showEff=False, showSysInfo=False, event=["", False, {}]): - return __DoLogic_PutItemInPack(curPlayer, curGiveItem, [IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere], - showEff=showEff, showSysInfo=showSysInfo, event=event) - ## 获得背包的一个空格子 def GetItemPackSpaceIndex(curPlayer, packindex): @@ -328,7 +319,8 @@ # @return True or False # @remarks 函数详细说明. def CanPackItemByItemType(srcItemID, srcItemIsBind, destItemID, destItemIsBind): - if srcItemID == destItemID and srcItemIsBind == destItemIsBind: + ## 拍品项目,只有非拍品可堆叠,即绑定物品 + if srcItemID == destItemID and srcItemIsBind == destItemIsBind and srcItemIsBind: return True return False @@ -1120,16 +1112,18 @@ self.__CrossServerPutInItem(packIndex, tagItem, event) tagItem.Clear() return True - if CheckChangeOldItem(curPlayer, tagItem): - tagItem.Clear() - return True packIndex = ChConfig.GetItemPackType(curItemData.GetType(), packIndex) - if not self.CanPutInItem(packIndex, tagItem.GetItemTypeID(), GetItemCount(tagItem), tagItem.GetIsBind(), defaultPile): + tagItemCount = GetItemCount(tagItem) + isBind = tagItem.GetIsBind() + isAuctionItem = not isBind + auctionGroup = 1 if isAuctionItem else 0 # 物品实例默认一组 + if not self.CanPutInItem(packIndex, tagItem.GetItemTypeID(), tagItemCount, auctionGroup, defaultPile): GameWorld.DebugLog("背包满,不能放入物品 count = %d"%GetItemCount(tagItem)) tagItem.Clear() return False + isNeedRecord = False itemID = tagItem.GetItemTypeID() #激活成就的道具 if tagItem.GetType() == ChConfig.Def_ItemType_SuccessItem: @@ -1143,6 +1137,11 @@ return True defaultPile = True maxPackCount = ChConfig.Def_UpperLimit_DWord # 转化物品叠加上限不取物品表的, 暂定堆叠上限20亿 + elif auctionGroup > 0: + maxPackCount = max(1, tagItemCount / auctionGroup) # 每组至少1个 + defaultPile = False # 新放入的拍品只能放空位置,所以不判断堆叠 + #isBind = False + isNeedRecord = True # 拍品要记录 else: maxPackCount = curItemData.GetPackCount() @@ -1159,10 +1158,9 @@ curPack = self.__PlayerItemManager.GetPack(packIndex) #itemFactory = GameWorld.GetItemFactory() - isBind = tagItem.GetIsBind() - isNeedRecord = False + #isBind = tagItem.GetIsBind() # 目前暂只记录放入背包的 - if packIndex in [IPY_GameWorld.rptItem, ShareDefine.rptTreasure, ShareDefine.rptRune, ShareDefine.rptGatherSoul]: + if not isNeedRecord and packIndex in [IPY_GameWorld.rptItem, ShareDefine.rptTreasure, ShareDefine.rptRune, ShareDefine.rptGatherSoul]: isNeedRecord = ItemNeedRecord(tagItem) or isForceEvent putResult = False @@ -1227,7 +1225,7 @@ #可以摆放 if curItemCount > canPutinCount: #需要创建新物品放入 - curCreateItem = GetOutPutItemObj(tagItem.GetItemTypeID(), canPutinCount, isBind) + curCreateItem = GetOutPutItemObj(tagItem.GetItemTypeID(), canPutinCount, isAuctionItem) #注意: 不能在这里AssignItem, 否则会有2个物品指针指向同一个物品实例 . 巨大的错误在这一句 : curCreateItem.Assign(tagItem) #如果是装备,那么 maxPackCount 为1 这里会循环自动创建新物品,所以直接 GetOutPutItemObj 即可, 暂不支持定制装备拆解 @@ -1341,25 +1339,25 @@ # @param packIndex 背包索引 # @param curItemID 当前物品ID # @param curItemCount 当前物品数量 - # @param isBind 是否绑定 + # @param auctionGroup 拍品组数 # @param defaultPile 默认先判断是否能进行物品堆叠 # @return True or False # @remarks 函数详细说明. - def CanPutInItem(self, packIndex, curItemID, curItemCount, isBind, defaultPile=True): + def CanPutInItem(self, packIndex, curItemID, curItemCount, auctionGroup, defaultPile=True): if GameWorld.IsCrossServer(): return True - checkRet, putIndex = self.CanPutInItemEx(packIndex, curItemID, curItemCount, isBind, defaultPile) + checkRet, putIndex = self.CanPutInItemEx(packIndex, curItemID, curItemCount, auctionGroup, defaultPile) return checkRet ## 是否能放入物品 # @param packIndex 背包索引 # @param curItemID 当前物品ID # @param curItemCount 当前物品数量 - # @param isBind 是否绑定 + # @param auctionGroup 拍品组数 # @param defaultPile 默认先判断是否能进行物品堆叠 # @return True or False, 第一个可放入的位置 # @remarks 函数详细说明. - def CanPutInItemEx(self, packIndex, curItemID, curItemCount, isBind, defaultPile=True): + def CanPutInItemEx(self, packIndex, curItemID, curItemCount, auctionGroup, defaultPile=True): gameData = GameWorld.GetGameData() curItemData = gameData.GetItemByTypeID(curItemID) @@ -1367,11 +1365,16 @@ GameWorld.Log("找不到ItemID = %d" % curItemID) return False, 0 + isBind = True if curItemID in ChConfig.Def_TransformItemIDList: # 货币直接转换的物品如果是放入背包的则直接转化,无需暂用格子 if packIndex == IPY_GameWorld.rptItem: return True, 0 maxPackCount = ChConfig.Def_UpperLimit_DWord # 转化物品叠加上限不取物品表的, 暂定堆叠上限20亿 + elif auctionGroup > 0: + maxPackCount = max(1, curItemCount / auctionGroup) # 每组至少1个 + defaultPile = False # 新放入的拍品只能放空位置,所以不判断堆叠 + isBind = False else: maxPackCount = curItemData.GetPackCount() @@ -1543,7 +1546,8 @@ curItemTypeID = curItem.GetItemTypeID() #curItemGUID = curItem.GetGUID() curItemCount = curItem.GetCount() - curItemIsBind = curItem.GetIsBind() + #curItemIsBind = curItem.GetIsBind() + auctionGroup = 1 if not curItem.GetIsBind() else 0 # 已经生成的物品实例默认1组 #toPackIndex = ChConfig.GetItemPackType(curItem.GetType(), toPackIndex) # 常规物品转移到虚拟符印背包 @@ -1552,7 +1556,7 @@ return False return itemControl.PutItemInVPack(toPackIndex, curItem) - checkRet, putIndex = itemControl.CanPutInItemEx(toPackIndex, curItemTypeID, curItemCount, curItemIsBind) + checkRet, putIndex = itemControl.CanPutInItemEx(toPackIndex, curItemTypeID, curItemCount, auctionGroup) if not checkRet: return False return DragItem(curPlayer, fromPackIndex, itemIndex, toPackIndex, putIndex, curItemCount) @@ -1845,6 +1849,10 @@ if itemType1 == itemType2: if item1.GetItemColor() == item2.GetItemColor(): if item1.GetItemQuality() == item2.GetItemQuality(): + if item1.GetItemTypeID() == item2.GetItemTypeID(): + if item1.GetIsBind() == item2.GetIsBind(): + return -cmp(item1.GetCount(), item2.GetCount()) + return -cmp(item1.GetIsBind(), item2.GetIsBind()) return cmp(item1.GetItemTypeID(), item2.GetItemTypeID()) else: return cmp(0-item1.GetItemQuality(), 0-item2.GetItemQuality()) @@ -1874,7 +1882,7 @@ for curItem in curList: curCount = curItem.GetCount() - if not CanPackItem(curItem, addItem) : + if not CanPackItem(curItem, addItem): continue if curCount >= packCount: @@ -2048,21 +2056,11 @@ return -#--------------------------------------------------------------------- -## 给玩家物品 -# @param curPlayer 当前玩家 -# @param itemID 物品ID -# @param itemCount 物品数量 -# @param itemIsBind 物品是否绑定 -# @param packIndexList 背包索引列表 -# @param showEff 显示放入背包的特效 -# @param defaultPile 默认先判断是否能进行物品堆叠 -# @param returnItemObj 是否返回物品对象 -# @param showSysInfo 是否显示系统提示 -# @return 布尔值 -# @remarks -def GivePlayerItem(curPlayer, itemID, itemCount, itemIsBind, packIndexList, showEff=False, defaultPile=True, +def GivePlayerItem(curPlayer, itemID, itemCount, auctionGroup, packIndexList, showEff=False, defaultPile=True, returnItemObj=False, showSysInfo=False, event=["", False, {}]): + '''给玩家物品 + @param auctionGroup: 拍品组数,0为非拍品,大于0为总给的物品数拆成的拍品组数;注意这个不一定按叠加拆分,策划自行决定非几组拍 + ''' if itemCount <= 0: return False @@ -2070,12 +2068,28 @@ if not curItemData: return False + if auctionGroup > 0: + ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID) + if not ipyData: + GameWorld.ErrLog("非拍卖物品,不能按拍品分组,默认转为非拍品! itemID=%s,itemCount=%s,auctionGroup=%s" + % (itemID, itemCount, auctionGroup), curPlayer.GetPlayerID()) + auctionGroup = 0 + isAuctionItem = True if auctionGroup > 0 else False + defaultPack = IPY_GameWorld.rptItem if not packIndexList else packIndexList[0] packIndex = ChConfig.GetItemPackType(curItemData.GetType(), defaultPack) if packIndex != defaultPack or not packIndexList: packIndexList = [packIndex] - if not __Check_CanPutItemInPack(curPlayer, itemID, itemCount, itemIsBind, packIndexList, defaultPile): + #物品管理器 + canPutIn = False + itemControl = PlayerItemControler(curPlayer) + for packIndex in packIndexList: + #可以放入背包 + if itemControl.CanPutInItem(packIndex, itemID, itemCount, auctionGroup, defaultPile): + canPutIn = True + break + if not canPutIn: #不可放入 return False @@ -2083,7 +2097,7 @@ if GetAppointItemRealID(itemID): isOK = False for _ in xrange(itemCount): - if GivePlayerAppointItem(curPlayer, itemID, False, event): + if GivePlayerAppointItem(curPlayer, itemID, isAuctionItem, event): isOK = True # 只要有成功的就返回成功,防止异常情况失败可能导致被刷 return isOK @@ -2091,21 +2105,29 @@ if ItemCommon.GetIsEquip(curItemData): isOK = False for _ in xrange(itemCount): - outPutEquip = GetOutPutItemObj(itemID, 1, itemIsBind) - if __DoLogic_PutItemInPack(curPlayer, outPutEquip, packIndexList, showEff, defaultPile, returnItemObj, - showSysInfo, event): + outPutEquip = GetOutPutItemObj(itemID, 1, isAuctionItem, curPlayer=curPlayer) + if not outPutEquip: + return isOK + if DoLogic_PutItemInPack(curPlayer, outPutEquip, event, packIndexList, defaultPile): isOK = True # 只要有成功的就返回成功,防止异常情况失败可能导致被刷 return isOK - giveItem = GetOutPutItemObj(itemID, itemCount, itemIsBind) - if not giveItem: - GameWorld.ErrLog('GivePlayerItem itemID = %s, Error, giveCnt = %s, isBind = %s' % \ - (itemID, itemCount, itemIsBind), curPlayer.GetID()) - return False - - #将物品放入背包 - return __DoLogic_PutItemInPack(curPlayer, giveItem, packIndexList, showEff, defaultPile, returnItemObj, - showSysInfo, event) + isOK = False + doCount = itemCount + maxPackCount = max(1, itemCount / auctionGroup) # 每组至少1个 + while itemCount > 0 and doCount > 0: + doCount -= 1 + giveCount = maxPackCount if itemCount >= maxPackCount else itemCount + if giveCount <= 0: + break + itemCount -= giveCount + giveItem = GetOutPutItemObj(itemID, giveCount, isAuctionItem, curPlayer=curPlayer) + if not giveItem: + return isOK + if DoLogic_PutItemInPack(curPlayer, giveItem, event, packIndexList, defaultPile): + isOK = True # 只要有成功的就返回成功,防止异常情况失败可能导致被刷 + + return isOK def GivePlayerAppointItem(curPlayer, appointID, isAuctionItem, event=["", False, {}]): @@ -2164,11 +2186,11 @@ # @param defaultPile 默认先判断是否能进行物品堆叠 # @param showSysInfo 是否显示系统提示 # @return None -def GivePlayerEquip(curPlayer, itemData, showEff=False, packType=[IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere], - defaultPile=True, returnItemObj=False, showSysInfo=False, event=["", False, {}]): +def GivePlayerEquip(curPlayer, itemData, event=["", False, {}], packType=[IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere], + defaultPile=True): equipItem = GetItemByData(itemData) #将物品放入背包 - return __DoLogic_PutItemInPack(curPlayer, equipItem, packType, showEff, defaultPile, returnItemObj, showSysInfo, event) + return DoLogic_PutItemInPack(curPlayer, equipItem, event, packType, defaultPile) ## 根据物品data字典创建物品 @@ -2222,27 +2244,6 @@ #--------------------------------------------------------------------- -##检查是否可以放入此物品. -# @param curPlayer 玩家实例 -# @param giveItemID 物品ID -# @param giveItemCnt 物品数量 -# @param giveItemBind 物品是否绑定 -# @param packIndexList 背包列表 -# @param defaultPile 默认先判断是否能进行物品堆叠 -# @return 返回值无意义 -# @remarks 客户端封包响应 -def __Check_CanPutItemInPack(curPlayer, giveItemID, giveItemCnt, giveItemBind, packIndexList, defaultPile=True): - #物品管理器 - itemControl = PlayerItemControler(curPlayer) - - for packIndex in packIndexList: - #可以放入背包 - if itemControl.CanPutInItem(packIndex, giveItemID, giveItemCnt, giveItemBind, defaultPile): - return True - - #不可放入 - return False - ## 执行物品放入背包逻辑 # @param curPlayer 背包拥有者 # @param curGiveItem 放入的物品 @@ -2252,8 +2253,7 @@ # @param returnItemObj 是否返回物品对象 # @param showSysInfo 是否显示系统提示 # @return 布尔值 -def __DoLogic_PutItemInPack(curPlayer, curGiveItem, packIndexList, showEff=False, defaultPile=True, - returnItemObj=False, showSysInfo=False, event=["", False, {}]): +def DoLogic_PutItemInPack(curPlayer, curGiveItem, event=["", False, {}], packIndexList=[IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere], defaultPile=True): #itemID = curGiveItem.GetItemTypeID() #count = curGiveItem.GetCount() itemControl = PlayerItemControler(curPlayer) @@ -2269,14 +2269,14 @@ # PlayerControl.NotifyCode(curPlayer, "ObtainRes01", [itemID, count]) #=================================================================== - if returnItemObj: - return curGiveItem + #if returnItemObj: + # return curGiveItem return True #玩家背包已满, 清空物品,否则创建物品不删除,将导致内存溢出 curGiveItem.Clear() #前面验证过了, 走到这里就是逻辑Bug了 - GameWorld.ErrLog('ItemControler.GivePlayerItem Error 物品无法放入背包') + GameWorld.ErrLog('DoLogic_PutItemInPack Error 物品无法放入背包') return False ## 设置物品是否绑定 @@ -2601,63 +2601,9 @@ for tempItem in tempItemList: itemControl.PutInItem(IPY_GameWorld.rptItem, tempItem, event=event) for itemID, itemCnt, isBind in extraItemList: - GivePlayerItem(curPlayer, itemID, itemCnt, isBind, - [IPY_GameWorld.rptItem], event=event) + GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem], event=event) ClearPack(curPlayer, ShareDefine.rptTempItem) - return - - -def CheckChangeOldItem(curPlayer, tagItem): - ##替换旧物品 - itemID = tagItem.GetItemTypeID() - changeOldItemDict = IpyGameDataPY.GetFuncEvalCfg('ChangeOldItem', 1, {}) - if itemID not in changeOldItemDict: - return - itemCnt = GetItemCount(tagItem) - isBind = tagItem.GetIsBind() - toItemID, toCnt, mailKey = changeOldItemDict[itemID] - giveCnt = itemCnt * toCnt - PlayerControl.SendMailByKey(mailKey, [curPlayer.GetPlayerID()], [[toItemID, giveCnt, isBind]]) - return True - -def LoginCheckChangeOldItem(curPlayer): - ##登录检查替换旧物品 - if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_GodWeaponItem): - return - GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_GodWeaponItem, 1) - giveItemDict = {} - mailDict = {} - for packIndex in [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse, ShareDefine.rptTreasure]: - curPack = curPlayer.GetItemManager().GetPack(packIndex) - for i in xrange(curPack.GetCount()): - curItem = curPack.GetAt(i) - if not curItem: - continue - itemID = curItem.GetItemTypeID() - changeOldItemDict = IpyGameDataPY.GetFuncEvalCfg('ChangeOldItem', 1, {}) - if itemID not in changeOldItemDict: - continue - isBind = curItem.GetIsBind() - itemCount = curItem.GetCount() - toItemID, toCnt, mailKey = changeOldItemDict[itemID] - giveCnt = itemCount * toCnt - keyStr = '%s_%s'%(toItemID, isBind) - giveItemDict[keyStr] = giveItemDict.get(keyStr, 0) + giveCnt - ItemCommon.DelItem(curPlayer, curItem, itemCount, False, "ChangeOldItem") - if mailKey not in mailDict: - mailDict[mailKey] = [keyStr] - if keyStr not in mailDict[mailKey]: - mailDict[mailKey].append(keyStr) - for mailKey, keyStrList in mailDict.items(): - itemList = [] - for keyStr in keyStrList: - if keyStr not in giveItemDict: - continue - giveCnt = giveItemDict[keyStr] - itemID, isBind = keyStr.split('_') - itemList.append([int(itemID), giveCnt, int(isBind)]) - PlayerControl.SendMailByKey(mailKey, [curPlayer.GetID()], itemList) return def GivePlayerItemOrMail(curPlayer, itemList, mailKey=None, event=["", False, {}]): @@ -2682,6 +2628,5 @@ GameWorld.DebugLog("GivePlayerItemOrMail背包空间不够,发送邮件: mailItemList=%s" % str(itemList), curPlayer.GetPlayerID()) else: for itemID, itemCnt, isBind in itemList: - GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem], - event=event) - return \ No newline at end of file + GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem], event=event) + return -- Gitblit v1.8.0