From 84ede803777ff10b5cbe93b1ec0168af08f55d5e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 13 一月 2021 18:11:26 +0800
Subject: [PATCH] 8677 【BT】【后端】跨服冲榜活动; 新增跨服活动时间管理模块、跨服榜单;跨服邮件;跨服广播优化;相关GM命令、后台工具;
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py | 334 +++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 234 insertions(+), 100 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py
index 43e26d5..d664808 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/Operate_EquipStar.py
@@ -22,16 +22,20 @@
import PlayerControl
import IPY_GameWorld
import DataRecordPack
+import PlayerAuctionHouse
import IpyGameDataPY
+import PlayerSuccess
import GameWorld
import EventShell
import ChConfig
import ChEquip
+
+import math
#-------------------------------------------------------------------------------------------
-#===============================================================================
#// A5 C5 装备部位升星 #tagCMEquipPartStarUp
+#
#struct tagCMEquipPartStarUp
#{
# tagHead Head;
@@ -39,13 +43,8 @@
# BYTE CostEquipCnt; // 装备个数
# WORD CostEquipIndex[CostEquipCnt]; // 装备索引
# DWORD CostEquipID[CostEquipCnt]; // 装备物品ID
+# BYTE AutoBuy; // 自动购买 0-不自动购买,1-自动购买并升星,2-自动购买预览(未满概率时预览消耗时使用)
#};
-#===============================================================================
-## 部位升星
-# @param playerIndex: 玩家
-# @param clientData: 封包
-# @param tick: 当前时间
-# @return None
def OnEquipPartStarUp(playerIndex, clientData, tick):
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
playerID = curPlayer.GetPlayerID()
@@ -66,9 +65,9 @@
return
# 当前装备等级是否到达最高等级
- curPack = curPlayer.GetItemManager().GetPack(packType)
- curEquip = curPack.GetAt(equipPackIndex)
- if not curEquip or curEquip.IsEmpty():
+ equipPack = curPlayer.GetItemManager().GetPack(packType)
+ curEquip = equipPack.GetAt(equipPackIndex)
+ if not ItemCommon.CheckItemCanUse(curEquip):
GameWorld.DebugLog("OnEquipPartStarUp() equip is empty")
return
@@ -77,101 +76,94 @@
if curPartStar >= maxStar:
GameWorld.Log("OnEquipPartStarUp:curPartStar(%s) >= maxStar(%s)" % (curPartStar, maxStar), playerID)
return
-
- # 升星处理
- result = DoLogic_EquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, clientData)
- if result == ChConfig.Def_ComposeState_None:
- return
- updPartStar = ChEquip.GetEquipPartStar(curPlayer, equipPackIndex)
- GameWorld.DebugLog(" 装备升星 equipPackIndex=%s result=%s,curPartStar=%s,updPartStar=%s" % (equipPackIndex, result, curPartStar, updPartStar), playerID)
- if result == ChConfig.Def_ComposeState_Sucess:
- # 星级变更时处理
- #刷新属性
- ChEquip.RefreshPlayerEquipAttribute(curPlayer, classLV)
- playControl = PlayerControl.PlayerControl(curPlayer)
- playControl.RefreshPlayerAttrState()
-
- if updPartStar in IpyGameDataPY.GetFuncEvalCfg('EquipPartStarNotify'):
- itemID = curEquip.GetItemTypeID()
- userData = curEquip.GetUserData()
- guid = ItemCommon.CacheNotifyEquipDetailInfo(curPlayer, curEquip)
- msgParamList = [curPlayer.GetPlayerName(), itemID, userData, guid, updPartStar]
- PlayerControl.WorldNotify(0, "StarLevelUp", msgParamList)
- EventShell.EventRespons_EquipStarUp(curPlayer)
- return
-
-
-## 开始装备升星
-# @param index 为装备位
-# @return
-def DoLogic_EquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, clientData):
- result = ChConfig.Def_ComposeState_None
- nextStar = curPartStar + 1
- ipyData = IpyGameDataPY.GetIpyGameData("EquipStarUp", classLV, equipPlace, nextStar)
- if not ipyData:
- return result
- costEquipCnt = ipyData.GetCostEquipCnt()
- if clientData.CostEquipCnt < costEquipCnt:
- GameWorld.DebugLog(' 开始装备升星,装备材料不足 %s' % costEquipCnt)
- return result
- costEquipPlaceList = ipyData.GetCostEquipPlace()
- costEquipColorList = ipyData.GetCostEquipColor()
- isJobLimit = ipyData.GetIsJobLimit()
- suitTotalRate = ipyData.GetSuitTotalRate()
itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
- delEquipIndexList = []
- totalEquipStars = ChEquip.GetTotalEquipStars(curPlayer)
+ costEquipIndexList = clientData.CostEquipIndex
+ costEquipIDList = clientData.CostEquipID
+ autoBuy = clientData.AutoBuy
- if not costEquipCnt:
- curRate = 100
- else:
- curRate = 0 #成功概率
+ checkCostResult = __CheckCostInfo(curPlayer, classLV, equipPlace, curPartStar, costEquipIndexList, costEquipIDList, itemPack, autoBuy)
+ if not checkCostResult:
+ return
+ curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney = checkCostResult
+
+ if autoBuy:
+ isAutoBuyPreview = autoBuy == 2
+ # 概率未满 且 自动购买, 则需要执行拍卖行购买装备
+ if curRate < 100:
+ playerGoldPaper = curPlayer.GetGoldPaper()
+ queryData = [classLV, equipPlace, curPartStar, equipPackIndex, isAutoBuyPreview, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, playerGoldPaper]
+ PlayerAuctionHouse.QueryGameServer_AuctionHouse(playerID, "EquipStarAutoBuy", queryData)
+ return
- for i, index in enumerate(clientData.CostEquipIndex):
- costEquip = itemPack.GetAt(index)
- if not costEquip or costEquip.IsEmpty():
- return result
- equipID = costEquip.GetItemTypeID()
- if equipID != clientData.CostEquipID[i]:
- GameWorld.ErrLog(' 装备升星 客户端发的物品索引与实际物品ID不对应 index=%s,eatItemID=%s,wantEatItemID=%s' % (index, equipID, clientData.CostEquipID[i]))
- return result
- itemColor = costEquip.GetItemColor()
- equipPlace = costEquip.GetEquipPlace()
- if itemColor not in costEquipColorList:
- return result
- if equipPlace not in costEquipPlaceList:
- return result
- if isJobLimit and not ItemCommon.CheckJob(curPlayer, costEquip):
- return result
- delEquipIndexList.append(index)
- isSuite = 1 if costEquip.GetSuiteID() else 0
-
- ipyData = IpyGameDataPY.GetIpyGameData('EquipStarUpRate', ItemCommon.GetItemClassLV(costEquip),
- itemColor, equipPlace, isSuite
- )
- if not ipyData:
+ if lackItemCostMoney:
+ if isAutoBuyPreview:
+ # 满概率时自动购买必要材料的,暂不处理,前端自己判断就行
return
- curRate += ipyData.GetRate()
+
+ if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, lackItemCostMoney):
+ GameWorld.DebugLog("自动购买必要物品货币不足,无法升星! %s" % lackItemCostMoney, playerID)
+ return
+
+ elif lackItemCostMoney:
+ GameWorld.DebugLog("缺少必要物品,不自动购买,无法升星! %s" % lackItemCostMoney, playerID)
+ return
+
+ # 升星处理
+ buyEquipCostMoney = 0
+ __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney)
+ return
+
+def GameServer_EquipStarAutoBuy(curPlayer, result):
+ ## GameServer自动购买拍品结果返回
+ classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney = result
+ __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney)
+ return
+
+def __DoEquipStarUp(curPlayer, classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney):
+ ## 执行装备部位升星
+
+ playerID = curPlayer.GetPlayerID()
+ #自动购买货币
+ costMoneyTotal = lackItemCostMoney + buyEquipCostMoney
+ if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costMoneyTotal):
+ return
+
+ nextStar = curPartStar + 1
+ totalEquipStars = ChEquip.GetTotalEquipStars(curPlayer)
if totalEquipStars < IpyGameDataPY.GetFuncCfg('EquipStarCustomized'):
curRate = 100
- if curRate <= 0:
- GameWorld.Log('装备升星异常 概率为0!!equipPackIndex=%s'%equipPackIndex)
- return result
isOK = GameWorld.CanHappen(curRate, 100)
- #判断普通物品材料 成功才扣
- costItemDict = ipyData.GetCostItemDict()
- if isOK and costItemDict:
- delItemDict = {}
- for itemID, itemCnt in costItemDict.items():
- hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(itemID, itemPack, itemCnt)
- if not hasEnough:
- return result
- delItemDict[tuple(indexList)] = itemCnt
- for itemIndexList, delCnt in delItemDict.items():
- ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, delCnt, True, ChConfig.ItemDel_EquipStarUp)
- #扣装备
- ItemCommon.ReduceItem(curPlayer, itemPack, delEquipIndexList, len(delEquipIndexList), True, ChConfig.ItemDel_EquipStarUp)
+ GameWorld.DebugLog("装备升星最终总概率: %s, isOK=%s, lackItemCostMoney=%s,buyEquipCostMoney=%s"
+ % (curRate, isOK, lackItemCostMoney, buyEquipCostMoney), playerID)
+
+ itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
+ #扣材料物品,因为可能还需要先到GameServer,再回MapServer扣除物品,故中间过程物品位置可能发生变化,所以这里不能直接通过index去扣物品,需要重新精确定位
+ for delItemID, delCount in delItemInfoDict.items():
+ if not delCount:
+ continue
+ hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(delItemID, itemPack, delCount)
+ GameWorld.DebugLog(" 扣除道具: delItemID=%s,delCount=%s,indexList=%s" % (delItemID, delCount, indexList))
+ ItemCommon.ReduceItem(curPlayer, itemPack, indexList, delCount, True, ChConfig.ItemDel_EquipStarUp)
+
+ delItemByGUIDDict = {}
+ for index, itemGUID in delEquipGUIDDict.items():
+ delCnt = 1
+ curEquip = itemPack.GetAt(index)
+ if not ItemCommon.CheckItemCanUse(curEquip) or curEquip.GetGUID() != itemGUID:
+ delItemByGUIDDict[itemGUID] = delCnt
+ continue
+ GameWorld.DebugLog(" 扣除装备: index=%s, %s" % (index, itemGUID))
+ ItemCommon.DelItem(curPlayer, curEquip, delCnt, recordName=ChConfig.ItemDel_EquipStarUp)
+ if delItemByGUIDDict:
+ GameWorld.DebugLog(" 扣除装备位置错误,通过GUID补扣! %s" % delItemByGUIDDict)
+ ItemCommon.DelItemByGUID(curPlayer, itemPack, delItemByGUIDDict, recordName=ChConfig.ItemDel_EquipStarUp)
+
+ drDict = {"PlayerID":playerID, "AccID":curPlayer.GetAccID(), "classLV":classLV, "equipPlace":equipPlace, "IsSuccess":isOK,
+ "curRate":curRate, "nextStar":nextStar, 'totalEquipStars':totalEquipStars,
+ "lackItemCostMoney":lackItemCostMoney, "buyEquipCostMoney":buyEquipCostMoney}
+ if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costMoneyTotal, ChConfig.Def_Cost_EquipStar, drDict):
+ return
if isOK:
ChEquip.SetEquipPartStar(curPlayer, equipPackIndex, nextStar)
@@ -180,8 +172,150 @@
else:
result = ChConfig.Def_ComposeState_Fail
curPlayer.Sync_MakeItemAnswer(ShareDefine.Def_mitEquipStarUp, result)
- drDict = {"PlayerID":curPlayer.GetPlayerID(), "AccID":curPlayer.GetAccID(), "classLV":classLV, "equipPlace":equipPlace, "IsSuccess":isOK,
- "curRate":curRate, "nextStar":nextStar, 'totalEquipStars':totalEquipStars}
DataRecordPack.SendEventPack("EquipStarUp", drDict, curPlayer)
- return result
+
+ if not isOK:
+ return
+
+ EventShell.EventRespons_EquipStarUp(curPlayer)
+ updPartStar = ChEquip.GetEquipPartStar(curPlayer, equipPackIndex)
+ GameWorld.DebugLog(" 装备升星 equipPackIndex=%s result=%s,curPartStar=%s,updPartStar=%s" % (equipPackIndex, result, curPartStar, updPartStar), playerID)
+
+ # 成就
+ EquipStarSuccess(curPlayer, classLV)
+
+ # 星级变更时处理
+ # 刷新属性
+ ChEquip.RefreshPlayerEquipAttribute(curPlayer, classLV)
+ playControl = PlayerControl.PlayerControl(curPlayer)
+ playControl.RefreshPlayerAttrState()
+
+ if updPartStar in IpyGameDataPY.GetFuncEvalCfg('EquipPartStarNotify'):
+ equipPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
+ curEquip = equipPack.GetAt(equipPackIndex)
+ if ItemCommon.CheckItemCanUse(curEquip):
+ itemID = curEquip.GetItemTypeID()
+ userData = curEquip.GetUserData()
+ guid = ItemCommon.CacheNotifyEquipDetailInfo(curPlayer, curEquip)
+ msgParamList = [curPlayer.GetPlayerName(), itemID, userData, guid, updPartStar]
+ PlayerControl.WorldNotify(0, "StarLevelUp", msgParamList)
+
+ return
+
+def __CheckCostInfo(curPlayer, classLV, equipPlace, curPartStar, costEquipIndexList, costEquipIDList, itemPack, isAutoBuy):
+ nextStar = curPartStar + 1
+ ipyData = IpyGameDataPY.GetIpyGameData("EquipStarUp", classLV, equipPlace, nextStar)
+ if not ipyData:
+ return
+
+ costEquipCnt = ipyData.GetCostEquipCnt() # 是否消耗装备
+ costEquipPlaceList = ipyData.GetCostEquipPlace()
+ costEquipColorList = ipyData.GetCostEquipColor()
+ isJobLimit = ipyData.GetIsJobLimit()
+ delEquipGUIDDict = {}
+ totalEquipStars = ChEquip.GetTotalEquipStars(curPlayer)
+
+ if not costEquipCnt:
+ curRate = 100 # 不用消耗装备的默认满概率
+ else:
+ curRate = 0 #成功概率
+ diffClassChangeRatePerInfo = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 1)
+ unSuitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 2)
+ suitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 3)
+ if len(diffClassChangeRatePerInfo) != 2 or len(unSuitRateRange) != 2 or len(suitRateRange) != 2:
+ GameWorld.ErrLog('升星不同阶概率配置错误!')
+ return
+
+ for i, index in enumerate(costEquipIndexList):
+ costEquip = itemPack.GetAt(index)
+ if not costEquip or costEquip.IsEmpty():
+ return
+ equipID = costEquip.GetItemTypeID()
+ if equipID != costEquipIDList[i]:
+ GameWorld.ErrLog(' 装备升星 客户端发的物品索引与实际物品ID不对应 index=%s,eatItemID=%s,wantEatItemID=%s' % (index, equipID, costEquipIDList[i]))
+ return
+ costEquipColor = costEquip.GetItemColor()
+ costEquipPlace = costEquip.GetEquipPlace()
+ if costEquipColor not in costEquipColorList:
+ return
+ if costEquipPlace not in costEquipPlaceList:
+ return
+ if isJobLimit and not ItemCommon.CheckJob(curPlayer, costEquip):
+ return
+
+ if costEquip.GetSuiteID():
+ baseRate = ipyData.GetSuitRate()
+ minRate, maxRate = suitRateRange
+ else:
+ baseRate = ipyData.GetUnSuitRate()
+ minRate, maxRate = unSuitRateRange
+
+ GameWorld.DebugLog("equipID=%s,baseRate=%s,minRate=%s,maxRate=%s" % (equipID, baseRate, minRate, maxRate))
+ addRate = baseRate
+ costClassLV = ItemCommon.GetItemClassLV(costEquip)
+
+ #吞高阶
+ if costClassLV > classLV:
+ diffClassChangeRatePer = diffClassChangeRatePerInfo[0] * (costClassLV - classLV)
+ addRate = int(math.ceil(round(baseRate * (100 + diffClassChangeRatePer) / 100.0, 2)))
+ GameWorld.DebugLog(" 吞高阶 costClassLV=%s,classLV=%s,diffClassChangeRatePer=%s,addRate=%s" % (costClassLV, classLV, diffClassChangeRatePer, addRate))
+ #吞低阶
+ elif costClassLV < classLV:
+ diffClassChangeRatePer = diffClassChangeRatePerInfo[1] * (classLV - costClassLV)
+ addRate = int(math.ceil(round(baseRate * (100 - diffClassChangeRatePer) / 100.0, 2)))
+ GameWorld.DebugLog(" 吞低阶 costClassLV=%s,classLV=%s,diffClassChangeRatePer=%s,addRate=%s" % (costClassLV, classLV, diffClassChangeRatePer, addRate))
+ addRate = max(minRate, min(addRate, maxRate))
+ curRate += addRate
+ GameWorld.DebugLog(" 本件装备增加概率=%s,当前总概率=%s" % (addRate, curRate))
+ delEquipGUIDDict[index] = costEquip.GetGUID()
+
+ delItemInfoDict = {}
+ lackItemCostMoney = 0
+ costItemDict = ipyData.GetCostItemDict()
+ if costItemDict:
+ for itemID, itemCnt in costItemDict.items():
+ hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(itemID, itemPack, itemCnt)
+ if not hasEnough:
+ if not isAutoBuy:
+ GameWorld.DebugLog(" 缺少必要物品,不自动购买!itemID=%s,lackCnt=%s" % (itemID, lackCnt))
+ return
+ itemGoldPaper = ItemCommon.GetShopItemPrice(itemID, IPY_GameWorld.TYPE_Price_Gold_Paper)
+ if not itemGoldPaper:
+ GameWorld.DebugLog(" 找不到物品自动购买消耗货币!itemID=%s,lackCnt=%s" % (itemID, lackCnt))
+ return
+ lackItemCostMoney += itemGoldPaper * lackCnt
+ delCount = itemCnt - lackCnt
+ GameWorld.DebugLog(" 缺少必要物品: itemID=%s,lackMoney(%s)*Count(%s)=%s" % (itemID, itemGoldPaper, lackCnt, itemGoldPaper * lackCnt))
+ else:
+ delCount = itemCnt
+ delItemInfoDict[itemID] = delCount
+
+ if totalEquipStars < IpyGameDataPY.GetFuncCfg('EquipStarCustomized'):
+ curRate = 100
+ #if curRate <= 0:
+ # GameWorld.ErrLog('装备升星异常 概率为0!!classLV=%s, equipPlace=%s' % (classLV, equipPlace))
+ # return
+ if curRate >= IpyGameDataPY.GetFuncCfg("EquipStarRate", 4): # 优化高概率体验
+ curRate = 100
+
+ return curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney
+
+
+def EquipStarSuccess(curPlayer, classLV):
+ ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition('EquipPlaceIndexMap', {'ClassLV':classLV}, True)
+ if not ipyDataList:
+ return
+
+ starCountDict = {}
+ for ipyData in ipyDataList:
+ index = ipyData.GetGridIndex()
+ equipStar = ChEquip.GetEquipPartStar(curPlayer, index)
+ if not equipStar:
+ continue
+ conditionKey = (classLV, equipStar)
+ starCountDict[conditionKey] = starCountDict.get(conditionKey, 0) + 1
+
+ #GameWorld.DebugLog("升星成就数据: classLV=%s,starCountDict=%s" % (classLV, starCountDict))
+ PlayerSuccess.UpdateSuccessProgressByConditions(curPlayer, ShareDefine.SuccType_EquipStar, starCountDict)
+ return
--
Gitblit v1.8.0