From f57e8ca8c2c367578d5e7a358aa44f7b7cadf3bb Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 28 四月 2025 15:00:07 +0800
Subject: [PATCH] 10367 【越南】【英语】【BT】【砍树】仙盟攻城战-服务端(FamilyGCZ命令支持技能攻击)

---
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py |  460 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 325 insertions(+), 135 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
index 7af148d..e22fe79 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldMineArea.py
@@ -15,11 +15,13 @@
 #"""Version = 2024-03-07 19:30"""
 #-------------------------------------------------------------------------------
 
+import ChConfig
 import GameWorld
 import NetPackCommon
 import PyDataManager
 import ChPyNetSendPack
 import PyGameDataStruct
+import PlayerCompensation
 import PlayerViewCache
 import PlayerDBGSEvent
 import PlayerControl
@@ -42,6 +44,7 @@
 # 物品实例额外属性名
 MineItemAttr_MoveSpeed = "MoveSpeed"
 MineItemAttr_EndTime = "EndTime"
+MineItemAttr_HelpTick = "HelpTick"
 
 # 物品类型
 MineType_Normal = 0 # 常规物品
@@ -163,7 +166,6 @@
         self.viewAreaPlayerIDDict = {} # 正在查看某个福地中的玩家ID {areaPlayerID:[viewPlayerID, ...], ...}
         
         self.neighborIDListDict = {} # 玩家周围福地玩家ID列表 {playerID:[playerID, ...], ...}
-        self.socialIDListDict = {} # 玩家有关系道友福地玩家ID列表 {playerID:[playerID, ...], ...} playerID列表倒序
         return
     
     def AddViewAreaPlayerID(self, viewPlayerID, areaPlayerID):
@@ -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
         
@@ -671,6 +701,8 @@
     AddMineItemRecord(awardPlayerID, MineAreaRecordType_Pull, areaPlayerID, mineID, curTime)
     if areaPlayerID != awardPlayerID:
         AddMineItemRecord(areaPlayerID, MineAreaRecordType_BeRobbed, awardPlayerID, mineID, curTime)
+        DecRobValue(awardPlayerID, areaPlayerID, 1)
+        AddRobValue(areaPlayerID, awardPlayerID, 1)
         
         # 被抢的
         if IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 3) > 0:
@@ -706,60 +738,199 @@
     recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()
     recordList = recordMgr.AddPlayerRecord(recordData)
     
-    # 被人抢,更新关系福地ID记录
-    if recordData.RecordType == MineAreaRecordType_BeRobbed:
-        __DoUpdSocialPlayerIDList(playerID)
-    
     if len(recordList) > Def_RecordMax:
         recordList.pop(0) # 删除最早一条
     return
 
-def __DoUpdSocialPlayerIDList(playerID):
-    ## 更新有关系的道友ID列表
-    recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()
-    recordList = recordMgr.playerMineRecordListDict.get(playerID, [])
-    
-    socialAreaMax = IpyGameDataPY.GetFuncCfg("MineAreaRob", 1) # 道友福地个数
-    socialIDList = [] # 反序
-    for recData in recordList[::-1]:
-        if recData.RecordType != MineAreaRecordType_BeRobbed:
-            ## 优先保留被抢记录关系玩家
+def DecRobValue(playerID, tagPlayerID, decValue):
+    ## 减少敌对值
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, False)
+    if not robRecData:
+        GameWorld.DebugLog("没有敌对福地记录!", playerID)
+        return 0
+    # 抢劫的人减少与对方敌对值
+    setRobValue = 0
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("减少与对方敌对值: tagPlayerID=%s,decValue=%s" % (tagPlayerID, decValue), playerID)
+    GameWorld.DebugLog("    bef robValueList=%s" % robValueList, playerID)
+    for index, robValueInfo in enumerate(robValueList):
+        robValue, pID = robValueInfo
+        if pID != tagPlayerID:
             continue
-        if recData.TagPlayerID not in socialIDList:
-            socialIDList.append(recData.TagPlayerID)
-            if len(socialIDList) >= socialAreaMax:
-                break
-            
+        robValue -= decValue
+        GameWorld.DebugLog("    tagPlayerID=%s,更新敌对值=%s" % (tagPlayerID, robValue), playerID)
+        if robValue <= 0:
+            robValueList.pop(index)
+        else:
+            robValueList[index] = [robValue, pID]
+        setRobValue = robValue
+        robRecData.SetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, robValueList, True)
+        break
+    
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("    aft robValueList=%s" % robValueList, playerID)
+    return setRobValue
+
+def AddRobValue(playerID, tagPlayerID, addValue):
+    ## 被抢的人增加与对方敌对值,并置顶
+    
+    if playerID <= Def_FakeAreaCount:
+        return 0
+    
+    GameWorld.DebugLog("增加与对方敌对值: tagPlayerID=%s,addValue=%s" % (tagPlayerID, addValue), playerID)
+    setRobValue = 0
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, True)
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("    bef robValueList=%s" % robValueList, playerID)
+    for index, robValueInfo in enumerate(robValueList):
+        robValue, pID = robValueInfo
+        if pID != tagPlayerID:
+            continue
+        robValueList.pop(index)
+        setRobValue = robValue
+        break
+    setRobValue += addValue
+    GameWorld.DebugLog("    tagPlayerID=%s,更新敌对值=%s" % (tagPlayerID, setRobValue), playerID)
+    
+    robValueList.insert(0, [setRobValue, tagPlayerID])
+    robRecData.SetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, robValueList)
+    
+    robValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    GameWorld.DebugLog("    aft robValueList=%s" % robValueList, playerID)    
+    return setRobValue
+
+def GetRobPlayerIDList(playerID):
+    ## 获取敌对玩家ID列表
+    if playerID <= Def_FakeAreaCount:
+        return []
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, False)
+    if not robRecData:
+        return []
+    robIDList = []
+    rPlayerRobValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    for robValueInfo in rPlayerRobValueList:
+        _, pID = robValueInfo
+        robIDList.append(pID)
+    return robIDList
+
+def GetRobValueDict(playerID):
+    ## 获取敌对玩家敌对值字典
+    if playerID <= Def_FakeAreaCount:
+        return {}
+    playerRecMgr = PyDataManager.GetDBPlayerRecDataManager()
+    robRecData = playerRecMgr.GetPlayerRecDataFirst(ShareDefine.Def_PlayerRecType_MineAreaRecord, playerID, False)
+    if not robRecData:
+        return {}
+    robValueDict = {}
+    rPlayerRobValueList = robRecData.GetUserDataByKey(ChConfig.Def_RecDataKey_RobValueList, [])
+    for robValueInfo in rPlayerRobValueList:
+        robValue, pID = robValueInfo
+        robValueDict[pID] = robValue
+    return robValueDict
+
+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()
-    socialIDListBef = mineItemMgr.socialIDListDict.get(playerID, [])
-    # 优先使用历史记录
-    if len(socialIDList) < socialAreaMax:
-        for socialIDBef in socialIDListBef:
-            if socialIDBef not in socialIDList:
-                socialIDList.append(socialIDBef)
-                if len(socialIDList) >= socialAreaMax:
-                    break
-                
-    # 优先随机真人
-    if len(socialIDList) < socialAreaMax and mineItemMgr.realAreaPlayerIDList:
-        random.shuffle(mineItemMgr.realAreaPlayerIDList)
-        for areaPlayerID in mineItemMgr.realAreaPlayerIDList:
-            if areaPlayerID not in socialIDList and areaPlayerID != playerID:
-                socialIDList.append(areaPlayerID)
-                if len(socialIDList) >= socialAreaMax:
-                    break
-                
-    # 不够补充假人
-    if len(socialIDList) < socialAreaMax and mineItemMgr.fackAreaPlayerIDList:
-        random.shuffle(mineItemMgr.fackAreaPlayerIDList)
-        for areaPlayerID in mineItemMgr.fackAreaPlayerIDList:
-            if areaPlayerID not in socialIDList:
-                socialIDList.append(areaPlayerID)
-                if len(socialIDList) >= socialAreaMax:
-                    break
-                
-    mineItemMgr.socialIDListDict[playerID] = socialIDList
-    return socialIDList
+    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, "out")
+    
+    # 帮助的发奖
+    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()
@@ -773,16 +944,22 @@
     
     # 拉物品
     if msgType == "Pull":
-        __DoPullItem(playerID, curPlayer, dataMsg)
+        ret = __DoPullItem(playerID, curPlayer, dataMsg)
 
     # 刷新福地物品
     elif msgType == "MineItemRefresh":
         playerID, isSuper = dataMsg
-        __DoMineItemRefresh(playerID, curPlayer, isSuper=isSuper)
+        __DoMineItemRefresh(playerID, curPlayer, isSuper=isSuper, queryType=99, queryValue=isSuper)
 
     # 地图结算奖励OK
     elif msgType == "MineAreaAwardGetOK":
         __DoMineAreaAwardGetOK(curPlayer, dataMsg)
+        
+    # 刷新周围玩家
+    elif msgType == "MineRobRefresh":
+        tick = GameWorld.GetGameWorld().GetTick()
+        queryType, queryValue = 3, 1
+        SyncNeighborAreaInfo(curPlayer, tick, queryType, queryValue)
         
     if ret == None:
         return
@@ -795,7 +972,7 @@
         return
     if workerCount <= 0:
         if not isPreview:
-            __DoCancelPull(playerID, areaPlayerID, itemIndex)
+            __DoCancelPull(playerID, areaPlayerID, itemIndex, "cancel")
         return
     GameWorld.DebugLog("请求福地拉物品! areaPlayerID=%s,itemIndex=%s,workerCount=%s,workerState=%s,workerTotal=%s,isPreview=%s" 
                        % (areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview), playerID)
@@ -844,7 +1021,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,9 +1063,9 @@
     __RefreshMineItemSpeed(mineItemData, True)
     
     SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)
-    return
+    return [areaPlayerID]
 
-def __DoCancelPull(playerID, areaPlayerID, itemIndex):
+def __DoCancelPull(playerID, areaPlayerID, itemIndex, reason=""):
     ## 取消拉取
     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
     mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)
@@ -923,9 +1100,12 @@
         __RefreshMineItemSpeed(mineItemData, True)
         
     SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)
+    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+    if curPlayer:
+        MapServer_QueryPlayerResult(curPlayer, "MineAreaCancelPull", [areaPlayerID, reason])
     return
 
-def __DoMineItemRefresh(areaPlayerID, areaPlayer=None, isSys=False, isSuper=False, isNotify=True, refreshIndexList=None, setPosition=None, setItemLV=None, setMineID=None):
+def __DoMineItemRefresh(areaPlayerID, areaPlayer=None, isSys=False, isSuper=False, isNotify=True, refreshIndexList=None, setPosition=None, setItemLV=None, setMineID=None, queryType=0, queryValue=0):
     '''刷新福地物品
     @param areaPlayerID: 福地玩家ID,可能是假人
     @param areaPlayer: 福地玩家实例
@@ -1024,7 +1204,7 @@
         GameWorld.DebugLog("    index=%s,randMineID=%s,position=%s,mineType=%s,itemLV=%s" % (index, randMineID, position, mineType, itemLV), areaPlayerID)
         
     if isNotify and refreshDict:
-        SyncMineAreaItemInfo(areaPlayerID, refreshDict.keys())
+        SyncMineAreaItemInfo(areaPlayerID, refreshDict.keys(), queryType=queryType, queryValue=queryValue)
     return refreshDict
 
 #// B0 33 福地查看 #tagCGMineAreaView
@@ -1061,6 +1241,7 @@
                 
     # 查看周围随机福地列表
     elif queryType == 3:
+        queryValue = 0 # GameServer默认只给查询,刷新列表改为从MapServer发起 B0 31 福地物品刷新 #tagCMMineItemRefresh 请求
         SyncNeighborAreaInfo(curPlayer, tick, queryType, queryValue)
         
     # 退出他人福地
@@ -1073,7 +1254,7 @@
         
     return
 
-def SyncMineAreaItemInfo(areaPlayerID, mineIndexList, notifyPlayerIDListEx=None):
+def SyncMineAreaItemInfo(areaPlayerID, mineIndexList, notifyPlayerIDListEx=None, queryType=0, queryValue=0):
     '''某个福地物品变更时同步,会同步给相关玩家
     @param areaPlayerID: 福地玩家ID,可能是假人
     @param mineIndexList: 需要同步的矿物索引
@@ -1090,9 +1271,9 @@
         notifyPlayerIDList.append(areaPlayerID)
         
     # 列表中
-    for playerID, socialIDList in mineItemMgr.socialIDListDict.items():
-        if areaPlayerID in socialIDList:
-            notifyPlayerIDList.append(playerID)
+    robPlayerIDList = GetRobPlayerIDList(areaPlayerID)
+    if robPlayerIDList:
+        notifyPlayerIDList += robPlayerIDList
     for playerID, neighborIDList in mineItemMgr.neighborIDListDict.items():
         if areaPlayerID in neighborIDList:
             notifyPlayerIDList.append(playerID)
@@ -1114,7 +1295,7 @@
     if not notifyPlayerIDList:
         return
     
-    clientPack = __GetMineAreaInfoPack([[areaPlayerID, mineIndexList]])
+    clientPack = __GetMineAreaInfoPack([[areaPlayerID, mineIndexList]], queryType=queryType, queryValue=queryValue)
     # 去重同步
     playerManager = GameWorld.GetPlayerManager()
     for playerID in set(notifyPlayerIDList):
@@ -1129,16 +1310,12 @@
     return
 
 def SyncSocialAreaInfo(curPlayer, queryType=0, queryValue=0):
-    ## 同步有关系的道友福地列表
+    ## 同步有关系的道友福地列表 - 敌对列表
     playerID = curPlayer.GetPlayerID()
-    mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()
-    if playerID in mineItemMgr.socialIDListDict:
-        socialIDList = mineItemMgr.socialIDListDict[playerID]
-    else:
-        socialIDList = __DoUpdSocialPlayerIDList(playerID)
-        
+    socialIDList = GetRobPlayerIDList(playerID)
+    robValueDict = GetRobValueDict(playerID)
     areaMineList = [[areaPlayerID, []] for areaPlayerID in socialIDList]
-    clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)
+    clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue, robValueDict)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
 
@@ -1161,7 +1338,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:
@@ -1170,9 +1348,14 @@
             if neighborIDBef in areaPlayerIDList:
                 areaPlayerIDList.remove(neighborIDBef)
         neighborCount = IpyGameDataPY.GetFuncCfg("MineAreaRob", 2)
+        realmLV = curPlayer.GetOfficialRank()
+        officialNeighborCountList = IpyGameDataPY.GetFuncEvalCfg("MineAreaRob2", 1)
+        for needRLV, nCount in officialNeighborCountList:
+            if realmLV >= needRLV:
+                neighborCount = nCount
         neighborIDList = areaPlayerIDList[:neighborCount]
         mineItemMgr.neighborIDListDict[playerID] = neighborIDList
-        GameWorld.DebugLog("刷新周围随机福地: %s" % neighborIDList, playerID)
+        GameWorld.DebugLog("刷新周围随机福地: realmLV=%s,neighborCount=%s,%s" % (realmLV, neighborCount, neighborIDList), playerID)
         
     areaMineList = [[areaPlayerID, []] for areaPlayerID in neighborIDList]
     clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)
@@ -1203,7 +1386,7 @@
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return
 
-def __GetMineAreaInfoPack(areaMineList, queryType=0, queryValue=0):
+def __GetMineAreaInfoPack(areaMineList, queryType=0, queryValue=0, robValueDict=None):
     ''' 获取同步福地详细信息包
     @param areaMineList: [[areaPlayerID, mineIndexList], ...] 按指定福地ID顺序列表获取,mineIndexList为空时同步该福地全部物品,否则只同步指定索引物品
     '''
@@ -1218,8 +1401,11 @@
         if areaPlayerID > Def_FakeAreaCount:
             cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))
             areaInfo.PlayerName = cacheDict.get("Name", "")
+            areaInfo.Job = cacheDict.get("Job", 0)
             areaInfo.Face = cacheDict.get("Face", 0)
-                    
+            areaInfo.FacePic = cacheDict.get("FacePic", 0)
+            areaInfo.RobValue = robValueDict.get(areaPlayerID, 0) if robValueDict else 0 # 敌对值,前端仅queryType为2时才更新敌对值
+            
         areaInfo.MineItemList = []
         if not mineIndexList:
             mineIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))
@@ -1232,16 +1418,18 @@
             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
             if mineItemData.RobPlayerID:
                 robCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(mineItemData.RobPlayerID))
                 mineItem.RobPlayerName = robCacheDict.get("Name", "")
+                mineItem.RobJob = robCacheDict.get("Job", 0)
                 mineItem.RobFace = robCacheDict.get("Face", 0)
+                mineItem.RobFacePic = robCacheDict.get("FacePic", 0)
             areaInfo.MineItemList.append(mineItem)
         areaInfo.MineCount = len(areaInfo.MineItemList)
         
@@ -1265,7 +1453,9 @@
         if playerID != recordInfo.TagPlayerID and recordInfo.TagPlayerID > Def_FakeAreaCount:
             tagCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(recordInfo.TagPlayerID))
             recordInfo.TagPlayerName = tagCacheDict.get("Name", "")
+            recordInfo.TagJob = tagCacheDict.get("Job", 0)
             recordInfo.TagFace = tagCacheDict.get("Face", 0)
+            recordInfo.TagFacePic = tagCacheDict.get("FacePic", 0)
         clientPack.AreaRecordList.append(recordInfo)
     clientPack.RecordCount = len(clientPack.AreaRecordList)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
@@ -1305,7 +1495,7 @@
         itemCount = ipyData.GetItemCount()
         itemLV = ipyData.GetItemLV()
         awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount
-        awardInfoList.append([GUID, awardTime, workerCount, areaPlayerID, mineID, itemLV, itemID, itemCount])
+        awardInfoList.append([awardTime, workerCount, areaPlayerID, mineID, itemLV, itemID, itemCount])
         
     # 通知地图玩家给物品
     curPlayer.SetDict(MineAreaAwardGetTick, tick)
@@ -1315,17 +1505,17 @@
 def __DoMineAreaAwardGetOK(curPlayer, dataMsg):
     
     playerID = curPlayer.GetPlayerID()
-    GUIDList, awardItemList = dataMsg
+    _, awardItemList = dataMsg
     curPlayer.SetDict(MineAreaAwardGetTick, 0)
     
     awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()
     awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})
     if not awardDict:
         return
+    GameWorld.DebugLog("福地结算奖励OK: %s" % len(awardDict), playerID)
     
-    for GUID in GUIDList:
-        awardDict.pop(GUID, None)
-        
+    awardMgr.playerAreaAwardDict[playerID] = {}
+    
     SyncMineAwardAward(curPlayer, 1, awardItemList)
     return
 

--
Gitblit v1.8.0