From f355e99a5f181ca869bdddf79fec1a27f237d194 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期二, 10 九月 2024 11:13:47 +0800 Subject: [PATCH] 10264 【越南】【砍树】BOSS凭证掉落新增个人BOSS --- ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py | 252 ++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 192 insertions(+), 60 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py index 7af148d..e03977e 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py @@ -20,6 +20,7 @@ import PyDataManager import ChPyNetSendPack import PyGameDataStruct +import PlayerCompensation import PlayerViewCache import PlayerDBGSEvent import PlayerControl @@ -42,6 +43,7 @@ # 物品实例额外属性名 MineItemAttr_MoveSpeed = "MoveSpeed" MineItemAttr_EndTime = "EndTime" +MineItemAttr_HelpTick = "HelpTick" # 物品类型 MineType_Normal = 0 # 常规物品 @@ -226,6 +228,7 @@ # 不入库的属性 setattr(mineItemData, MineItemAttr_EndTime, 0) setattr(mineItemData, MineItemAttr_MoveSpeed, 0) + setattr(mineItemData, MineItemAttr_HelpTick, 0) return def GetMineItem(self, playerID, index): @@ -282,21 +285,61 @@ mineItemData.clear() pos += mineItemData.readData(datas, pos, dataslen) - OnLoadMineItemData(mineItemData) + playerID = mineItemData.PlayerID + index = mineItemData.Index + if playerID not in self.playerMineItemDict: + self.playerMineItemDict[playerID] = {} + itemDict = self.playerMineItemDict[playerID] + itemDict[index] = mineItemData + # 启动直接覆盖同玩家索引位数据,这里存在一个问题,合服后假人玩家ID是重复的,一般是新服的替换旧服的假人 OnLoadMineItemOK() return pos + +def DoOnDayEx(): + if GameWorld.IsCrossServer(): + return + ''' + 待处理:合服本身会删除部分玩家数据,之后如果多次合服后数据量较大再考虑处理 + 1. 删除1星期前的自己拉物品记录,至少保留最近10条被人抢记录 + 2. 删除1星期前未领取的奖励记录 + 3. 清除超过1星期没有更新福地记录的玩家数据,保底保留x个玩家 + ''' +# socialAreaMax = IpyGameDataPY.GetFuncCfg("MineAreaRob", 1) # 道友福地个数 +# inValidSeconds = 7 * 24 * 3600 +# curTime = int(time.time()) +# outofDateTime = curTime - inValidSeconds +# delPlayerIDList = [] +# recordMgr = PyDataManager.GetDBPyMineAreaRecordManager() +# for playerID, recordList in recordMgr.playerMineRecordListDict.items(): +# isActiveAreaPlayer = False +# beRobbedPlayerIDList = [] +# for recordData in recordList[::-1]: # 反序处理 +# if recordData.RecordTime > outofDateTime: +# isActiveAreaPlayer = True # 近期内还有记录的视为福地活跃玩家,无论主动或被抢记录 +# if recordData.RecordType == MineAreaRecordType_BeRobbed: +# # 至少保留被x个不同玩家抢的记录,用于更新关心道友福地 +# tagPlayerID = recordData.TagPlayerID +# if len(beRobbedPlayerIDList) < socialAreaMax and tagPlayerID not in beRobbedPlayerIDList: +# beRobbedPlayerIDList.append(tagPlayerID) +# continue +# if recordData.RecordTime <= outofDateTime: +# recordList.remove(recordData) # 删除过期数据 +# +# if not isActiveAreaPlayer: +# if playerID not in delPlayerIDList: +# delPlayerIDList.append(playerID) + return def DoMineAreaFuncOpen(curPlayer): ## 福地功能开启 playerID = curPlayer.GetPlayerID() - mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() - # 还没有福地物品数据,则刷新初始化 - if playerID not in mineItemMgr.playerMineItemDict: - __DoMineItemRefresh(playerID, curPlayer) + __DoMineItemRefresh(playerID, curPlayer) return def OnPlayerLogin(curPlayer): + if GameWorld.IsCrossServer(): + return playerID = curPlayer.GetPlayerID() # 自己福地数据 @@ -315,43 +358,10 @@ return -def OnLoadMineItemData(mineItemData): - ## 加载矿物 - playerID = mineItemData.PlayerID - index = mineItemData.Index - mineID = mineItemData.MineID - if not mineID: - return - mineType = mineItemData.MineType - workerCount = mineItemData.WorkerCount - robPlayerID = mineItemData.RobPlayerID - robWorkerCount = mineItemData.RobWorkerCount - - mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() - - if playerID not in mineItemMgr.playerMineItemDict: - mineItemMgr.playerMineItemDict[playerID] = {} - itemDict = mineItemMgr.playerMineItemDict[playerID] - itemDict[index] = mineItemData - mineItemMgr.AddMineAreaPlayerID(playerID) - - if mineType == MineType_Super and not workerCount and not robWorkerCount and mineItemData not in mineItemMgr.freeSuperItemList: - mineItemMgr.freeSuperItemList.append(mineItemData) - - if workerCount: - mineItemMgr.AddPlayerPullingItem(playerID, mineItemData) - - if robPlayerID and robWorkerCount: - mineItemMgr.AddPlayerPullingItem(robPlayerID, mineItemData) - - __RefreshMineItemSpeed(mineItemData) - return - def OnLoadMineItemOK(): - __SortMineItem() - __MakeFackArea() + if GameWorld.IsCrossServer(): + return - # 启动默认补充空位置物品... refreshIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1)) mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() for areaPlayerID, itemDict in mineItemMgr.playerMineItemDict.items(): @@ -364,11 +374,32 @@ if not mineItemData or not mineItemData.MineID: emptyIndexList.append(index) continue - if not emptyIndexList: - continue - GameWorld.DebugLog("启动默认补充空位置物品: areaPlayerID=%s,emptyIndexList=%s" % (areaPlayerID, emptyIndexList)) - __DoMineItemRefresh(areaPlayerID, refreshIndexList=emptyIndexList) - + + # 矿物初始数据处理 + mineType = mineItemData.MineType + workerCount = mineItemData.WorkerCount + robPlayerID = mineItemData.RobPlayerID + robWorkerCount = mineItemData.RobWorkerCount + + mineItemMgr.AddMineAreaPlayerID(areaPlayerID) + + if mineType == MineType_Super and not workerCount and not robWorkerCount and mineItemData not in mineItemMgr.freeSuperItemList: + mineItemMgr.freeSuperItemList.append(mineItemData) + + if workerCount: + mineItemMgr.AddPlayerPullingItem(areaPlayerID, mineItemData) + + if robPlayerID and robWorkerCount: + mineItemMgr.AddPlayerPullingItem(robPlayerID, mineItemData) + + __RefreshMineItemSpeed(mineItemData) + + if emptyIndexList: + GameWorld.DebugLog("启动默认补充空位置物品: areaPlayerID=%s,emptyIndexList=%s" % (areaPlayerID, emptyIndexList)) + __DoMineItemRefresh(areaPlayerID, refreshIndexList=emptyIndexList) + + __SortMineItem() + __MakeFackArea() return def __MakeFackArea(): @@ -397,7 +428,7 @@ playerID = mineItemData.PlayerID index = mineItemData.Index mineID = mineItemData.MineID - curPos = GameWorld.ToIntDef(mineItemData.Position, Def_PositionMid) + curPos = GameWorld.ToFloat(mineItemData.Position, Def_PositionMid) if not playerID or not mineID: return curPos @@ -405,7 +436,7 @@ robWorkerCount = mineItemData.RobWorkerCount if not curWorkerCount and not robWorkerCount: return curPos - moveSpeed = getattr(mineItemData, MineItemAttr_MoveSpeed) + moveSpeed = getattr(mineItemData, MineItemAttr_MoveSpeed, 0) if not moveSpeed: return curPos passSeconds = curTime - mineItemData.UpdTime @@ -430,7 +461,7 @@ if not playerID or not mineID: return - curPos = GameWorld.ToIntDef(mineItemData.Position, Def_PositionMid) + curPos = GameWorld.ToFloat(mineItemData.Position, Def_PositionMid) allMineItemByEndTimeList = PyDataManager.GetDBPyMineAreaItemManager().allMineItemByEndTimeList curWorkerCount = mineItemData.WorkerCount robWorkerCount = mineItemData.RobWorkerCount @@ -499,6 +530,9 @@ battleRatio = workerBattleRatioList[len(workerBattleRatioList) - 1] if batWorkerCount > len(workerBattleRatioList) else workerBattleRatioList[batWorkerCount - 1] needSeconds = int(dist * itemWeight * baseTime * workRatio * battleRatio) # 还需工作时长,秒 + if needSeconds <= 0: + return 0, 0 + moveSpeed = dist / float(needSeconds) # 移动速度 x格/秒 needHms = "%02d:%02d:%02d" % (needSeconds / 3600, needSeconds % 3600 / 60, needSeconds % 60) @@ -525,15 +559,11 @@ GameWorld.Log("福地系统定时刷新! %s" % str(curHourMinute)) mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() for playerID in mineItemMgr.playerMineItemDict.keys(): - __DoMineItemRefresh(playerID, isSuper=True) + __DoMineItemRefresh(playerID, isSys=True) return def OnMineItemTimeProcess(curTime, tick): ## 定时处理,每秒触发一次 - - # 待优化处理... - # 定时删除多余数据,如过天处理,多余记录 - # 合服多余数据清理,合服假人ID重复问题 mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() __Process_EndItemRefresh(mineItemMgr.endSelfItemList, IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 2), curTime) @@ -606,7 +636,7 @@ while doCount > 0 and allMineItemByEndTimeList: doCount -= 1 mineItemData = allMineItemByEndTimeList[index] - endTime = getattr(mineItemData, MineItemAttr_EndTime) + endTime = getattr(mineItemData, MineItemAttr_EndTime, 0) if curTime < endTime: break @@ -761,6 +791,107 @@ mineItemMgr.socialIDListDict[playerID] = socialIDList return socialIDList +def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList): + + # 摇人帮助请求、自己驱赶请求 + if funcLineID == 0 or funcLineID == 1: + return __OnMineHelpRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList) + + return + +def OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList): + + # 摇人帮助结果、自己驱赶结果 + if funcLineID == 0 or funcLineID == 1: + return __OnMineHelpOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList) + + return + +def __OnMineHelpRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList): + # 摇人帮助请求、自己驱赶请求 + playerID = curPlayer.GetPlayerID() + if not valueList or len(valueList) < 2: + GameWorld.DebugLog("没有指定valueList!", playerID) + return + areaPlayerID = valueList[0] + itemIndex = valueList[1] + + if funcLineID == 0: + if playerID == areaPlayerID: + GameWorld.DebugLog("不能帮助自己! areaPlayerID=%s" % areaPlayerID, playerID) + return + elif funcLineID == 1: + if playerID != areaPlayerID: + GameWorld.DebugLog("不是自己的福地,无法自己驱赶! areaPlayerID=%s" % areaPlayerID, playerID) + return + + mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() + mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex) + mineID = mineItemData.MineID + if not mineID: + # 该资源已消失 + PlayerControl.NotifyCode(curPlayer, "MineDisappeared") + return + + robPlayerID = mineItemData.RobPlayerID + if not robPlayerID or robPlayerID != tagPlayerID: + # 当前资源无争夺者或已被其他玩家完成 + PlayerControl.NotifyCode(curPlayer, "MineHelpFinished") + return + + tick = GameWorld.GetGameWorld().GetTick() + helpTick = getattr(mineItemData, MineItemAttr_HelpTick, 0) + if helpTick and tick - helpTick < 10000: + GameWorld.DebugLog("已经有其他人在帮助中!", playerID) + return + setattr(mineItemData, MineItemAttr_HelpTick, tick) + + return True + +def __OnMineHelpOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList): + # 摇人帮助结果、自己驱赶结果 + + playerID = curPlayer.GetPlayerID() + helpPlayerName = curPlayer.GetName() + + areaPlayerID = valueList[0] + itemIndex = valueList[1] + isWin = fightRet[0] + + mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager() + mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex) + setattr(mineItemData, MineItemAttr_HelpTick, 0) + + if not isWin: + #GameWorld.DebugLog("帮助失败") + return + + robPlayerID = mineItemData.RobPlayerID + # 赶走抢夺者 + if robPlayerID and robPlayerID == tagPlayerID: + __DoCancelPull(tagPlayerID, areaPlayerID, itemIndex) + + # 帮助的发奖 + if funcLineID == 0: + robCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(tagPlayerID)) + robPlayerName = robCacheDict.get("Name", "") + + areaCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID)) + areaPlayerName = areaCacheDict.get("Name", "") + + # 邮件发放奖励 + PlayerCompensation.SendMailByKey("MineHelpAward", [playerID], awardItemList, [areaPlayerName, robPlayerName]) + + # 通知福地玩家 + PlayerCompensation.SendMailByKey("MineHelpReqOK", [areaPlayerID], [], [helpPlayerName, robPlayerName]) + + # 自己驱赶的 + elif funcLineID == 1: + # 自己驱赶的,不用再通知地图,直接return + return + + return True + def MapServer_MineArea(curPlayer, msgList): mapID = curPlayer.GetRealMapID() playerID = curPlayer.GetPlayerID() @@ -773,7 +904,7 @@ # 拉物品 if msgType == "Pull": - __DoPullItem(playerID, curPlayer, dataMsg) + ret = __DoPullItem(playerID, curPlayer, dataMsg) # 刷新福地物品 elif msgType == "MineItemRefresh": @@ -844,7 +975,7 @@ if isPreview: ## 预览速度时间 - curPos = GameWorld.ToIntDef(mineItemData.Position, Def_PositionMid) + curPos = GameWorld.ToFloat(mineItemData.Position, Def_PositionMid) if playerID == areaPlayerID: curWorkerCount = assignWorkerCount curWorkerState = workerState @@ -886,7 +1017,7 @@ __RefreshMineItemSpeed(mineItemData, True) SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx) - return + return True def __DoCancelPull(playerID, areaPlayerID, itemIndex): ## 取消拉取 @@ -1161,7 +1292,8 @@ neighborIDList = mineItemMgr.neighborIDListDict.get(playerID, []) if not neighborIDList: - random.shuffle(mineItemMgr.realAreaPlayerIDList) + # 优先随机真人 + random.shuffle(mineItemMgr.realAreaPlayerIDList) random.shuffle(mineItemMgr.fackAreaPlayerIDList) areaPlayerIDList = mineItemMgr.realAreaPlayerIDList + mineItemMgr.fackAreaPlayerIDList if playerID in areaPlayerIDList: @@ -1232,9 +1364,9 @@ mineItem.UpdTime = mineItemData.UpdTime mineItem.Position = mineItemData.Position mineItem.PosLen = len(mineItem.Position) - mineItem.MoveSpeed = "%s" % getattr(mineItemData, MineItemAttr_MoveSpeed) + mineItem.MoveSpeed = "%s" % getattr(mineItemData, MineItemAttr_MoveSpeed, 0) mineItem.SpeedLen = len(mineItem.MoveSpeed) - mineItem.EndTime = getattr(mineItemData, MineItemAttr_EndTime) + mineItem.EndTime = getattr(mineItemData, MineItemAttr_EndTime, 0) mineItem.WorkerCount = mineItemData.WorkerCount mineItem.RobPlayerID = mineItemData.RobPlayerID mineItem.RobWorkerCount = mineItemData.RobWorkerCount -- Gitblit v1.8.0