8346 【恺英】【后端】协助系统(初版,可完成协助完整流程,增加新NPC伤血管理,支持协助、支持超过20亿伤害)
| | |
| | | PacketSubCMD_3=0x03
|
| | | PacketCallFunc_3=OnQueryXMZZInfo
|
| | |
|
| | | [PlayerAssist]
|
| | | ScriptName = Player\PlayerAssist.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 4
|
| | |
|
| | | PacketCMD_1=0xB0
|
| | | PacketSubCMD_1=0x12
|
| | | PacketCallFunc_1=OnStartAssistBoss
|
| | |
|
| | | PacketCMD_2=0xB0
|
| | | PacketSubCMD_2=0x13
|
| | | PacketCallFunc_2=OnCancelAssistBoss
|
| | |
|
| | | PacketCMD_3=0xB0
|
| | | PacketSubCMD_3=0x14
|
| | | PacketCallFunc_3=OnUseAssistThanksGift
|
| | |
|
| | | PacketCMD_4=0xB0
|
| | | PacketSubCMD_4=0x15
|
| | | PacketCallFunc_4=OnGetAssistThanksGift
|
| | |
|
| | | [PlayerTalk]
|
| | | ScriptName = Player\PlayerTalk.py
|
| | | Writer = alee
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.Assist
|
| | | #
|
| | | # @todo:显示当前协助列表
|
| | | # @author hxp
|
| | | # @date 2019-12-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 显示当前协助列表
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-12-06 21:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PyDataManager
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #全局变量
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #逻辑实现
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmList [cmdIndex gmAccID msg]
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(curPlayer, gmList):
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | GameWorld.Log("---------- 当前总协助条数: %s" % len(assistMgr.allAssistDict))
|
| | | for assist in assistMgr.allAssistDict.values():
|
| | | GameWorld.DebugLog("%s" % assist.outputString())
|
| | | GameWorld.DebugLog("IsSaveDB=%s,ObjID=%s,AssistType=%s,AssistPlayerIDList=%s" % (assist.IsSaveDB, assist.ObjID, assist.AssistType, assist.AssistPlayerIDList))
|
| | | GameWorld.DebugLog("--- ")
|
| | | |
| | | GameWorld.DebugLog("--- ")
|
| | | for familyID, assistList in assistMgr.familyAssistDict.items():
|
| | | GameWorld.DebugLog("仙盟协助列表: %s, 条数: %s" % (familyID, len(assistList)))
|
| | | for assist in assistList:
|
| | | GameWorld.DebugLog(" %s" % assist.GUID)
|
| | | |
| | | GameWorld.DebugLog("--- ")
|
| | | for playerID, assistList in assistMgr.playerNoSaveDBAssistDict.items():
|
| | | GameWorld.DebugLog("玩家协助列表: %s, 条数: %s" % (playerID, len(assistList)))
|
| | | for assist in assistList:
|
| | | GameWorld.DebugLog(" %s" % assist.GUID)
|
| | | |
| | | GameWorld.DebugLog("--- ")
|
| | | for playerID, assist in assistMgr.playerAssistingDict.items():
|
| | | GameWorld.DebugLog("玩家协助中的: %s, %s" % (playerID, assist.GUID))
|
| | | |
| | | GameWorld.DebugLog("-----------------------------------------")
|
| | | return
|
| | |
|
| | |
| | | import IPY_PlayerDefine
|
| | | import CrossRealmPK
|
| | | import AuctionHouse
|
| | | import PlayerAssist
|
| | | import PlayerFB
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
| | | PlayerZhuXianBoss.OnPlayerLogin(curPlayer)
|
| | | #骑宠boss状态通知
|
| | | PlayerHorsePetBoss.OnLogin(curPlayer)
|
| | | #协助
|
| | | PlayerAssist.OnPlayerLogin(curPlayer, False)
|
| | | GMT_CTG.OnPlayerLogin(curPlayer)
|
| | | |
| | | else:
|
| | | #协助
|
| | | PlayerAssist.OnPlayerLogin(curPlayer, True)
|
| | | |
| | | return
|
| | |
|
| | | def __UpdOnedayJobPlayerLoginoffTime(curPlayer):
|
| | |
| | | SetPlayerOfflineTime(curPlayer)
|
| | | #拍卖行
|
| | | AuctionHouse.OnPlayerLeaveServer(curPlayer)
|
| | | #协助
|
| | | PlayerAssist.OnLeaveServer(curPlayer)
|
| | | #------------镖车逻辑
|
| | | #TruckPlayerDisconnectProcess(curPlayer, tick)
|
| | |
|
| | |
| | | PlayerTeam.SetTeamCheckState(curPlayer, packValue)
|
| | | return
|
| | |
|
| | | #if packType == IPY_GameServer.CDBPlayerRefresh_ExAttr1:
|
| | | # PlayerControl.SetAssistTagPlayerID(curPlayer, packValue)
|
| | | # return
|
| | | |
| | | if packType == IPY_GameServer.CDBPlayerRefresh_ExAttr3:
|
| | | PlayerControl.SetFBFuncLineID(curPlayer, packValue)
|
| | | return
|
| | | |
| | | #---常规逻辑处理---
|
| | |
|
| | | elif packType == IPY_GameServer.CDBPlayerRefresh_LV:
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerAssist
|
| | | #
|
| | | # @todo:协助系统
|
| | | # @author hxp
|
| | | # @date 2019-12-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 协助系统
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-12-06 21:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import PyDataManager
|
| | | import NetPackCommon
|
| | | import PyGameDataStruct
|
| | | import ChPyNetSendPack
|
| | | import PlayerControl
|
| | | import PlayerFamily
|
| | | import ShareDefine
|
| | | import PlayerTeam
|
| | | import GameWorld
|
| | | import ChConfig
|
| | |
|
| | | import uuid
|
| | |
|
| | | # 协助类型
|
| | | (
|
| | | AssistType_Unknown,
|
| | | AssistType_Boss, # boss
|
| | | AssistType_TeamFB, # 组队副本
|
| | | ) = range(3)
|
| | |
|
| | |
|
| | | def OnPlayerLogin(curPlayer, isTJ=False):
|
| | | ## 玩家上线
|
| | | # @param isTJ: 是否脱机上线
|
| | | |
| | | familyID = curPlayer.GetFamilyID()
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if not familyID:
|
| | | return
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if playerID in assistMgr.playerNoSaveDBAssistDict:
|
| | | playerNoSaveList = assistMgr.playerNoSaveDBAssistDict[playerID]
|
| | | |
| | | # 非脱机上线
|
| | | if not isTJ:
|
| | | GameWorld.DebugLog("玩家上线,恢复协助发布到仙盟列表!", playerID)
|
| | | if familyID not in assistMgr.familyAssistDict:
|
| | | assistMgr.familyAssistDict[familyID] = []
|
| | | recoverList = []
|
| | | familyAssistList = assistMgr.familyAssistDict[familyID]
|
| | | for assistObj in playerNoSaveList:
|
| | | familyAssistList.append(assistObj)
|
| | | recoverList.append(assistObj)
|
| | | GameWorld.DebugLog(" 恢复: %s" % assistObj.GUID)
|
| | | |
| | | if recoverList:
|
| | | # 通知本盟其他玩家
|
| | | PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack(recoverList), [playerID])
|
| | | |
| | | # 脱机上线
|
| | | else:
|
| | | GameWorld.DebugLog("玩家脱机上线,强制取消发布的非存库协助!", playerID)
|
| | | for assistObj in playerNoSaveList:
|
| | | OnCancelPlayerRequestAssist(assistObj, "TJGLogin", True)
|
| | | |
| | | if not isTJ:
|
| | | SyncFamilyAssist(curPlayer)
|
| | | |
| | | # 没有协助中的信息
|
| | | if playerID in assistMgr.playerAssistingDict:
|
| | | assistObj = assistMgr.playerAssistingDict[playerID]
|
| | | if not isTJ:
|
| | | tagPlayerID = assistObj.PlayerID
|
| | | GameWorld.DebugLog("非脱机上线,继续协助!tagPlayerID=%s" % tagPlayerID, playerID)
|
| | | |
| | | PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID)
|
| | | assistPack = ChPyNetSendPack.tagGCAssistingInfo()
|
| | | assistPack.AssistGUID = assistObj.GUID
|
| | | NetPackCommon.SendFakePack(curPlayer, assistPack)
|
| | | |
| | | # 脱机上线
|
| | | else:
|
| | | OnCancelPlayerAssist(curPlayer, playerID, assistObj, "TJGLogin", True)
|
| | | |
| | | return
|
| | |
|
| | | def OnLeaveServer(curPlayer):
|
| | | ## 玩家离线
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | return
|
| | | |
| | | if PlayerControl.GetAssistTagPlayerID(curPlayer):
|
| | | PlayerControl.SetAssistTagPlayerID(curPlayer, 0)
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if familyID not in assistMgr.familyAssistDict:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID not in assistMgr.playerNoSaveDBAssistDict:
|
| | | #GameWorld.DebugLog("玩家没有发布过协助,离线不处理!", playerID)
|
| | | return
|
| | | playerNoSaveList = assistMgr.playerNoSaveDBAssistDict[playerID] |
| | | familyAssistList = assistMgr.familyAssistDict[familyID]
|
| | | # 暂时移除离线玩家发布的不存库协助信息,不再让其他盟友继续前往协助,已经在协助的不影响
|
| | | for assistObj in playerNoSaveList:
|
| | | if assistObj not in familyAssistList:
|
| | | continue
|
| | | familyAssistList.remove(assistObj)
|
| | | SyncFamilyClearAssist(familyID, assistObj.GUID)
|
| | | GameWorld.DebugLog("玩家下线,暂时从仙盟协助列表移除玩家发布的协助: %s" % assistObj.GUID)
|
| | | |
| | | return
|
| | |
|
| | | def OnPlayerLeaveFamily(familyID, leavePlayerID, leavePlayer):
|
| | | ## 玩家离开仙盟
|
| | | ## @param leavePlayer: 可能不在线为None
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | |
| | | # 玩家发布的
|
| | | if leavePlayerID in assistMgr.playerNoSaveDBAssistDict:
|
| | | playerAssistList = assistMgr.playerNoSaveDBAssistDict[leavePlayerID]
|
| | | for assistObj in playerAssistList[::-1]:
|
| | | OnCancelPlayerRequestAssist(assistObj, "LeaveFamily", True)
|
| | | |
| | | # 玩家协助中的
|
| | | if leavePlayerID in assistMgr.playerAssistingDict:
|
| | | assistObj = assistMgr.playerAssistingDict[leavePlayerID]
|
| | | OnCancelPlayerAssist(leavePlayer, leavePlayerID, assistObj, "LeaveFamily", True)
|
| | | |
| | | return
|
| | |
|
| | | def OnInitAssistData(dbData, isSaveDB):
|
| | | ## 加载协助数据额外处理
|
| | | setattr(dbData, "IsSaveDB", isSaveDB) # 是否保存数据库,离线可协助的需要存库,如挖矿类
|
| | | setattr(dbData, "ObjID", 0) # NPC实例ID
|
| | | |
| | | assistType = AssistType_Unknown
|
| | | if dbData.NPCID:
|
| | | assistType = AssistType_Boss
|
| | | else:
|
| | | assMapID = dbData.MapID
|
| | | gameMap = GameWorld.GetMap(assMapID)
|
| | | if gameMap and gameMap.GetMapFBType() == ChConfig.fbtTeam:
|
| | | assistType = AssistType_TeamFB
|
| | | setattr(dbData, "AssistType", assistType) # 协助类型
|
| | | setattr(dbData, "AssistPlayerIDList", []) # 协助中的玩家ID列表
|
| | | return
|
| | |
|
| | | #// B0 12 开始协助Boss #tagCGStartAssistBoss
|
| | | #
|
| | | #struct tagCGStartAssistBoss
|
| | | #
|
| | | #{
|
| | | # tagHead Head;
|
| | | # char AssistGUID[40]; //协助GUID
|
| | | #};
|
| | | def OnStartAssistBoss(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | assistGUID = clientData.AssistGUID
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if assistGUID not in assistMgr.allAssistDict:
|
| | | GameWorld.DebugLog("不存在该协助!assistGUID=%s" % assistGUID)
|
| | | return
|
| | | assistObj = assistMgr.allAssistDict[assistGUID]
|
| | | if assistObj.AssistType != AssistType_Boss:
|
| | | return
|
| | | if assistObj.PlayerID == curPlayer.GetPlayerID():
|
| | | GameWorld.DebugLog("不能协助自己!")
|
| | | return
|
| | | |
| | | if assistObj.FamilyID != curPlayer.GetFamilyID():
|
| | | GameWorld.DebugLog("非同盟玩家不能协助!")
|
| | | return
|
| | | |
| | | mapID = assistObj.MapID
|
| | | lineID = assistObj.LineID
|
| | | gameMap = GameWorld.GetMap(mapID)
|
| | | if not gameMap:
|
| | | return
|
| | | if gameMap.GetMapFBType() != ChConfig.fbtNull:
|
| | | playerMapID = curPlayer.GetMapID()
|
| | | playerLineID = PlayerControl.GetFBFuncLineID(curPlayer)
|
| | | if playerMapID != mapID or playerLineID != lineID:
|
| | | #副本中无法协助
|
| | | PlayerControl.NotifyCode(curPlayer, "AssistFBLimit")
|
| | | return
|
| | | |
| | | # 设定协助必须离开队伍
|
| | | if gameMap.GetMapFBType() != ChConfig.fbtTeam:
|
| | | curTeam = curPlayer.GetTeam()
|
| | | if curTeam:
|
| | | PlayerTeam.DoPlayerLeaveTeam(curPlayer, curTeam, tick)
|
| | | |
| | | SetPlayerStartAssistBoss(curPlayer, assistObj)
|
| | | return
|
| | |
|
| | | #// B0 13 取消协助Boss #tagCGCancelAssistBoss
|
| | | #
|
| | | #struct tagCGCancelAssistBoss
|
| | | #
|
| | | #{
|
| | | # tagHead Head;
|
| | | # char AssistGUID[40]; //协助GUID
|
| | | #};
|
| | | def OnCancelAssistBoss(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | assistGUID = clientData.AssistGUID
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if playerID not in assistMgr.playerAssistingDict:
|
| | | GameWorld.DebugLog("没有在协助中,无需取消!", playerID)
|
| | | return
|
| | | assistObj = assistMgr.playerAssistingDict[playerID]
|
| | | if assistGUID != assistObj.GUID:
|
| | | GameWorld.DebugLog("非正在协助中的GUID,不能取消!assistGUID=%s,assisting=%s" % (assistGUID, assistObj.GUID), playerID)
|
| | | return
|
| | | OnCancelPlayerAssist(curPlayer, curPlayer.GetPlayerID(), assistObj, "ClientCancel", True)
|
| | | return
|
| | |
|
| | | def SetPlayerStartAssistBoss(curPlayer, assistObj):
|
| | | ## 玩家开始协助 boss
|
| | | |
| | | assistGUID = assistObj.GUID
|
| | | tagPlayerID = assistObj.PlayerID
|
| | | mapID = assistObj.MapID
|
| | | lineID = assistObj.LineID
|
| | | npcID = assistObj.NPCID
|
| | | objID = assistObj.ObjID
|
| | | |
| | | tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID)
|
| | | if not tagPlayer:
|
| | | GameWorld.DebugLog("玩家已离线,无法协助!tagPlayerID=%s" % (tagPlayerID))
|
| | | return
|
| | | |
| | | if tagPlayer.GetMapID() != mapID:
|
| | | GameWorld.DebugLog("目标玩家已不在请求协助的地图,无法协助!tagPlayerID=%s" % (tagPlayerID))
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | # 设置新协助之前需要先取消正在进行中的协助
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if playerID in assistMgr.playerAssistingDict:
|
| | | assistingObj = assistMgr.playerAssistingDict[playerID]
|
| | | if assistGUID != assistingObj.GUID:
|
| | | OnCancelPlayerAssist(curPlayer, playerID, assistingObj, "StartNewAssistBoss", True)
|
| | | assistMgr.playerAssistingDict[playerID] = assistObj
|
| | | |
| | | #if playerID in assistObj.AssistPlayerIDList:
|
| | | # GameWorld.DebugLog("已经在协助中!", playerID)
|
| | | # return
|
| | | if playerID not in assistObj.AssistPlayerIDList:
|
| | | assistObj.AssistPlayerIDList.append(playerID)
|
| | | |
| | | GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s" % (tagPlayerID, mapID, lineID, npcID, objID), playerID)
|
| | | |
| | | # 设置协助
|
| | | PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID)
|
| | | |
| | | # 通知目标玩家
|
| | | assistPlayerID = curPlayer.GetPlayerID()
|
| | | assistPlayerName = curPlayer.GetName()
|
| | | # xxx开始协助你
|
| | | PlayerControl.NotifyCode(tagPlayer, "AssistStart", [assistPlayerName])
|
| | | |
| | | tagPlayerName = tagPlayer.GetName()
|
| | | tagTeamID = tagPlayer.GetTeamID()
|
| | | assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID]
|
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData)
|
| | | return
|
| | |
|
| | | def OnAddAssistBossPlayerOK(queryData):
|
| | | ## 添加协助Boss的玩家成功,通知协助玩家可以前往
|
| | | assistGUID, assistPlayerID = queryData
|
| | | assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID)
|
| | | if not assistPlayer:
|
| | | return
|
| | | |
| | | assistPack = ChPyNetSendPack.tagGCAssistingInfo()
|
| | | assistPack.AssistGUID = assistGUID
|
| | | NetPackCommon.SendFakePack(assistPlayer, assistPack)
|
| | | return
|
| | |
|
| | | def SetPlayerStartAssistTeamFB(curPlayer, queryData):
|
| | | ## 开始协助组队副本 - 玩家进入副本后才真正进入协助状态
|
| | | |
| | | #mapID, lineID, tagPlayerID = queryData
|
| | | |
| | | return
|
| | |
|
| | | def MapServer_PlayerAssistLogic(curPlayer, msgList, tick):
|
| | | ## 地图同步的协助信息逻辑处理
|
| | | |
| | | playerID = 0 if not curPlayer else curPlayer.GetPlayerID()
|
| | | familyID = 0 if not curPlayer else curPlayer.GetFamilyID()
|
| | | queryType, queryData = msgList
|
| | | #result = []
|
| | | |
| | | GameWorld.Log("收到地图协助信息: familyID=%s,queryType=%s,queryData=%s" % (familyID, queryType, queryData), playerID)
|
| | | |
| | | # 请求协助boss
|
| | | if queryType == "RequestAssistBoss":
|
| | | __DoRequestAssistBoss(curPlayer, queryData)
|
| | | return
|
| | | |
| | | # 添加协助Boss的玩家成功
|
| | | elif queryType == "AddAssistBossPlayerOK":
|
| | | OnAddAssistBossPlayerOK(queryData)
|
| | | return
|
| | | |
| | | # 取消boss协助发布
|
| | | elif queryType == "OnCancelBossRequestAssist":
|
| | | mapID, lineID, npcID, objID, reason, cancelPlayerIDList = queryData
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | for cancelPlayerID in cancelPlayerIDList:
|
| | | if cancelPlayerID in assistMgr.playerNoSaveDBAssistDict:
|
| | | playerAssistList = assistMgr.playerNoSaveDBAssistDict[cancelPlayerID]
|
| | | for assistObj in playerAssistList:
|
| | | if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
|
| | | OnCancelPlayerRequestAssist(assistObj, reason, False)
|
| | | break
|
| | | return
|
| | | |
| | | # 取消协助Boss
|
| | | elif queryType == "OnCancelBossAssist":
|
| | | mapID, lineID, npcID, objID, reason = queryData
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if playerID in assistMgr.playerAssistingDict:
|
| | | assistObj = assistMgr.playerAssistingDict[playerID]
|
| | | if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
|
| | | OnCancelPlayerAssist(curPlayer, playerID, assistObj, reason, False)
|
| | | return
|
| | | |
| | | ## -------------------------------------------------------------------------------------------
|
| | | |
| | | # 请求协助组队副本
|
| | | elif queryType == "RequestAssistTeamFB":
|
| | | __DoRequestAssistTeamFB(curPlayer, queryData)
|
| | | return
|
| | | |
| | | # 开始协助组队副本
|
| | | elif queryType == "OnStartAssistTeamFB":
|
| | | SetPlayerStartAssistTeamFB(curPlayer, queryData)
|
| | | return
|
| | | |
| | | #QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result)
|
| | | return
|
| | |
|
| | | #def QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result=[]):
|
| | | # if not curPlayer:
|
| | | # return
|
| | | # resultMsg = str([queryType, queryData, result])
|
| | | # curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerAssist", resultMsg, len(resultMsg))
|
| | | # GameWorld.DebugLog("协助信息发送 MapServer: playerID=%s,queryType=%s,queryData=%s" % (curPlayer.GetPlayerID(), queryType, queryData))
|
| | | # return
|
| | |
|
| | | def __DoRequestAssistBoss(curPlayer, queryData):
|
| | | ## 请求协助Boss
|
| | | |
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | return
|
| | | mapID, lineID, npcID, objID = queryData
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | assistObj = None
|
| | | addNewAssist = True
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if playerID in assistMgr.playerNoSaveDBAssistDict:
|
| | | playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
|
| | | for assistObj in playerAssistList:
|
| | | if assistObj.AssistType != AssistType_Boss:
|
| | | continue
|
| | | if npcID != assistObj.NPCID or lineID != assistObj.LineID or objID != assistObj.ObjID:
|
| | | OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistBoss", True)
|
| | | else:
|
| | | addNewAssist = False
|
| | | break
|
| | | |
| | | if addNewAssist:
|
| | | assistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID)
|
| | | |
| | | if not assistObj:
|
| | | return
|
| | | |
| | | # 通知本仙盟玩家
|
| | | PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj]))
|
| | | # 求助信息已发送,请等待盟友支援
|
| | | PlayerControl.NotifyCode(curPlayer, "AssistRequestOK")
|
| | | return
|
| | |
|
| | | def __DoRequestAssistTeamFB(curPlayer, queryData):
|
| | | ## 请求协助组队副本
|
| | | |
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | return
|
| | | mapID, lineID = queryData
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | assistObj = None
|
| | | addNewAssist = False
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if playerID in assistMgr.playerNoSaveDBAssistDict:
|
| | | playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
|
| | | for assistObj in playerAssistList:
|
| | | if assistObj.AssistType != AssistType_TeamFB:
|
| | | continue
|
| | | if mapID != assistObj.MapID or lineID != assistObj.LineID:
|
| | | OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistTeamFB", True)
|
| | | addNewAssist = True
|
| | | break
|
| | | else:
|
| | | addNewAssist = True
|
| | | |
| | | if addNewAssist:
|
| | | assistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID)
|
| | | |
| | | if not assistObj:
|
| | | return
|
| | | |
| | | # 通知本仙盟玩家
|
| | | PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj]))
|
| | | # 求助信息已发送,请等待盟友支援
|
| | | PlayerControl.NotifyCode(curPlayer, "AssistRequestOK")
|
| | | return
|
| | |
|
| | | def __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID=0, objID=0, exData="", isSaveDB=0):
|
| | | ## 添加新协助请求
|
| | | assistGUID = str(uuid.uuid1())
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | assistObj = PyGameDataStruct.tagDBAssist()
|
| | | assistObj.GUID = assistGUID
|
| | | assistObj.FamilyID = familyID
|
| | | assistObj.PlayerID = playerID
|
| | | assistObj.PlayerName = curPlayer.GetName()
|
| | | assistObj.Job = curPlayer.GetJob()
|
| | | assistObj.LV = curPlayer.GetLV()
|
| | | assistObj.RealmLV = curPlayer.GetOfficialRank()
|
| | | assistObj.MapID = mapID
|
| | | assistObj.LineID = lineID
|
| | | assistObj.NPCID = npcID
|
| | | assistObj.ExData = exData
|
| | | assistObj.ExDataLen = len(exData)
|
| | | |
| | | # 以下是非DB字段属性
|
| | | OnInitAssistData(assistObj, isSaveDB)
|
| | | assistObj.ObjID = objID
|
| | | |
| | | #assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | assistMgr.allAssistDict[assistGUID] = assistObj
|
| | | if familyID not in assistMgr.familyAssistDict:
|
| | | assistMgr.familyAssistDict[familyID] = []
|
| | | familyAssistList = assistMgr.familyAssistDict[familyID]
|
| | | familyAssistList.append(assistObj)
|
| | | |
| | | if not isSaveDB:
|
| | | if playerID not in assistMgr.playerNoSaveDBAssistDict:
|
| | | assistMgr.playerNoSaveDBAssistDict[playerID] = []
|
| | | playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
|
| | | playerAssistList.append(assistObj)
|
| | | |
| | | GameWorld.DebugLog(" 增加新协助请求: familyID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s,exData=%s,assistGUID=%s" |
| | | % (familyID, mapID, lineID, npcID, objID, exData, assistGUID), playerID)
|
| | | return assistObj
|
| | |
|
| | | def GetAssistInfoListPack(familyAssistList):
|
| | | ## 协助列表封包数据
|
| | | assistList = []
|
| | | for assistObj in familyAssistList:
|
| | | assistInfo = ChPyNetSendPack.tagGCAssistInfo()
|
| | | assistInfo.AssistGUID = assistObj.GUID
|
| | | assistInfo.PlayerName = assistObj.PlayerName
|
| | | assistInfo.Job = assistObj.Job
|
| | | assistInfo.LV = assistObj.LV
|
| | | assistInfo.RealmLV = assistObj.RealmLV
|
| | | assistInfo.MapID = assistObj.MapID
|
| | | assistInfo.LineID = assistObj.LineID
|
| | | assistInfo.NPCID = assistObj.NPCID
|
| | | assistInfo.ExData = assistObj.ExData
|
| | | assistInfo.ExDataLen = len(assistObj.ExData)
|
| | | assistList.append(assistInfo)
|
| | | |
| | | infoListPack = ChPyNetSendPack.tagGCAssistInfoList()
|
| | | infoListPack.AssistInfoList = assistList
|
| | | infoListPack.Count = len(assistList)
|
| | | return infoListPack
|
| | |
|
| | | def OnCancelPlayerRequestAssist(assistObj, reason, isGameServer):
|
| | | '''取消玩家协助 - 发布方
|
| | | MapServer 触发取消
|
| | | 1. 攻击了另一只boss
|
| | | 2. 重新发布了另一条协助boss/组队副本
|
| | | 3. 进入协助状态,即本来在打同一只boss,后面直接改为协助
|
| | | 4. 退出了发布协助地图
|
| | | |
| | | GameServer 触发取消
|
| | | 5. 被踢/退出仙盟
|
| | | '''
|
| | | |
| | | assistGUID = assistObj.GUID
|
| | | playerID = assistObj.PlayerID
|
| | | familyID = assistObj.FamilyID
|
| | | assistType = assistObj.AssistType
|
| | | mapID = assistObj.MapID
|
| | | lineID = assistObj.LineID
|
| | | npcID = assistObj.NPCID
|
| | | objID = assistObj.ObjID
|
| | | |
| | | GameWorld.DebugLog("取消发布的协助请求: mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s" |
| | | % (mapID, lineID, npcID, objID, reason, isGameServer, assistGUID))
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if assistGUID not in assistMgr.allAssistDict:
|
| | | return
|
| | | assistMgr.allAssistDict.pop(assistGUID)
|
| | | |
| | | if familyID in assistMgr.familyAssistDict:
|
| | | familyAssistList = assistMgr.familyAssistDict[familyID]
|
| | | if assistObj in familyAssistList:
|
| | | familyAssistList.remove(assistObj)
|
| | | |
| | | if playerID in assistMgr.playerNoSaveDBAssistDict:
|
| | | playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID]
|
| | | if assistObj in playerAssistList:
|
| | | playerAssistList.remove(assistObj)
|
| | | |
| | | SyncFamilyClearAssist(familyID, assistGUID)
|
| | | |
| | | # 取消boss协助
|
| | | if assistType == AssistType_Boss:
|
| | | |
| | | # 强制取消正在协助中的玩家
|
| | | playerMgr = GameWorld.GetPlayerManager()
|
| | | for assPlayerID in assistObj.AssistPlayerIDList[::-1]:
|
| | | assistObj.AssistPlayerIDList.remove(assPlayerID)
|
| | | if assPlayerID in assistMgr.playerAssistingDict:
|
| | | assistingObj = assistMgr.playerAssistingDict[assPlayerID]
|
| | | if assistingObj.GUID == assistGUID:
|
| | | assPlayer = playerMgr.FindPlayerByID(assPlayerID)
|
| | | OnCancelPlayerAssist(assPlayer, assPlayerID, assistObj, reason, isGameServer, isNotify=False)
|
| | | |
| | | # 发布方取消不需要通知地图,对地图发布玩家没有影响,可继续攻击boss
|
| | | |
| | | # 取消副本协助
|
| | | elif assistType == AssistType_TeamFB:
|
| | | # 暂不需要处理
|
| | | pass
|
| | | |
| | | return
|
| | |
|
| | | def OnCancelPlayerAssist(cancelPlayer, cancelPlayerID, assistObj, reason, isGameServer, isNotify=True):
|
| | | '''取消玩家协助 - 协助方
|
| | | MapServer 触发取消
|
| | | 1. 攻击了另一只boss
|
| | | 2. 退出了当前协助的协助地图
|
| | | |
| | | GameServer 触发取消
|
| | | 3. 重新协助了另一条协助boss/组队副本
|
| | | 4. 被踢/退出仙盟
|
| | | 5. 主动点取消
|
| | | |
| | | 其他,发布方取消方式
|
| | | 6. 发布方取消了发布的协助
|
| | | '''
|
| | | |
| | | assistGUID = assistObj.GUID
|
| | | tagPlayerID = assistObj.PlayerID
|
| | | mapID = assistObj.MapID
|
| | | lineID = assistObj.LineID
|
| | | npcID = assistObj.NPCID
|
| | | objID = assistObj.ObjID
|
| | | |
| | | GameWorld.DebugLog("取消协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s" |
| | | % (tagPlayerID, mapID, lineID, npcID, objID, reason, isGameServer, assistGUID), cancelPlayerID)
|
| | | |
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | if cancelPlayerID in assistMgr.playerAssistingDict:
|
| | | assistMgr.playerAssistingDict.pop(cancelPlayerID)
|
| | | |
| | | if cancelPlayerID in assistObj.AssistPlayerIDList:
|
| | | assistObj.AssistPlayerIDList.remove(cancelPlayerID)
|
| | | |
| | | if cancelPlayer:
|
| | | PlayerControl.SetAssistTagPlayerID(cancelPlayer, 0)
|
| | | |
| | | # 取消boss协助
|
| | | if assistObj.AssistType == AssistType_Boss:
|
| | | |
| | | # GameServer取消的需要通知协助boss地图,删除协助玩家记录
|
| | | if isGameServer:
|
| | | assistData = [mapID, "Cancel", cancelPlayerID, lineID, objID, npcID]
|
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData)
|
| | | |
| | | if isNotify and cancelPlayer:
|
| | | tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID)
|
| | | if tagPlayer:
|
| | | # xxx取消对你协助
|
| | | PlayerControl.NotifyCode(tagPlayer, "AssistCancel", [cancelPlayer.GetName()])
|
| | | |
| | | # 取消副本协助
|
| | | elif assistObj.AssistType == AssistType_TeamFB:
|
| | | pass
|
| | | |
| | | return
|
| | |
|
| | | #// B0 14 使用协助感谢礼盒 #tagCGUseAssistThanksGift
|
| | | #
|
| | | #struct tagCGUseAssistThanksGift
|
| | | #
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD ItemID;
|
| | | # char GiftGUID[40]; //预览时GUID不发,确认使用时需发送预览返回的GUID
|
| | | #};
|
| | | def OnUseAssistThanksGift(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | itemID = clientData.ItemID
|
| | | giftGUID = clientData.GiftGUID
|
| | | return
|
| | |
|
| | | #// B0 15 领取协助感谢礼物 #tagCGGetAssistThanksGift
|
| | | #
|
| | | #struct tagCGGetAssistThanksGift
|
| | | #
|
| | | #{
|
| | | # tagHead Head;
|
| | | # char GiftGUID[40]; //礼盒GUID
|
| | | #};
|
| | | def OnGetAssistThanksGift(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | giftGUID = clientData.GiftGUID
|
| | | return
|
| | |
|
| | | def SyncFamilyAssist(curPlayer):
|
| | | ## 同步当前仙盟所有协助请求信息
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | return
|
| | | assistMgr = PyDataManager.GetPlayerAssistPyManager()
|
| | | familyAssistList = assistMgr.familyAssistDict.get(familyID, [])
|
| | | if not familyAssistList:
|
| | | return
|
| | | NetPackCommon.SendFakePack(curPlayer, GetAssistInfoListPack(familyAssistList))
|
| | | return
|
| | |
|
| | | def SyncFamilyClearAssist(familyID, assistGUID):
|
| | | # 封包通知仙盟清除协助
|
| | | clearPack = ChPyNetSendPack.tagGCClearAssist()
|
| | | clearPack.AssistGUID = assistGUID
|
| | | PlayerFamily.SendFamilyFakePack(familyID, clearPack)
|
| | | return
|
| | |
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------------------------------
|
| | | ## 协助目标玩家ID
|
| | | def SetAssistTagPlayerID(curPlayer, value):
|
| | | curPlayer.SetExAttr1(value)
|
| | | SetMapServerPlayerAttrValue(curPlayer, "SetAssistTagPlayerID", value)
|
| | | return
|
| | | def GetAssistTagPlayerID(curPlayer): return curPlayer.GetExAttr1()
|
| | |
|
| | | ## 副本功能线路ID
|
| | | def SetFBFuncLineID(curPlayer, funcLineID): return curPlayer.SetExAttr3(funcLineID)
|
| | | def GetFBFuncLineID(curPlayer): return curPlayer.GetExAttr3()
|
| | |
|
| | | ##VIP到期时间
|
| | | def GetVIPExpireTime(curPlayer): return curPlayer.GetExAttr9()
|
| | |
| | | import PlayerViewCache
|
| | | import GameWorldBoss
|
| | | import AuctionHouse
|
| | | import PlayerAssist
|
| | | import PlayerTalk
|
| | | import PlayerTeam
|
| | |
|
| | |
| | | PlayerFamilyParty.NotifyFamilyPartyQuestion(jionPlayer)
|
| | | #通知守卫人皇信息
|
| | | PlayerFamilySWRH.NotifySWRHInfo(jionPlayer, curFamily.GetID())
|
| | | #通知仙盟协助信息
|
| | | PlayerAssist.SyncFamilyAssist(jionPlayer)
|
| | | #oss记录加入家族信息
|
| | | DataRecordPack.DR_PlayerJoinFamily(jionPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount())
|
| | | return
|
| | |
| | | #===============================================================================================
|
| | | return
|
| | |
|
| | | def SendFamilyFakePack(familyID, clientPack):
|
| | | def SendFamilyFakePack(familyID, clientPack, excludePlayerIDList=[]):
|
| | | ## 广播家族成员PY封包
|
| | | family = GameWorld.GetFamilyManager().FindFamily(familyID)
|
| | | if not family:
|
| | |
| | | for index in xrange(family.GetCount()):
|
| | | member = family.GetAt(index)
|
| | | memPlayer = member.GetPlayer()
|
| | | if memPlayer:
|
| | | if not memPlayer:
|
| | | continue
|
| | | if excludePlayerIDList and memPlayer.GetPlayerID() in excludePlayerIDList:
|
| | | continue
|
| | | NetPackCommon.SendFakePack(memPlayer, clientPack)
|
| | | return
|
| | |
|
| | |
| | | [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick)
|
| | | #删除玩家
|
| | | curFamily.DeleteMember(tagPlayerID)
|
| | | __DoPlayerLeaveFamilyByID(curFamily, tagPlayerID)
|
| | | |
| | | tagPlayer = playerManager.FindPlayerByID(tagMemberID)
|
| | | |
| | | __DoPlayerLeaveFamilyByID(curFamily, tagPlayerID, tagPlayer)
|
| | | #玩家在线, 设置这个玩家的属性
|
| | | PlayerForceLeaveFamily(tagPlayer, tick)
|
| | |
|
| | |
| | | curFamily.DeleteMember(curMember.GetPlayerID())
|
| | | #玩家在线, 设置这个玩家的属性
|
| | | PlayerForceLeaveFamily(curPlayer, tick)
|
| | | __DoPlayerLeaveFamilyByID(curFamily, curPlayerID)
|
| | | __DoPlayerLeaveFamilyByID(curFamily, curPlayerID, curPlayer)
|
| | |
|
| | | DataRecordPack.DR_PlayerLeaveFamily(curPlayer, curFamily.GetID(), curFamily.GetName(), curFamily.GetCount(),
|
| | | familyLV, curPlayer.GetPlayerID(), curPlayer.GetName(), familyLV, updTime)
|
| | |
| | | # @param curFamily 离开的家族
|
| | | # @param leavePlayerID 离开的玩家ID
|
| | | # @return None
|
| | | def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID):
|
| | | def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, tagPlayer=None):
|
| | | PlayerFamilyAction.DelFamilyOfficerModelEquip(curFamily.GetID(), leavePlayerID)
|
| | | # 玩家战盟名变更处理
|
| | | __OnFamilyNameChange(leavePlayerID, '')
|
| | | AddFamilyIDToFightPowerChangeList(curFamily.GetID())
|
| | | PlayerViewCache.OnPlayerFamilyChange(leavePlayerID, 0, "")
|
| | | PlayerAssist.OnPlayerLeaveFamily(curFamily.GetID(), leavePlayerID, tagPlayer)
|
| | | if leavePlayerID in PyGameData.g_autoViceleaderDict.get(curFamily.GetID(),[]):
|
| | | PyGameData.g_autoViceleaderDict[curFamily.GetID()].remove(leavePlayerID)
|
| | | return
|
| | |
| | | import AuctionHouse
|
| | | import PlayerFairyDomain
|
| | | import GameWorldItem
|
| | | import PlayerAssist
|
| | |
|
| | | import time
|
| | | import datetime
|
| | |
| | | AuctionHouse.MapServer_AuctionHouseLogic(curPlayer, eval(resultName), tick)
|
| | | return
|
| | |
|
| | | # 协助
|
| | | if callName == "PlayerAssist":
|
| | | curPlayer = None
|
| | | if srcPlayerID:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | PlayerAssist.MapServer_PlayerAssistLogic(curPlayer, eval(resultName), tick)
|
| | | return
|
| | | |
| | | if callName == "TeamMemFuncData":
|
| | | PlayerTeam.MapServer_TeamMemFuncData(srcPlayerID, eval(resultName))
|
| | | return
|
| | |
| | | PlayerControl.NotifyCode(curPlayer, "TeamEnterForbid")
|
| | | return False
|
| | |
|
| | | if PlayerControl.GetAssistTagPlayerID(curPlayer):
|
| | | #协助中无法执行此操作
|
| | | PlayerControl.NotifyCode(curPlayer, "InAssistForbid")
|
| | | return False
|
| | | |
| | | if tagPlayer:
|
| | | tagPlayerID = tagPlayer.GetPlayerID()
|
| | | #检查ID
|
| | |
| | | PlayerControl.NotifyCode(curPlayer, "TeamEnterForbid")
|
| | | return False
|
| | |
|
| | | if PlayerControl.GetAssistTagPlayerID(tagPlayer):
|
| | | #对方协助中,无法执行此操作
|
| | | PlayerControl.NotifyCode(curPlayer, "TagInAssistForbid")
|
| | | return False
|
| | | |
| | | return True
|
| | |
|
| | | #===============================================================================
|
| | |
| | | import PyGameData
|
| | | import CrossRealmPK
|
| | | import AuctionHouse
|
| | | import PlayerAssist
|
| | | import PyGameDataStruct
|
| | | import CommFunc
|
| | |
|
| | |
| | | class PlayerAssistPyManager(object):
|
| | |
|
| | | def __init__(self):
|
| | | self.playerAssistDict = {} # 所有协助 {GUID:tagDBAssist, ...}
|
| | | self.allAssistDict = {} # 所有协助 {GUID:tagDBAssist, ...}
|
| | | self.familyAssistDict = {} # 仙盟协助缓存 {familyID:[tagDBAssist, ...], ...}
|
| | | |
| | | self.playerNoSaveDBAssistDict = {} # 玩家发布的不存库协助 {playerID:[tagDBAssist, ...], ...}
|
| | | self.playerAssistingDict = {} # 玩家正在协助中的协助,只能存在一条 {playerID:tagDBAssist, ...}
|
| | | return
|
| | |
|
| | | # 保存数据 存数据库和realtimebackup
|
| | |
| | | cntData = ""
|
| | | cnt = 0
|
| | |
|
| | | for dbData in self.playerAssistDict.values():
|
| | | for dbData in self.allAssistDict.values():
|
| | | if not dbData.IsSaveDB:
|
| | | continue
|
| | | cnt += 1
|
| | | savaData += dbData.getBuffer()
|
| | |
|
| | |
| | | dbData.clear()
|
| | | pos += dbData.readData(datas, pos, dataslen)
|
| | |
|
| | | self.playerAssistDict[dbData.GUID] = dbData
|
| | | PlayerAssist.OnInitAssistData(dbData, 1)
|
| | | |
| | | self.allAssistDict[dbData.GUID] = dbData
|
| | | familyID = dbData.FamilyID
|
| | | if familyID not in self.familyAssistDict:
|
| | | self.familyAssistDict[familyID] = []
|
| | |
| | | Def_Notify_WorldKey_RedPacketOutput = 'RedPacketOutput' # 红包产出信息
|
| | | Def_Notify_WorldKey_HurtLog = 'HurtLog' # 战斗伤害日志
|
| | | Def_Notify_WorldKey_FairyDomainLimit = "FairyDomainLimit" # 缥缈仙域限制事件
|
| | |
|
| | | Def_Notify_WorldKey_AssistBoss = "AssistBoss" # 协助boss
|
| | |
|
| | | #运营活动表名定义
|
| | | OperationActionName_ExpRate = "ActExpRate" # 多倍经验活动
|
| | | OperationActionName_CostRebate = "ActCostRebate" # 消费返利活动
|
| | |
| | | PacketSubCMD_1=0x25
|
| | | PacketCallFunc_1=OnDailyActionBuyCnt
|
| | |
|
| | | ;协助
|
| | | [PlayerAssist]
|
| | | ScriptName = Player\PlayerAssist.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 2
|
| | |
|
| | | PacketCMD_1=0xB0
|
| | | PacketSubCMD_1=0x10
|
| | | PacketCallFunc_1=OnRequestAssistBoss
|
| | |
|
| | | PacketCMD_2=0xB0
|
| | | PacketSubCMD_2=0x11
|
| | | PacketCallFunc_2=OnRequestAssistTeamFB
|
| | |
|
| | | ;缥缈仙域
|
| | | [PlayerFairyDomain]
|
| | | ScriptName = Player\PlayerFairyDomain.py
|
| | |
| | | import BuffSkill
|
| | | import PlayerState
|
| | | import ChPyNetSendPack
|
| | | import NPCHurtManager
|
| | | import NetPackCommon
|
| | | import FamilyRobBoss
|
| | | import FBCommon
|
| | |
| | | # @param hurtHP 攻击伤血值
|
| | | # @return None or True
|
| | | # @remarks 函数详细说明.
|
| | | def NPCAddObjInHurtList(curObj, curTagObj, curTaglNPCHPBefore, hurtHP) :
|
| | | def NPCAddObjInHurtList(curObj, curTagObj, curTaglNPCHPBefore, hurtHP, isBounce=False):
|
| | | if curObj == None:
|
| | | GameWorld.ErrLog("NPCAddObjInHurtList NoFindObj")
|
| | | return
|
| | |
| | | if curTaglNPCHPBefore < hurtHP:
|
| | | hurtHP = curTaglNPCHPBefore
|
| | |
|
| | | defNPCHurtList = curTagObj.GetPlayerHurtList()
|
| | | curObjType = curObj.GetGameObjType()
|
| | | if curObjType == IPY_GameWorld.gotPlayer:
|
| | | #BossHurtMng.BossAddPlayerInHurtList(curObj, curTagObj, hurtHP)
|
| | |
| | | FBLogic.DoFB_Player_HurtNPC(curObj, curTagObj, hurtHP)
|
| | | if GameObj.GetHP(curTagObj) == 0:
|
| | | curTagObj.SetDict(ChConfig.Def_PlayerKey_LastHurt, curObj.GetPlayerID())
|
| | | |
| | | if NPCHurtManager.AddHurtValue(curObj, curTagObj, hurtHP, isBounce):
|
| | | return
|
| | |
|
| | | curTeam = curObj.GetTeam()
|
| | |
|
| | |
| | | # return False
|
| | |
|
| | | #击杀次数判断
|
| | | if not CheckKillNPCByCnt(attacker, defender):
|
| | | if not NPCHurtManager.IsAssistPlayer(attacker.GetPlayerID(), defender) and not CheckKillNPCByCnt(attacker, defender):
|
| | | return False
|
| | |
|
| | | #仙盟归属NPC判断
|
| | |
| | | # return False
|
| | |
|
| | | #击杀次数判断
|
| | | if not CheckKillNPCByCnt(defender, attacker, False):
|
| | | if not CheckKillNPCByCnt(defender, attacker, False) and not NPCHurtManager.IsAssistPlayer(defender.GetPlayerID(), attacker):
|
| | | return False
|
| | |
|
| | | #仙盟归属NPC判断
|
| | |
| | | if PetControl.IsPet(attacker) or attacker.GetGameNPCObjType()== IPY_GameWorld.gnotSummon:
|
| | | #击杀次数判断
|
| | | if not CheckKillNPCByCnt(attacker, defender, False):
|
| | | ownerPlayer = GetAttackPlayer(attacker)[0]
|
| | | if ownerPlayer and not NPCHurtManager.IsAssistPlayer(ownerPlayer.GetPlayerID(), defender):
|
| | | return False
|
| | |
|
| | | #仙盟归属NPC判断
|
| | |
| | | # GameWorld.DebugLog("不能攻击,不反弹")
|
| | | # return
|
| | | #杀怪次数判断
|
| | | if not CheckKillNPCByCnt(defObj, atkObj, False):
|
| | | if not CheckKillNPCByCnt(defObj, atkObj, False) and not NPCHurtManager.IsAssistPlayer(defObj.GetPlayerID(), atkObj):
|
| | | #GameWorld.DebugLog("不能攻击,不反弹")
|
| | | return
|
| | |
|
| | |
| | | lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
|
| | | if lastHP > 0 :
|
| | | #添加伤血列表
|
| | | AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP)
|
| | | AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP, True)
|
| | | #给这个玩家的召唤兽增加仇恨
|
| | | AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, hurtHP)
|
| | | #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
|
| | |
| | | 1000 * 15, # 渡劫鼓舞间隔
|
| | | 1000 * 1, # vip体验时效
|
| | | 1000 * 1, # 限时抢购
|
| | | 1000 * 5, # 请求协助间隔
|
| | | ]
|
| | | TYPE_Player_Tick_Count = len(TYPE_Player_Tick_Time)
|
| | |
|
| | |
| | | TYPE_Player_Tick_DuJieInspire, # 渡劫鼓舞间隔
|
| | | TYPE_Player_Tick_VIPExperience, #vip体验时效
|
| | | TYPE_Player_Tick_FlashSale, #限时抢购
|
| | | TYPE_Player_Tick_RequestAssist, #请求协助间隔
|
| | | ) = range(0, TYPE_Player_Tick_Count)
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | import FamilyRobBoss
|
| | | import NPCCommon
|
| | | import ChConfig
|
| | | import NPCHurtManager
|
| | | import PlayerTeam
|
| | |
|
| | | ##查看点选的NPC仇恨列表
|
| | | # @param curPlayer 玩家实例
|
| | |
| | | GameWorld.DebugAnswer(curPlayer, "objID(%s) 错误 找不到对应NPC" % objID)
|
| | | return
|
| | |
|
| | | GameWorld.DebugAnswer(curPlayer, "---%s,ID=%s,team=%s,family=%s" |
| | | % (GameWorld.GetGameWorld().GetTick()%1000, curPlayer.GetPlayerID(), curPlayer.GetTeamID(), curPlayer.GetFamilyID()))
|
| | | GameWorld.DebugAnswer(curPlayer, "---------------- %s" % (GameWorld.GetGameWorld().GetTick() % 1000))
|
| | | GameWorld.DebugAnswer(curPlayer, "ID=%s,team=%s,family=%s" % (curPlayer.GetPlayerID(), curPlayer.GetTeamID(), curPlayer.GetFamilyID()))
|
| | |
|
| | | # 归属仙盟的,取仙盟伤血统计
|
| | | if NPCCommon.GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
|
| | | FamilyRobBoss.OnGMPrintFamilyOwnerBossHurt(curPlayer, curNPC)
|
| | | return
|
| | |
|
| | | isPyHurtList = True
|
| | | npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
|
| | | if not npcHurtList:
|
| | | npcHurtList = curNPC.GetPlayerHurtList()
|
| | | isPyHurtList = False
|
| | | if isSort:
|
| | | npcHurtList.Sort() #sort以后伤血列表从大到小排序
|
| | |
|
| | | GameWorld.DebugAnswer(curPlayer, "ID=%s, NPCID=%s, 伤血数=%s, isSort=%s" % (curNPC.GetID(), curNPC.GetNPCID(), npcHurtList.GetHurtCount(), isSort))
|
| | | if isPyHurtList:
|
| | | for playerID, assistPlayerIDList in npcHurtList.GetNoAssitPlayerIDDict().items():
|
| | | GameWorld.DebugAnswer(curPlayer, "玩家:%s, 协助玩家:%s" % (playerID, assistPlayerIDList))
|
| | | for assistPlayerID, tagPlayerID in npcHurtList.GetAssistPlayerIDDict().items():
|
| | | GameWorld.DebugAnswer(curPlayer, "协助玩家:%s, 目标:%s" % (assistPlayerID, tagPlayerID))
|
| | | |
| | | for index in xrange(npcHurtList.GetHurtCount()):
|
| | | #获得伤血对象
|
| | | hurtObj = npcHurtList.GetHurtAt(index)
|
| | |
| | | d = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), hurtPlayer.GetPosX(), hurtPlayer.GetPosY())
|
| | | GameWorld.DebugAnswer(curPlayer, "%s 玩家ID=%s,距离=%s, V=%s" % (index, hurtID, d, hurtValue))
|
| | |
|
| | | if isPyHurtList:
|
| | | playerHurtValue, assistPlayerHurtDict = npcHurtList.GetPlayerHurtDetail(hurtID)
|
| | | GameWorld.DebugAnswer(curPlayer, " 非协id=%s,v=%s" % (hurtID, playerHurtValue))
|
| | | for assistPlayerID, assistHurtValue in assistPlayerHurtDict.items():
|
| | | GameWorld.DebugAnswer(curPlayer, " 协助id=%s,v=%s" % (assistPlayerID, assistHurtValue))
|
| | | |
| | | elif hurtType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | #获得当前队伍
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(hurtID)
|
| | |
| | | else:
|
| | | GameWorld.DebugAnswer(curPlayer, "%s 队伍ID=%s,人数=%s, V=%s" % (index, hurtID, curTeam.GetMemberCount(), hurtValue))
|
| | |
|
| | | if isPyHurtList:
|
| | | mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(hurtID)
|
| | | for teamPlayerID in mapTeamPlayerIDList:
|
| | | if not npcHurtList.IsNoAssistPlayer(teamPlayerID):
|
| | | continue
|
| | | playerHurtValue, assistPlayerHurtDict = npcHurtList.GetPlayerHurtDetail(teamPlayerID)
|
| | | GameWorld.DebugAnswer(curPlayer, " 非协id=%s,v=%s" % (teamPlayerID, playerHurtValue))
|
| | | for assistPlayerID, assistHurtValue in assistPlayerHurtDict.items():
|
| | | GameWorld.DebugAnswer(curPlayer, " 协助id=%s,v=%s" % (assistPlayerID, assistHurtValue))
|
| | | |
| | | elif hurtType == ChConfig.Def_NPCHurtTypeNPC:
|
| | | GameWorld.DebugAnswer(curPlayer, "%s NPC=%s, V=%s" % (index, hurtID, hurtValue))
|
| | |
|
| | |
| | | # @remarks 函数详细说明.
|
| | | def OnExec(curPlayer, paramList):
|
| | | #输入命令格式错误
|
| | | if not paramList:
|
| | | GameWorld.DebugAnswer(curPlayer, "SetWorldPos mapID posX posY")
|
| | | return
|
| | | mapID, posX, posY = paramList[:3]
|
| | | lineID = paramList[3] if len(paramList) > 3 else - 1
|
| | | if not mapID:
|
| | |
| | | import PlayerNewFairyCeremony
|
| | | import GameLogic_CrossGrassland
|
| | | import PlayerWeekParty
|
| | | import NPCHurtManager
|
| | | import PlayerActLogin
|
| | | import FamilyRobBoss
|
| | | import IpyGameDataPY
|
| | |
| | | AttackCommon.ClearTeamPlayerHurtValue(curNPC)
|
| | | # 清除自定义伤血列表
|
| | | #BossHurtMng.ClearHurtValueList(curNPC)
|
| | | NPCHurtManager.DeletePlayerHurtList(curNPC)
|
| | | if curNPC.GetType() == ChConfig.ntRobot:
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {})
|
| | |
| | | # @remarks 类初始化
|
| | | def __init__(self, iNPC):
|
| | | self.__Instance = iNPC
|
| | | self.__MaxHurtPlayer = None # 最大伤血者,队伍取队长
|
| | | self.__LastHurtPlayer = None # 最后一击的玩家
|
| | | self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致
|
| | | self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者
|
| | |
| | | npcHurtList.Clear()
|
| | | return True
|
| | |
|
| | | def __IsBossHurtOfflineProtect(self, refreshPoint, playerID, tick):
|
| | | ## boss伤血是否掉线保护中
|
| | | # 是否离线超过3分钟,下线坐标是否不在boss区域等
|
| | | leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID)
|
| | | leavePos = PlayerControl.GetPlayerLeaveServerPos(playerID)
|
| | | if not leaveTick or not leavePos:
|
| | | GameWorld.DebugLog("玩家不在本地图或已长久离线!清除该伤血!playerID=%s" % playerID)
|
| | | return False
|
| | | |
| | | if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime:
|
| | | GameWorld.DebugLog("本地图离线玩家超过保护时长!清除该伤血!playerID=%s,tick=%s,leaveTick=%s" % (playerID, tick, leaveTick))
|
| | | return False
|
| | | |
| | | if not self.GetIsInRefreshPoint(leavePos[0], leavePos[1], refreshPoint):
|
| | | GameWorld.DebugLog("本地图离线玩家不在保护区域内!playerID=%s,leavePos=%s" % (playerID, leavePos))
|
| | | return False
|
| | | |
| | | return True
|
| | | |
| | | def __IsClearPlayerHurt(self, hurtPlayer, refreshPoint, hurtID, tick):
|
| | | if hurtPlayer == None:
|
| | | if not self.__IsBossHurtOfflineProtect(refreshPoint, hurtID, tick):
|
| | | return True
|
| | | |
| | | #GameWorld.DebugLog("本地图离线玩家伤血值保护中!playerID=%s" % (hurtID))
|
| | | return False
|
| | | |
| | | #if hurtPlayer.GetHP() <= 0:
|
| | | # GameWorld.DebugLog("伤血玩家血量为0,清除该伤血!playerID=%s" % hurtID)
|
| | | # return True
|
| | | |
| | | curNPC = self.__Instance
|
| | | if hurtPlayer.GetInitOK() and (not hurtPlayer.GetVisible() or hurtPlayer.GetSightLevel() != curNPC.GetSightLevel()):
|
| | | GameWorld.DebugLog("伤血玩家不可见,清除该伤血!playerID=%s" % hurtID)
|
| | | return True
|
| | | |
| | | if not self.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint):
|
| | | GameWorld.DebugLog("伤血玩家不在boss范围里,清除该伤血!playerID=%s" % hurtID)
|
| | | return True
|
| | | |
| | | if hurtPlayer.GetTeamID():
|
| | | # 这种情况一般是玩家未加入队伍前对该NPC有伤血,加入到某个队伍后,将该伤害转移到队伍中
|
| | | return True
|
| | | |
| | | if hurtPlayer.GetHP() <= 0 or hurtPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | deadTime = hurtPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
|
| | | if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
|
| | | #GameWorld.DebugLog("伤血玩家死亡超过伤血保护时长,清除该伤血!playerID=%s" % hurtID)
|
| | | return True
|
| | | |
| | | #GameWorld.DebugLog("正常玩家伤血保护中!playerID=%s" % hurtID)
|
| | | return False
|
| | | |
| | | def __GetTeamHurtNPCPlayerIDList(self, refreshPoint, teamID, tick):
|
| | | |
| | | curNPC = self.__Instance
|
| | | teamHurtPlayerIDList = []
|
| | | # 如果没有在线队员在有效范围内,则进一步判断离线队员是否有伤血保护中的
|
| | | playerMgr = GameWorld.GetPlayerManager()
|
| | | copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
|
| | | mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID) # 因为需要判断离线队员,所以只能用含离线的队伍缓存
|
| | | for playerID in mapTeamPlayerIDList:
|
| | | |
| | | curTeamPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if curTeamPlayer:
|
| | | if curTeamPlayer.GetCopyMapID() != copyMapID:
|
| | | #GameWorld.DebugLog("队员不在本线路,不计!playerID=%s" % playerID)
|
| | | continue
|
| | | |
| | | if curTeamPlayer.GetInitOK() and (not curTeamPlayer.GetVisible() or curTeamPlayer.GetSightLevel() != curNPC.GetSightLevel()):
|
| | | #GameWorld.DebugLog("队员不可见,不计!playerID=%s" % playerID)
|
| | | continue
|
| | | |
| | | if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | deadTime = curTeamPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
|
| | | if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
|
| | | #GameWorld.DebugLog("伤血队员死亡超过伤血保护时长,不计!playerID=%s" % playerID)
|
| | | continue
|
| | | |
| | | #if curTeamPlayer.GetHP() > 0 and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
|
| | | if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
|
| | | and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False):
|
| | | #GameWorld.DebugLog("有队员在boss范围内,保留队伍伤血!teamID=%s,playerID=%s" % (teamID, curTeamPlayer.GetPlayerID()))
|
| | | teamHurtPlayerIDList.append(playerID)
|
| | | else:
|
| | | if self.__IsBossHurtOfflineProtect(refreshPoint, playerID, tick):
|
| | | #GameWorld.DebugLog("有队员对boss离线伤血保护中!teamID=%s,playerID=%s" % (teamID, playerID))
|
| | | teamHurtPlayerIDList.append(playerID)
|
| | | |
| | | if not teamHurtPlayerIDList:
|
| | | GameWorld.DebugLog("伤血队伍没有符合条件的队员在boss区域内,清除该伤血!teamID=%s,mapTeamPlayerIDList=%s" % (teamID, mapTeamPlayerIDList))
|
| | | return teamHurtPlayerIDList
|
| | | |
| | | def RefreshHurtList(self, tick, refreshInterval=3000):
|
| | | ## 刷新伤血列表
|
| | | # @return: 可攻击的最大伤血数值对象 IPY_PlayerHurtValue
|
| | | |
| | | curNPC = self.__Instance
|
| | | if not curNPC.GetIsBoss() or GetDropOwnerType(curNPC) != ChConfig.DropOwnerType_MaxHurt:
|
| | | return
|
| | | |
| | | npcHurtList = curNPC.GetPlayerHurtList()
|
| | | if tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < (refreshInterval):
|
| | | if npcHurtList.GetHurtCount():
|
| | | return self.__GetAtkObjByHurtList(npcHurtList)
|
| | | return
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick)
|
| | | |
| | | hurtPlayerDict = {} # {playerID:teamID, ...}
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | hurtCount = npcHurtList.GetHurtCount()
|
| | | isInHurt = 0
|
| | | for index in xrange(hurtCount):
|
| | | #获得伤血对象
|
| | | hurtObj = npcHurtList.GetHurtAt(index)
|
| | | hurtType = hurtObj.GetValueType()
|
| | | hurtID = hurtObj.GetValueID()
|
| | | hurtValue = hurtObj.GetHurtValue()
|
| | | if not hurtID:
|
| | | continue
|
| | | |
| | | # Clear()只会把伤血类型及数值重置为0,不会清除该伤血数值对象
|
| | | |
| | | if hurtType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | hurtPlayer = GameWorld.GetObj(hurtID, IPY_GameWorld.gotPlayer)
|
| | | if self.__IsClearPlayerHurt(hurtPlayer, refreshPoint, hurtID, tick):
|
| | | hurtObj.Clear()
|
| | | teamID = 0 if not hurtPlayer else hurtPlayer.GetTeamID()
|
| | | if teamID:
|
| | | GameWorld.DebugLog("加入队伍,之气的伤血转移到队伍中!playerID=%s,teamID=%s" % (hurtID, teamID))
|
| | | AttackCommon.AddHurtValue(curNPC, teamID, ChConfig.Def_NPCHurtTypeTeam, hurtValue)
|
| | | else:
|
| | | isInHurt = 1
|
| | | hurtPlayerDict[hurtID] = 0
|
| | | |
| | | elif hurtType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | teamHurtPlayerIDList = self.__GetTeamHurtNPCPlayerIDList(refreshPoint, hurtID, tick)
|
| | | if not teamHurtPlayerIDList:
|
| | | hurtObj.Clear()
|
| | | else:
|
| | | isInHurt = 1
|
| | | for tPlayerID in teamHurtPlayerIDList:
|
| | | hurtPlayerDict[tPlayerID] = hurtID
|
| | | |
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | if IsMapNeedBossShunt(mapID):
|
| | | self.__UpdBossShuntInfo(mapID, hurtPlayerDict, tick)
|
| | | |
| | | #GameWorld.DebugLog("RefreshHurtList, hurtCount=%s,isInHurt=%s" % (hurtCount, isInHurt))
|
| | | npcHurtList.Sort()
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_InHurtProtect, isInHurt)
|
| | | |
| | | if hurtCount:
|
| | | # 排序后的,第一个可攻击的最大伤血对象
|
| | | return self.__GetAtkObjByHurtList(npcHurtList)
|
| | | return
|
| | | |
| | | def __UpdBossShuntInfo(self, mapID, hurtPlayerDict, tick):
|
| | | ## 更新本地图线路boss分流信息
|
| | | curNPC = self.__Instance
|
| | | npcID = curNPC.GetNPCID()
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | key = (mapID, lineID)
|
| | | shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})
|
| | | |
| | | shuntChange = False
|
| | | for playerID, shuntInfo in shuntPlayerDict.items():
|
| | | bossID, teamID, relatedTick = shuntInfo
|
| | | if bossID != npcID:
|
| | | # 不是该boss的伤害不处理
|
| | | continue
|
| | | |
| | | # 还在伤血中
|
| | | if playerID in hurtPlayerDict:
|
| | | newTeamID = hurtPlayerDict[playerID]
|
| | | if newTeamID != teamID:
|
| | | shuntPlayerDict[playerID] = [npcID, newTeamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 玩家对该boss的伤害变更队伍!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" |
| | | % (playerID, npcID, teamID, newTeamID), lineID)
|
| | | elif relatedTick:
|
| | | shuntPlayerDict[playerID] = [npcID, newTeamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 玩家对该boss的关联状态转为伤害状态!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" |
| | | % (playerID, npcID, teamID, newTeamID), lineID)
|
| | | |
| | | # 不在伤血中,更新关联tick
|
| | | elif not relatedTick:
|
| | | shuntPlayerDict[playerID] = [npcID, teamID, tick]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 玩家不在该boss伤血中,设置为关联状态!playerID=%s,npcID=%s,teamID=%s,tick=%s" |
| | | % (playerID, npcID, teamID, tick), lineID)
|
| | | |
| | | # 伤先优先级最高,可直接覆盖更新
|
| | | for playerID, teamID in hurtPlayerDict.items():
|
| | | if playerID not in shuntPlayerDict:
|
| | | shuntPlayerDict[playerID] = [npcID, teamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 新增玩家对boss伤害!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID)
|
| | | |
| | | elif shuntPlayerDict[playerID][0] != npcID:
|
| | | shuntPlayerDict[playerID] = [npcID, teamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 伤害转移到本boss上!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID)
|
| | | |
| | | if shuntChange:
|
| | | PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict
|
| | | GameServer_WorldBossShuntInfo(mapID, lineID)
|
| | | return
|
| | | |
| | | def __GetAtkObjByHurtList(self, npcHurtList):
|
| | | '''第一个可攻击的最大伤血对象,也是实际的归属者或队伍
|
| | | 因为玩家伤血掉线、死亡有一定时间的保留机制,故最大伤血不一定是可攻击目标(归属者)
|
| | | 注意: 该规则必须与最终算归属的规则一致,不然可能导致归属错乱
|
| | | '''
|
| | | for index in xrange(npcHurtList.GetHurtCount()):
|
| | | #获得伤血对象
|
| | | hurtObj = npcHurtList.GetHurtAt(index)
|
| | | |
| | | curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, True)
|
| | | |
| | | if curPlayer or curTeam:
|
| | | return hurtObj
|
| | | return
|
| | | |
| | | def IsInHurtProtect(self):
|
| | | '''NPC是否伤血保护中
|
| | | 因为手游比较会出现网络切换的情况,此时会可能会引起掉线重连
|
| | |
| | | self.ClearNPCHurtList()
|
| | | #清除所有身上buff
|
| | | self.ClearAllBuff(isClearAuraBuff)
|
| | | curNPC = self.__Instance
|
| | | NPCHurtManager.ClearPlayerHurtList(curNPC)
|
| | | return True
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | curNPC = self.__Instance
|
| | | self.__FeelPlayerList = []
|
| | |
|
| | | npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
|
| | | if not npcHurtList:
|
| | | npcHurtList = curNPC.GetPlayerHurtList()
|
| | | #npcHurtList.Sort() #这里不排序,只要有伤害就算
|
| | |
|
| | |
| | | #objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx()
|
| | | self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家
|
| | |
|
| | | isGameBoss = ChConfig.IsGameBoss(curNPC)
|
| | | self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo(isGameBoss)
|
| | |
| | | for curPlayer in self.__AllKillerDict.values():
|
| | | if not self.__LastHurtPlayer:
|
| | | self.__LastHurtPlayer = curPlayer
|
| | | if not self.__MaxHurtPlayer:
|
| | | self.__MaxHurtPlayer = curPlayer
|
| | | if not self.__Killer:
|
| | | self.__Killer = curPlayer
|
| | |
|
| | |
| | | if OnNPCDie:
|
| | | OnNPCDie(curNPC, hurtType, hurtID)
|
| | |
|
| | | #执行玩家连轧逻辑
|
| | | lastTimeHurtObj = self.__FindLastTimeHurtObj()
|
| | | if lastTimeHurtObj[0] == None and lastTimeHurtObj[1] == None:
|
| | | return
|
| | | |
| | | return
|
| | |
|
| | | ## 最后一击处理
|
| | |
| | | return
|
| | |
|
| | | curNPC = self.__Instance
|
| | | #npcID = curNPC.GetNPCID()
|
| | | #mapID = GameWorld.GetMap().GetMapID()
|
| | | #playerName = lastHurtPlayer.GetPlayerName()
|
| | | |
| | | #===========================================================================================
|
| | | # # 最后一击奖励
|
| | | # lastTimeHurtBossAwardDict = ReadChConfig.GetEvalChConfig("LastTimeHurtBossAward")
|
| | | # if npcID in lastTimeHurtBossAwardDict:
|
| | | # giveItemList = lastTimeHurtBossAwardDict[npcID]
|
| | | # playerID = lastHurtPlayer.GetPlayerID()
|
| | | # bossAwardMailInfo = ReadChConfig.GetEvalChConfig("LastTimeHurtBossAwardMail")
|
| | | # title, content, getDays = bossAwardMailInfo
|
| | | # mailContent = content % (npcID)
|
| | | # PlayerControl.SendMail(title, mailContent, getDays, [playerID], giveItemList)
|
| | | # |
| | | # # 广播
|
| | | # if len(giveItemList) > 0:
|
| | | # itemID = giveItemList[0][0] # 默认取第一个奖励物品广播
|
| | | # PlayerControl.WorldNotify(0, "GeRen_liubo_698214", [playerName, mapID, npcID, itemID, itemID])
|
| | | #===========================================================================================
|
| | | |
| | | #===========================================================================================
|
| | | # # 最后一击广播
|
| | | # LastHurtNotifyDict = ReadChConfig.GetEvalChConfig("LastHurtNotify")
|
| | | # for npcIDTuple, notifyMark in LastHurtNotifyDict.items():
|
| | | # if npcID in npcIDTuple:
|
| | | # PlayerControl.WorldNotify(0, notifyMark, [playerName, mapID, npcID])
|
| | | # break
|
| | | #===========================================================================================
|
| | |
|
| | | # VIP杀怪加攻
|
| | | PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, curNPC)
|
| | |
| | | if isGameBoss:
|
| | | GameWorld.Log(" 归属最大伤血队伍: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID()))
|
| | | return killerDict, curTeam, ChConfig.Def_NPCHurtTypeTeam, curTeam.GetTeamID()
|
| | | # 最大伤血玩家 - 伤血不会被重置
|
| | | elif dropOwnerType == ChConfig.DropOwnerType_MaxHurtPlayer:
|
| | | if self.__MaxHurtPlayer:
|
| | | maxHurtPlayerID = self.__MaxHurtPlayer.GetPlayerID()
|
| | | if maxHurtPlayerID not in killerDict:
|
| | | killerDict[maxHurtPlayerID] = self.__MaxHurtPlayer
|
| | | #GameWorld.DebugLog(" 特殊归属最大伤害玩家: playerID=%s" % maxHurtPlayerID)
|
| | | return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, maxHurtPlayerID
|
| | |
|
| | | # 最大仇恨
|
| | | elif dropOwnerType == ChConfig.DropOwnerType_MaxAngry:
|
| | |
| | | return curTag, GameWorld.GetTeamManager().FindTeam(teamID)
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ## 获取补刀者,包含队伍
|
| | | # @param self 类实例
|
| | | # @return 返回值 玩家或者None
|
| | | # @remarks |
| | | def __FindLastTimeHurtObj(self):
|
| | | curNPC = self.__Instance
|
| | | npcHurtList = curNPC.GetPlayerHurtList()
|
| | | if npcHurtList.GetHurtCount() <= 0:
|
| | | return (None, None)
|
| | | |
| | | maxHurtObj = npcHurtList.GetLastTimeHurtValue()
|
| | | return self.__GetTagByHurtObj(maxHurtObj)
|
| | |
|
| | |
|
| | | ## 获取补刀者(这个绝对是玩家)
|
| | | # @param self 类实例
|
| | |
| | | playerID = curNPC.GetDictByKey(ChConfig.Def_PlayerKey_LastHurt)
|
| | |
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return None
|
| | | |
| | | return curPlayer
|
| | | |
| | | def __FindBossMaxHurtObj(self):
|
| | | # py自定义伤血所得到的Boss最大伤血玩家
|
| | | curNPC = self.__Instance
|
| | | maxHurtID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_BossMaxHurtID % (curNPC.GetID(), curNPC.GetNPCID()))
|
| | | |
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(maxHurtID)
|
| | | if not curPlayer:
|
| | | return None
|
| | |
|
| | |
| | |
|
| | | if not self.__LastHurtPlayer:
|
| | | self.__LastHurtPlayer = playerlist[0]
|
| | | if not self.__MaxHurtPlayer:
|
| | | self.__MaxHurtPlayer = playerlist[0]
|
| | | if not self.__Killer:
|
| | | self.__Killer = playerlist[0]
|
| | | maxHurtID = playerlist[0].GetPlayerID()
|
| | |
| | | # 赶时间,先简单处理直接取最大等级的,之后可按实际情况来
|
| | | if not self.__LastHurtPlayer:
|
| | | self.__LastHurtPlayer = dropPlayer
|
| | | if not self.__MaxHurtPlayer:
|
| | | self.__MaxHurtPlayer = dropPlayer
|
| | | if not self.__Killer:
|
| | | self.__Killer = dropPlayer
|
| | | maxHurtID = dropPlayer.GetPlayerID()
|
| | |
| | | GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s"
|
| | | % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))
|
| | | if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
|
| | | maxHurtObj = self.RefreshHurtList(tick, refreshInterval)
|
| | | if maxHurtObj:
|
| | | ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID()
|
| | | if ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | tagObj = self.__GetMaxHurtTeamPlayer(ownerID, isDead)
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead)
|
| | | if maxHurtInfo:
|
| | | tagObj, ownerType, ownerID = maxHurtInfo
|
| | |
|
| | | elif dropOwnerType == ChConfig.DropOwnerType_Family:
|
| | | ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval)
|
| | |
| | | if isDead:
|
| | | GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))
|
| | |
|
| | | hurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
|
| | | # 刷新归属
|
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if curPlayer:
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if not hurtList or hurtList.HaveHurtValue(playerID):
|
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID
|
| | | killerDict[playerID] = curPlayer
|
| | | self.__AddDropOwnerPlayerBuff(curPlayer, tick)
|
| | | if dropOwnerType == ChConfig.DropOwnerType_Contend:
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, curNPC.GetID())
|
| | | else:
|
| | | BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | |
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | |
| | | continue
|
| | |
|
| | | if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \
|
| | | and (not hurtList or hurtList.HaveHurtValue(curTeamPlayer.GetPlayerID()))\
|
| | | and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
|
| | | and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible():
|
| | | self.__AddDropOwnerPlayerBuff(curTeamPlayer, tick)
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package NPCHurtManager
|
| | | #
|
| | | # @todo:NPC伤血管理
|
| | | # @author hxp
|
| | | # @date 2019-12-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: NPC伤血管理
|
| | | # 因为加入了协助系统,协助玩家暂无上限限制,所以总伤害会超过20亿
|
| | | # 原伤血列表不支持协助、不支持总伤害超过20亿,故重写一套py版伤血管理,函数命名与c++接口提供的函数名一致
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-12-06 21:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PyGameData
|
| | | import PlayerAssist
|
| | | import AttackCommon
|
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import ChPyNetSendPack
|
| | | import ItemControler
|
| | | import NetPackCommon
|
| | | import IpyGameDataPY
|
| | | import ShareDefine
|
| | | import PlayerTeam
|
| | | import NPCCommon
|
| | | import ChConfig
|
| | |
|
| | | import time
|
| | |
|
| | |
|
| | | class HurtValueObj():
|
| | | ''' 伤血对象,可能是玩家、队伍等,支持协助信息等
|
| | | '''
|
| | | |
| | | def __init__(self):
|
| | | self.__hurtID = 0
|
| | | self.__hurtType = ChConfig.Def_NPCHurtTypePlayer # 均默认是玩家
|
| | | self.__hurtName = ""
|
| | | self.__hurtValue = 0
|
| | | return
|
| | | |
| | | def GetValueID(self): return self.__hurtID
|
| | | def SetValueID(self, hurtID): self.__hurtID = hurtID
|
| | | def GetValueType(self): return self.__hurtType
|
| | | def SetValueType(self, hurtType): self.__hurtType = hurtType
|
| | | def GetHurtName(self): return self.__hurtName
|
| | | def SetHurtName(self, hurtName): self.__hurtName = hurtName
|
| | | def GetHurtValue(self): return self.__hurtValue
|
| | | def SetHurtValue(self, hurtValue): self.__hurtValue = hurtValue
|
| | | |
| | | class PlayerHurtList():
|
| | | ''' 伤血列表, 类似 IPY_GameObj.IPY_PlayerHurtList
|
| | | '''
|
| | | |
| | | def __init__(self, lineID, objID, npcID):
|
| | | GameWorld.DebugLog("初始化NPC伤血列表实例!", npcID, lineID)
|
| | | self.lineID = lineID
|
| | | self.objID = objID
|
| | | self.npcID = npcID
|
| | | self.curNPC = GameWorld.FindNPCByID(objID)
|
| | | self.__noAssitPlayerIDDict = {} # 非协助玩家ID字典 {playerID:[assistPlayerID, ...], ...}
|
| | | self.__assistPlayerIDDict = {} # 协助玩家对应目标ID字典 {assistPlayerID:tagPlayerID, ...}
|
| | | self.__hurtPlayerDict = {} # 所有伤血玩家个体实例字典,含协助玩家 {playerID:HurtValueObj, ...}
|
| | | |
| | | self.__hurtSortList = []
|
| | | self.__hurtDict = {} # 伤血列表实例字典,实际的NPC伤血列表实例,可能不是玩家{(hurtID, hurtType):HurtValueObj, ...}
|
| | | return
|
| | | |
| | | def Clear(self):
|
| | | # 在NPC触发重置伤血时重置,不重置协助关系及伤血玩家实例,只重置伤血值
|
| | | |
| | | GameWorld.DebugLog("Clear重置NPC伤血!", self.npcID, self.lineID)
|
| | | self.__hurtSortList = []
|
| | | self.__hurtDict = {}
|
| | | # 重置所有玩家伤血值
|
| | | for hurtObj in self.__hurtPlayerDict.values():
|
| | | hurtObj.SetHurtValue(0)
|
| | | return
|
| | | |
| | | def OnDelete(self):
|
| | | # 删除伤血列表,NPC死亡调用
|
| | | |
| | | cancelPlayerIDList = self.__noAssitPlayerIDDict.keys()
|
| | | if cancelPlayerIDList:
|
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | queryData = [mapID, self.lineID, self.npcID, self.objID, "OnBossDead", cancelPlayerIDList]
|
| | | PlayerAssist.QueryGameServer_PlayerAssist(0, "OnCancelBossRequestAssist", queryData)
|
| | | |
| | | return
|
| | | |
| | | def __GetHurtTypeObj(self, hurtID, hurtType, hurtName=""):
|
| | | ## 获取伤血列表伤血类型实例
|
| | | hurtObj = None
|
| | | hurtKey = (hurtID, hurtType)
|
| | | if hurtKey not in self.__hurtDict:
|
| | | GameWorld.DebugLog("添加伤血列表对象: hurtID=%s,hurtType=%s" % (hurtID, hurtType), self.npcID, self.lineID)
|
| | | hurtObj = HurtValueObj()
|
| | | hurtObj.SetValueID(hurtID)
|
| | | hurtObj.SetValueType(hurtType)
|
| | | hurtObj.SetHurtName(hurtName)
|
| | | self.__hurtDict[hurtKey] = hurtObj
|
| | | hurtObj = self.__hurtDict[hurtKey]
|
| | | return hurtObj
|
| | | |
| | | def __GetHurtPlayer(self, playerID, playerName=""):
|
| | | ## 获取伤血玩家实例, 每个玩家独立, 且伤血独立统计
|
| | | hurtPlayer = None
|
| | | if playerID not in self.__hurtPlayerDict:
|
| | | GameWorld.DebugLog("添加伤血玩家: playerID=%s,playerName=%s" % (playerID, playerName), self.npcID, self.lineID)
|
| | | hurtPlayer = HurtValueObj()
|
| | | hurtPlayer.SetValueID(playerID)
|
| | | #hurtPlayer.SetHurtName(playerName)
|
| | | self.__hurtPlayerDict[playerID] = hurtPlayer
|
| | | hurtPlayer = self.__hurtPlayerDict[playerID]
|
| | | # 因为伤血玩家可能在某些情况下创建了没有名字的实例,所以这里在有传入名字时进行强制更新
|
| | | if playerName:
|
| | | hurtPlayer.SetHurtName(playerName)
|
| | | return hurtPlayer
|
| | | |
| | | def AddAssistPlayer(self, assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID):
|
| | | ## 添加助战玩家
|
| | | # @param assistPlayerID: 协助玩家ID
|
| | | # @param tagPlayerID: 目标玩家ID,即发布协助的玩家ID
|
| | | |
| | | if assistPlayerID == tagPlayerID:
|
| | | # 不能协助自己
|
| | | return
|
| | | |
| | | if tagPlayerID not in self.__noAssitPlayerIDDict or tagPlayerID not in self.__hurtPlayerDict:
|
| | | GameWorld.ErrLog("新增协助玩家异常,不存在该常规伤血玩家,无法协助他!assistPlayerID=%s,tagPlayerID=%s" |
| | | % (assistPlayerID, tagPlayerID), self.npcID, self.lineID)
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("新增协助玩家: assistPlayerID=%s,tagPlayerID=%s,tagTeamID=%s" |
| | | % (assistPlayerID, tagPlayerID, tagTeamID), self.npcID, self.lineID)
|
| | | |
| | | if assistPlayerID in self.__noAssitPlayerIDDict:
|
| | | GameWorld.DebugLog("原来为常规玩家,需要先删除!", self.npcID, self.lineID)
|
| | | self.DelHurtPlayer(assistPlayerID, "BecomeAssistPlayer")
|
| | | |
| | | assistPlayerIDList = self.__noAssitPlayerIDDict[tagPlayerID]
|
| | | if assistPlayerID not in assistPlayerIDList:
|
| | | assistPlayerIDList.append(assistPlayerID)
|
| | | self.__assistPlayerIDDict[assistPlayerID] = tagPlayerID
|
| | | |
| | | GameWorld.DebugLog(" self.__noAssitPlayerIDDict=%s" % (self.__noAssitPlayerIDDict), self.npcID, self.lineID)
|
| | | GameWorld.DebugLog(" self.__assistPlayerIDDict=%s" % (self.__assistPlayerIDDict), self.npcID, self.lineID)
|
| | | return
|
| | | |
| | | def DelHurtPlayer(self, playerID, reason, isMapServerDel=True):
|
| | | ## 删除伤血玩家, 可能由地图、GameServer触发删除
|
| | | |
| | | if playerID not in self.__hurtPlayerDict:
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("删除伤血玩家: playerID=%s,reason=%s,isMapServerDel=%s" % (playerID, reason, isMapServerDel), self.npcID, self.lineID)
|
| | | |
| | | #非协助玩家
|
| | | if playerID in self.__noAssitPlayerIDDict:
|
| | | # 先清玩家伤血
|
| | | self.__ClearPlayerHurt(playerID)
|
| | | |
| | | assistPlayerIDList = self.__noAssitPlayerIDDict.pop(playerID, [])
|
| | | GameWorld.DebugLog(" 是常规玩家,同时删除协助玩家: assistPlayerIDList=%s" % assistPlayerIDList, self.npcID, self.lineID)
|
| | | |
| | | # 强制删除所有协助该玩家,列表倒序删
|
| | | for assistPlayerID in assistPlayerIDList[::-1]:
|
| | | self.DelHurtPlayer(assistPlayerID, "RequestPlayerCancel_%s" % reason, isMapServerDel)
|
| | | |
| | | # 地图删除的同步GameServer
|
| | | if isMapServerDel:
|
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | cancelPlayerIDList = [playerID]
|
| | | queryData = [mapID, self.lineID, self.npcID, self.objID, reason, cancelPlayerIDList]
|
| | | PlayerAssist.QueryGameServer_PlayerAssist(0, "OnCancelBossRequestAssist", queryData)
|
| | | |
| | | # 协助玩家
|
| | | elif playerID in self.__assistPlayerIDDict:
|
| | | # 先清玩家伤血
|
| | | self.__ClearPlayerHurt(playerID)
|
| | | |
| | | tagPlayerID = self.__assistPlayerIDDict.pop(playerID, 0)
|
| | | |
| | | # 移除协助对应关系
|
| | | if tagPlayerID in self.__noAssitPlayerIDDict:
|
| | | assistPlayerIDList = self.__noAssitPlayerIDDict[tagPlayerID]
|
| | | if playerID in assistPlayerIDList:
|
| | | assistPlayerIDList.remove(playerID)
|
| | | GameWorld.DebugLog(" 是协助玩家,删除协助关系: tagPlayerID=%s,assistPlayerIDList=%s" |
| | | % (tagPlayerID, self.__noAssitPlayerIDDict[tagPlayerID]), self.npcID, self.lineID)
|
| | | |
| | | # 地图删除的同步GameServer
|
| | | if isMapServerDel:
|
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | queryData = [mapID, self.lineID, self.npcID, self.objID, reason]
|
| | | PlayerAssist.QueryGameServer_PlayerAssist(playerID, "OnCancelBossAssist", queryData)
|
| | | |
| | | self.__hurtPlayerDict.pop(playerID) # 放在最后pop伤血实例
|
| | | |
| | | if not self.__hurtPlayerDict:
|
| | | GameWorld.DebugLog("没有伤血玩家了!", self.npcID, self.lineID)
|
| | | self.Clear()
|
| | | |
| | | return
|
| | | |
| | | def HaveHurtValue(self, playerID):
|
| | | ## 是否对该boss有伤害贡献
|
| | | |
| | | if playerID not in self.__hurtPlayerDict:
|
| | | return False
|
| | | |
| | | hurtPlayer = self.__GetHurtPlayer(playerID)
|
| | | if hurtPlayer.GetHurtValue():
|
| | | return True
|
| | | |
| | | if playerID in self.__noAssitPlayerIDDict:
|
| | | assistPlayerIDList = self.__noAssitPlayerIDDict[playerID]
|
| | | for assistPlayerID in assistPlayerIDList:
|
| | | assHurtPlayer = self.__GetHurtPlayer(assistPlayerID)
|
| | | if assHurtPlayer.GetHurtValue():
|
| | | return True
|
| | | |
| | | return False
|
| | | |
| | | def GetPlayerHurtDetail(self, playerID):
|
| | | ## 玩家伤血输出明细 - 暂时GM命令输出数据用
|
| | | # @return: hurtValue, {assistPlayerID:hurtValue, ...}
|
| | | |
| | | if playerID in self.__noAssitPlayerIDDict:
|
| | | hurtPlayer = self.__GetHurtPlayer(playerID)
|
| | | assistPlayerHurtDict = {}
|
| | | assistPlayerIDList = self.__noAssitPlayerIDDict[playerID]
|
| | | for assistPlayerID in assistPlayerIDList:
|
| | | assHurtPlayer = self.__GetHurtPlayer(assistPlayerID)
|
| | | assistPlayerHurtDict[assistPlayerID] = assHurtPlayer.GetHurtValue()
|
| | | return hurtPlayer.GetHurtValue(), assistPlayerHurtDict
|
| | | |
| | | if playerID in self.__assistPlayerIDDict:
|
| | | assHurtPlayer = self.__GetHurtPlayer(playerID)
|
| | | return assHurtPlayer.GetHurtValue(), {}
|
| | | |
| | | return 0, {}
|
| | | |
| | | def GetNoAssitPlayerIDDict(self): return self.__noAssitPlayerIDDict
|
| | | def GetAssistPlayerIDDict(self): return self.__assistPlayerIDDict
|
| | | |
| | | def IsNoAssistPlayer(self, playerID):
|
| | | ## 是否非助战伤血玩家
|
| | | return playerID in self.__noAssitPlayerIDDict
|
| | | |
| | | def IsAssistPlayer(self, playerID):
|
| | | ## 是否助战伤血玩家
|
| | | return playerID in self.__assistPlayerIDDict
|
| | | |
| | | def OnHurtPlayerEnterTeam(self, playerID, playerName, befTeamID, newTeam, tick):
|
| | | ''' 伤血玩家加入队伍
|
| | | 个人伤害并入队伍伤害,个人所有协助玩家伤害重新统计,表现在协助伤害排行榜,协助玩家之后的伤害计入队伍伤害
|
| | | '''
|
| | | if playerID not in self.__noAssitPlayerIDDict:
|
| | | # 只处理非协助玩家
|
| | | return
|
| | | |
| | | newTeamID = newTeam.GetTeamID()
|
| | | |
| | | if befTeamID:
|
| | | # 因为必须是先退队再进队的,所以进入队伍时不存在有之前队伍ID的情况
|
| | | GameWorld.ErrLog("玩家进入时已有队伍!playerID=%s,befTeamID=%s,newTeamID=%s" % (playerID, befTeamID, newTeamID), self.npcID, self.lineID)
|
| | | return
|
| | | |
| | | # 更新玩家个人伤血类型、ID
|
| | | hurtPlayer = self.__GetHurtPlayer(playerID, playerName)
|
| | | hurtPlayer.SetValueType(ChConfig.Def_NPCHurtTypeTeam)
|
| | | hurtPlayer.SetValueID(newTeamID)
|
| | | |
| | | # 删除个人伤血列表实例
|
| | | playerTotalHurt = 0
|
| | | playerHurtKey = (playerID , ChConfig.Def_NPCHurtTypePlayer)
|
| | | if playerHurtKey in self.__hurtDict:
|
| | | playerHurtObj = self.__hurtDict.pop(playerHurtKey)
|
| | | playerTotalHurt = playerHurtObj.GetHurtValue()
|
| | | |
| | | GameWorld.DebugLog("常规伤血玩家加入队伍: playerID=%s,playerTotalHurt=%s,newTeamID=%s" |
| | | % (playerID, playerTotalHurt, newTeamID), self.npcID, self.lineID)
|
| | | |
| | | # 伤血并入队伍伤血
|
| | | if playerTotalHurt:
|
| | | teamHurtObj = self.__GetHurtTypeObj(newTeamID , ChConfig.Def_NPCHurtTypeTeam, playerName)
|
| | | teamHurtValue = teamHurtObj.GetHurtValue()
|
| | | updTeamHurtValue = teamHurtValue + playerTotalHurt
|
| | | teamHurtObj.SetHurtValue(updTeamHurtValue)
|
| | | GameWorld.DebugLog(" 个人总伤血并入新队伍伤血: teamHurtValue=%s,playerTotalHurt=%s,updTeamHurtValue=%s" |
| | | % (teamHurtValue, playerTotalHurt, updTeamHurtValue), self.npcID, self.lineID)
|
| | | self.__UpdHurtTeamName(newTeamID)
|
| | | |
| | | self.Sort()
|
| | | return
|
| | | |
| | | def OnHurtPlayerLeaveTeam(self, playerID, leaveTeamID, tick):
|
| | | ''' 伤血玩家退出队伍
|
| | | 原队伍伤害不变,个人及所有协助玩家伤害重新计算,协助玩家之后的伤害计入个人伤害;
|
| | | 离线被踢离队的情况协助玩家可继续协助输出并获得协助奖励,伤害计入个人,但是离线玩家无法获得归属
|
| | | '''
|
| | | if playerID not in self.__noAssitPlayerIDDict:
|
| | | # 只处理非协助玩家
|
| | | return
|
| | | |
| | | # 玩家个人伤血类型、ID
|
| | | hurtPlayer = self.__GetHurtPlayer(playerID)
|
| | | hurtPlayer.SetValueType(ChConfig.Def_NPCHurtTypePlayer)
|
| | | hurtPlayer.SetValueID(playerID)
|
| | | |
| | | # 统计个人及协助总伤害
|
| | | playerTotalHurt = hurtPlayer.GetHurtValue()
|
| | | assistPlayerIDList = self.__noAssitPlayerIDDict.get(playerID, [])
|
| | | for assistPlayerID in assistPlayerIDList:
|
| | | assistHurtPlayer = self.__GetHurtPlayer(assistPlayerID)
|
| | | playerTotalHurt += assistHurtPlayer.GetHurtValue()
|
| | | |
| | | GameWorld.DebugLog("常规伤血玩家离开队伍: playerID=%s,playerTotalHurt=%s,leaveTeamID=%s" |
| | | % (playerID, playerTotalHurt, leaveTeamID), self.npcID, self.lineID)
|
| | | |
| | | if not playerTotalHurt:
|
| | | return
|
| | | |
| | | # 原队伍扣除对应伤害
|
| | | teamHurtKey = (leaveTeamID , ChConfig.Def_NPCHurtTypeTeam)
|
| | | if teamHurtKey in self.__hurtDict:
|
| | | teamHurtObj = self.__hurtDict[teamHurtKey]
|
| | | teamHurtValue = teamHurtObj.GetHurtValue()
|
| | | updTeamHurtValue = max(0, teamHurtValue - playerTotalHurt)
|
| | | teamHurtObj.SetHurtValue(updTeamHurtValue)
|
| | | GameWorld.DebugLog(" 原队伍伤害扣除: teamHurtValue=%s,playerTotalHurt=%s,updTeamHurtValue=%s" |
| | | % (teamHurtValue, playerTotalHurt, updTeamHurtValue), self.npcID, self.lineID)
|
| | | self.__UpdHurtTeamName(leaveTeamID)
|
| | | |
| | | # 创建新个人伤害列表实例
|
| | | newHurtObj = self.__GetHurtTypeObj(playerID, ChConfig.Def_NPCHurtTypePlayer, hurtPlayer.GetHurtName())
|
| | | newHurtObj.SetHurtValue(playerTotalHurt)
|
| | | |
| | | self.Sort()
|
| | | return
|
| | | |
| | | def __UpdHurtTeamName(self, teamID):
|
| | | ## 更新队伍伤血名称,队长在优先使用队长名字,否则使用任意一个在线攻击此boss的非协助队员名
|
| | | |
| | | hurtTeamObj = self.__GetHurtTypeObj(teamID , ChConfig.Def_NPCHurtTypeTeam)
|
| | | |
| | | updName = ""
|
| | | copyPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID)
|
| | | for memPlayerID in mapTeamPlayerIDList:
|
| | | if memPlayerID not in self.__noAssitPlayerIDDict:
|
| | | continue
|
| | | player = copyPlayerManager.FindPlayerByID(memPlayerID)
|
| | | if not player:
|
| | | continue
|
| | | playerName = player.GetPlayerName()
|
| | | if player.GetTeamLV() == IPY_GameWorld.tmlLeader:
|
| | | hurtTeamObj.SetHurtName(playerName)
|
| | | GameWorld.DebugLog(" 更新队伍名称,使用队长名称!teamID=%s" % teamID, self.npcID, self.lineID)
|
| | | return
|
| | | if not updName:
|
| | | updName = playerName
|
| | | |
| | | if updName:
|
| | | hurtTeamObj.SetHurtName(updName)
|
| | | GameWorld.DebugLog(" 更新队伍名称,使用队员名称!teamID=%s" % teamID, self.npcID, self.lineID)
|
| | | return
|
| | | |
| | | def AddPlayerHurtValue(self, atkPlayerID, atkName, value, atkTeamID=0, isSort=False):
|
| | | ## 添加玩家伤血
|
| | | |
| | | tagPlayerID = 0 # 协助目标玩家ID
|
| | | atkHurtPlayer = self.__GetHurtPlayer(atkPlayerID, atkName)
|
| | | if atkPlayerID in self.__assistPlayerIDDict:
|
| | | tagPlayerID = self.__assistPlayerIDDict[atkPlayerID]
|
| | | tagHurtPlayer = self.__GetHurtPlayer(tagPlayerID)
|
| | | tagPlayerName = tagHurtPlayer.GetHurtName()
|
| | | hurtID, hurtType = tagHurtPlayer.GetValueID(), tagHurtPlayer.GetValueType()
|
| | | #GameWorld.DebugLog("协助玩家伤血: atkPlayerID=%s,value=%s,tagPlayerID=%s" % (atkPlayerID, value, tagPlayerID), self.npcID, self.lineID)
|
| | | |
| | | else:
|
| | | if atkTeamID:
|
| | | hurtID, hurtType = atkTeamID, ChConfig.Def_NPCHurtTypeTeam
|
| | | else:
|
| | | hurtID, hurtType = atkPlayerID, ChConfig.Def_NPCHurtTypePlayer
|
| | | atkHurtPlayer.SetValueType(hurtType)
|
| | | atkHurtPlayer.SetValueID(hurtID)
|
| | | if atkPlayerID not in self.__noAssitPlayerIDDict:
|
| | | self.__noAssitPlayerIDDict[atkPlayerID] = []
|
| | | GameWorld.DebugLog("新增常规玩家: atkPlayerID=%s" % (atkPlayerID), self.npcID, self.lineID)
|
| | | #GameWorld.DebugLog("常规玩家伤血: atkPlayerID=%s,value=%s" % (atkPlayerID, value), self.npcID, self.lineID)
|
| | | |
| | | hurtObj = self.__GetHurtTypeObj(hurtID, hurtType, tagPlayerName if tagPlayerID else atkName)
|
| | | |
| | | # 伤血列表伤血累加
|
| | | befValue = hurtObj.GetHurtValue()
|
| | | updValue = befValue + value
|
| | | hurtObj.SetHurtValue(updValue)
|
| | | isNewHurt = befValue == 0 and updValue > 0
|
| | | |
| | | # 伤血玩家伤血累加,这个仅伤血玩家自己的个人输出,非伤血列表中的汇总输出
|
| | | updAtkHurtValue = atkHurtPlayer.GetHurtValue() + value
|
| | | atkHurtPlayer.SetHurtValue(updAtkHurtValue)
|
| | | |
| | | #GameWorld.DebugLog(" hurtID=%s,hurtType=%s,hurtValue=%s (%s + %s) updAtkHurtValue=%s" |
| | | # % (hurtID, hurtType, updValue, befValue, value, updAtkHurtValue), self.npcID, self.lineID)
|
| | | |
| | | if isNewHurt or isSort:
|
| | | self.Sort()
|
| | | |
| | | return
|
| | | |
| | | def RefreshHurtList(self, tick, refreshInterval=3000, isDead=False):
|
| | | ## 刷新伤血列表
|
| | | # @return: atkPlayer, hurtID, hurtType
|
| | | |
| | | curNPC = self.curNPC
|
| | | if not self.__hurtDict:
|
| | | return
|
| | | |
| | | if not isDead:
|
| | | if refreshInterval and tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < refreshInterval:
|
| | | return self.__GetAtkObjByHurtList()
|
| | | |
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick)
|
| | | |
| | | hurtPlayerDict = {} # {playerID:teamID, ...}
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | for hurtKey in self.__hurtDict.keys():
|
| | | #获得伤血对象
|
| | | hurtID, hurtType = hurtKey
|
| | | if not hurtID:
|
| | | continue
|
| | | |
| | | if hurtType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | teamID = 0
|
| | | playerID = hurtID
|
| | | if self.__UnAssistPlayerHurtValidLogic(playerID, refreshPoint, tick):
|
| | | hurtPlayerDict[playerID] = teamID
|
| | | |
| | | elif hurtType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | teamID = hurtID
|
| | | mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID)
|
| | | for teamPlayerID in mapTeamPlayerIDList:
|
| | | if self.__UnAssistPlayerHurtValidLogic(teamPlayerID, refreshPoint, tick):
|
| | | hurtPlayerDict[teamPlayerID] = teamID
|
| | | |
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | if NPCCommon.IsMapNeedBossShunt(mapID):
|
| | | self.__UpdBossShuntInfo(mapID, hurtPlayerDict, tick)
|
| | | |
| | | self.Sort()
|
| | | |
| | | if isDead:
|
| | | self.__DoGiveAssistAward()
|
| | | |
| | | isInHurt = self.__hurtSortList != []
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_InHurtProtect, isInHurt)
|
| | | return self.__GetAtkObjByHurtList()
|
| | | |
| | | def __UnAssistPlayerHurtValidLogic(self, playerID, refreshPoint, tick):
|
| | | ## 非协助玩家伤血有效性检查逻辑
|
| | | |
| | | valid = False
|
| | | checkPlayerIDList = [playerID] + self.__noAssitPlayerIDDict.get(playerID, []) # 检查所有有关系的玩家ID
|
| | | for checkPlayerID in checkPlayerIDList:
|
| | | if self.__IsPlayerHurtValid(checkPlayerID, refreshPoint, tick):
|
| | | valid = True
|
| | | else:
|
| | | self.__ClearPlayerHurt(checkPlayerID)
|
| | | |
| | | return valid
|
| | | |
| | | def __IsPlayerHurtValid(self, playerID, refreshPoint, tick):
|
| | | ## 玩家伤血是否还有效
|
| | | |
| | | if playerID not in self.__hurtPlayerDict:
|
| | | return False
|
| | | |
| | | hurtPlayer = self.__GetHurtPlayer(playerID)
|
| | | hurtValue = hurtPlayer.GetHurtValue()
|
| | | if not hurtValue:
|
| | | return False
|
| | | |
| | | player = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(playerID)
|
| | | if player:
|
| | | if playerID in self.__noAssitPlayerIDDict:
|
| | | if not AttackCommon.CheckKillNPCByCnt(player, self.curNPC, False):
|
| | | GameWorld.DebugLog("非协助伤血玩家没有攻击boss次数,不计!playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | if player.GetInitOK() and (not player.GetVisible() or player.GetSightLevel() != self.curNPC.GetSightLevel()):
|
| | | GameWorld.DebugLog("伤血玩家不可见,不计!playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | if player.GetHP() <= 0 or player.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | deadTime = player.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
|
| | | if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
|
| | | GameWorld.DebugLog("伤血玩家死亡超过伤血保护时长,不计!playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | if not self.__GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):
|
| | | GameWorld.DebugLog("伤血玩家不在boss范围内,不计!playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | return True
|
| | | |
| | | else:
|
| | | |
| | | # 是否离线超过3分钟,下线坐标是否不在boss区域等
|
| | | leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID)
|
| | | leavePos = PlayerControl.GetPlayerLeaveServerPos(playerID)
|
| | | if not leaveTick or not leavePos:
|
| | | GameWorld.DebugLog("伤血玩家不在本地图或已长久离线,不计!playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime:
|
| | | GameWorld.DebugLog("伤血离线玩家超过保护时长,不计!playerID=%s,tick=%s,leaveTick=%s" % (playerID, tick, leaveTick), self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | if not self.__GetIsInRefreshPoint(leavePos[0], leavePos[1], refreshPoint):
|
| | | GameWorld.DebugLog("伤血离线玩家不在保护区域内,不计!playerID=%s,leavePos=%s" % (playerID, leavePos), self.npcID, self.lineID)
|
| | | return False
|
| | | |
| | | return True
|
| | | |
| | | return False
|
| | | |
| | | def __ClearPlayerHurt(self, playerID):
|
| | | ## 清除玩家伤血,不删实例
|
| | | |
| | | if playerID not in self.__hurtPlayerDict:
|
| | | return
|
| | | |
| | | hurtPlayer = self.__GetHurtPlayer(playerID)
|
| | | hurtValue = hurtPlayer.GetHurtValue()
|
| | | if not hurtValue:
|
| | | return
|
| | | hurtPlayer.SetHurtValue(0)
|
| | | |
| | | # 协助玩家
|
| | | if playerID in self.__assistPlayerIDDict:
|
| | | tagPlayerID = self.__assistPlayerIDDict[playerID]
|
| | | tagHurtPlayer = self.__GetHurtPlayer(tagPlayerID)
|
| | | hurtID = tagHurtPlayer.GetValueID()
|
| | | hurtType = tagHurtPlayer.GetValueType()
|
| | | else:
|
| | | hurtID = hurtPlayer.GetValueID()
|
| | | hurtType = hurtPlayer.GetValueType()
|
| | | |
| | | GameWorld.DebugLog(" 清除玩家伤血: playerID=%s,hurtValue=%s,hurtID=%s,hurtType=%s" |
| | | % (playerID, hurtValue, hurtID, hurtType), self.npcID, self.lineID)
|
| | | |
| | | hurtKey = (hurtID, hurtType)
|
| | | if hurtKey not in self.__hurtDict:
|
| | | return
|
| | | |
| | | # 扣除伤血列表实例伤血
|
| | | hurtObj = self.__GetHurtTypeObj(hurtID, hurtType)
|
| | | befValue = hurtObj.GetHurtValue()
|
| | | updValue = max(0, befValue - hurtValue)
|
| | | hurtObj.SetHurtValue(updValue)
|
| | | GameWorld.DebugLog(" 扣除伤血更新: hurtID=%s,hurtType=%s,befValue=%s,updValue=%s" |
| | | % (hurtID, hurtType, befValue, updValue), self.npcID, self.lineID)
|
| | | |
| | | if not updValue:
|
| | | self.__hurtDict.pop(hurtKey)
|
| | | else:
|
| | | # 如果是非协助玩家队伍队员伤血被清,则更新伤血队伍名称
|
| | | if playerID in self.__noAssitPlayerIDDict and hurtType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | self.__UpdHurtTeamName(hurtID)
|
| | | |
| | | return
|
| | | |
| | | def __GetAtkObjByHurtList(self):
|
| | | '''第一个可攻击的最大伤血对象,也是实际的归属者或队伍
|
| | | 因为玩家伤血掉线、死亡有一定时间的保留机制,故最大伤血不一定是可攻击目标(归属者)
|
| | | 注意: 该规则必须与最终算归属的规则一致,不然可能导致归属错乱
|
| | | @return: atkPlayer, hurtType, hurtID
|
| | | '''
|
| | | |
| | | atkPlayer, atkHurtType, atkHurtID = None, 0, 0
|
| | | curNPC = self.curNPC
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | for hurtObj in self.__hurtSortList:
|
| | | |
| | | hurtID = hurtObj.GetValueID()
|
| | | hurtType = hurtObj.GetValueType()
|
| | | |
| | | playerIDList = []
|
| | | if hurtType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | assistPlayerIDList = self.__noAssitPlayerIDDict.get(hurtID, [])
|
| | | playerIDList = [hurtID] + assistPlayerIDList
|
| | | |
| | | elif hurtType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | teamID = hurtID
|
| | | mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID)
|
| | | for teamPlayerID in mapTeamPlayerIDList:
|
| | | if teamPlayerID not in self.__noAssitPlayerIDDict:
|
| | | continue
|
| | | playerIDList.append(teamPlayerID)
|
| | | assistPlayerIDList = self.__noAssitPlayerIDDict.get(teamPlayerID, [])
|
| | | playerIDList.extend(assistPlayerIDList)
|
| | | |
| | | else:
|
| | | continue
|
| | | |
| | | maxHurtValue = 0
|
| | | for playerID in playerIDList:
|
| | | |
| | | player = GameWorld.GetObj(playerID, IPY_GameWorld.gotPlayer)
|
| | | if player == None:
|
| | | continue
|
| | | |
| | | if player.GetHP() <= 0 or player.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | continue
|
| | | |
| | | if not player.GetVisible() or player.GetSightLevel() != curNPC.GetSightLevel():
|
| | | continue
|
| | | |
| | | if not self.__GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):
|
| | | continue
|
| | | |
| | | if playerID not in self.__hurtPlayerDict:
|
| | | continue
|
| | | hurtPlayer = self.__hurtPlayerDict[playerID]
|
| | | hurtValue = hurtPlayer.GetHurtValue() |
| | | if hurtValue > maxHurtValue:
|
| | | maxHurtValue = hurtValue
|
| | | atkPlayer, atkHurtType, atkHurtID = player, hurtType, hurtID
|
| | | |
| | | if maxHurtValue:
|
| | | return atkPlayer, atkHurtType, atkHurtID
|
| | | |
| | | return atkPlayer, atkHurtType, atkHurtID
|
| | | |
| | | def __GetIsInRefreshPoint(self, curPosX, curPosY, refreshPoint):
|
| | | if not refreshPoint:
|
| | | return False
|
| | | |
| | | if (curPosX >= refreshPoint.GetPosX() - refreshPoint.GetMoveDist() and
|
| | | curPosX <= refreshPoint.GetPosX() + refreshPoint.GetMoveDist() and
|
| | | curPosY >= refreshPoint.GetPosY() - refreshPoint.GetMoveDist() and
|
| | | curPosY <= refreshPoint.GetPosY() + refreshPoint.GetMoveDist()):
|
| | | return True
|
| | | |
| | | return False
|
| | | |
| | | def __UpdBossShuntInfo(self, mapID, hurtPlayerDict, tick):
|
| | | ## 更新本地图线路boss分流信息
|
| | | npcID = self.npcID
|
| | | lineID = self.lineID
|
| | | key = (mapID, lineID)
|
| | | shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})
|
| | | |
| | | shuntChange = False
|
| | | for playerID, shuntInfo in shuntPlayerDict.items():
|
| | | bossID, teamID, relatedTick = shuntInfo
|
| | | if bossID != npcID:
|
| | | # 不是该boss的伤害不处理
|
| | | continue
|
| | | |
| | | # 还在伤血中
|
| | | if playerID in hurtPlayerDict:
|
| | | newTeamID = hurtPlayerDict[playerID]
|
| | | if newTeamID != teamID:
|
| | | shuntPlayerDict[playerID] = [npcID, newTeamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 玩家对该boss的伤害变更队伍!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" |
| | | % (playerID, npcID, teamID, newTeamID), lineID)
|
| | | elif relatedTick:
|
| | | shuntPlayerDict[playerID] = [npcID, newTeamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 玩家对该boss的关联状态转为伤害状态!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" |
| | | % (playerID, npcID, teamID, newTeamID), lineID)
|
| | | |
| | | # 不在伤血中,更新关联tick
|
| | | elif not relatedTick:
|
| | | shuntPlayerDict[playerID] = [npcID, teamID, tick]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 玩家不在该boss伤血中,设置为关联状态!playerID=%s,npcID=%s,teamID=%s,tick=%s" |
| | | % (playerID, npcID, teamID, tick), lineID)
|
| | | |
| | | # 伤先优先级最高,可直接覆盖更新
|
| | | for playerID, teamID in hurtPlayerDict.items():
|
| | | if playerID not in shuntPlayerDict:
|
| | | shuntPlayerDict[playerID] = [npcID, teamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 新增玩家对boss伤害!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID)
|
| | | |
| | | elif shuntPlayerDict[playerID][0] != npcID:
|
| | | shuntPlayerDict[playerID] = [npcID, teamID, 0]
|
| | | shuntChange = True
|
| | | GameWorld.DebugLog("boss分流 -> 伤害转移到本boss上!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID)
|
| | | |
| | | if shuntChange:
|
| | | PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict
|
| | | NPCCommon.GameServer_WorldBossShuntInfo(mapID, lineID)
|
| | | return
|
| | | |
| | | def __DoGiveAssistAward(self):
|
| | | ''' 执行协助奖励逻辑
|
| | | '''
|
| | | |
| | | liheItemID = 2244 # 感谢礼盒物品ID,暂山寨,感谢系统再修改
|
| | | |
| | | GameWorld.DebugLog("执行协助奖励逻辑", self.npcID, self.lineID)
|
| | | copyPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for playerID, assistPlayerIDList in self.__noAssitPlayerIDDict.items():
|
| | | if not assistPlayerIDList:
|
| | | GameWorld.DebugLog("发布方没有发布协助,不给奖励: playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | continue
|
| | | |
| | | player = copyPlayerManager.FindPlayerByID(playerID)
|
| | | if player:
|
| | | GameWorld.DebugLog("发布方给感谢礼盒奖励: playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | ItemControler.GivePlayerItemOrMail(player, [[liheItemID, 1, 0]])
|
| | | else:
|
| | | GameWorld.DebugLog("发布方离线或不在本地图,不给感谢礼盒奖励: playerID=%s" % playerID, self.npcID, self.lineID)
|
| | | |
| | | for assistPlayerID in assistPlayerIDList:
|
| | | assistHurtPlayer = self.__GetHurtPlayer(assistPlayerID)
|
| | | if not assistHurtPlayer.GetHurtValue():
|
| | | GameWorld.DebugLog("协助方没有输出,不给奖励: assistPlayerID=%s" % assistPlayerID, self.npcID, self.lineID)
|
| | | continue
|
| | | assPlayer = copyPlayerManager.FindPlayerByID(assistPlayerID)
|
| | | if not assPlayer:
|
| | | GameWorld.DebugLog("协助方离线或不在本地图,不给活跃令奖励: assistPlayerID=%s" % assistPlayerID, self.npcID, self.lineID)
|
| | | continue
|
| | | GameWorld.DebugLog("协助方给活跃令奖励: assistPlayerID=%s" % assistPlayerID, self.npcID, self.lineID)
|
| | | PlayerControl.GiveMoney(assPlayer, ShareDefine.TYPE_Price_FamilyActivity, 35)
|
| | | |
| | | return
|
| | | |
| | | def __CmpHurtValue(self, hurtObjA, hurtObjB):
|
| | | ## 伤害排序比较函数
|
| | | if hurtObjA.GetHurtValue() > hurtObjB.GetHurtValue():
|
| | | return 1
|
| | | if hurtObjA.GetHurtValue() == hurtObjB.GetHurtValue():
|
| | | return 0
|
| | | return -1
|
| | | |
| | | def Sort(self, isSync=True):
|
| | | ## 伤血排序
|
| | | self.__hurtSortList = sorted(self.__hurtDict.values(), cmp=self.__CmpHurtValue, reverse=True)
|
| | | |
| | | if not isSync:
|
| | | return
|
| | | |
| | | syncPlayerIDList = self.__noAssitPlayerIDDict.keys() + self.__assistPlayerIDDict.keys()
|
| | | if not syncPlayerIDList:
|
| | | return
|
| | | |
| | | # 暂定排序后默认同步伤血列表给所有相关玩家,伤血为0的不同步前端,仅用于后端逻辑用
|
| | | hurtValueList = []
|
| | | for hurtObj in self.__hurtSortList:
|
| | | hurtValue = hurtObj.GetHurtValue()
|
| | | if not hurtValue:
|
| | | continue
|
| | | hurtValueObj = ChPyNetSendPack.tagMCBossHurtValue()
|
| | | hurtValueObj.HurtID = hurtObj.GetValueID()
|
| | | hurtValueObj.HurtType = hurtObj.GetValueType()
|
| | | hurtValueObj.HurtName = hurtObj.GetHurtName()
|
| | | hurtValueObj.HurtValue = hurtValue % ShareDefine.Def_PerPointValue
|
| | | hurtValueObj.HurtValueEx = hurtValue / ShareDefine.Def_PerPointValue
|
| | | hurtValueList.append(hurtValueObj)
|
| | | |
| | | bossHurtInfoPack = ChPyNetSendPack.tagMCBossHurtValueRankInfo()
|
| | | bossHurtInfoPack.ObjID = self.objID
|
| | | bossHurtInfoPack.HurtValueList = hurtValueList
|
| | | bossHurtInfoPack.HurtCount = len(hurtValueList)
|
| | | |
| | | assistHurtValueListDict = {}
|
| | | copyPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for playerID in syncPlayerIDList:
|
| | | player = copyPlayerManager.FindPlayerByID(playerID)
|
| | | if not player:
|
| | | continue
|
| | | |
| | | if playerID in self.__noAssitPlayerIDDict:
|
| | | assTagPlayerID = playerID
|
| | | elif playerID in self.__assistPlayerIDDict:
|
| | | assTagPlayerID = self.__assistPlayerIDDict[playerID]
|
| | | else:
|
| | | continue
|
| | | |
| | | if assTagPlayerID not in assistHurtValueListDict: |
| | | assistPlayerIDList = self.__noAssitPlayerIDDict[assTagPlayerID]
|
| | | assistHurtValueList = []
|
| | | for assistPlayerID in assistPlayerIDList:
|
| | | assHurtPlayer = self.__GetHurtPlayer(assistPlayerID)
|
| | | assHurtValue = assHurtPlayer.GetHurtValue()
|
| | | if not assHurtValue:
|
| | | continue
|
| | | assHurtValueObj = ChPyNetSendPack.tagMCBossHurtValueAssist()
|
| | | assHurtValueObj.PlayerID = assHurtPlayer.GetValueID()
|
| | | assHurtValueObj.PlayerName = assHurtPlayer.GetHurtName()
|
| | | assHurtValueObj.HurtValue = assHurtValue % ShareDefine.Def_PerPointValue
|
| | | assHurtValueObj.HurtValueEx = assHurtValue / ShareDefine.Def_PerPointValue
|
| | | assistHurtValueList.append(assHurtValueObj)
|
| | | assistHurtValueListDict[assTagPlayerID] = assistHurtValueList
|
| | | |
| | | assistHurtValueList = assistHurtValueListDict[assTagPlayerID]
|
| | | bossHurtInfoPack.AssistHurtValueList = assistHurtValueList
|
| | | bossHurtInfoPack.AssistHurtCount = len(assistHurtValueList)
|
| | | NetPackCommon.SendFakePack(player, bossHurtInfoPack)
|
| | | |
| | | return
|
| | | |
| | | def GetHurtCount(self): return len(self.__hurtSortList)
|
| | | def GetHurtAt(self, index): return self.__hurtSortList[index]
|
| | | |
| | | def GetMaxHurtValue(self): return None if not self.__hurtSortList else self.__hurtSortList[0]
|
| | | def GetLastTimeHurtValue(self):
|
| | | return
|
| | |
|
| | | def OnPlayerLeaveMap(curPlayer):
|
| | | ## 玩家离开地图处理
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | for hurtList in PyGameData.g_npcHurtDict.values():
|
| | | if hurtList.IsNoAssistPlayer(playerID) or hurtList.IsAssistPlayer(playerID):
|
| | | GameWorld.DebugLog("玩家离开地图, 删除boss伤血玩家!npcID=%s" % (hurtList.npcID), playerID)
|
| | | hurtList.DelHurtPlayer(playerID, "LeaveMap")
|
| | | break
|
| | | |
| | | return
|
| | |
|
| | | def OnSetAssistTagPlayerID(curPlayer, value):
|
| | | '''玩家更新了新的协助对象玩家ID
|
| | | 需要 清除本地图中玩家以非协助身份正在攻击的boss
|
| | | |
| | | 以协助身份攻击的通过GameServer进行清除,因为玩家可能不和协助目标同一个地图
|
| | | 比如先点了协助A玩家,还没过去的时候,又点了协助B玩家,所以需要通过GameServer清除协助目标的相关数据
|
| | | '''
|
| | | |
| | | if not value:
|
| | | # 只处理有协助目标的情况
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | for hurtList in PyGameData.g_npcHurtDict.values():
|
| | | if hurtList.IsNoAssistPlayer(playerID):
|
| | | GameWorld.DebugLog("玩家开始协助其他人, 删除该boss伤血!npcID=%s" % (hurtList.npcID), playerID)
|
| | | hurtList.DelHurtPlayer(playerID, "StartAssistBoss")
|
| | | break
|
| | | |
| | | return
|
| | |
|
| | | def ClearPlayerHurtList(curNPC):
|
| | | ## 清空伤血列表
|
| | | defendHurtList = GetPlayerHurtList(curNPC)
|
| | | if not defendHurtList:
|
| | | return
|
| | | defendHurtList.Clear()
|
| | | return
|
| | |
|
| | | def DeletePlayerHurtList(curNPC):
|
| | | ## 删除伤血列表
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | key = (lineID, objID, npcID)
|
| | | if key in PyGameData.g_npcHurtDict:
|
| | | hurtList =PyGameData.g_npcHurtDict.pop(key)
|
| | | hurtList.OnDelete()
|
| | | |
| | | return
|
| | |
|
| | | def GetPlayerHurtList(curNPC):
|
| | | ## 获取伤血列表,可能为None
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | return GetPlayerHurtListEx(lineID, objID, npcID)
|
| | | def GetPlayerHurtListEx(lineID, objID, npcID):
|
| | | ## 获取伤血列表,可能为None
|
| | | key = (lineID, objID, npcID)
|
| | | defendHurtList = None
|
| | | if key not in PyGameData.g_npcHurtDict:
|
| | | ## 只统计最大伤血归属的boss
|
| | | npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
|
| | | if not npcData:
|
| | | return defendHurtList
|
| | | if not npcData.GetIsBoss() or NPCCommon.GetDropOwnerType(npcData) != ChConfig.DropOwnerType_MaxHurt:
|
| | | return defendHurtList
|
| | | defendHurtList = PlayerHurtList(lineID, objID, npcID)
|
| | | PyGameData.g_npcHurtDict[key] = defendHurtList
|
| | | defendHurtList = PyGameData.g_npcHurtDict[key]
|
| | | return defendHurtList
|
| | |
|
| | | def OnNPCHurtPlayerEnterTeam(playerID, playerName, befTeamID, newTeam, tick):
|
| | | ## 伤血玩家加入队伍
|
| | | for hurtList in PyGameData.g_npcHurtDict.values():
|
| | | hurtList.OnHurtPlayerEnterTeam(playerID, playerName, befTeamID, newTeam, tick)
|
| | | return
|
| | |
|
| | | def OnNPCHurtPlayerLeaveTeam(playerID, leaveTeamID, tick):
|
| | | ## 伤血玩家离开队伍
|
| | | for hurtList in PyGameData.g_npcHurtDict.values():
|
| | | hurtList.OnHurtPlayerLeaveTeam(playerID, leaveTeamID, tick)
|
| | | return
|
| | |
|
| | | def AddHurtValue(atkPlayer, defNPC, value, isBounce):
|
| | | '''添加伤血
|
| | | @param isBounce: 是否反弹伤害,反弹伤害不计入非主动攻击的玩家伤血,因为规定玩家攻击另一个boss则要清除同地图上一个boss的该玩家伤害
|
| | | 防止死亡回复活点跑图中被主动型boss攻击计入伤血导致清除同地图上一个主动攻击的boss伤血
|
| | | '''
|
| | | |
| | | defendHurtList = GetPlayerHurtList(defNPC)
|
| | | if not defendHurtList:
|
| | | return
|
| | | atkPlayerID = atkPlayer.GetPlayerID()
|
| | | |
| | | if isBounce and not defendHurtList.HaveHurtValue(atkPlayerID):
|
| | | GameWorld.DebugLog("还没有伤害输出时反弹伤害不计入!", atkPlayerID)
|
| | | return
|
| | | |
| | | objID = defNPC.GetID()
|
| | | npcID = defNPC.GetNPCID()
|
| | | # 删除其他boss伤血、协助
|
| | | for hurtList in PyGameData.g_npcHurtDict.values():
|
| | | if hurtList.npcID == npcID and hurtList.objID == objID:
|
| | | continue
|
| | | if not hurtList.IsNoAssistPlayer(atkPlayerID) and not hurtList.IsAssistPlayer(atkPlayerID):
|
| | | continue
|
| | | GameWorld.Log("玩家主动攻击了其他boss,取消原boss伤血协助等数据! befNPCID=%s,newNPCID=%s" % (hurtList.npcID, npcID))
|
| | | hurtList.DelHurtPlayer(atkPlayerID, "AttackNewBoss")
|
| | | |
| | | defendHurtList.AddPlayerHurtValue(atkPlayerID, atkPlayer.GetPlayerName(), value, atkPlayer.GetTeamID())
|
| | | return True
|
| | |
|
| | | def RefreshHurtList(curNPC, tick, refreshInterval=3000, isDead=False):
|
| | | defendHurtList = GetPlayerHurtList(curNPC)
|
| | | if not defendHurtList:
|
| | | return
|
| | | return defendHurtList.RefreshHurtList(tick, refreshInterval, isDead)
|
| | |
|
| | | def IsAssistPlayer(playerID, defNPC):
|
| | | ## 是否协助中的玩家
|
| | | defendHurtList = GetPlayerHurtList(defNPC)
|
| | | if not defendHurtList:
|
| | | return False
|
| | | return defendHurtList.IsAssistPlayer(playerID)
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerAssist
|
| | | #
|
| | | # @todo:协助系统
|
| | | # @author hxp
|
| | | # @date 2019-12-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 协助系统
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-12-06 21:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import IpyGameDataPY
|
| | | import PlayerControl
|
| | | import NPCHurtManager
|
| | | import IPY_GameWorld
|
| | |
|
| | | import ChConfig
|
| | |
|
| | | #// B0 10 请求协助Boss #tagCMRequestAssistBoss
|
| | | #
|
| | | #struct tagCMRequestAssistBoss
|
| | | #
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD ObjID;
|
| | | # DWORD NPCID;
|
| | | #};
|
| | | def OnRequestAssistBoss(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | objID = clientData.ObjID
|
| | | npcID = clientData.NPCID
|
| | | |
| | | if not curPlayer.GetFamilyID():
|
| | | GameWorld.DebugLog("没有仙盟不能请求协助!", playerID)
|
| | | return
|
| | | |
| | | curNPC = GameWorld.FindNPCByNPCID(npcID)
|
| | | if not curNPC or curNPC.GetID() != objID:
|
| | | GameWorld.DebugLog("协助NPC不存在无法协助!", playerID)
|
| | | return
|
| | | |
| | | ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcID)
|
| | | if not ipyData or not ipyData.GetCanAssist():
|
| | | GameWorld.DebugLog("该NPC不能协助!npcID=%s" % npcID, playerID)
|
| | | return
|
| | | |
| | | hurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
|
| | | if not hurtList.IsNoAssistPlayer(playerID):
|
| | | GameWorld.DebugLog("不是该boss的非助战伤血玩家,无法发起协助!npcID=%s" % npcID, playerID)
|
| | | return
|
| | | |
| | | if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_RequestAssist, tick):
|
| | | GameWorld.DebugLog("请求协助CD中!npcID=%s" % npcID, playerID)
|
| | | return
|
| | | |
| | | mapID = curPlayer.GetMapID()
|
| | | lineID = 0
|
| | | if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull: # 副本型boss,如封魔坛
|
| | | lineID = PlayerControl.GetFBFuncLineID(curPlayer)
|
| | | queryData = [mapID, lineID, npcID, objID]
|
| | | QueryGameServer_PlayerAssist(playerID, "RequestAssistBoss", queryData)
|
| | | return
|
| | |
|
| | |
|
| | | #// B0 11 请求协助组队副本 #tagCMRequestAssistTeamFB
|
| | | #
|
| | | #struct tagCMRequestAssistTeamFB
|
| | | #
|
| | | #{
|
| | | # tagHead Head;
|
| | | # WORD MapID;
|
| | | # WORD LineID;
|
| | | #};
|
| | | def OnRequestAssistTeamFB(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | mapID = clientData.MapID
|
| | | lineID = clientData.LineID
|
| | | |
| | | if not curPlayer.GetFamilyID():
|
| | | GameWorld.DebugLog("没有仙盟不能请求协助!", playerID)
|
| | | return
|
| | | |
| | | if GameWorld.GetMap().GetMapFBTypeByMapID(mapID) != IPY_GameWorld.fbtTeam:
|
| | | GameWorld.DebugLog("非组队副本不能请求协助!mapID=%s" % mapID, playerID)
|
| | | return
|
| | | |
| | | if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_RequestAssist, tick):
|
| | | GameWorld.DebugLog("请求协助CD中!mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | return
|
| | | |
| | | queryData = [mapID, lineID]
|
| | | QueryGameServer_PlayerAssist(playerID, "RequestAssistTeamFB", queryData)
|
| | | return
|
| | |
|
| | | def OnStartAssistTeamFB(playerID, mapID, lineID, tagPlayerID):
|
| | | ## 开始协助组队副本,协助玩家进入副本调用
|
| | | queryData = [mapID, lineID, tagPlayerID]
|
| | | QueryGameServer_PlayerAssist(playerID, "OnStartAssistTeamFB", queryData)
|
| | | return
|
| | |
|
| | | def QueryGameServer_PlayerAssist(playerID, queryType, queryData):
|
| | | msgInfo = str([queryType, queryData])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "PlayerAssist", msgInfo, len(msgInfo))
|
| | | GameWorld.DebugLog("协助信息发送 GameServer: playerID=%s,queryType=%s,queryData=%s" % (playerID, queryType, queryData))
|
| | | return
|
| | |
|
| | | def QueryResult_PlayerAssist(curPlayer, resultList):
|
| | | ## 协助信息GameServer返回处理
|
| | | if len(resultList) != 3:
|
| | | return
|
| | | #queryType, queryData, result = resultList
|
| | | |
| | | return
|
| | |
|
| | | def GameServer_AssistBossMsg(assistData):
|
| | | ## GameServer推送到指定boss地图的信息
|
| | | |
| | | GameWorld.DebugLog("GameServer同步Boss协助信息: %s" % assistData)
|
| | | |
| | | msgType = assistData[0]
|
| | | |
| | | # 开始协助
|
| | | if msgType == "Start":
|
| | | assistGUID, assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID = assistData[1:]
|
| | | npchurtList = NPCHurtManager.GetPlayerHurtListEx(lineID, objID, npcID)
|
| | | if not npchurtList:
|
| | | return
|
| | | |
| | | npchurtList.AddAssistPlayer(assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID)
|
| | | QueryGameServer_PlayerAssist(0, "AddAssistBossPlayerOK", [assistGUID, assistPlayerID])
|
| | | |
| | | # 取消协助
|
| | | elif msgType == "Cancel":
|
| | | assistPlayerID, lineID, objID, npcID = assistData[1:]
|
| | | npchurtList = NPCHurtManager.GetPlayerHurtListEx(lineID, objID, npcID)
|
| | | if not npchurtList:
|
| | | return
|
| | | npchurtList.DelHurtPlayer(assistPlayerID, "Cancel", isMapServerDel=False)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | |
| | | import FunctionNPCCommon
|
| | | import CrossRealmPlayer
|
| | | import CrossPlayerData
|
| | | import NPCHurtManager
|
| | | import ChNetSendPack
|
| | | import PlayerCoat
|
| | | import PlayerState
|
| | |
| | | NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBLineID, lineID)
|
| | | GameWorld.DebugLog("进入副本时,最后一次离开的可返回的副本ID更新!mapID=%s,lineID=%s,Pos(%s,%s)" % (mapID, lineID, posX, posY))
|
| | |
|
| | | # 离开地图,暂时只处理离开中立、组队副本
|
| | | if curPlayer.GetMapID() in IpyGameDataPY.GetFuncEvalCfg("MapLine", 4) or GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtTeam:
|
| | | NPCHurtManager.OnPlayerLeaveMap(curPlayer)
|
| | | |
| | | # 从副本中切图
|
| | | if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:
|
| | | #默认回满血
|
| | |
| | | def __GetBossShuntLineID(curPlayer, curMapID, curLineID, tagMapID, npcID, lineIDList):
|
| | | '''获取目标地图boss分流线路
|
| | | 根据人数分流玩家,优先分配到活着的线路
|
| | | 队伍无视任何规则,默认分配到队伍队员多的那条线
|
| | | 队伍默认分配到队伍队员多的那条线
|
| | | 协助默认分配到目标玩家线路,优先级最高
|
| | |
|
| | | 前端:
|
| | | 1.在中立地图的时候,显示当前线路BOSS的状态
|
| | |
| | | lineIDList.remove(activityLineID)
|
| | | GameWorld.DebugLog(" 非1线的活动线路不参与分流: activityLineID=%s,lineIDList=%s" % (activityLineID, lineIDList), playerID)
|
| | |
|
| | | assistTagPlayerID = GetAssistTagPlayerID(curPlayer)
|
| | | for lineID in lineIDList:
|
| | | key = (tagMapID, lineID)
|
| | | # boss分流玩家信息{(mapID, lineID):{playerID:[bossID, teamID, relatedTick], ...}, ...}
|
| | | shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})
|
| | | if assistTagPlayerID and assistTagPlayerID in shuntPlayerDict:
|
| | | GameWorld.DebugLog(" 分流到协助目标玩家线路 assistTagPlayerID=%s,lineID=%s" % (assistTagPlayerID, lineID), playerID)
|
| | | return lineID
|
| | | playerCount = 0
|
| | | teamPlayerCount = 0
|
| | | for shuntPlayerID, shuntInfo in shuntPlayerDict.items():
|
| | |
| | | curPlayer.SendPropertyRefresh(ShareDefine.CDBPlayerRefresh_ForbidenTalk, value, False)
|
| | | return
|
| | |
|
| | | ## 协助目标玩家ID
|
| | | def SetAssistTagPlayerID(curPlayer, value):
|
| | | curPlayer.SetExAttr1(value, True, False) # 不通知GameServer
|
| | | NPCHurtManager.OnSetAssistTagPlayerID(curPlayer, value)
|
| | | return
|
| | | def GetAssistTagPlayerID(curPlayer): return curPlayer.GetExAttr1()
|
| | |
|
| | | ## 队伍相关审核开关状态, joinReqCheck-入队申请是否需要审核; inviteCheck-组队邀请是否需要审核;
|
| | | def SetTeamCheckStateEx(curPlayer, joinReqCheck, inviteCheck): return SetTeamCheckState(curPlayer, joinReqCheck * 10 + inviteCheck)
|
| | | def SetTeamCheckState(curPlayer, checkState): return curPlayer.SetExAttr2(checkState, False, True)
|
| | | def GetTeamCheckState(curPlayer): return curPlayer.GetExAttr2()
|
| | |
|
| | | ## 副本功能线路ID, 这里做db存储,防止在合并地图副本中掉线重上时前端无法加载正确的场景资源,登录加载场景时机为0102包
|
| | | def SetFBFuncLineID(curPlayer, funcLineID): return curPlayer.SetExAttr3(funcLineID, False, False)
|
| | | def SetFBFuncLineID(curPlayer, funcLineID): return curPlayer.SetExAttr3(funcLineID, False, True)
|
| | | def GetFBFuncLineID(curPlayer): return curPlayer.GetExAttr3()
|
| | |
|
| | | ## 跨服状态所在地图ID: 0-非跨服状态,非0-跨服状态对应的地图ID
|
| | |
| | | import FamilyRobBoss
|
| | | import FBHelpBattle
|
| | | import QuestManager
|
| | | import PlayerAssist
|
| | | import PyGameData
|
| | | import PlayerTJG
|
| | |
|
| | |
| | | GameLogic_FamilyParty.DoAddFamilyMemberFamilyActivity(familyID, addFamilyActivity)
|
| | | return
|
| | |
|
| | | if key == ShareDefine.Def_Notify_WorldKey_AssistBoss:
|
| | | assistData = eval(msgValue)
|
| | | if GameWorld.GetMap().GetMapID() == assistData[0]:
|
| | | PlayerAssist.GameServer_AssistBossMsg(assistData[1:])
|
| | | return
|
| | | |
| | | if key == ShareDefine.Def_Notify_WorldKey_AddFamilyAuctionItem:
|
| | | mapID, familyAuctionItemDict = eval(msgValue)
|
| | | if GameWorld.GetMap().GetMapID() == mapID:
|
| | |
| | | import SkillCommon
|
| | | import IPY_GameWorld
|
| | | import DataRecordPack
|
| | | import NPCHurtManager
|
| | | #import PlayerTruck
|
| | | import ShareDefine
|
| | | import SkillShell
|
| | |
| | | #curMapTeam.SetTeamType(recvPack.GetTeamType())
|
| | | DR_Team("RefreshPlayerTeamID_Create", teamID, dataDict)
|
| | |
|
| | | if playerTeamID != teamID or not curTeam:
|
| | | isNewTeam = playerTeamID != teamID # 切地图/上线时teamID可能不变,但是team为None
|
| | | if (playerTeamID != teamID or not curTeam) and curMapTeam:
|
| | | #isNewTeam = playerTeamID != teamID # 切地图/上线时teamID可能不变,但是team为None
|
| | | #GameWorld.DebugLog(" 玩家当前无队伍,处理玩家进队!isNewTeam=%s" % isNewTeam, playerID)
|
| | | __OnEnterTeam(curPlayer, curMapTeam, isNewTeam, tick, dataDict)
|
| | | __OnEnterTeam(curPlayer, curMapTeam, playerTeamID, tick, dataDict)
|
| | | else:
|
| | | dataDict["MemberCount"] = 0 if not curMapTeam else curMapTeam.GetMemberCount()
|
| | | DR_Team("RefreshPlayerTeamID_Update", teamID, dataDict)
|
| | |
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def __OnEnterTeam(curPlayer, curMapTeam, isNewTeam, tick, dataDict):
|
| | | def __OnEnterTeam(curPlayer, curMapTeam, playerTeamID, tick, dataDict):
|
| | | teamID = curMapTeam.GetTeamID()
|
| | | memCount = curMapTeam.GetMemberCount()
|
| | | if memCount >= ShareDefine.Def_Team_MaxPlayerCount:
|
| | |
| | | #PlayerTruck.ChangeTruckNoteInfo(curPlayer)
|
| | |
|
| | | #以下为进入一个新的队伍额外处理
|
| | | if not isNewTeam:
|
| | | return
|
| | | if playerTeamID != teamID:
|
| | | NPCHurtManager.OnNPCHurtPlayerEnterTeam(playerID, curPlayer.GetPlayerName(), playerTeamID, curMapTeam, tick)
|
| | | return
|
| | |
|
| | | def __OnPlayerLeaveTeam(copyMapID, playerID, leaveTeamID, tick):
|
| | |
| | |
|
| | | __DelPlayerIDFromTeamPlayer(playerID, False)
|
| | |
|
| | | NPCHurtManager.OnNPCHurtPlayerLeaveTeam(playerID, leaveTeamID, tick)
|
| | | |
| | | dataDict = {"playerID":playerID, "copyMapID":copyMapID}
|
| | | ### =========================== 以下逻辑是玩家存在时才需要处理的 =================================
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.RemoteQuery.GY_Query_PlayerAssist
|
| | | #
|
| | | # @todo:协助系统
|
| | | # @author hxp
|
| | | # @date 2019-12-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 协助系统
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-12-06 21:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import PlayerAssist
|
| | | import GameWorld
|
| | |
|
| | |
|
| | | ## 请求逻辑
|
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 请求的玩家ID
|
| | | # @param packCMDList 发包命令 [ ]
|
| | | # @param tick 当前时间
|
| | | # @return resultDisc
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick):
|
| | | return
|
| | | |
| | | #---------------------------------------------------------------------
|
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | try:
|
| | | funResultList = eval(funResult)
|
| | | except:
|
| | | GameWorld.ErrLog("GY_Query_PlayerAssist %s eval Error" % funResult, curPlayer.GetPlayerID())
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("GY_Query_PlayerAssist ResultList=%s" % str(funResultList), curPlayer.GetPlayerID())
|
| | | PlayerAssist.QueryResult_PlayerAssist(curPlayer, funResultList)
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | |
| | |
|
| | | g_filterEquipDict = {} # 按装备条件过滤的装备ID,不分职业 {"classLV_color_star":{(itemJob,itemPlace):itemID, ...}, ...}
|
| | |
|
| | | g_npcHurtDict = {} # npc伤血列表信息字典 {(lineID,objID,npcID):PlayerHurtList, ...}
|
| | |
|
| | | g_teamPlayerHurtValue = {} # 队伍玩家对NPC伤害输出量 {(lineID, objID, npcID):{(teamID, playerID):hurtValue, ...}, }
|
| | | g_teamPlayerDict = {} # 地图队伍对应玩家ID列表,含离线玩家 {teamID:[playerID, ...], ...}
|
| | |
|
| | |
| | | Def_Notify_WorldKey_RedPacketOutput = 'RedPacketOutput' # 红包产出信息
|
| | | Def_Notify_WorldKey_HurtLog = 'HurtLog' # 战斗伤害日志
|
| | | Def_Notify_WorldKey_FairyDomainLimit = "FairyDomainLimit" # 缥缈仙域限制事件
|
| | |
|
| | | Def_Notify_WorldKey_AssistBoss = "AssistBoss" # 协助boss
|
| | |
|
| | | #运营活动表名定义
|
| | | OperationActionName_ExpRate = "ActExpRate" # 多倍经验活动
|
| | | OperationActionName_CostRebate = "ActCostRebate" # 消费返利活动
|