10263 【越南】【英文】后端支持NPC仿真实玩家战斗和快速战斗
# Conflicts:
# PySysDB/PySysDBPY.h
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/CommFunc.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
| | |
| | | list StarAttrValue; //累计总属性值
|
| | | };
|
| | |
|
| | | //技能搭配表
|
| | |
|
| | | struct tagSkillMatch
|
| | | {
|
| | | BYTE _IDIndex;
|
| | | list Skills; //主动技能(职业1id|职业2id)
|
| | | };
|
| | |
|
| | | //创角表
|
| | |
|
| | | struct tagCreateRole
|
| | |
| | |
|
| | | Def_PlayerKey_PrivateTalk = 'PrivateTalk' #追踪密频(1:开启 0:关闭)
|
| | | #---------------------------------------------------------------------
|
| | | # GameWorld.GetGameWorld().SendDBLogic(BYTE queryType, DWORD id, char* sData, int nDataLen)
|
| | | # GameServer请求db逻辑类型,db接受 OnGameServerToDBLogic,回调 RecvDGDBLogicResult
|
| | | (
|
| | | gstDBLogic_PlayerPackData, # 请求打包玩家数据 0
|
| | | ) = range(1)
|
| | |
|
| | | #GM工具回复值
|
| | | Def_GMTool_Succeed = 1
|
| | | Def_GMTool_Fail = 250
|
| | |
| | | Def_Billboard_MaxCnt = 100
|
| | | #---------------------------------------------------------------------
|
| | | #请求类型(需要和MapServer中的一致)
|
| | | Def_QueryType_Count = 56
|
| | | Def_QueryType_Count = 55
|
| | | (
|
| | | queryType_sqtPlayer, #查询玩家
|
| | | queryType_sqtFamilyWar, #家族战
|
| | |
| | | queryType_EnterFB, #进入副本
|
| | | queryType_NPCInfo, #查询NPCInfo
|
| | | queryType_NPCCnt, #查询NPC数量
|
| | | queryType_MirrorPlayer, #镜像玩家
|
| | | ) = range(0, Def_QueryType_Count)
|
| | | #------------------------------------------------------------------------------
|
| | | #家族某行为类型保存的条数
|
| | |
| | | ItemData19 = "" #(String ItemData19)
|
| | | ItemDataSize20 = 0 #(WORD ItemDataSize20)
|
| | | ItemData20 = "" #(String ItemData20)
|
| | | PackDataSyncState = 0 #(BYTE PackDataSyncState)// 打包数据同步状态: 0-不同步;个位-是否同步本服;十位-是否同步跨服
|
| | | PackDataLen = 0 #(DWORD PackDataLen)
|
| | | PackData = "" #(String PackData)
|
| | | PackMsgLen = 0 #(WORD PackMsgLen)
|
| | | PackMsg = "" #(String PackMsg)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | |
| | | self.ItemData19,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemDataSize19)
|
| | | self.ItemDataSize20,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.ItemData20,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemDataSize20)
|
| | | self.PackDataSyncState,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.PackDataLen,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PackData,_pos = CommFunc.ReadString(_lpData, _pos,self.PackDataLen)
|
| | | self.PackMsgLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.PackMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.PackMsgLen)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | |
| | | self.ItemData19 = ""
|
| | | self.ItemDataSize20 = 0
|
| | | self.ItemData20 = ""
|
| | | self.PackDataSyncState = 0
|
| | | self.PackDataLen = 0
|
| | | self.PackData = ""
|
| | | self.PackMsgLen = 0
|
| | | self.PackMsg = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | |
| | | length += len(self.ItemData19)
|
| | | length += 2
|
| | | length += len(self.ItemData20)
|
| | | length += 1
|
| | | length += 4
|
| | | length += len(self.PackData)
|
| | | length += 2
|
| | | length += len(self.PackMsg)
|
| | |
|
| | | return length
|
| | |
|
| | |
| | | data = CommFunc.WriteString(data, self.ItemDataSize19, self.ItemData19)
|
| | | data = CommFunc.WriteWORD(data, self.ItemDataSize20)
|
| | | data = CommFunc.WriteString(data, self.ItemDataSize20, self.ItemData20)
|
| | | data = CommFunc.WriteBYTE(data, self.PackDataSyncState)
|
| | | data = CommFunc.WriteDWORD(data, self.PackDataLen)
|
| | | data = CommFunc.WriteString(data, self.PackDataLen, self.PackData)
|
| | | data = CommFunc.WriteWORD(data, self.PackMsgLen)
|
| | | data = CommFunc.WriteString(data, self.PackMsgLen, self.PackMsg)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | |
| | | ItemDataSize19:%d,
|
| | | ItemData19:%s,
|
| | | ItemDataSize20:%d,
|
| | | ItemData20:%s
|
| | | ItemData20:%s,
|
| | | PackDataSyncState:%d,
|
| | | PackDataLen:%d,
|
| | | PackData:%s,
|
| | | PackMsgLen:%d,
|
| | | PackMsg:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | |
| | | self.ItemDataSize19,
|
| | | self.ItemData19,
|
| | | self.ItemDataSize20,
|
| | | self.ItemData20
|
| | | self.ItemData20,
|
| | | self.PackDataSyncState,
|
| | | self.PackDataLen,
|
| | | self.PackData,
|
| | | self.PackMsgLen,
|
| | | self.PackMsg
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A1 09 同步打包玩家数据 #tagCMSycnPlayerPackData
|
| | |
|
| | | class tagCMSycnPlayerPackData(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xA1
|
| | | self.SubCmd = 0x09
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xA1
|
| | | self.SubCmd = 0x09
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMSycnPlayerPackData)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// A1 09 同步打包玩家数据 //tagCMSycnPlayerPackData:
|
| | | Cmd:%s,
|
| | | SubCmd:%s
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMSycnPlayerPackData=tagCMSycnPlayerPackData()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSycnPlayerPackData.Cmd,m_NAtagCMSycnPlayerPackData.SubCmd))] = m_NAtagCMSycnPlayerPackData
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #A1 03 设置是否成年 #tagCMAdult
|
| | |
|
| | | class tagCMAdult(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B4 11 镜像战斗 #tagCMMirrorFight
|
| | |
|
| | | class tagCMMirrorFight(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("MapID", c_int), # 自定义地图ID,如竞技场等
|
| | | ("FuncLineID", c_ushort), |
| | | ("TagPlayeID", c_int), # 目标玩家ID,支持跨服玩家ID
|
| | | ("CmdType", c_ubyte), # 命令类型: 0-创建战斗;1-开始战斗;2-战斗中跳过;3-不创建战斗直接得结果
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xB4
|
| | | self.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xB4
|
| | | self.SubCmd = 0x11
|
| | | self.MapID = 0
|
| | | self.FuncLineID = 0
|
| | | self.TagPlayeID = 0
|
| | | self.CmdType = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMMirrorFight)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// B4 11 镜像战斗 //tagCMMirrorFight:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | MapID:%d,
|
| | | FuncLineID:%d,
|
| | | TagPlayeID:%d,
|
| | | CmdType:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.MapID,
|
| | | self.FuncLineID,
|
| | | self.TagPlayeID,
|
| | | self.CmdType
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMMirrorFight=tagCMMirrorFight()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMirrorFight.Cmd,m_NAtagCMMirrorFight.SubCmd))] = m_NAtagCMMirrorFight
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B4 0F 回收私有专属木桩怪 #tagCMRecyclePriWoodPile
|
| | |
|
| | | class tagCMRecyclePriWoodPile(Structure):
|
| | |
| | | ## 服务器组ID,必须唯一,代表这台物理服务器
|
| | | return ToIntDef(ReadChConfig.GetPyMongoConfig("platform", "GroupID"), 0)
|
| | |
|
| | | def GetMainServerID(serverID):
|
| | | ## 获取服务器ID所属主服ID
|
| | | ServerIDMainServerDict = IpyGameDataPY.GetConfigEx("ServerIDMainServerDict")
|
| | | if ServerIDMainServerDict == None:
|
| | | filePath = ChConfig.GetDBPath() + ("\\MixServerMap_%s.json" % GetPlatform())
|
| | | if not os.path.isfile(filePath):
|
| | | SendGameErrorEx("GetMainServerIDError", "file can not found. %s" % filePath)
|
| | | else:
|
| | | fileObj = open(filePath, 'rb')
|
| | | content = fileObj.read()
|
| | | fileObj.close()
|
| | | MixServerMapDict = eval(content)
|
| | | |
| | | ServerIDMainServerDict = {}
|
| | | for mainServerIDStr, serverIDList in MixServerMapDict.items():
|
| | | mainServerID = int(mainServerIDStr)
|
| | | for sID in serverIDList:
|
| | | ServerIDMainServerDict[sID] = mainServerID
|
| | | IpyGameDataPY.SetConfigEx("ServerIDMainServerDict", ServerIDMainServerDict)
|
| | | Log("加载 ServerIDMainServerDict=%s" % ServerIDMainServerDict)
|
| | | |
| | | if not ServerIDMainServerDict:
|
| | | return serverID
|
| | | return ServerIDMainServerDict.get(serverID, serverID)
|
| | |
|
| | | def GetPlatformServerNum(platform):
|
| | | # 获取服务器的平台编号
|
| | | platformNumDict = ReadChConfig.GetDBEvalChConfig("DBPlatformNum")
|
| | |
| | | def GetPlayerServerID(curPlayer): return GetAccIDServerID(curPlayer.GetAccID())
|
| | | def GetAccIDServerID(accID):
|
| | | infoList = accID.split(Def_AccID_Split_Sign)
|
| | | return 0 if len(infoList) < 3 else int(infoList[-1][1:])
|
| | | return 0 if len(infoList) < 3 else ToIntDef(infoList[-1][1:])
|
| | |
|
| | | def GetPlayerServerSID(curPlayer):
|
| | | # 返回含s的serverID
|
| | |
| | | SendGameError("GameServerRaiseException", errorMsg)
|
| | | return
|
| | |
|
| | | def SendGameErrorEx(errType, msgInfo="", playerID=0):
|
| | | ErrLog("SendGameErrorEx: %s -> %s" % (errType, msgInfo), playerID)
|
| | | if GetGameWorld().GetDebugLevel():
|
| | | raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | else:
|
| | | SendGameError(errType, msgInfo)
|
| | | return
|
| | |
|
| | | def SendGameError(errType, msgInfo=""):
|
| | | ''' 向运维发送邮件,用于需要紧急处理的信息
|
| | | @param errType: 错误类型,自定义即可
|
| | |
| | | import ShareDefine
|
| | | import PlayerAssist
|
| | | import PlayerControl
|
| | | import PlayerPackData
|
| | | import PlayerFuncTeam
|
| | | import CrossLuckyCloudBuy
|
| | | import IPY_GameServer
|
| | |
| | |
|
| | | elif msgType == ShareDefine.ClientServerMsg_ViewPlayerCache:
|
| | | CrossRealmPlayer.ClientServerMsg_ViewPlayerCache(serverGroupID, msgData)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_PullOtherPlayerPackData:
|
| | | PlayerPackData.ClientServerMsg_PullOtherPlayerPackData(serverGroupID, msgData)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_PlayerPackData:
|
| | | PlayerPackData.ClientServerMsg_PlayerPackData(serverGroupID, msgData)
|
| | |
|
| | | elif msgType == ShareDefine.ClientServerMsg_QueryNPCInfo:
|
| | | PlayerQuery.ClientServerMsg_QueryNPCInfo(serverGroupID, msgData)
|
| | |
| | | elif msgType == ShareDefine.CrossServerMsg_ViewPlayerCacheRet:
|
| | | CrossRealmPlayer.CrossServerMsg_ViewPlayerCacheRet(msgData, tick)
|
| | |
|
| | | elif msgType == ShareDefine.CrossServerMsg_PlayerPackDataState:
|
| | | PlayerPackData.CrossServerMsg_PlayerPackDataState(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PullPlayerPackData:
|
| | | PlayerPackData.CrossServerMsg_PullPlayerPackData(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PushPlayerPackData:
|
| | | PlayerPackData.CrossServerMsg_PushPlayerPackData(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKMatchReqRet:
|
| | | CrossRealmPK.CrossServerMsg_PKMatchReqRet(msgData)
|
| | |
|
| | |
| | | #
|
| | | # @todo:GameServer向DB请求的回复信息
|
| | |
|
| | | import GameWorld
|
| | | import PlayerPackData
|
| | | import IPY_GameServer
|
| | | import ChConfig
|
| | |
|
| | |
| | | if result == 0:
|
| | | return
|
| | | queryType = dbResultPack.GetQueryType()
|
| | | if queryType == 0:
|
| | | data = eval(dbResultPack.GetData())
|
| | | playerID = data['id'] #发起请求的玩家ID
|
| | | mapID = data['mapid']
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | if queryType == ChConfig.gstDBLogic_PlayerPackData:
|
| | | mirrorID = dbResultPack.GetID()
|
| | | playerData = dbResultPack.GetResultSet()
|
| | | msgInfo = eval(dbResultPack.GetData())
|
| | | PlayerPackData.OnDBPlayerPackData(mirrorID, playerData, msgInfo)
|
| | |
|
| | | data['playerData'] = dbResultPack.GetResultSet()
|
| | | dateStr = str(data)
|
| | | GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, ChConfig.queryType_MirrorPlayer, playerID, mapID,
|
| | | "PlayerMirror", dateStr, len(dateStr), curPlayer.GetRouteServerIndex())
|
| | | return |
| | | return
|
| | |
|
| | |
| | | import PlayerFuncTeam
|
| | | import PyDataManager
|
| | | import GameWorldMineArea
|
| | | import PlayerPackData
|
| | | import PlayerRecData
|
| | | import GameWorship
|
| | | import GameXiangong
|
| | |
| | | CrossYaomoBoss.OnPlayerLogin(curPlayer)
|
| | | #玩家记录
|
| | | PlayerRecData.OnPlayerLogin(curPlayer)
|
| | | |
| | | PlayerPackData.OnPlayerLogin(curPlayer)
|
| | | #在线状态变更,放最后
|
| | | __OnPlayerOnlineStateChange(curPlayer, True)
|
| | |
|
| | |
| | | cacheBase = msgData["cacheBase"]
|
| | |
|
| | | isLogout = not isOnline
|
| | | olMgr = GetOnlinePlayerMgr()
|
| | | olMgr.SetOnlineState(playerID, isOnline, cacheBase.get("ServerGroupID", 0))
|
| | | |
| | | PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase, isLogout)
|
| | | serverID = GameWorld.GetAccIDServerID(cacheBase["AccID"])
|
| | |
|
| | | # 上线
|
| | | if isOnline:
|
| | | PlayerPackData.OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID)
|
| | | GameXiangong.OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID)
|
| | |
|
| | | # 下线
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package PlayerPackData
|
| | | #
|
| | | # @todo:玩家打包数据
|
| | | # @author hxp
|
| | | # @date 2024-10-17
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 玩家打包数据
|
| | | # |
| | | # 应用场景:主要用于PK类功能,与镜像PK
|
| | | # 1. 既定功能类型: |
| | | # 如匹配竞技场等,这种一般需要先报名或登记等,或者已经在积分排行榜上的
|
| | | # 所以打包数据表一般会保存玩家打包数据直到活动结算结束
|
| | | # 报名、登记、同步: 这种一般是通过玩家主动自主发起的行为
|
| | | # 排行榜:这种相当于被动式报名,即首次上榜触发拉取数据
|
| | | # 2. 系统自动PK功能类:
|
| | | # 如根据某个资格规则,系统自动生成n个玩家随机匹配PK的功能,玩家两两镜像系统自动对打晋级加积分决出名次等
|
| | | # 这种为被动式,即目标玩家可能不存在打包数据表中,需要取拉取
|
| | | # 3. 随意PK类型:
|
| | | # 如切磋一下,玩家可以在任意场景对任意本服或跨服玩家发起切磋,与其镜像进行一场友谊PK,纯娱乐
|
| | | # 这种为被动式,即目标玩家可能不存在打包数据表中,需要取拉取
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2024-10-17 15:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import CommFunc
|
| | | import GameWorld
|
| | | import PyDataManager
|
| | | import PlayerViewCache
|
| | | import PyGameDataStruct
|
| | | import CrossRealmMsg
|
| | | import PlayerControl
|
| | | import ShareDefine
|
| | | import PyGameData
|
| | | import ChConfig
|
| | |
|
| | | import time
|
| | |
|
| | | class DBPlayerPackDataManager():
|
| | | ## 玩家打包数据管理
|
| | | |
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | | |
| | | def Clear(self):
|
| | | self.playerPackDataDict = {} # {playerID:tagDBPlayerPackData, ...}
|
| | | return
|
| | | |
| | | def GetPlayerPackObj(self, playerID, isAddNew=False):
|
| | | packDataObj = None
|
| | | if playerID in self.playerPackDataDict:
|
| | | packDataObj = self.playerPackDataDict[playerID]
|
| | | elif isAddNew:
|
| | | packDataObj = PyGameDataStruct.tagDBPlayerPackData()
|
| | | packDataObj.PlayerID = playerID
|
| | | self.playerPackDataDict[playerID] = packDataObj
|
| | | return packDataObj
|
| | | |
| | | def UpdPlayerPackData(self, playerID, packData):
|
| | | if not packData:
|
| | | return
|
| | | packObj = self.GetPlayerPackObj(playerID, True)
|
| | | packObj.UpdTime = int(time.time())
|
| | | packObj.PackData = packData
|
| | | packObj.PackDataSize = len(packObj.PackData)
|
| | | return
|
| | | |
| | | # 保存数据 存数据库和realtimebackup
|
| | | def GetSaveData(self):
|
| | | savaData = ""
|
| | | cntData = ""
|
| | | cnt = 0
|
| | | |
| | | for dbData in self.playerPackDataDict.values():
|
| | | cnt += 1
|
| | | savaData += dbData.getBuffer()
|
| | | |
| | | GameWorld.Log("Save DBPlayerPackData count :%s len=%s" % (cnt, len(savaData)))
|
| | | return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
| | | |
| | | # 从数据库载入数据
|
| | | def LoadPyGameData(self, datas, pos, dataslen):
|
| | | cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
| | | GameWorld.Log("Load DBPlayerPackData count :%s" % cnt)
|
| | | |
| | | self.Clear()
|
| | | |
| | | for _ in xrange(cnt):
|
| | | dbData = PyGameDataStruct.tagDBPlayerPackData()
|
| | | pos += dbData.readData(datas, pos, dataslen)
|
| | | |
| | | self.playerPackDataDict[dbData.PlayerID] = dbData
|
| | | |
| | | return pos
|
| | |
|
| | | def IsSaveDB(packDataObj):
|
| | | ## 是否入库
|
| | | if not packDataObj:
|
| | | return False
|
| | | |
| | | # 功能固定需要的
|
| | | # ...
|
| | | |
| | | maxDays = 7 # 默认7天
|
| | | MaxTime = maxDays * 3600 * 24
|
| | | curTime = int(time.time())
|
| | | passTime = curTime - packDataObj.UpdTime
|
| | | if passTime < MaxTime:
|
| | | return True
|
| | | |
| | | return False
|
| | |
|
| | | def DelOutofTimePackData():
|
| | | ## 删除过期
|
| | | |
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | playerPackDataDict = packDataMgr.playerPackDataDict
|
| | | for playerID, packDataObj in playerPackDataDict.items():
|
| | | if IsSaveDB(packDataObj):
|
| | | continue
|
| | | playerPackDataDict.pop(playerID)
|
| | | |
| | | return
|
| | |
|
| | | def IsPackDataPlayer(playerID):
|
| | | return playerID in PyDataManager.GetDBPlayerPackDataManager().playerPackDataDict
|
| | |
|
| | | def OnPlayerLogin(curPlayer):
|
| | | ## 本服登录逻辑
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | if playerID in packDataMgr.playerPackDataDict:
|
| | | isCross, isNeed = 0, 1
|
| | | QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", [isCross, isNeed])
|
| | | return
|
| | |
|
| | | def OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID):
|
| | | ## 跨服登录逻辑
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | if playerID in packDataMgr.playerPackDataDict:
|
| | | dataMsg = {"playerID":playerID}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PlayerPackDataState, dataMsg, [serverGroupID])
|
| | | return
|
| | |
|
| | | def SetNeedPackData(playerIDList):
|
| | | ## 设置需要打包数据的玩家ID列表,如果没有数据,则会主动去拉取数据,跨服本服通用
|
| | | |
| | | if not playerIDList:
|
| | | return
|
| | | |
| | | pullPlayerIDList = []
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | for playerID in playerIDList:
|
| | | if playerID in packDataMgr.playerPackDataDict:
|
| | | continue
|
| | | pullPlayerIDList.append(playerID)
|
| | | |
| | | if not pullPlayerIDList:
|
| | | return
|
| | | OnPullPlayerPackData(pullPlayerIDList)
|
| | | return
|
| | |
|
| | | def OnPullPlayerPackData(pullPlayerIDList, msgInfo=None):
|
| | | '''请求拉取玩家数据,该函数仅在打包数据表中不存在玩家数据时才需要调用,跨服本服通用
|
| | | 1. 跨服拉子服玩家数据: 直接推送给子服拉对应玩家数据,拉取到数据后同时存入打包数据表中
|
| | | 2. 子服拉其他子服玩家数据:直接推送给跨服服务器拉取
|
| | | 3. 子服拉本服玩家数据
|
| | | a.如果是跨服服务器请求的,优先取打包数据表中数据,有则返回,没有则继续往下走
|
| | | b.玩家在线时从地图拉取,拉取到数据后同时存入打包数据表中
|
| | | c.玩家离线时从db拉取,拉取到数据后同时存入打包数据表中
|
| | | @param msgInfo: 功能拉取玩家数据时自定义的功能信息,透传参数
|
| | | '''
|
| | | if msgInfo == None:
|
| | | msgInfo = {}
|
| | | |
| | | GameWorld.DebugLog("拉取玩家打包数据: %s, %s" % (pullPlayerIDList, msgInfo))
|
| | | |
| | | # pullFrom 0-跨服拉子服; >0-子服通过跨服拉子服
|
| | | if GameWorld.IsCrossServer():
|
| | | # 广播给子服拉数据
|
| | | msgInfo["pullFrom"] = 0
|
| | | dataMsg = {"pullPlayerIDList":pullPlayerIDList, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PullPlayerPackData, dataMsg)
|
| | | else:
|
| | | msgInfo["pullFrom"] = GameWorld.GetServerGroupID()
|
| | | otherServerPlayerIDList = [] # 其他服玩家ID
|
| | | for playerID in pullPlayerIDList:
|
| | | if PlayerControl.GetDBPlayerAccIDByID(playerID):
|
| | | DoPullPlayerPackData(playerID, msgInfo) # 拉本服
|
| | | else:
|
| | | otherServerPlayerIDList.append(playerID)
|
| | | |
| | | # 拉其他服玩家,通过跨服拉
|
| | | if otherServerPlayerIDList:
|
| | | dataMsg = {"pullPlayerIDList":otherServerPlayerIDList, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PullOtherPlayerPackData, dataMsg)
|
| | | |
| | | return
|
| | |
|
| | | def DoPullPlayerPackData(playerID, msgInfo):
|
| | | ## 子服执行拉取本服某个玩家数据,只处理属于本服的玩家
|
| | | # @param pullFrom: 0-跨服拉; >0-子服拉
|
| | | if not PlayerControl.GetDBPlayerAccIDByID(playerID):
|
| | | # 非本服玩家
|
| | | return
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | GameWorld.DebugLog("玩家不在线的调用打包db数据! playerID=%s" % (playerID), playerID)
|
| | | data = str(msgInfo)
|
| | | GameWorld.GetGameWorld().SendDBLogic(ChConfig.gstDBLogic_PlayerPackData, playerID, data, len(data))
|
| | | return
|
| | | GameWorld.DebugLog("玩家在线的发给地图打包数据! playerID=%s" % (playerID), playerID)
|
| | | # 在线的转发给地图
|
| | | QueryPlayerResult_PlayerMirror(curPlayer, "PullPlayerPackData", msgInfo)
|
| | | return
|
| | |
|
| | | def ReuestPlayerPackDataRet(msgInfo, packMirrorID=0, packData=""):
|
| | | '''请求玩家打包数据汇总,如同时请求多个的话会逐一进行汇总整合,直到所有请求的玩家数据均有后再统一执行之后的逻辑
|
| | | '''
|
| | | requestID = msgInfo.get("requestID") # 可以是玩家ID,或者是系统自定义的请求ID
|
| | | if requestID not in PyGameData.g_requestPlayerPackDataInfo:
|
| | | GameWorld.DebugLog("不存在该[玩家打包数据]请求! requestID=%s,packMirrorID=%s,%s" % (requestID, packMirrorID, msgInfo))
|
| | | return
|
| | | recInfo = PyGameData.g_requestPlayerPackDataInfo[requestID] # 记录的汇总信息
|
| | | |
| | | recMsgInfo = recInfo.get("msgInfo", {}) |
| | | packDataDict = recInfo.get("packDataDict", {})
|
| | | if msgInfo.get("requestTime") != recMsgInfo.get("requestTime"):
|
| | | # 因为请求的数据有一定的延迟,收到回调汇总后可能已经不是之前请求的了,验证不通过则不处理
|
| | | # 暂以请求时间戳作为验证依据即可,同一秒内不可重复发起请求,所以单秒内一定是唯一的
|
| | | return
|
| | | |
| | | mirrorIDList = msgInfo["mirrorIDList"]
|
| | | if packMirrorID:
|
| | | if packMirrorID not in mirrorIDList:
|
| | | # 不在需要的请求ID里不处理,一般不可能,仅作为防范验证
|
| | | return
|
| | | if packMirrorID not in packDataDict:
|
| | | packDataDict[packMirrorID] = packData
|
| | | |
| | | for mirrorID in mirrorIDList:
|
| | | if mirrorID not in packDataDict:
|
| | | GameWorld.DebugLog("还有目标玩家没有数据,稍等后处理! requestID=%s,mirrorID=%s,mirrorIDList=%s,packIDList=%s" |
| | | % (requestID, mirrorID, mirrorIDList, packDataDict.keys()))
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("汇总玩家打包数据完毕: requestID=%s,packMirrorID=%s, %s" % (requestID, packMirrorID, msgInfo))
|
| | | PyGameData.g_requestPlayerPackDataInfo.pop(requestID, None) # 汇总完毕,清除汇总信息
|
| | | |
| | | msgType = msgInfo.get("msgType")
|
| | | # 镜像战斗
|
| | | if msgType == "MirrorBattle":
|
| | | playerID = msgInfo.get("playerID", 0)
|
| | | # 玩家发起的
|
| | | if playerID:
|
| | | playerID = msgInfo["playerID"]
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | tagMapID = GameWorld.GetQueryPlayerMapID(curPlayer)
|
| | | routeIndex = curPlayer.GetRouteServerIndex()
|
| | | else:
|
| | | tagMapID = msgInfo.get("requestMapID", 0)
|
| | | routeIndex = -1
|
| | | |
| | | sendMsg = str([msgInfo, packDataDict])
|
| | | GameWorld.DebugLog("MapServer_QueryPlayer tagMapID=%s,len=%s" % (tagMapID, len(sendMsg)), playerID)
|
| | | GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, playerID, tagMapID, "PlayerMirror", sendMsg, len(sendMsg), routeIndex)
|
| | | |
| | | # 其他功能可再扩展
|
| | | else:
|
| | | pass
|
| | | |
| | | return
|
| | |
|
| | | def ClientServerMsg_PlayerPackData(serverGroupID, msgData):
|
| | | ## 收到子服同步的玩家打包数据
|
| | | playerID = msgData["playerID"]
|
| | | packData = msgData["packData"]
|
| | | cacheBase = msgData.get("cacheBase", {})
|
| | | if cacheBase:
|
| | | PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase)
|
| | | PyDataManager.GetDBPlayerPackDataManager().UpdPlayerPackData(playerID, packData)
|
| | | |
| | | msgInfo = msgData.get("msgInfo", {})
|
| | | if not msgInfo:
|
| | | return
|
| | | |
| | | pullFrom = msgInfo.get("pullFrom")
|
| | | # 跨服自身需要的
|
| | | if pullFrom == 0:
|
| | | ReuestPlayerPackDataRet(msgInfo, playerID, packData)
|
| | | |
| | | # 其他子服发起的,推给目标子服
|
| | | elif pullFrom > 0:
|
| | | tagServerGroupID = pullFrom
|
| | | dataMsg = {"playerID":playerID, "packData":packData, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PushPlayerPackData, dataMsg, [tagServerGroupID])
|
| | | |
| | | return
|
| | |
|
| | | def ClientServerMsg_PullOtherPlayerPackData(serverGroupID, msgData):
|
| | | ## 收到子服请求拉取玩家打包数据
|
| | | |
| | | msgInfo = msgData["msgInfo"]
|
| | | pullPlayerIDList = msgData["pullPlayerIDList"]
|
| | | |
| | | otherServerPlayerIDList = []
|
| | | packDataDict = {}
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | for playerID in pullPlayerIDList:
|
| | | packObj = packDataMgr.GetPlayerPackObj(playerID)
|
| | | # 已经有的数据先推送回去
|
| | | if packObj:
|
| | | packDataDict[playerID] = packObj.PackData
|
| | | dataMsg = {"playerID":playerID, "packData":packObj.PackData, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PushPlayerPackData, dataMsg, [serverGroupID])
|
| | | else:
|
| | | otherServerPlayerIDList.append(playerID)
|
| | | |
| | | # 还没有数据的,广播给其他子服拉数据
|
| | | if otherServerPlayerIDList:
|
| | | dataMsg = {"pullPlayerIDList":otherServerPlayerIDList, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PullPlayerPackData, dataMsg)
|
| | | |
| | | return
|
| | |
|
| | | ##-------------------------------------------------------------------------------------------------
|
| | |
|
| | | def CrossServerMsg_PlayerPackDataState(msgData):
|
| | | ## 收到跨服服务器玩家打包数据状态同步
|
| | | playerID = msgData["playerID"]
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | isCross, isNeed = 1, 1
|
| | | QueryPlayerResult_PlayerMirror(curPlayer, "PackDataSyncState", [isCross, isNeed])
|
| | | return
|
| | |
|
| | | def CrossServerMsg_PullPlayerPackData(msgData):
|
| | | ## 收到跨服服务器拉取玩家打包数据
|
| | | |
| | | msgInfo = msgData["msgInfo"]
|
| | | pullPlayerIDList = msgData["pullPlayerIDList"]
|
| | | |
| | | needPullPlayerIDList = []
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | for playerID in pullPlayerIDList:
|
| | | packObj = packDataMgr.GetPlayerPackObj(playerID)
|
| | | if packObj:
|
| | | # 本服有数据,直接推给跨服
|
| | | dataMsg = {"playerID":playerID, "packData":packObj.PackData, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
|
| | | else:
|
| | | needPullPlayerIDList.append(playerID)
|
| | | |
| | | DoPullPlayerPackData(needPullPlayerIDList, msgInfo)
|
| | | return
|
| | |
|
| | | def CrossServerMsg_PushPlayerPackData(msgData):
|
| | | ## 收到跨服服务器推送的玩家打包数据
|
| | | playerID = msgData["playerID"]
|
| | | packData = msgData["packData"]
|
| | | msgInfo = msgData["msgInfo"]
|
| | | ReuestPlayerPackDataRet(msgInfo, playerID, packData)
|
| | | return
|
| | |
|
| | | def QueryPlayerResult_PlayerMirror(curPlayer, msgType, msgData=None):
|
| | | sysMsg = str([msgType, msgData])
|
| | | curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerMirror", sysMsg, len(sysMsg))
|
| | | return
|
| | |
|
| | | def OnMGUpdatePlayerPackData(curPlayer, curPackData):
|
| | | ## 地图同步更新的玩家打包数据
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | playerID = curPackData.PlayerID
|
| | | packDataSyncState = curPackData.PackDataSyncState
|
| | | packData = curPackData.PackData
|
| | | if not packDataSyncState or not packData:
|
| | | return
|
| | | msgInfo = eval(curPackData.PackMsg) if curPackData.PackMsg else {} # 打包数据附带的信息
|
| | | |
| | | # 本服需要,先更新数据
|
| | | if packDataSyncState % 10:
|
| | | PyDataManager.GetDBPlayerPackDataManager().UpdPlayerPackData(playerID, packData)
|
| | | |
| | | # 跨服需要,同步给跨服,由跨服服务器再进一步处理
|
| | | if packDataSyncState / 10:
|
| | | cacheBase = PlayerViewCache.GetSyncCrossCacheBase(curPlayer) if curPlayer else {}
|
| | | dataMsg = {"playerID":playerID, "packData":packData, "cacheBase":cacheBase, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
|
| | | |
| | | # 本服需要的功能
|
| | | pullFrom = msgInfo.get("pullFrom")
|
| | | if pullFrom > 0 and pullFrom == GameWorld.GetServerGroupID():
|
| | | ReuestPlayerPackDataRet(msgInfo, playerID, packData)
|
| | | |
| | | return
|
| | |
|
| | | def OnDBPlayerPackData(playerID, packData, msgInfo):
|
| | | ## 收到db打包玩家数据回调
|
| | | |
| | | GameWorld.DebugLog("收到db打包玩家数据回调: playerID=%s, %s" % (playerID, msgInfo))
|
| | | pullFrom = msgInfo.get("pullFrom")
|
| | | # 跨服需要,同步给跨服,由跨服服务器再进一步处理
|
| | | if pullFrom == 0 or (pullFrom > 0 and pullFrom != GameWorld.GetServerGroupID()):
|
| | | dataMsg = {"playerID":playerID, "packData":packData, "msgInfo":msgInfo}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerPackData, dataMsg)
|
| | | return
|
| | | |
| | | # 本服需要,汇总结果
|
| | | ReuestPlayerPackDataRet(msgInfo, playerID, packData)
|
| | | return
|
| | |
|
| | | def OnMGReuestPlayerPackData(msgInfo):
|
| | | ## 地图请求需要玩家打包数据信息
|
| | | #"msgType":"MirrorBattle", "msgData":msgData, "mirrorIDList":mirrorIDList, "requestTime":requestTime, "requestID":playerID, "playerID":playerID
|
| | | |
| | | packDataDict = {}
|
| | | |
| | | pullPlayerIDList = []
|
| | | packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
|
| | | requestID = msgInfo["requestID"]
|
| | | mirrorIDList = msgInfo["mirrorIDList"]
|
| | | for mirrorID in mirrorIDList:
|
| | | packObj = packDataMgr.GetPlayerPackObj(mirrorID)
|
| | | if packObj:
|
| | | packDataDict[mirrorID] = packObj.PackData
|
| | | continue
|
| | | pullPlayerIDList.append(mirrorID)
|
| | | |
| | | # 每次请求直接覆盖,由地图控制请求限制
|
| | | PyGameData.g_requestPlayerPackDataInfo[requestID] = {"msgInfo":msgInfo, "packDataDict":packDataDict}
|
| | | |
| | | # 还有玩家没有缓存打包数据,需要先完全拉取后再同步给地图
|
| | | if pullPlayerIDList:
|
| | | OnPullPlayerPackData(pullPlayerIDList, msgInfo)
|
| | | return
|
| | | |
| | | ReuestPlayerPackDataRet(msgInfo)
|
| | | return
|
| | |
|
| | |
| | | import GameWorldOpenServerCampaign
|
| | | import ShareDefine
|
| | | import GameDataRecord
|
| | | import PlayerPackData
|
| | | import PlayerCompensation
|
| | | import PlayerFB
|
| | | import UpdatePlayerName
|
| | |
| | | # 查询地图NPC数量
|
| | | elif queryType == ChConfig.queryType_NPCCnt:
|
| | | __QueryMapNPCCntInfo(curPlayer, queryCallName, sendCMD, tick)
|
| | | return
|
| | | elif queryType == ChConfig.queryType_MirrorPlayer:
|
| | | data = str({"id" : curPlayer.GetPlayerID(), "mapid" : GameWorld.GetQueryPlayerMapID(curPlayer)})
|
| | | GameWorld.GetGameWorld().SendDBLogic(0, queryID, data, len(data))
|
| | | return
|
| | | else:
|
| | | GameWorld.ErrLog('unKnow queryType = %s' % (queryType))
|
| | |
| | | GameDataRecord.ChangeCoinCnt(eval(resultName))
|
| | | return
|
| | |
|
| | | #请求玩家的打包数据
|
| | | if callName == "ReuestPlayerPackData":
|
| | | PlayerPackData.OnMGReuestPlayerPackData(eval(resultName))
|
| | | return
|
| | | |
| | | #跨服排位PK战斗结算
|
| | | if callName == "CrossChampionshipPKOver":
|
| | | CrossChampionship.MapServer_CrossChampionshipPKOver(eval(resultName), tick)
|
| | |
| | | import CrossBattlefield
|
| | | import CrossRealmPlayer
|
| | | import PyGameDataStruct
|
| | | import PlayerPackData
|
| | | import IpyGameDataPY
|
| | | import PyDataManager
|
| | | import CrossRealmPK
|
| | |
| | | return True
|
| | |
|
| | | if GameWorldSkyTower.IsSkyTowerPassPlayer(playerID):
|
| | | return True
|
| | | |
| | | if PlayerPackData.IsPackDataPlayer(playerID):
|
| | | return True
|
| | |
|
| | | #跨服榜单上的默认保留
|
| | |
| | |
|
| | | def DelOutofTimeViewCacheData():
|
| | | ## 删除过期的查看缓存数据
|
| | | |
| | | PlayerPackData.DelOutofTimePackData()
|
| | |
|
| | | pyViewCacheMgr = PyDataManager.GetPlayerViewCachePyManager()
|
| | | playerViewCachePyDict = pyViewCacheMgr.playerViewCachePyDict
|
| | |
| | |
|
| | | def UpdCrossCacheBase(playerID, cacheBase, isLogout=False):
|
| | | ## 更新同步跨服基础查看缓存
|
| | | #更新跨服在线状态,只要有同步即视为在线,除了指定是Logout的
|
| | | olMgr = ChPlayer.GetOnlinePlayerMgr()
|
| | | olMgr.SetOnlineState(playerID, not isLogout, cacheBase.get("ServerGroupID", 0))
|
| | | curCache = FindViewCache(playerID, True)
|
| | | if not curCache:
|
| | | return {}
|
| | |
| | | # ... ...
|
| | | # WORD ItemDataSize20;
|
| | | # char ItemData20[ItemDataSize20];
|
| | | # BYTE PackDataSyncState; // 打包数据同步状态: 0-不同步;个位-是否同步本服;十位-是否同步跨服
|
| | | # DWORD PackDataLen;
|
| | | # char PackData[PackDataLen];
|
| | | # WORD PackMsgLen;
|
| | | # char PackMsg[PackMsgLen];
|
| | | #};
|
| | | def OnMGUpdatePlayerCache(routeIndex, mapID, curPackData, tick):
|
| | | playerID = curPackData.PlayerID
|
| | |
| | | setattr(curCache, "ItemDataSize%s" % classLV, itemDataSize)
|
| | | #GameWorld.DebugLog(" 更新Item数据: classLV=%s,size=%s, %s" % (classLV, itemDataSize, itemData), playerID)
|
| | |
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | # 在可能删除之前执行打包数据相关逻辑
|
| | | PlayerPackData.OnMGUpdatePlayerPackData(curPlayer, curPackData)
|
| | | |
| | | if isLogout:
|
| | | #不需要保存离线数据的,直接删除缓存数据
|
| | | if not IsSaveDBViewCache(curCache):
|
| | | DeleteViewCache(playerID)
|
| | | return
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | curCache.GeTuiID = curPlayer.GetGeTuiClientID()
|
| | | curCache.GeTuiIDSize = len(curCache.GeTuiID)
|
| | |
| | | import PlayerRecData
|
| | | import GameWorldMineArea
|
| | | import PyGameDataStruct
|
| | | import PlayerPackData
|
| | | import PlayerFuncTeam
|
| | | import IpyGameDataPY
|
| | | import PlayerCharm
|
| | |
| | |
|
| | | class PyGameDataManager(object):
|
| | | def __init__(self):
|
| | | self.DBPlayerPackDataManager = PlayerPackData.DBPlayerPackDataManager()
|
| | | self.DBGameRecDataManager = GameRecData.DBGameRecDataManager()
|
| | | self.DBPyFuncTeamManager = PlayerFuncTeam.DBPyFuncTeamManager()
|
| | | self.DBPyFuncTeamMemManager = PlayerFuncTeam.DBPyFuncTeamMemManager()
|
| | |
| | |
|
| | | def GetSaveData(self):
|
| | | buff = ""
|
| | | buff += self.DBPlayerPackDataManager.GetSaveData()
|
| | | buff += self.DBGameRecDataManager.GetSaveData()
|
| | | buff += self.DBPyFuncTeamManager.GetSaveData()
|
| | | buff += self.DBPyFuncTeamMemManager.GetSaveData()
|
| | |
| | | return buff
|
| | |
|
| | | def LoadGameData(self, gameBuffer, pos):
|
| | | pos = self.DBPlayerPackDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.DBGameRecDataManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.DBPyFuncTeamManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.DBPyFuncTeamMemManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | |
| | | pyGameDataMgr = GetPyGameDataManager()
|
| | | return pyGameDataMgr.DBGameRecDataManager
|
| | |
|
| | | def GetDBPlayerPackDataManager():
|
| | | # 玩家打包数据管理
|
| | | pyGameDataMgr = GetPyGameDataManager()
|
| | | return pyGameDataMgr.DBPlayerPackDataManager
|
| | |
|
| | | def GetDBPyFuncTeamManager():
|
| | | # 功能队伍管理
|
| | | pyGameDataMgr = GetPyGameDataManager()
|
| | |
| | | g_crossActAllRechargeInfo = {} # 跨服全民充值信息,本服用 {zoneID:{playerID:总充值, ...}, ...}
|
| | | g_crossYaomoBossHurtInfo = {} # 跨服妖魔boss伤害信息,本服用 {playerID:hurtTotal, ...}
|
| | |
|
| | | g_requestPlayerPackDataInfo = {} # 请求玩家打包数据汇总信息 {requestID:{"msgInfo":msgInfo, "packDataDict":packDataDict}, ...}
|
| | |
|
| | | g_familyTalkCache = {} #{familyID:[[time,content,extras],..]}
|
| | | g_worldTalkCache = [] #[[time,name, playerID, content,extras],..]
|
| | |
|
| | |
| | | )
|
| | | return output
|
| | |
|
| | |
|
| | | # 玩家数据打包表 #tagDBPlayerPackData
|
| | | class tagDBPlayerPackData(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('PlayerID', ctypes.c_ulong),
|
| | | ('UpdTime', ctypes.c_ulong),
|
| | | ('PackDataSize', ctypes.c_ulong),
|
| | | ('PackData', ctypes.c_char_p),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.PlayerID = 0
|
| | | self.UpdTime = 0
|
| | | self.PackDataSize = 0
|
| | | self.PackData = ''
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.UpdTime, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.PackDataSize, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.PackDataSize)
|
| | | self.PackData = ctypes.c_char_p(tmp)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteDWORD(buf, self.PlayerID)
|
| | | buf = CommFunc.WriteDWORD(buf, self.UpdTime)
|
| | | buf = CommFunc.WriteDWORD(buf, self.PackDataSize)
|
| | | buf = CommFunc.WriteString(buf, self.PackDataSize, self.PackData)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += self.PackDataSize
|
| | | return length
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 玩家数据打包表 #tagDBPlayerPackData:
|
| | | PlayerID = %s,
|
| | | UpdTime = %s,
|
| | | PackDataSize = %s,
|
| | | PackData = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.PlayerID,
|
| | | self.UpdTime,
|
| | | self.PackDataSize,
|
| | | self.PackData,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | |
| | | CrossServerMsg_Notify = "Notify" # 提示信息
|
| | | CrossServerMsg_ChatCrossWorld = "ChatCrossWorld" # 跨服世界聊天
|
| | | CrossServerMsg_ViewPlayerCacheRet = "ViewPlayerCacheRet"# 查看跨服玩家信息结果
|
| | | CrossServerMsg_PlayerPackDataState = "PlayerPackDataState"# 玩家打包数据同步状态
|
| | | CrossServerMsg_PullPlayerPackData = "PullPlayerPackData"# 拉取玩家打包数据
|
| | | CrossServerMsg_PushPlayerPackData = "PushPlayerPackData"# 推送玩家打包数据
|
| | | CrossServerMsg_PKMatchReqRet = "PKMatchReqRet" # 跨服PK匹配请求结果
|
| | | CrossServerMsg_PKMatchResult = "PKMatchResult" # 跨服PK匹配结果
|
| | | CrossServerMsg_PKReadyOKRoomList = "PKReadyOKRoomList" # 跨服PK已准备好的房间列表
|
| | |
| | | ClientServerMsg_ChatCrossWorld = "ChatCrossWorld" # 跨服世界聊天
|
| | | ClientServerMsg_GMCMD = "GMCMD" # GM命令
|
| | | ClientServerMsg_ViewPlayerCache = "ViewPlayerCache" # 查看跨服玩家信息
|
| | | ClientServerMsg_PullOtherPlayerPackData = "PullOtherPlayerPackData" # 拉其他服玩家打包数据
|
| | | ClientServerMsg_PlayerPackData = "PlayerPackData" # 玩家打包数据同步
|
| | | ClientServerMsg_PKMatch = "PKMatch" # 跨服PK匹配
|
| | | ClientServerMsg_PKRobotOver = "PKRobotOver" # 跨服PK机器人结算
|
| | | ClientServerMsg_PKCancel = "PKCancel" # 跨服PK取消匹配
|
| | |
| | | PacketSubCMD_1=0x10
|
| | | PacketCallFunc_1=OnTurnFight
|
| | |
|
| | | ;镜像战斗
|
| | | [MirrorAttack]
|
| | | ScriptName = Attack\MirrorAttack.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 2
|
| | |
|
| | | PacketCMD_1=0xA1
|
| | | PacketSubCMD_1=0x09
|
| | | PacketCallFunc_1=OnSycnPlayerPackData
|
| | |
|
| | | PacketCMD_2=0xB4
|
| | | PacketSubCMD_2=0x11
|
| | | PacketCallFunc_2=OnMirrorFight
|
| | |
|
| | | ;砍树
|
| | | [PlayerCutTree]
|
| | | ScriptName = Player\PlayerCutTree.py
|
| | |
| | | import GameObj
|
| | | import BuffSkill
|
| | | import PlayerState
|
| | | import MirrorAttack
|
| | | import ChPyNetSendPack
|
| | | import NPCHurtManager
|
| | | import NetPackCommon
|
| | |
| | | 恶意攻击自己的玩家无论什么情况下都可反击,不用切换模式
|
| | | '''
|
| | | #关系有3层,无-友好-敌人
|
| | | |
| | | #镜像PK下,无视PK区域、PK模式等,仅验证双方是否同一阵营
|
| | | curBattleID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID)
|
| | | tagBattleID = tagPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID)
|
| | | if curBattleID and curBattleID == tagBattleID:
|
| | | battle = MirrorAttack.GetMirrorBattleByID(curBattleID)
|
| | | if battle.batState != ChConfig.Def_MirrorBatState_Fight:
|
| | | return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None
|
| | | if curPlayer.GetFaction() != tagPlayer.GetFaction():
|
| | | return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
|
| | | return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
|
| | | |
| | | #判断是否可释放(增/减)技能或普攻
|
| | | if CheckPlayersRelationInFB_IsNone(curPlayer, tagPlayer):
|
| | | return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package MirrorAttack
|
| | | #
|
| | | # @todo:镜像战斗
|
| | | # @author hxp
|
| | | # @date 2024-10-17
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 镜像战斗,支持与玩家镜像数据战斗,以NPC为战斗实例,支持快速战斗
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2024-10-17 15:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ChPlayer
|
| | | import ChConfig
|
| | | import EffGetSet
|
| | | import PlayerPet
|
| | | import PetControl
|
| | | import PyGameData
|
| | | import ShareDefine
|
| | | import PlayerHorse
|
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import OperControlManager
|
| | | import PlayerViewCacheTube
|
| | | import PassiveBuffEffMng
|
| | | import ChNetSendPack
|
| | | import IpyGameDataPY
|
| | | import AttackCommon
|
| | | import SkillCommon
|
| | | import PlayerState
|
| | | import SkillShell
|
| | | import CommFunc
|
| | | import PlayerFB
|
| | | import GameMap
|
| | | import FBLogic
|
| | | import GameObj
|
| | |
|
| | | import time
|
| | |
|
| | | class MirrorBattle():
|
| | | ## 某场战斗
|
| | | |
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | | |
| | | def Clear(self):
|
| | | self.isSysbg = False # 是否系统后台进行战斗的,玩家无感知,仅知道结果
|
| | | self.requestID = 0 # 请求ID,一般是玩家ID或者系统自定的ID,如某一场PK的标识信息
|
| | | self.playerID = 0 # 所属玩家ID,可能为0
|
| | | self.battleID = 0 # 该场战斗的ID,一般玩家发起的为playerID,系统发起的为大于十亿的值,即 1000000000 + 该系统场次对应功能值
|
| | | self.mapID = 0 # 功能mapID,代表某一个功能
|
| | | self.funcLineID = 0
|
| | | self.batState = 0 # 状态:0-无;1-准备中;2-战斗中;3-快速结束中,4-结束
|
| | | self.mirrorIDDict = {} # 该场所有玩家镜像实例ID对应真实ID {playerID:realPlayerID, ...}
|
| | | self.realIDDict = {} # 该场所有真实玩家对应初始信息 {playerID:{k:v, ...}, ...}
|
| | | self.playerFactionDict = {} # 该场所有玩家阵营信息,真实玩家+镜像玩家 {playerID:faction, ...}
|
| | | self.playerAutoSkillInfo = {} # 玩家自动释放技能列表 {playerID:[skillTypeID, ...], ...}
|
| | | self.deadPlayerIDList = [] # 已被击杀的玩家ID列表
|
| | | |
| | | self.isLogout = False # 是否下线的
|
| | | self.isQuick = False # 是否快速战斗结束的
|
| | | self.winFaction = 0 # 获胜阵营
|
| | | return
|
| | | |
| | | def AddBattlePlayer(self, curPlayer, faction, posX=0, posY=0):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | realPlayerID = curPlayer.GetRealPlayerID()
|
| | | if realPlayerID:
|
| | | self.mirrorIDDict[playerID] = realPlayerID
|
| | | else:
|
| | | self.realIDDict[playerID] = {"SightLevel":curPlayer.GetSightLevel(), "Faction":curPlayer.GetFaction(), "PosX":curPlayer.GetPosX(), "PosY":curPlayer.GetPosY()}
|
| | | self.playerFactionDict[playerID] = faction
|
| | | |
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, self.battleID)
|
| | | if posX and posY:
|
| | | curPlayer.ResetPos(posX, posY)
|
| | | curPlayer.SetCanAttack(True)
|
| | | curPlayer.SetFaction(faction)
|
| | | PlayerControl.SetPlayerSightLevel(curPlayer, self.battleID) # 视野层级默认为战场ID,每场战斗的玩家独立视野
|
| | | GameObj.SetHPFull(curPlayer) # 回满血
|
| | | SkillCommon.ResetAllSkillCD(curPlayer) # 重置技能CD
|
| | | return
|
| | | |
| | | def GetPlayerAutoUseSkillList(self, curPlayer):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID in self.playerAutoSkillInfo:
|
| | | return self.playerAutoSkillInfo[playerID]
|
| | | |
| | | # J.技能搭配表.xlsx 配置的技能
|
| | | job = curPlayer.GetJob()
|
| | | defaultSkillList = []
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetSkillMatchCount()):
|
| | | ipyData = ipyDataMgr.GetSkillMatchByIndex(index)
|
| | | skills = ipyData.GetSkills()
|
| | | if job > len(skills):
|
| | | continue
|
| | | defaultSkillList.append(skills[job - 1])
|
| | | |
| | | playerSetting = curPlayer.GetSetting()
|
| | | autoUseSkillList = CommFunc.ParseSetting_AutoSkillList(playerSetting, defaultSkillList)
|
| | | curJobCommAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("JobFitterSkill", job)
|
| | | # 普攻放最后
|
| | | for commSkillID in curJobCommAtkSkillIDList:
|
| | | autoUseSkillList.append(commSkillID)
|
| | | GameWorld.DebugLog("加载玩家设置的自动技能: %s" % autoUseSkillList, playerID)
|
| | | self.playerAutoSkillInfo[playerID] = autoUseSkillList
|
| | | return autoUseSkillList
|
| | | |
| | | def AddMirrorBattle(battleID, mapID=0, funcLineID=0, requestID=0, isSysbg=False, playerID=0):
|
| | | ## 增加镜像战斗管理
|
| | | # @param battleID: 战斗ID
|
| | | battle = None
|
| | | if battleID and battleID not in PyGameData.g_mirrorBattleDict:
|
| | | battle = MirrorBattle()
|
| | | battle.battleID = battleID
|
| | | battle.mapID = mapID
|
| | | battle.funcLineID = funcLineID
|
| | | battle.requestID = requestID
|
| | | battle.isSysbg = isSysbg
|
| | | battle.playerID = playerID
|
| | | PyGameData.g_mirrorBattleDict[battleID] = battle
|
| | | return battle
|
| | |
|
| | | def GetMirrorBattle(curPlayer):
|
| | | ## 获取玩家实例所属的战场
|
| | | return GetMirrorBattleByID(curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID))
|
| | |
|
| | | def GetMirrorBattleByID(battleID):
|
| | | battle = None
|
| | | if battleID in PyGameData.g_mirrorBattleDict:
|
| | | battle = PyGameData.g_mirrorBattleDict[battleID]
|
| | | # 不会执行,仅为了代码编辑.时出提示
|
| | | if False:
|
| | | battle = MirrorBattle()
|
| | | return battle
|
| | |
|
| | | def ClearMirrorBattleByPlayer(curPlayer):
|
| | | ## 清除玩家创建的镜像战斗
|
| | | ClearMirrorBattleByID(curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def ClearMirrorBattleByID(battleID):
|
| | | ## 清除镜像战斗
|
| | | battle = PyGameData.g_mirrorBattleDict.pop(battleID, None)
|
| | | if not battle:
|
| | | return
|
| | | isSysbg = battle.isSysbg
|
| | | playerMgr = GameWorld.GetPlayerManager()
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | |
| | | # 回收镜像玩家
|
| | | for mirrorID in battle.mirrorIDDict.keys():
|
| | | mirrorPlayer = playerMgr.FindPlayerByID(mirrorID)
|
| | | if mirrorPlayer:
|
| | | PlayerControl.DeleteMirror(mirrorPlayer, isSysbg) # 系统场延迟回收
|
| | | |
| | | # 重置真实玩家
|
| | | for playerID, info in battle.realIDDict.items():
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | continue
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, 0)
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleTime, 0)
|
| | | if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie or GameObj.GetHP(curPlayer) <= 0:
|
| | | ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_System, tick, isAddSuperBuff=False)
|
| | | if "PosX" in info:
|
| | | curPlayer.ResetPos(info["PosX"], info["PosY"]) # 回到进去前的坐标
|
| | | curPlayer.SetFaction(0)
|
| | | PlayerControl.SetPlayerSightLevel(curPlayer, 0)
|
| | | GameObj.SetHPFull(curPlayer) # 回满血
|
| | | SkillCommon.ResetAllSkillCD(curPlayer) # 重置技能CD
|
| | | curPlayer.SetAttackTick(tick)
|
| | | ChPlayer.__Sync_ClientBuff(curPlayer)
|
| | | |
| | | # 所属玩家
|
| | | playerID = battle.playerID
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleID, 0)
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleTime, 0)
|
| | | |
| | | return
|
| | |
|
| | | def CreateMirrorPlayer(battleID, mirrorPlayerID, mirrorPlayerData, posX=0, posY=0, faction=0, curPlayer=None):
|
| | | ''' 创建镜像玩家 |
| | | @param battleID: 所属的战斗ID
|
| | | @param mirrorPlayerID: 目标镜像玩家ID
|
| | | @param mirrorPlayerData: 目标镜像玩家数据
|
| | | @param curPlayer: 执行创建的玩家
|
| | | '''
|
| | | |
| | | battle = GetMirrorBattleByID(battleID)
|
| | | if not battle:
|
| | | GameWorld.ErrLog("没有该镜像战斗ID,无法创建玩家镜像! battleID=%s" % battleID)
|
| | | return
|
| | | mapID = battle.mapID
|
| | | funcLineID = battle.funcLineID
|
| | | |
| | | playerID = 0
|
| | | if curPlayer:
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | # playerData为base64后的数据
|
| | | mirrorPlayer = GameWorld.GetGameWorld().CreateMirrorPlayer(mirrorPlayerData, posX, posY)
|
| | | if not mirrorPlayer:
|
| | | GameWorld.ErrLog("CreateMirrorPlayer mirrorPlayerID=%s,posX=%s,posY=%s,faction=%s" |
| | | % (mirrorPlayerID, posX, posY, faction), playerID)
|
| | | return
|
| | | PlayerControl.SetCustomMap(mirrorPlayer, mapID, funcLineID)
|
| | | mirrorID = mirrorPlayer.GetID()
|
| | | realPlayerID = mirrorPlayer.GetRealPlayerID()
|
| | | dataFightPower = PlayerControl.GetFightPower(mirrorPlayer)
|
| | | GameWorld.DebugLog("CreateMirrorPlayer mirrorID=%s,realPlayerID=%s,mapID=%s,funcLineID=%s,posX=%s,posY=%s,faction=%s,dataFightPower=%s,,accID=%s" |
| | | % (mirrorID, realPlayerID, mapID, funcLineID, posX, posY, faction, dataFightPower, mirrorPlayer.GetAccID()), playerID)
|
| | | |
| | | ChPlayer.InitPlayerPack(mirrorPlayer)
|
| | | PlayerHorse.PlayerRideHorseUp(mirrorPlayer, False, False)
|
| | | |
| | | #是否镜像玩家 判断 mirrorPlayer.GetRealPlayerID()是否为0
|
| | | #python自己处理,以下逻辑,可以在DoPlayerLogin函数最后 判断是镜像玩家后统一处理
|
| | | #index = mirrorPlayer.GetIndex()
|
| | | #tick = GameWorld.GetGameWorld().GetTick()
|
| | | #ChPlayer.PlayerLogin
|
| | | #PlayerEventCounter.GameServer_InitOK(index, tick)
|
| | | #ChPlayer.LoadMapOK(index, tick)
|
| | | #GameServerRefresh.GameSever_PlayerInitOK(index, tick)
|
| | | mirrorPlayer.SendToBServerServerInitOK()
|
| | | mirrorPlayer.SetMapLoadOK(True)
|
| | | #将玩家放置在这个地图上
|
| | | mirrorPlayer.InitPos(mirrorPlayer.GetPosX(), mirrorPlayer.GetPosY())
|
| | | #把玩家设置为初始化成功状态
|
| | | mirrorPlayer.SetCanAttack(True)
|
| | | mirrorPlayer.SetCanMove(True)
|
| | | mirrorPlayer.SetIsNeedProcess(True)
|
| | | mirrorPlayer.SetInitOK(True)
|
| | | mirrorPlayer.EndLoadMap()
|
| | | mirrorPlayer.SetGameServerInitOK(True)
|
| | | |
| | | #刷被动、属性
|
| | | PassiveBuffEffMng.OnLoadMapGFPassive(mirrorPlayer)
|
| | | mirrorControl = PlayerControl.PlayerControl(mirrorPlayer)
|
| | | mirrorControl.ReCalcAllState()
|
| | | refreshFightPower = PlayerControl.GetFightPower(mirrorPlayer)
|
| | | if refreshFightPower != dataFightPower:
|
| | | GameWorld.ErrLog("CreateMirrorPlayer mirrorID=%s,realPlayerID=%s,dataFightPower=%s != refreshFightPower=%s" |
| | | % (mirrorID, realPlayerID, dataFightPower, refreshFightPower), playerID)
|
| | | |
| | | battle.AddBattlePlayer(mirrorPlayer, faction, posX, posY)
|
| | | |
| | | #最后设置可见,刷新视野
|
| | | mirrorPlayer.SetVisible(True)
|
| | | mirrorPlayer.RefreshView()
|
| | | |
| | | #灵宠有些属性取主人玩家,所以在玩家刷完属性后处理,也必须在主人刷新视野后处理,不然出现封包顺序可能不对,导致前端无法显示灵宠
|
| | | PetControl.DoLogic_PetLoadMapOK(mirrorPlayer)
|
| | | |
| | | if GameWorld.GetGameWorld().GetDebugLevel():
|
| | | DebugLogPlayerInfo(mirrorPlayer)
|
| | | if playerID == realPlayerID:
|
| | | DebugLogPlayerInfo(curPlayer)
|
| | | return mirrorPlayer
|
| | |
|
| | | def DebugLogPlayerInfo(curPlayer):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("-------------- DebugLogPlayerInfo玩家信息 --------------", playerID)
|
| | | realPlayerID = curPlayer.GetRealPlayerID()
|
| | | posX = curPlayer.GetPosX()
|
| | | posY = curPlayer.GetPosY()
|
| | | sightLevel = curPlayer.GetSightLevel()
|
| | | GameWorld.DebugLog("realPlayerID=%s,posX=%s,posY=%s,sightLevel=%s" % (realPlayerID, posX, posY, sightLevel), playerID)
|
| | | GameWorld.DebugLog("生命=%s/%s, 护盾=%s/%s" |
| | | % (GameObj.GetHP(curPlayer), GameObj.GetMaxHP(curPlayer), |
| | | PlayerControl.GetProDef(curPlayer), PlayerControl.GetMaxProDef(curPlayer)), playerID)
|
| | | |
| | | # 属性
|
| | | attrInfo = ""
|
| | | for index in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):
|
| | | value = EffGetSet.GetValueByEffIndex(curPlayer, index)
|
| | | if value:
|
| | | attrInfo = "%s,%s=%s" % (attrInfo, index, value)
|
| | | GameWorld.DebugLog("AttrInfo=%s" % attrInfo, playerID)
|
| | | GameWorld.DebugLog("FightPower=%s" % (PlayerControl.GetFightPower(curPlayer)), playerID)
|
| | | |
| | | # 技能
|
| | | skillDict = {}
|
| | | skillManager = curPlayer.GetSkillManager()
|
| | | for i in range(0 , skillManager.GetSkillCount()):
|
| | | curSkill = skillManager.GetSkillByIndex(i)
|
| | | if not curSkill:
|
| | | continue
|
| | | funcType = curSkill.GetFuncType()
|
| | | if funcType not in skillDict:
|
| | | skillDict[funcType] = {}
|
| | | skillInfo = skillDict[funcType]
|
| | | skillInfo[curSkill.GetSkillID()] = curSkill.GetSkillName()
|
| | | for funcType, skillInfo in skillDict.items():
|
| | | skillIDList = skillInfo.keys()
|
| | | skillIDList.sort()
|
| | | GameWorld.DebugLog("Skill FuncType=%s,count=%s,%s" % (funcType, len(skillIDList), skillIDList), playerID)
|
| | | |
| | | # 被动
|
| | | passiveEff = PassiveBuffEffMng.GetPassiveEffManager().GetPassiveEff(curPlayer)
|
| | | if passiveEff:
|
| | | GameWorld.DebugLog("被动效果 :%s" % passiveEff.AffectSkillDict, playerID)
|
| | | GameWorld.DebugLog("选中的被动技能效果 :%s" % passiveEff.AffectPassiveSkillSetDict, playerID)
|
| | | GameWorld.DebugLog("被动BUFF效果 :%s" % passiveEff.AffectBuffDict, playerID)
|
| | | GameWorld.DebugLog("神兽被动效果 :%s" % passiveEff.AffectDogzSkillDict, playerID)
|
| | | else:
|
| | | GameWorld.DebugLog("无技能被动效果!", playerID)
|
| | | |
| | | fightPet = curPlayer.GetPetMgr().GetFightPet()
|
| | | if fightPet:
|
| | | GameWorld.DebugLog("出战宠物技能%s-%s" % PlayerPet.GetPetLearnSkill(curPlayer), playerID)
|
| | | passiveEff = PassiveBuffEffMng.GetPassiveEffManager().GetPassiveEff(fightPet)
|
| | | if passiveEff:
|
| | | GameWorld.DebugLog("宠物被动效果 :%s" % passiveEff.AffectSkillDict, playerID)
|
| | | GameWorld.DebugLog("宠物被动BUFF效果 :%s" % passiveEff.AffectBuffDict, playerID)
|
| | | else:
|
| | | GameWorld.DebugLog("无技能被动效果!", playerID)
|
| | | |
| | | # 物品
|
| | | for packType in [IPY_GameWorld.rptEquip, ShareDefine.rptPet, ShareDefine.rptDogzEquip]:
|
| | | curPack = curPlayer.GetItemManager().GetPack(packType)
|
| | | itemCount = 0
|
| | | for i in range(0, curPack.GetCount()):
|
| | | item = curPack.GetAt(i)
|
| | | if not item.GetItemTypeID():
|
| | | continue
|
| | | itemCount += 1
|
| | | #GameWorld.DebugLog("packType=%s,i=%s,itemID=%s,userData=%s" % (packType, i, item.GetItemTypeID(), item.GetUserData()))
|
| | | GameWorld.DebugLog("packType:%s,count=%s/%s" % (packType, itemCount, curPack.GetCount()), playerID)
|
| | | |
| | | GameWorld.DebugLog("-------------------------------------------------------", playerID)
|
| | | return
|
| | |
|
| | | #// A1 09 同步打包玩家数据 #tagCMSycnPlayerPackData
|
| | | #
|
| | | #struct tagCMSycnPlayerPackData
|
| | | #{
|
| | | # tagHead Head;
|
| | | #};
|
| | | def OnSycnPlayerPackData(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
|
| | | return
|
| | |
|
| | | #// B4 11 镜像战斗 #tagCMMirrorFight
|
| | | #
|
| | | #struct tagCMMirrorFight
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD MapID; // 自定义地图ID,如竞技场等
|
| | | # WORD FuncLineID;
|
| | | # DWORD TagPlayeID; // 目标玩家ID,支持跨服玩家ID
|
| | | # BYTE CmdType; // 命令类型: 0-创建战斗;1-开始战斗;2-战斗中跳过;3-不创建战斗直接得结果
|
| | | #};
|
| | | def OnMirrorFight(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | mapID = clientData.MapID
|
| | | funcLineID = clientData.FuncLineID
|
| | | tagPlayeID = clientData.TagPlayeID
|
| | | cmdType = clientData.CmdType
|
| | | |
| | | if not tagPlayeID:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | #if tagPlayeID == playerID:
|
| | | # GameWorld.DebugLog("不能打自己!", playerID)
|
| | | # return
|
| | | |
| | | # 创建战斗,玩家自身参与
|
| | | if cmdType == 0:
|
| | | isSysbg = False
|
| | | requestID = playerID
|
| | | posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
|
| | | battlePlayerList = []
|
| | | battlePlayerList.append({"playerID":playerID, "faction":1, "posX":posX, "posY":posY})
|
| | | battlePlayerList.append({"playerID":tagPlayeID, "faction":2, "posX":posX + 5, "posY":posY})
|
| | | OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, battlePlayerList, isSysbg, curPlayer)
|
| | | return
|
| | | |
| | | # 开始战斗
|
| | | if cmdType == 1:
|
| | | battle = GetMirrorBattle(curPlayer)
|
| | | if battle:
|
| | | OnMirrorBattleStart(battle.battleID)
|
| | | return
|
| | | |
| | | # 战斗中跳过
|
| | | if cmdType == 2:
|
| | | battle = GetMirrorBattle(curPlayer)
|
| | | if battle:
|
| | | DoMirrorBattleQuick(battle.battleID)
|
| | | return
|
| | | |
| | | # 不战斗直接跳过,即玩家没有参与,创建系统战斗场,之后扩展
|
| | | if cmdType == 3:
|
| | | isSysbg = True
|
| | | requestID = playerID
|
| | | posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
|
| | | battlePlayerList = []
|
| | | battlePlayerList.append({"playerID":playerID, "faction":1, "posX":posX, "posY":posY})
|
| | | battlePlayerList.append({"playerID":tagPlayeID, "faction":2, "posX":posX + 5, "posY":posY})
|
| | | OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, battlePlayerList, isSysbg, curPlayer)
|
| | | return
|
| | | |
| | | # 可不做验证,PK结束后由各个功能自行做结算验证
|
| | | return
|
| | |
|
| | | def OnPlayerLeaveMap(curPlayer):
|
| | | ## 玩家离开地图
|
| | | if curPlayer.GetRealPlayerID():
|
| | | return
|
| | | battle = GetMirrorBattle(curPlayer)
|
| | | if not battle:
|
| | | return
|
| | | |
| | | # 如果还在战斗中,直接快速执行战斗结果
|
| | | if battle.batState == ChConfig.Def_MirrorBatState_Fight:
|
| | | DoMirrorBattleQuick(battle.battleID, True)
|
| | | |
| | | # 统一退出
|
| | | if PlayerControl.GetCustomMapID(curPlayer):
|
| | | PlayerFB.DoExitCustomScene(curPlayer)
|
| | | return
|
| | |
|
| | | def OnRequestCreateMirrorBattle(mapID, funcLineID, requestID, battlePlayerList, isSysbg=False, curPlayer=None):
|
| | | ''' 请求创建镜像战斗,支持多对多,支持跨服,本服跨服地图中均可直接请求
|
| | | @param mapID: 功能地图ID
|
| | | @param funcLineID: 功能地图线路ID
|
| | | @param requestID: 请求ID,如果是玩家发起的,一般传入玩家ID;如果是系统发起的,由系统自行决定,比如roomID之类
|
| | | @param battlePlayerList: 战斗的玩家信息列表 [{"playerID":玩家ID, "posX":坐标x, "posY":坐标y, "faction":阵营}, ...]
|
| | | @param isSysbg: 是否后台战斗,默认否,但是系统发起的默认是
|
| | | @param curPlayer: 发起的玩家,为空时代表系统发起创建的
|
| | | '''
|
| | | |
| | | playerID = 0
|
| | | if curPlayer:
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | curTime = int(time.time())
|
| | | # 请求cd验证
|
| | | requestTime = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleTime)
|
| | | if requestTime and (curTime - requestTime) <= 20: # 20秒内不重复请求
|
| | | PlayerControl.NotifyCode(curPlayer, "RequestLater")
|
| | | return
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MirrorBattleTime, curTime)
|
| | | else:
|
| | | isSysbg = True # 系统发起的默认后台战斗
|
| | | |
| | | mirrorIDList = []
|
| | | for battleInfo in battlePlayerList:
|
| | | batPlayerID = battleInfo["playerID"]
|
| | | faction = battleInfo["faction"]
|
| | | if batPlayerID == playerID and faction == 1 and not isSysbg:
|
| | | # 自己不用,使用自身进行战斗即可
|
| | | continue
|
| | | if batPlayerID not in mirrorIDList:
|
| | | mirrorIDList.append(batPlayerID)
|
| | | |
| | | # 战斗相关的数据
|
| | | msgData = {"mapID":mapID, "funcLineID":funcLineID, "battlePlayerList":battlePlayerList, "isSysbg":isSysbg}
|
| | | |
| | | # 发送GameServer请求玩家打包数据
|
| | | requestTime = curTime # 请求的时间戳,每个玩家最多允许同时存在一场战斗,每次重新请求后覆盖数据
|
| | | requestMapID = GameWorld.GetGameWorld().GetRealMapID()
|
| | | sendMsg = str({"msgType":"MirrorBattle", "msgData":msgData, "mirrorIDList":mirrorIDList, |
| | | "requestTime":requestTime, "requestID":requestID, "requestMapID":requestMapID, "playerID":playerID})
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "ReuestPlayerPackData", sendMsg, len(sendMsg))
|
| | | GameWorld.DebugLog("请求创建镜像战斗: %s" % sendMsg, playerID)
|
| | | return
|
| | |
|
| | | def OnMirrorBattleInit(msgInfo, packDataDict, curPlayer=None):
|
| | | ''' 镜像战斗初始化 |
| | | @param msgInfo: OnRequestCreateMirrorBattle 发送GameServer的信息
|
| | | @param packDataDict: 返回需要的玩家打包数据 {playerID:packData, ...}
|
| | | @param curPlayer: 如果是玩家发起的则不为空
|
| | | '''
|
| | | |
| | | requestID = msgInfo["requestID"]
|
| | | playerID = msgInfo.get("playerID", 0)
|
| | | msgData = msgInfo["msgData"]
|
| | | |
| | | mapID = msgData.get("mapID", 0)
|
| | | funcLineID = msgData.get("funcLineID", 0)
|
| | | battlePlayerList = msgData.get("battlePlayerList", [])
|
| | | isSysbg = msgData.get("isSysbg", 0) # 系统后台战斗
|
| | | |
| | | battleID = 0
|
| | | if isSysbg:
|
| | | sysBattleIDStart = 1000000000 # 系统场从十亿开始
|
| | | for num in range(sysBattleIDStart, sysBattleIDStart + 1000):
|
| | | if num not in PyGameData.g_mirrorBattleDict:
|
| | | battleID = num
|
| | | break
|
| | | elif playerID:
|
| | | battleID = playerID
|
| | | |
| | | battle = AddMirrorBattle(battleID, mapID, funcLineID, requestID, isSysbg, playerID)
|
| | | if not battle:
|
| | | GameWorld.ErrLog("镜像战场ID已存在! battleID=%s,msgInfo=%s" % (battleID, msgInfo), requestID)
|
| | | return
|
| | | GameWorld.DebugLog("镜像战斗初始化: msgData=%s,packIDList=%s" % (msgData, packDataDict.keys()), battleID)
|
| | | |
| | | for battleInfo in battlePlayerList:
|
| | | batPlayerID = battleInfo["playerID"]
|
| | | posX = battleInfo.get("posX", 0)
|
| | | posY = battleInfo.get("posY", 0)
|
| | | faction = battleInfo.get("faction", 0)
|
| | | |
| | | if curPlayer and batPlayerID == playerID and faction == 1 and not isSysbg:
|
| | | battle.AddBattlePlayer(curPlayer, faction, posX, posY)
|
| | | continue
|
| | | |
| | | packData = packDataDict.get(batPlayerID)
|
| | | if not packData:
|
| | | GameWorld.ErrLog("初始化镜像战斗时没有玩家镜像数据! batPlayerID=%s" % batPlayerID, playerID)
|
| | | continue
|
| | | |
| | | CreateMirrorPlayer(battleID, batPlayerID, packData, posX, posY, faction, curPlayer)
|
| | | |
| | | battle.batState = ChConfig.Def_MirrorBatState_Prepare
|
| | | |
| | | if not isSysbg:
|
| | | return
|
| | | |
| | | # 系统场默认直接开始、快速战斗结束
|
| | | OnMirrorBattleStart(battleID)
|
| | | DoMirrorBattleQuick(battleID)
|
| | | return
|
| | |
|
| | | def OnMirrorBattleStart(battleID):
|
| | | ## 镜像战斗开始
|
| | | battle = GetMirrorBattleByID(battleID)
|
| | | if not battle:
|
| | | return
|
| | | if battle.batState >= ChConfig.Def_MirrorBatState_Fight:
|
| | | return
|
| | | battle.batState = ChConfig.Def_MirrorBatState_Fight
|
| | | return
|
| | |
|
| | | def ProcessPlayerMirrorAI(curPlayer, tick):
|
| | | ## 镜像战斗AI
|
| | | battle = GetMirrorBattle(curPlayer)
|
| | | if not battle:
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if battle.batState != ChConfig.Def_MirrorBatState_Fight:
|
| | | #GameWorld.DebugLog("镜像玩家仅自由战斗状态下需要处理! battleID=%s,batState=%s" % (battle.battleID, battle.batState), playerID)
|
| | | return
|
| | | |
| | | if not battle.isQuick:
|
| | | realPlayerID = curPlayer.GetRealPlayerID()
|
| | | if not realPlayerID:
|
| | | # 常规战斗下,真实玩家不处理,由玩家自行控制
|
| | | return
|
| | | |
| | | if GameObj.GetHP(curPlayer) <= 0:
|
| | | #GameWorld.DebugLog("镜像玩家已被击杀", playerID)
|
| | | return
|
| | | |
| | | # 攻击间隔
|
| | | if tick - curPlayer.GetPlayerAttackTick() < curPlayer.GetAtkInterval():
|
| | | GameWorld.DebugLog("攻击间隔: %s < %s" % (tick - curPlayer.GetPlayerAttackTick(), curPlayer.GetAtkInterval()), playerID)
|
| | | return
|
| | | |
| | | autoUseSkillList = battle.GetPlayerAutoUseSkillList(curPlayer)
|
| | | GameWorld.DebugLog("镜像AI攻击: autoUseSkillList=%s" % (autoUseSkillList), playerID)
|
| | | |
| | | if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse:
|
| | | PlayerHorse.PlayerRideHorseDown(curPlayer)
|
| | | |
| | | isOK = False
|
| | | actionObj = PlayerState.__GetCanAttack_ObjDetel(curPlayer, tick)
|
| | | if actionObj:
|
| | | isOK = PlayerAttack(curPlayer, actionObj, tick, autoUseSkillList)
|
| | | |
| | | if not isOK:
|
| | | curFaction = curPlayer.GetFaction()
|
| | | playerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for batPlayerID, faction in battle.playerFactionDict.items():
|
| | | if faction == curFaction:
|
| | | continue
|
| | | if actionObj and actionObj.GetID() == batPlayerID:
|
| | | continue
|
| | | tagObj = playerMgr.FindPlayerByID(batPlayerID)
|
| | | isOK = PlayerAttack(curPlayer, tagObj, tick, autoUseSkillList)
|
| | | if isOK:
|
| | | break
|
| | | |
| | | if isOK:
|
| | | # 每次处理仅执行一次成功行为
|
| | | return
|
| | | |
| | | return
|
| | |
|
| | | def PlayerAttack(curPlayer, tagObj, tick, autoUseSkillList):
|
| | | ## 玩家攻击, 参考技能使用 #def UseSkillEx(index, clientData, tick):
|
| | | if not tagObj or GameObj.GetHP(tagObj) <= 0:
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
|
| | | tagObjType, tagObjID = tagObj.GetGameObjType(), tagObj.GetID()
|
| | | tagPosX, tagPosY = tagObj.GetPosX(), tagObj.GetPosY()
|
| | | curPlayer.SetActionObj(tagObj)
|
| | | |
| | | curPlayer.ClearUseSkillRec()
|
| | | curPlayer.SetAttackTargetPos(posX, posY)
|
| | | curPlayer.SetUseSkillPosX(tagPosX)
|
| | | curPlayer.SetUseSkillPosY(tagPosY)
|
| | | curPlayer.SetUseSkillTagType(tagObjType)
|
| | | curPlayer.SetUseSkillTagID(tagObjID)
|
| | | |
| | | needMoveto = False # 有可释放的技能优先释放技能,没有的话再移动
|
| | | useSkillResult = False
|
| | | skillMgr = curPlayer.GetSkillManager()
|
| | | for skillTypeID in autoUseSkillList:
|
| | | curSkill = skillMgr.FindSkillBySkillTypeID(skillTypeID)
|
| | | if not curSkill:
|
| | | continue
|
| | | skillID = curSkill.GetSkillID()
|
| | | |
| | | #CheckSkillCondition
|
| | | #被动技能无法使用
|
| | | if SkillCommon.isPassiveSkill(curSkill):
|
| | | continue
|
| | | #还在冷却时间内无法释放
|
| | | if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0:
|
| | | continue
|
| | | |
| | | if not AttackCommon.CheckPlayerAttackDist(curPlayer, tagObj, curSkill):
|
| | | needMoveto = True
|
| | | continue
|
| | | |
| | | curPlayer.SetUseSkill(curSkill.GetSkillData())
|
| | | useSkillData = curPlayer.GetUseSkill()
|
| | | if not PlayerState.__DoClientUseSkillEx(curPlayer, useSkillData, tick):
|
| | | GameWorld.DebugLog(" 技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID))
|
| | | continue
|
| | | useSkillResult = True
|
| | | GameWorld.DebugLog(" 技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID))
|
| | | |
| | | if useSkillData and useSkillData.GetSkillID() != ChConfig.Def_SkillID_Somersault:
|
| | | # 跟随玩家同频率攻击
|
| | | PetControl.PetFight(curPlayer, tick)
|
| | | PlayerState.SummonFollowAtk(curPlayer, tick)
|
| | | break
|
| | | |
| | | curPlayer.ClearUseSkillRec()
|
| | | |
| | | if useSkillResult:
|
| | | curPlayer.SetAttackTick(tick)
|
| | | else:
|
| | | if needMoveto:
|
| | | MoveToObj(curPlayer, tagObj, tick)
|
| | | return
|
| | | |
| | | return useSkillResult
|
| | |
|
| | | def MoveToObj(curPlayer, tagObj, tick):
|
| | | #不可移动行为状态, 服务端限制
|
| | | if not OperControlManager.IsObjCanDoAction(curPlayer,
|
| | | ChConfig.Def_Obj_ActState_ServerAct,
|
| | | IPY_GameWorld.oalMove):
|
| | | return
|
| | | |
| | | destX = tagObj.GetPosX()
|
| | | destY = tagObj.GetPosY()
|
| | | # 缩小两格子用于前方一小片区域
|
| | | resultPos = GameMap.GetEmptyPlaceInArea(destX, destY, 1)
|
| | | moveDestX = resultPos.GetPosX()
|
| | | moveDestY = resultPos.GetPosY()
|
| | | |
| | | if (tick - curPlayer.GetDictByKey("MoveTick")) < 1000:
|
| | | # .Move( 接口调用太快会导致移动时间不够长(不足一格)导致无法移动 或者移动过慢问题
|
| | | # SetDestPos 调用会导致反向移动偏快
|
| | | #curPlayer.SetDestPos(moveDestX, moveDestY)
|
| | | return
|
| | | curPlayer.SetDict("MoveTick", tick)
|
| | | #return curPlayer.Move(moveDestX, moveDestY)
|
| | | |
| | | # 执行一次重置位置,避免快速发包导致无法移动
|
| | | curPlayer.ChangePos(moveDestX, moveDestY)
|
| | | |
| | | sendPack = ChNetSendPack.tagObjMove()
|
| | | sendPack.Clear()
|
| | | sendPack.ObjID = curPlayer.GetID()
|
| | | sendPack.ObjType = IPY_GameWorld.gotNPC
|
| | | sendPack.MoveType = IPY_GameWorld.gotPlayer
|
| | | sendPack.DestPosX = moveDestX
|
| | | sendPack.DestPosY = moveDestY
|
| | | sendPack.Speed = curPlayer.GetSpeed()
|
| | | sendPack.StartPosX = curPlayer.GetPosX()
|
| | | sendPack.StartPosY = curPlayer.GetPosY()
|
| | | curPlayer.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
|
| | | return
|
| | |
|
| | | def DoMirrorBattleQuick(battleID, isLogout=False):
|
| | | ## 执行快速战斗
|
| | | battle = GetMirrorBattleByID(battleID)
|
| | | if not battle:
|
| | | return
|
| | | if battle.batState > ChConfig.Def_MirrorBatState_Fight:
|
| | | return
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | battle.batState = ChConfig.Def_MirrorBatState_Fight
|
| | | battle.isQuick = True
|
| | | battle.isLogout = isLogout
|
| | | |
| | | playerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | perLoopTick = 100 # 每次循环视为已过毫秒
|
| | | maxLoopCount = 60 * 1000 / perLoopTick # 循环次数上限,暂定最长PK时长60秒
|
| | | GameWorld.DebugLog("DoMirrorBattleQuick isLogout=%s,maxLoopCount=%s,tick=%s" % (isLogout, maxLoopCount, tick), battleID)
|
| | | |
| | | # 屏蔽发包
|
| | | for batPlayerID in battle.realIDDict.keys():
|
| | | curPlayer = playerMgr.FindPlayerByID(batPlayerID)
|
| | | if not curPlayer:
|
| | | continue
|
| | | curPlayer.SetForbiddenSyncClientState(True)
|
| | | |
| | | for loopCount in range(maxLoopCount):
|
| | | if battle.batState != ChConfig.Def_MirrorBatState_Fight:
|
| | | # 可能还没循环完毕就结束了
|
| | | break
|
| | | tick += loopCount * perLoopTick # 修改每次循环的tick
|
| | | GameWorld.DebugLog(" loopCount=%s,tick=%s" % (loopCount, tick), battleID)
|
| | | for batPlayerID in battle.playerFactionDict.keys():
|
| | | if batPlayerID in battle.deadPlayerIDList:
|
| | | continue
|
| | | curPlayer = playerMgr.FindPlayerByID(batPlayerID)
|
| | | if not curPlayer or GameObj.GetHP(curPlayer) <= 0:
|
| | | continue
|
| | | # 刷新定时处理的buff效果
|
| | | SkillShell.ProcessPersistBuff(curPlayer, tick)
|
| | | |
| | | #刷新玩家Buff时长
|
| | | reFlashBuff = PlayerState.ProcessRefreshBuffState(curPlayer, tick)
|
| | | |
| | | attrBuffResult, actBuffResult = PlayerState.ProcessRefreshActionBuffState(curPlayer, tick)
|
| | | playerControl = PlayerControl.PlayerControl(curPlayer)
|
| | | if actBuffResult:
|
| | | playerControl.RefreshPlayerActionState()
|
| | | |
| | | #此处才是真正的刷新人物属性值,需刷属性逻辑应在此行前调用
|
| | | if not playerControl.RefreshPlayerAttrStateEx():
|
| | | if reFlashBuff or attrBuffResult:
|
| | | playerControl.RefreshPlayerAttrByBuff()
|
| | | # 只刷BUFF情况
|
| | | playerControl.RefreshPlayerAttrByBuffEx() |
| | | |
| | | ProcessPlayerMirrorAI(curPlayer, tick)
|
| | | |
| | | if battle.winFaction:
|
| | | # 已经有获胜方了,代表已经触发过结算胜负
|
| | | return
|
| | | # 暂定没击杀算输,发起方为1
|
| | | GameWorld.DebugLog("没有击败对方阵营!", battleID)
|
| | | battle.winFaction = 2
|
| | | OnMirrorAttackOver(battleID)
|
| | | return
|
| | |
|
| | | def OnPlayerDead(curPlayer):
|
| | | battleID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_MirrorBattleID)
|
| | | if not battleID:
|
| | | return
|
| | | battle = GetMirrorBattleByID(battleID)
|
| | | if not battle:
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | curFaction = curPlayer.GetFaction()
|
| | | if playerID not in battle.deadPlayerIDList:
|
| | | battle.deadPlayerIDList.append(playerID)
|
| | | GameWorld.DebugLog("镜像战斗战场玩家被击杀! playerID=%s,curFaction=%s,deadPlayerIDList=%s" |
| | | % (playerID, curFaction, battle.deadPlayerIDList), battleID)
|
| | | |
| | | winFaction = 0
|
| | | for batPlayerID, faction in battle.playerFactionDict.items():
|
| | | if faction != curFaction:
|
| | | winFaction = faction
|
| | | continue
|
| | | if batPlayerID not in battle.deadPlayerIDList:
|
| | | #GameWorld.DebugLog("相同阵营还有未被击杀的玩家!")
|
| | | return
|
| | | |
| | | # 同阵营都被击杀了,结算胜负
|
| | | battle.winFaction = winFaction
|
| | | GameWorld.DebugLog("某一阵营已被击败! winFaction=%s" % winFaction, battleID)
|
| | | OnMirrorAttackOver(battleID)
|
| | | return
|
| | |
|
| | | def OnMirrorAttackOver(battleID):
|
| | | battle = GetMirrorBattleByID(battleID)
|
| | | if not battle:
|
| | | return
|
| | | if battle.batState >= ChConfig.Def_MirrorBatState_Over:
|
| | | # 已经结算过
|
| | | return
|
| | | battle.batState = ChConfig.Def_MirrorBatState_Over
|
| | | mapID = battle.mapID
|
| | | funcLineID = battle.funcLineID
|
| | | winFaction = battle.winFaction
|
| | | isQuick = battle.isQuick
|
| | | isLogout = battle.isLogout
|
| | | GameWorld.DebugLog("镜像战斗结束: mapID=%s,funcLineID=%s,winFaction=%s,isQuick=%s,isLogout=%s" |
| | | % (mapID, funcLineID, winFaction, isQuick, isLogout), battleID)
|
| | | |
| | | playerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | |
| | | #快速战斗结束的额外处理
|
| | | if isQuick:
|
| | | for playerID in battle.realIDDict.keys():
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | continue
|
| | | curPlayer.SetForbiddenSyncClientState(False)
|
| | | |
| | | for playerID in battle.playerFactionDict.keys():
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | continue
|
| | | # 重新通知最终血量及状态
|
| | | GameObj.SetHP(curPlayer, GameObj.GetHP(curPlayer))
|
| | | if playerID in battle.deadPlayerIDList:
|
| | | curPlayer.SetDead(curPlayer.GetDictByKey(ChConfig.Def_NPCDead_KillerID),
|
| | | curPlayer.GetDictByKey(ChConfig.Def_NPCDead_KillerType))
|
| | | |
| | | FBLogic.OnMirrorBattleOver(battleID, mapID)
|
| | | |
| | | if battle.isSysbg:
|
| | | ClearMirrorBattleByID(battleID)
|
| | | return
|
| | |
|
| | |
| | | Def_FBMapID_ArenaBattle = 31290
|
| | | #情缘副本
|
| | | Def_FBMapID_Love = 31300
|
| | | #镜像切磋
|
| | | Def_FBMapID_MirrorBattle = 100
|
| | |
|
| | | #回合战斗自定义地图ID
|
| | | Def_TFMapID_MineArea = 1 # 福地 1
|
| | |
| | | Def_TFMapID_SendToGameServer = [Def_TFMapID_MineArea, Def_FBMapID_ArenaBattle]
|
| | |
|
| | | #前端自定义场景地图
|
| | | ClientCustomScene = [Def_FBMapID_PersonalBoss, Def_FBMapID_ArenaBattle]
|
| | | ClientCustomSceneList = [Def_FBMapID_PersonalBoss, Def_FBMapID_ArenaBattle, Def_FBMapID_MirrorBattle]
|
| | |
|
| | | #注册上传跨服服务器数据后直接进入跨服服务器的地图
|
| | | RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonLand, Def_FBMapID_CrossDemonKing,
|
| | |
| | | 'MineArea':[Def_TFMapID_MineArea], #福地
|
| | | 'AlineInvade':[Def_TFMapID_AlineInvade], #异兽入侵
|
| | | 'Adventure':[Def_TFMapID_Adventure], #冒险
|
| | | 'MirrorBattle':[Def_FBMapID_MirrorBattle], #镜像切磋
|
| | | }
|
| | |
|
| | | #特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
|
| | |
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #请求类型(需要和GameServer中的一致)
|
| | | Def_QueryType_Count = 56
|
| | | Def_QueryType_Count = 55
|
| | | (
|
| | | queryType_sqtPlayer, #查询玩家
|
| | | queryType_sqtFamilyWar, #家族战
|
| | |
| | | queryType_EnterFB, #进入副本
|
| | | queryType_NPCInfo, #查询NPCInfo
|
| | | queryType_NPCCnt, #查询NPC数量
|
| | | queryType_MirrorPlayer, #镜像玩家
|
| | | ) = range(0, Def_QueryType_Count)
|
| | | #------------------------------------------------------------------------------
|
| | | #---------------------------------------------------------------------
|
| | |
| | | Def_PlayerState_Ice, # 寒冰状态(同减速) 19
|
| | | ) = range(20)
|
| | |
|
| | | #镜像战斗状态 0-无;1-准备中;2-自由战斗;3-结束
|
| | | (
|
| | | Def_MirrorBatState_Init, # 初始化 0
|
| | | Def_MirrorBatState_Prepare, # 初始化完毕,准备阶段 1
|
| | | Def_MirrorBatState_Fight, # 战斗阶段 2
|
| | | Def_MirrorBatState_Over, # 战斗结束 3
|
| | | ) = range(4)
|
| | |
|
| | | #---SetDict 含NPC字典KEY,不存于数据库---
|
| | | Def_GameObjKey_InheritOwner = "InheritOwner" # 类暴风雪计算时用主人属性
|
| | |
|
| | |
| | | Def_PlayerKey_TransTick = 'TransTick' # 传送tick
|
| | | Def_PlayerKey_SyncVIPKillNPCLVInfo = 'SyncVIPKillNPCLVInfo' # 击杀NPC增加VIP杀怪等级经验信息同步开关
|
| | | Def_PlayerKey_RequestEnterCrossServerTick = 'RequestEnterCrossServerTick' # 上次请求进入跨服tick
|
| | | Def_PlayerKey_MirrorBattleTime = 'MirrorBattleTime' # 最近一次请求镜像战斗时间戳
|
| | | Def_PlayerKey_MirrorBattleID = 'MirrorBattleID' # 镜像战斗ID,有值时代表处于镜像战斗中
|
| | |
|
| | | Def_PlayerKey_FamilyArrestQueryState = 'ArrestQueryState' # 家族悬赏任务完成查询状态
|
| | | Def_PlayerKey_Frist_Lock = "Frist_Lock" # 是否接受了任务1
|
| | |
| | | Def_PDict_ShareGameAwardState = "ShareGameAwardState" # 每日分享游戏领奖记录
|
| | | Def_PDict_GoodGameAwardState = "GoodGameAwardState" # 游戏好评领奖记录
|
| | | Def_PDict_EquipViewCacheState = "EquipViewCacheState" # 本次上线是否同步过装备缓存
|
| | | Def_PDict_PackDataSyncState = "PackDataSyncState" # 本次上线打包数据同步状态,按位存储是否同步 0-本服,1-跨服
|
| | | Def_PDict_PackDataSyncFightPower = "PackDataSyncFightPower" # 本次上线打包数据同步时的战力,用于对比,只对比求余亿部分即可
|
| | | Def_PDict_DayOnlineTime = "OnlineTime" # 当日在线时长
|
| | | Def_PDict_OnlineStartTick = "OnlineStartTime" # 在线计算时间
|
| | | Def_PDict_LVAwardGetRecord = "LVAwardGetRecord" # 等级奖励领取信息记录,按二进制位标示
|
| | |
| | | ItemData19 = "" #(String ItemData19)
|
| | | ItemDataSize20 = 0 #(WORD ItemDataSize20)
|
| | | ItemData20 = "" #(String ItemData20)
|
| | | PackDataSyncState = 0 #(BYTE PackDataSyncState)// 打包数据同步状态: 0-不同步;个位-是否同步本服;十位-是否同步跨服
|
| | | PackDataLen = 0 #(DWORD PackDataLen)
|
| | | PackData = "" #(String PackData)
|
| | | PackMsgLen = 0 #(WORD PackMsgLen)
|
| | | PackMsg = "" #(String PackMsg)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | |
| | | self.ItemData19,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemDataSize19)
|
| | | self.ItemDataSize20,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.ItemData20,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemDataSize20)
|
| | | self.PackDataSyncState,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.PackDataLen,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PackData,_pos = CommFunc.ReadString(_lpData, _pos,self.PackDataLen)
|
| | | self.PackMsgLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.PackMsg,_pos = CommFunc.ReadString(_lpData, _pos,self.PackMsgLen)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | |
| | | self.ItemData19 = ""
|
| | | self.ItemDataSize20 = 0
|
| | | self.ItemData20 = ""
|
| | | self.PackDataSyncState = 0
|
| | | self.PackDataLen = 0
|
| | | self.PackData = ""
|
| | | self.PackMsgLen = 0
|
| | | self.PackMsg = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | |
| | | length += len(self.ItemData19)
|
| | | length += 2
|
| | | length += len(self.ItemData20)
|
| | | length += 1
|
| | | length += 4
|
| | | length += len(self.PackData)
|
| | | length += 2
|
| | | length += len(self.PackMsg)
|
| | |
|
| | | return length
|
| | |
|
| | |
| | | data = CommFunc.WriteString(data, self.ItemDataSize19, self.ItemData19)
|
| | | data = CommFunc.WriteWORD(data, self.ItemDataSize20)
|
| | | data = CommFunc.WriteString(data, self.ItemDataSize20, self.ItemData20)
|
| | | data = CommFunc.WriteBYTE(data, self.PackDataSyncState)
|
| | | data = CommFunc.WriteDWORD(data, self.PackDataLen)
|
| | | data = CommFunc.WriteString(data, self.PackDataLen, self.PackData)
|
| | | data = CommFunc.WriteWORD(data, self.PackMsgLen)
|
| | | data = CommFunc.WriteString(data, self.PackMsgLen, self.PackMsg)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | |
| | | ItemDataSize19:%d,
|
| | | ItemData19:%s,
|
| | | ItemDataSize20:%d,
|
| | | ItemData20:%s
|
| | | ItemData20:%s,
|
| | | PackDataSyncState:%d,
|
| | | PackDataLen:%d,
|
| | | PackData:%s,
|
| | | PackMsgLen:%d,
|
| | | PackMsg:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | |
| | | self.ItemDataSize19,
|
| | | self.ItemData19,
|
| | | self.ItemDataSize20,
|
| | | self.ItemData20
|
| | | self.ItemData20,
|
| | | self.PackDataSyncState,
|
| | | self.PackDataLen,
|
| | | self.PackData,
|
| | | self.PackMsgLen,
|
| | | self.PackMsg
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A1 09 同步打包玩家数据 #tagCMSycnPlayerPackData
|
| | |
|
| | | class tagCMSycnPlayerPackData(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xA1
|
| | | self.SubCmd = 0x09
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xA1
|
| | | self.SubCmd = 0x09
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMSycnPlayerPackData)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// A1 09 同步打包玩家数据 //tagCMSycnPlayerPackData:
|
| | | Cmd:%s,
|
| | | SubCmd:%s
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMSycnPlayerPackData=tagCMSycnPlayerPackData()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSycnPlayerPackData.Cmd,m_NAtagCMSycnPlayerPackData.SubCmd))] = m_NAtagCMSycnPlayerPackData
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #A1 03 设置是否成年 #tagCMAdult
|
| | |
|
| | | class tagCMAdult(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B4 11 镜像战斗 #tagCMMirrorFight
|
| | |
|
| | | class tagCMMirrorFight(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("MapID", c_int), # 自定义地图ID,如竞技场等
|
| | | ("FuncLineID", c_ushort), |
| | | ("TagPlayeID", c_int), # 目标玩家ID,支持跨服玩家ID
|
| | | ("CmdType", c_ubyte), # 命令类型: 0-创建战斗;1-开始战斗;2-战斗中跳过;3-不创建战斗直接得结果
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xB4
|
| | | self.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xB4
|
| | | self.SubCmd = 0x11
|
| | | self.MapID = 0
|
| | | self.FuncLineID = 0
|
| | | self.TagPlayeID = 0
|
| | | self.CmdType = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMMirrorFight)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// B4 11 镜像战斗 //tagCMMirrorFight:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | MapID:%d,
|
| | | FuncLineID:%d,
|
| | | TagPlayeID:%d,
|
| | | CmdType:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.MapID,
|
| | | self.FuncLineID,
|
| | | self.TagPlayeID,
|
| | | self.CmdType
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMMirrorFight=tagCMMirrorFight()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMMirrorFight.Cmd,m_NAtagCMMirrorFight.SubCmd))] = m_NAtagCMMirrorFight
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B4 0F 回收私有专属木桩怪 #tagCMRecyclePriWoodPile
|
| | |
|
| | | class tagCMRecyclePriWoodPile(Structure):
|
| | |
| | | '''
|
| | | # 由于float会有不精确的现象出现xxx.9999999或xxx.0000000000001的问题,所以这里计算出的结果向上取整
|
| | | return int(math.ceil(round(floatRMB * 100)))
|
| | |
|
| | | #64进制符号,前端用*号补空
|
| | | symbols64 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'
|
| | | def Convert10To64(number):
|
| | | """将十进制数转换为64进制"""
|
| | | if number < 0:
|
| | | number = abs(number)
|
| | | result = ''
|
| | | while number > 0:
|
| | | result = symbols64[number % 64] + result
|
| | | number //= 64
|
| | | return result or '0'
|
| | |
|
| | | def Convert64To10(number64):
|
| | | """将64进制数转换为十进制"""
|
| | | value = 0
|
| | | for digit in number64:
|
| | | value = value * 64 + symbols64.index(digit)
|
| | | return value
|
| | |
|
| | | def ParseSetting(playerSetting, index, cLen=1):
|
| | | """解析玩家设置存储"""
|
| | | s = playerSetting[index:index+cLen]
|
| | | s = s.replace("*", "") # 前端*代表空
|
| | | if not s:
|
| | | return 0
|
| | | return Convert64To10(s)
|
| | |
|
| | | def ParseSetting_AutoSkillList(playerSetting, defaultSkillList):
|
| | | '''解析玩家设置 - 自动释放技能顺序列表
|
| | | @param playerSetting: 玩家设置保存串
|
| | | @param skillOrderList: 技能默认顺序列表
|
| | | '''
|
| | | playerSkillSetList = []
|
| | | SkillMatchPage = ParseSetting(playerSetting, 30, 1)
|
| | | fromIndex = 32 + SkillMatchPage * 15
|
| | | indexNum = 0
|
| | | for index in range(fromIndex, fromIndex + 15):
|
| | | skillIndex = indexNum
|
| | | v = ParseSetting(playerSetting, index, 1)
|
| | | if v:
|
| | | skillIndex = v - 1
|
| | | |
| | | if skillIndex >= len(defaultSkillList):
|
| | | break
|
| | | skillID = defaultSkillList[skillIndex]
|
| | | playerSkillSetList.append(skillID)
|
| | | indexNum += 1
|
| | | return playerSkillSetList
|
| | |
| | | for i in range(0, playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | EventResponse_OnAction(curPlayer, eventName, fileID)
|
| | |
| | |
|
| | |
|
| | | import GameWorld
|
| | | import PlayerControl
|
| | |
|
| | | ## GM命令执行入口
|
| | | # @param curPlayer 当前玩家
|
| | |
| | | if playerID != 0:
|
| | | mirrorPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if mirrorPlayer:
|
| | | mirrorPlayer.DeleteMirror()
|
| | | PlayerControl.DeleteMirror(mirrorPlayer)
|
| | | return
|
| | |
|
| | | ids = []
|
| | |
| | | mirrorPlayer = playerManager.FindPlayerByID(id)
|
| | | if not mirrorPlayer:
|
| | | continue
|
| | | mirrorPlayer.DeleteMirror() |
| | | PlayerControl.DeleteMirror(mirrorPlayer)
|
| | | |
| | | return
|
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | |
|
| | | ##@package PlayerMirror
|
| | | # 创建玩家镜像, 考虑地图人满问题,py可以做个预判,可调整地图配置的人数上限
|
| | |
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.PlayerMirror
|
| | | #
|
| | | # @todo:创建玩家镜像进行战斗
|
| | | # @author hxp
|
| | | # @date 2024-10-17
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 创建玩家镜像, 考虑地图人满问题,py可以做个预判,可调整地图配置的人数上限
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2024-10-17 15:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PlayerEventCounter
|
| | | import ChPlayer
|
| | | import GameServerRefresh
|
| | | import MirrorAttack
|
| | | import PlayerViewCacheTube
|
| | | import PlayerFB
|
| | | import ChConfig
|
| | |
|
| | | ## GM命令执行入口
|
| | | # @param curPlayer 当前玩家
|
| | | # @param playerList 参数列表 [玩家ID]
|
| | | # @param paramList 参数列表 [玩家ID]
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(curPlayer, playerList):
|
| | | playerID = 0
|
| | | if len(playerList) != 0:
|
| | | playerID = playerList[0]
|
| | | |
| | | if playerID != 0:
|
| | | #向GameServer请求其他玩家数据
|
| | | #开始查询
|
| | | curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_MirrorPlayer, playerID, 'PlayerMirror', '', 0)
|
| | | def OnExec(curPlayer, paramList):
|
| | | if not paramList:
|
| | | GameWorld.DebugAnswer(curPlayer, "-------------------%s" % GameWorld.GetCurrentDataTimeStr())
|
| | | GameWorld.DebugAnswer(curPlayer, "创建战斗: PlayerMirror c 是否后台 [目标ID ID2 ...]")
|
| | | GameWorld.DebugAnswer(curPlayer, "开始战斗: PlayerMirror s")
|
| | | GameWorld.DebugAnswer(curPlayer, "跳过战斗: PlayerMirror q")
|
| | | GameWorld.DebugAnswer(curPlayer, "退出战斗: PlayerMirror e")
|
| | | GameWorld.DebugAnswer(curPlayer, "更新镜像: PlayerMirror 5")
|
| | | GameWorld.DebugAnswer(curPlayer, "是否后台:0-玩家自身参与战斗")
|
| | | GameWorld.DebugAnswer(curPlayer, "是否后台:1-玩家无感知,系统直接出结果")
|
| | | GameWorld.DebugAnswer(curPlayer, "目标ID:无-自己;>0-其他玩家ID支持跨服玩家ID")
|
| | | GameWorld.DebugAnswer(curPlayer, "目标ID多个时为多对多战斗")
|
| | | GameWorld.DebugAnswer(curPlayer, "多对多阵营分配均分AABBB即玩家和AA对BBB")
|
| | | return
|
| | |
|
| | | playerData = curPlayer.GetPackData()
|
| | | # playerData为base64后的数据
|
| | | mirrorPlayer = GameWorld.GetGameWorld().CreateMirrorPlayer(playerData, curPlayer.GetPosX(), curPlayer.GetPosY())
|
| | |
|
| | | #是否镜像玩家 判断 mirrorPlayer.GetRealPlayerID()是否为0
|
| | | if mirrorPlayer:
|
| | | GameWorld.Log("mirrorPlayer.GetRealPlayerID %s"%mirrorPlayer.GetRealPlayerID())
|
| | | index = mirrorPlayer.GetIndex()
|
| | | mapID = ChConfig.Def_FBMapID_MirrorBattle
|
| | | lineID = 0
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | value1 = paramList[0]
|
| | | if value1 == "c":
|
| | | isSysbg = paramList[1] if len(paramList) > 1 else 0
|
| | | if not isSysbg:
|
| | | if not PlayerFB.DoEnterCustomScene(curPlayer, mapID, lineID, tick):
|
| | | GameWorld.DebugAnswer(curPlayer, "进入自定义PK创景失败:%s" % mapID)
|
| | | return
|
| | | |
| | | mirrorIDList = paramList[2:]
|
| | | if not mirrorIDList:
|
| | | mirrorIDList.append(playerID)
|
| | | |
| | | factionIDListA, factionIDListB = [playerID], []
|
| | | while mirrorIDList:
|
| | | # 后面为对手
|
| | | factionIDListB.append(mirrorIDList.pop(-1))
|
| | | # 前面为队友
|
| | | if mirrorIDList:
|
| | | factionIDListA.append(mirrorIDList.pop(0))
|
| | | |
| | | posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
|
| | | battlePlayerList = []
|
| | | for i, batPlayerID in enumerate(factionIDListA):
|
| | | battlePlayerList.append({"playerID":batPlayerID, "faction":1, "posX":posX, "posY":posY + i * 5})
|
| | | for i, batPlayerID in enumerate(factionIDListB):
|
| | | battlePlayerList.append({"playerID":batPlayerID, "faction":2, "posX":posX + 5, "posY":posY + i * 5})
|
| | | |
| | | GameWorld.DebugAnswer(curPlayer, "创建镜像: %s VS %s" % (factionIDListA, factionIDListB))
|
| | | requestID = playerID
|
| | | MirrorAttack.OnRequestCreateMirrorBattle(mapID, lineID, requestID, battlePlayerList, isSysbg, curPlayer)
|
| | | |
| | | elif value1 == "s":
|
| | | battle = MirrorAttack.GetMirrorBattle(curPlayer)
|
| | | if battle:
|
| | | MirrorAttack.OnMirrorBattleStart(battle.battleID)
|
| | | |
| | | elif value1 == "q":
|
| | | battle = MirrorAttack.GetMirrorBattle(curPlayer)
|
| | | if battle:
|
| | | MirrorAttack.DoMirrorBattleQuick(battle.battleID)
|
| | | |
| | | elif value1 == "e":
|
| | | PlayerFB.DoExitCustomScene(curPlayer)
|
| | | |
| | | elif value1 == 5:
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | ChPlayer.PlayerLogin(index, tick)
|
| | | PlayerEventCounter.GameServer_InitOK(index, tick)
|
| | | ChPlayer.LoadMapOK(index, tick)
|
| | | GameServerRefresh.GameSever_PlayerInitOK(index, tick) |
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
|
| | | GameWorld.DebugAnswer(curPlayer, "已更新最新镜像缓存!")
|
| | | |
| | | return
|
| | |
| | | import IPY_GameWorld
|
| | | import LogUI
|
| | | import ReadChConfig
|
| | | import IpyGameDataPY
|
| | | import random
|
| | | import math
|
| | | import sys
|
| | |
| | | if curPlayer.GetGMLevel() in [0 , ChConfig.Def_GM_LV_God]:
|
| | | return
|
| | |
|
| | | return True
|
| | |
|
| | | def IsMirrorPlayer(curPlayer):
|
| | | ## 是否镜像玩家
|
| | | if curPlayer.GetRealPlayerID() > 0:
|
| | | return True
|
| | | return False
|
| | |
|
| | | def IsNormalPlayer(curPlayer):
|
| | | '''是否正常可用的常规玩家,一般用于判断是否是一个正常的玩家
|
| | | 可用于封包通知判断、活动玩家判断等一切仅处理真实常规玩家的验证
|
| | | '''
|
| | | if not curPlayer or curPlayer.GetID() == 0 or curPlayer.IsEmpty():
|
| | | return False
|
| | | #if not curPlayer.GetInitOK():
|
| | | # return False
|
| | | #if IsTJGPlayer(curPlayer):
|
| | | # return False
|
| | | if IsMirrorPlayer(curPlayer):
|
| | | return False
|
| | | return True
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | ## 服务器组ID,必须唯一,代表这台物理服务器
|
| | | return ToIntDef(ReadChConfig.GetPyMongoConfig("platform", "GroupID"), 0)
|
| | |
|
| | | def GetMainServerID(serverID):
|
| | | ## 获取服务器ID所属主服ID
|
| | | ServerIDMainServerDict = IpyGameDataPY.GetConfigEx("ServerIDMainServerDict")
|
| | | if ServerIDMainServerDict == None:
|
| | | filePath = ChConfig.GetDBPath() + ("\\MixServerMap_%s.json" % GetPlatform())
|
| | | if not os.path.isfile(filePath):
|
| | | SendGameErrorEx("GetMainServerIDError", "file can not found. %s" % filePath)
|
| | | else:
|
| | | fileObj = open(filePath, 'rb')
|
| | | content = fileObj.read()
|
| | | fileObj.close()
|
| | | MixServerMapDict = eval(content)
|
| | | |
| | | ServerIDMainServerDict = {}
|
| | | for mainServerIDStr, serverIDList in MixServerMapDict.items():
|
| | | mainServerID = int(mainServerIDStr)
|
| | | for sID in serverIDList:
|
| | | ServerIDMainServerDict[sID] = mainServerID
|
| | | IpyGameDataPY.SetConfigEx("ServerIDMainServerDict", ServerIDMainServerDict)
|
| | | Log("加载 ServerIDMainServerDict=%s" % ServerIDMainServerDict)
|
| | | |
| | | if not ServerIDMainServerDict:
|
| | | return serverID
|
| | | return ServerIDMainServerDict.get(serverID, serverID)
|
| | |
|
| | | def GetPlatformServerNum(platform):
|
| | | # 获取服务器的平台编号
|
| | | platformNumDict = ReadChConfig.GetDBEvalChConfig("DBPlatformNum")
|
| | |
| | | def GetPlayerServerID(curPlayer):
|
| | | accID = curPlayer.GetAccID()
|
| | | infoList = accID.split(Def_AccID_Split_Sign)
|
| | | return 0 if len(infoList) < 3 else int(infoList[-1][1:])
|
| | | return 0 if len(infoList) < 3 else ToIntDef(infoList[-1][1:])
|
| | |
|
| | | def GetPlayerServerSID(curPlayer):
|
| | | # 返回含s的serverID
|
| | |
| | | SendGameError("MapServerRaiseException", errorMsg)
|
| | | return
|
| | |
|
| | | def SendGameErrorEx(errType, msgInfo="", playerID=0):
|
| | | ErrLog("SendGameErrorEx: %s -> %s" % (errType, msgInfo), playerID)
|
| | | if GetGameWorld().GetDebugLevel():
|
| | | raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | else:
|
| | | SendGameError(errType, msgInfo)
|
| | | return
|
| | |
|
| | | def SendGameError(errType, msgInfo=""):
|
| | | ''' 向运维发送邮件,用于需要紧急处理的信息
|
| | | @param errType: 错误类型,自定义即可
|
| | |
| | | # @remarks 函数详细说明.
|
| | | def DoFBOnKill_Player(curPlayer, defender, tick):
|
| | | do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
|
| | | mapID = PlayerControl.GetCustomMapID(curPlayer)
|
| | | if not mapID:
|
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | do_FBLogic_ID = __GetFBLogic_MapID(mapID)
|
| | |
|
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "DoFBOnKill_Player"))
|
| | |
|
| | |
| | |
|
| | | return callFunc(curPlayer, mapID, funcLineID, hurtObj, hurtValue, factionHurtValue)
|
| | |
|
| | | def OnMirrorBattleOver(battleID, mapID):
|
| | | ## 镜像战斗结束
|
| | | |
| | | do_FBLogic_ID = __GetFBLogic_MapID(mapID)
|
| | | |
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnMirrorBattleOver"))
|
| | | |
| | | if callFunc == None:
|
| | | return
|
| | | |
| | | return callFunc(battleID)
|
| | | |
| | |
| | | return dataMapID
|
| | | return mapID
|
| | |
|
| | | def GetGeneralTrainMapIDList():
|
| | | ## 获取通用养成副本
|
| | | GeneralTrainMapIDList = IpyGameDataPY.GetConfigEx("GeneralTrainMapIDList")
|
| | | if not GeneralTrainMapIDList:
|
| | | GeneralTrainMapIDList = []
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for i in xrange(ipyDataMgr.GetFBGeneralTrainCount()):
|
| | | ipyData = ipyDataMgr.GetFBGeneralTrainByIndex(i)
|
| | | dMapID = ipyData.GetDataMapID()
|
| | | if dMapID not in GeneralTrainMapIDList:
|
| | | GeneralTrainMapIDList.append(dMapID)
|
| | | GeneralTrainMapIDList = IpyGameDataPY.SetConfigEx("GeneralTrainMapIDList", GeneralTrainMapIDList)
|
| | | #GameWorld.Log("加载GeneralTrainMapIDList=%s" % GeneralTrainMapIDList)
|
| | | |
| | | return GeneralTrainMapIDList
|
| | |
|
| | | def GetClientCustomScene():
|
| | | ## 获取前端自定义副本场景
|
| | | mapIDList = GetGeneralTrainMapIDList()
|
| | | return mapIDList + ChConfig.ClientCustomSceneList
|
| | |
|
| | | ## 同步进入副本时间
|
| | | # @param curPlayer 玩家
|
| | | # @param syncMapID 同步的地图,默认0为全部
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GameWorldLogic.FBProcess.GameLogic_MirrorBattle
|
| | | #
|
| | | # @todo:镜像PK切磋
|
| | | # @author hxp
|
| | | # @date 2024-10-17
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 镜像PK切磋
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2024-10-17 15:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import MirrorAttack
|
| | | import FBCommon
|
| | | import GameObj
|
| | |
|
| | | ## 是否能够通过活动查询进入
|
| | | def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
|
| | | return True
|
| | |
|
| | | ## 客户端进入自定义场景
|
| | | def OnEnterCustomScene(curPlayer, mapID, lineID):
|
| | | return
|
| | |
|
| | | ##处理副本中杀死玩家逻辑
|
| | | def DoFBOnKill_Player(atkobj, defender, tick):
|
| | | GameWorld.DebugLog("镜像切磋击杀玩家: defID=%s" % (defender.GetID()), atkobj.GetID())
|
| | | return True
|
| | |
|
| | | def OnMirrorBattleOver(battleID):
|
| | | ## 镜像战斗结束
|
| | | |
| | | battle = MirrorAttack.GetMirrorBattleByID(battleID)
|
| | | if not battle:
|
| | | return
|
| | | isLogout = battle.isLogout
|
| | | |
| | | mapID = battle.mapID
|
| | | funcLineID = battle.funcLineID
|
| | | winFaction = battle.winFaction
|
| | | curPlayerID = battle.requestID # 副本所属玩家ID,该玩家不一定参与实际战斗
|
| | | curIsWin = 0
|
| | | GameWorld.DebugLog("镜像战斗结算: mapID=%s,funcLineID=%s,winFaction=%s,isLogout=%s" % (mapID, funcLineID, winFaction, isLogout), battleID)
|
| | | |
| | | playerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for playerID, faction in battle.playerFactionDict.items():
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | continue
|
| | | realPlayerID = curPlayer.GetRealPlayerID()
|
| | | isWin = (faction == winFaction)
|
| | | GameWorld.DebugLog("剩余血量: %s/%s,playerID=%s,realPlayerID=%s,faction=%s,isWin=%s" |
| | | % (GameObj.GetHP(curPlayer), GameObj.GetMaxHP(curPlayer), playerID, realPlayerID, faction, isWin), battleID)
|
| | | if isWin and faction == 1:
|
| | | curIsWin = 1
|
| | | |
| | | if not curPlayerID:
|
| | | return
|
| | | |
| | | curPlayer = playerMgr.FindPlayerByID(curPlayerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | # 结算奖励,通知结果
|
| | | giveItemList = []
|
| | | overDict = {"isWin":curIsWin, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(giveItemList)}
|
| | | FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isWin, overDict) |
| | | return
|
| | |
| | | ("list", "StarAttrValue", 0),
|
| | | ),
|
| | |
|
| | | "SkillMatch":(
|
| | | ("BYTE", "IDIndex", 1),
|
| | | ("list", "Skills", 0),
|
| | | ),
|
| | |
|
| | | "CreateRole":(
|
| | | ("BYTE", "RoleType", 1),
|
| | | ("list", "BaseAttrIDList", 0),
|
| | |
| | | def GetStarUpNeedItemList(self): return self.attrTuple[2] # 升该星所需物品 [[物品ID,个数], ...] list
|
| | | def GetStarAttrType(self): return self.attrTuple[3] # 累计总属性类型 list
|
| | | def GetStarAttrValue(self): return self.attrTuple[4] # 累计总属性值 list |
| | | |
| | | # 技能搭配表 |
| | | class IPY_SkillMatch(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetIDIndex(self): return self.attrTuple[0] # BYTE
|
| | | def GetSkills(self): return self.attrTuple[1] # 主动技能(职业1id|职业2id) list |
| | | |
| | | # 创角表 |
| | | class IPY_CreateRole(): |
| | |
| | | self.__LoadFileData("PlayerFaceStar", onlyCheck)
|
| | | self.__LoadFileData("PlayerFacePic", onlyCheck)
|
| | | self.__LoadFileData("PlayerFacePicStar", onlyCheck)
|
| | | self.__LoadFileData("SkillMatch", onlyCheck)
|
| | | self.__LoadFileData("CreateRole", onlyCheck)
|
| | | self.__LoadFileData("RolePoint", onlyCheck)
|
| | | self.__LoadFileData("LingQiAttr", onlyCheck)
|
| | |
| | | self.CheckLoadData("PlayerFacePicStar") |
| | | return self.ipyPlayerFacePicStarCache[index]
|
| | | |
| | | def GetSkillMatchCount(self): |
| | | self.CheckLoadData("SkillMatch") |
| | | return self.ipySkillMatchLen
|
| | | def GetSkillMatchByIndex(self, index): |
| | | self.CheckLoadData("SkillMatch") |
| | | return self.ipySkillMatchCache[index]
|
| | | |
| | | def GetCreateRoleCount(self): |
| | | self.CheckLoadData("CreateRole") |
| | | return self.ipyCreateRoleLen
|
| | |
| | | # @return 返回值无意义
|
| | | # @remarks 刷新装备对人物属性的改变
|
| | | def RefreshPlayerEquipAttribute(curPlayer, classLV=0):
|
| | | GameWorld.DebugLog("Start RefreshPlayerEquipAttribute classLV=%s!!!" % classLV)
|
| | | GameWorld.DebugLog("Start RefreshPlayerEquipAttribute classLV=%s!!!" % classLV, curPlayer.GetPlayerID())
|
| | | classlvList = xrange(1, IpyGameDataPY.GetFuncCfg('EquipMaxClasslv') + 1) if classLV == 0 else [classLV]
|
| | | for rclasslv in classlvList:
|
| | | __CalcEquips_Effect(curPlayer, rclasslv)
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCrossActAllRecharge(curPlayer)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCrossActCTGBillboard(curPlayer)
|
| | | return
|
| | |
| | | for i in range(0, playerManager.GetActivePlayerCount()):
|
| | | curPlayer = playerManager.GetActivePlayerByIndex(i)
|
| | |
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerControl.Sync_ExpRateChange(curPlayer)
|
| | |
| | | OSCBillboardDataLimitDict = IpyGameDataPY.GetFuncEvalCfg("OSCBillboardOpen", 1)
|
| | | campTypeS = str(campaignType)
|
| | | if campTypeS not in OSCBillboardDataLimitDict:
|
| | | GameWorld.DebugLog("不存在该开服活动类型: %s" % campaignType)
|
| | | #GameWorld.DebugLog("不存在该开服活动类型: %s" % campaignType)
|
| | | return False
|
| | | limitValue = OSCBillboardDataLimitDict[campTypeS][OSC_BillLimitValue]
|
| | | endOpenServerDay = OSCBillboardDataLimitDict[campTypeS][OSC_EndDay]
|
| | |
|
| | | openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
|
| | | if openServerDay > endOpenServerDay:
|
| | | GameWorld.DebugLog("该开服活动已结束,无法上榜!campaignType=%s,openServerDay=%s > endOpenServerDay=%s" % (campaignType, openServerDay, endOpenServerDay))
|
| | | #GameWorld.DebugLog("该开服活动已结束,无法上榜!campaignType=%s,openServerDay=%s > endOpenServerDay=%s" % (campaignType, openServerDay, endOpenServerDay))
|
| | | return False
|
| | |
|
| | | if curValue != None and curValue < limitValue:
|
| | | GameWorld.DebugLog("该开服活动数值不足,无法上榜!campaignType=%s,curValue=%s < limitValue=%s" % (campaignType, curValue, limitValue))
|
| | | #GameWorld.DebugLog("该开服活动数值不足,无法上榜!campaignType=%s,curValue=%s < limitValue=%s" % (campaignType, curValue, limitValue))
|
| | | return False
|
| | | return True
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if curPlayer.GetID() == 0: |
| | | if not GameWorld.IsNormalPlayer(curPlayer): |
| | | continue |
| | | __CheckPlayerBossTrialAction(curPlayer, actNum) |
| | | return |
| | |
| | | playerManager = GameWorld.GetPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if curPlayer.GetID() == 0: |
| | | if not GameWorld.IsNormalPlayer(curPlayer): |
| | | continue |
| | | __CheckPlayerCrossActBossTrial(curPlayer) |
| | | |
| | |
| | | playerManager = GameWorld.GetPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if curPlayer.GetID() == 0: |
| | | if not GameWorld.IsNormalPlayer(curPlayer): |
| | | continue |
| | | __CheckPlayerBuyCountGiftAction(curPlayer, actNum) |
| | | |
| | |
| | | playerManager = GameWorld.GetPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if curPlayer.GetID() == 0: |
| | | if not GameWorld.IsNormalPlayer(curPlayer): |
| | | continue |
| | | __CheckPlayerBuyOneAction(curPlayer, actNum) |
| | | return |
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCollectWordsAction(curPlayer, actNum)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if curPlayer.GetID() == 0: |
| | | if not GameWorld.IsNormalPlayer(curPlayer): |
| | | continue |
| | | __CheckPlayerFamilyCTGAssistAction(curPlayer, actNum) |
| | | return |
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerGarbageSortingAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerGodGiftAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerGrowupBuyAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerGubaoAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCrossActGubao(curPlayer)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | SyncHorsePetFeastInfo(curPlayer, actNum)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerHorsePetTrainAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCrossActHorsePetTrain(curPlayer)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerLoginAwardAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerActLoginAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerManyDayRechargeAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerRechargePrizeAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerRechargeRebateGoldAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerSingleRechargeAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerActTaskAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerTotalRechargeAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerTurntableAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerXianXiaMJAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCrossActXianXiaMJ(curPlayer)
|
| | |
|
| | |
| | | hadInit = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HadInitFruitAttr)
|
| | | if hadInit:
|
| | | return
|
| | | GameWorld.DebugLog("__InitPlayerAttrFruit")
|
| | | #GameWorld.DebugLog("__InitPlayerAttrFruit")
|
| | |
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | maxCnt = ipyDataMgr.GetAttrFruitCount()
|
| | |
| | |
|
| | | def UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=False):
|
| | | ##下线更新玩家排行榜
|
| | | if GameWorld.IsCrossServer():
|
| | | # 跨服服务器不用更新本服榜
|
| | | return
|
| | | #UpdateTotalRechargeBillboard(curPlayer)
|
| | |
|
| | | UpdatePlayerLVBillboard(curPlayer) # 等级榜
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerBossRebornAction(curPlayer)
|
| | | return
|
| | |
| | | import PlayerTrade
|
| | | import PlayerTeam
|
| | | import SkillCommon
|
| | | import MirrorAttack
|
| | | import GameMap
|
| | | import FBLogic
|
| | | import GameWorldProcess
|
| | |
| | |
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | def OnDelayDeleteMirror(curPlayer, tick):
|
| | | addTick = curPlayer.GetDictByKey("DelayDeleteMirror")
|
| | | if not addTick:
|
| | | return
|
| | | if tick - addTick < 10000: # 10s后回收
|
| | | return
|
| | | DeleteMirror(curPlayer, False)
|
| | | return True
|
| | |
|
| | | def DeleteMirror(curPlayer, isDelay=False):
|
| | | ''' 回收镜像玩家
|
| | | '''
|
| | | if not curPlayer.GetRealPlayerID():
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if isDelay:
|
| | | #由于系统场次快速战斗原因,如果立马回收可能导致某个功能出现问题
|
| | | #如被动技能效果,执行顺序的原因,如击杀后 -> 结算 -> 回收玩家 -> 触发被动技能,导致异常
|
| | | GameWorld.DebugLog("镜像玩家设置延迟回收!", playerID)
|
| | | SetPlayerSightLevel(curPlayer, playerID)
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | curPlayer.SetDict("DelayDeleteMirror", tick)
|
| | | return
|
| | | GameWorld.DebugLog("镜像玩家回收!", playerID)
|
| | | #杀死所有召唤的灵
|
| | | KillPlayerSummonNPC(curPlayer)
|
| | | #召唤回出战的宠物
|
| | | PetControl.ReCallFightPet(curPlayer)
|
| | | curPlayer.DeleteMirror()
|
| | | return
|
| | |
|
| | | ##杀死玩家所有的召唤兽死亡
|
| | | # @param curPlayer 玩家实例
|
| | | # @return 返回值无意义
|
| | |
| | | UpdateOnLineTime(curPlayer, tick)
|
| | |
|
| | | PassiveBuffEffMng.OnPlayerLeaveMap(curPlayer)
|
| | | |
| | | MirrorAttack.OnPlayerLeaveMap(curPlayer)
|
| | |
|
| | | #离开地图清空恶意攻击自己玩家信息
|
| | | if curPlayer.GetPlayerID() in PyGameData.g_maliciousAttackDict:
|
| | |
| | | # @return 返回值无意义
|
| | | # @remarks 刷新玩家所有状态
|
| | | def RefreshAllState(self, isSyncBuff=False, billboardFunc=None, isForce=False):
|
| | | GameWorld.DebugLog("Start RefreshAllState!!!")
|
| | | curPlayer = self.__Player
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("Start RefreshAllState!!!", playerID)
|
| | |
|
| | | self.RefreshPlayerActionState()
|
| | | self.RefreshPlayerAttrState(billboardFunc, isForce)
|
| | |
| | | # @return 返回值无意义
|
| | | # @remarks 刷新玩家所有状态
|
| | | def ReCalcAllState(self):
|
| | | GameWorld.DebugLog("Start ReCalcAllState!!!")
|
| | | curPlayer = self.__Player
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("Start ReCalcAllState!!!", playerID)
|
| | |
|
| | | for funcIndex in ChConfig.CalcAttrFuncList:
|
| | | ClearCalcAttrListValue(curPlayer, funcIndex)
|
| | |
| | | PlayerFace.CalcFaceAttr(curPlayer)
|
| | | PlayerFace.CalcFacePicAttr(curPlayer)
|
| | | self.RefreshAllState(isForce=True)
|
| | | GameWorld.DebugLog("End ReCalcAllState!!!")
|
| | | GameWorld.DebugLog("End ReCalcAllState!!!", playerID)
|
| | | return
|
| | |
|
| | |
|
| | |
| | | if curPlayer.GetDictByKey(ChConfig.Def_Player_RefreshAttrByBuff) != 1:
|
| | | return
|
| | |
|
| | | GameWorld.DebugLog("Start RefreshPlayerAttrByBuffEx!!!")
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("Start RefreshPlayerAttrByBuffEx!!!", playerID)
|
| | | beforeMaxHP = GameObj.GetMaxHP(curPlayer)
|
| | | beforeMoveSpeedValue = GetSpeedValue(curPlayer)
|
| | | #构建玩家刷新通知客户端字典, 缓存[索引, 数值]
|
| | | playerStateDict = {}
|
| | | for index in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):
|
| | | playerStateDict.update({index:EffGetSet.GetValueByEffIndex(curPlayer, index)})
|
| | | #GameWorld.DebugLog("刷属性前=%s" % playerStateDict)
|
| | | #GameWorld.DebugLog("刷属性前=%s" % playerStateDict, playerID)
|
| | | #self.PrintAttr(curPlayer, "ˢ֮ǰ")
|
| | | #---------------------------开始计算-------------------------------------
|
| | | curPlayer.BeginRefreshState()
|
| | |
| | | self.__DoRefreshAttrAfterLogic(beforeMaxHP, beforeMoveSpeedValue, playerStateDict)
|
| | |
|
| | | curPlayer.SetDict(ChConfig.Def_Player_RefreshAttrByBuff, 0)
|
| | | GameWorld.DebugLog("End RefreshPlayerAttrByBuffEx!!!")
|
| | | GameWorld.DebugLog("End RefreshPlayerAttrByBuffEx!!!", playerID)
|
| | | return
|
| | |
|
| | |
|
| | |
| | |
|
| | | PlayerGubao.CalcGubaoAttr(curPlayer) # 古宝定位为对贯通所有游戏功能系统的属性玩法,所以每次都重新刷新
|
| | |
|
| | | GameWorld.DebugLog("Start RefreshPlayerAttrStateEx!!!")
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("Start RefreshPlayerAttrStateEx!!!", playerID)
|
| | |
|
| | | #beforeAtkInterval = curPlayer.GetAtkInterval()
|
| | | beforeMaxHP = GameObj.GetMaxHP(curPlayer)
|
| | |
| | | playerStateDict = {}
|
| | | for index in xrange(1, ChConfig.Def_Calc_AllAttrType_MAX):
|
| | | playerStateDict.update({index:EffGetSet.GetValueByEffIndex(curPlayer, index)})
|
| | | #GameWorld.DebugLog("刷属性前=%s" % playerStateDict)
|
| | | #GameWorld.DebugLog("刷属性前=%s" % playerStateDict, playerID)
|
| | | #self.PrintAttr(curPlayer, "ˢ֮ǰ")
|
| | | #---------------------------开始计算-------------------------------------
|
| | | curPlayer.BeginRefreshState()
|
| | |
| | | attrInfo, insidePerAttrDict = GetCalcAttrListValue(curPlayer, funcIndex)[:2]
|
| | | if attrInfo == notAttrList and not insidePerAttrDict:
|
| | | continue
|
| | | GameWorld.DebugLog("功能点属性: %s(%s), %s, 内层百分比附加: %s" % (funcIndex, ChConfig.FuncIndexName.get(funcIndex, ""), attrInfo, insidePerAttrDict))
|
| | | GameWorld.DebugLog("功能点属性: %s(%s), %s, 内层百分比附加: %s" % (funcIndex, ChConfig.FuncIndexName.get(funcIndex, ""), attrInfo, insidePerAttrDict), playerID)
|
| | | funcAttrInfoList[funcIndex] = attrInfo
|
| | | funcInsidePerAttrList[funcIndex] = insidePerAttrDict
|
| | | # 不同功能点间的数值累加,需使用支持衰减递增的计算方式
|
| | |
| | | # 2.2 将基础属性累加到玩家身上
|
| | | if baseAttrDict or baseAttrNolineDict:
|
| | | # 因为基础属性会影响战斗属性计算,所以先统计增加基础属性
|
| | | GameWorld.DebugLog("功能附加点: baseAttrDict=%s,baseAttrNolineDict=%s" % (baseAttrDict, baseAttrNolineDict))
|
| | | GameWorld.DebugLog("功能附加点: baseAttrDict=%s,baseAttrNolineDict=%s" % (baseAttrDict, baseAttrNolineDict), playerID)
|
| | | CalcLineEffect.ChangePlayerAttrInLineEffectList(curPlayer, baseAttrDict)
|
| | | CalcNoLineEffect.ChangePlayerAttrInNoLineEffectList(curPlayer, baseAttrNolineDict)
|
| | |
|
| | |
| | | funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LingGenQuailty] = lingGenQualityAttrList
|
| | | funcInsidePerAttrList[ChConfig.Def_CalcAttrFunc_LingGenQuailty] = lingGenQualityInsidePerAttrDict
|
| | | GameWorld.DebugLog("功能点属性: %s(%s), %s, 内层百分比附加: %s"
|
| | | % (ChConfig.Def_CalcAttrFunc_RoleBase, ChConfig.FuncIndexName.get(ChConfig.Def_CalcAttrFunc_RoleBase, ""), roleBaseAttrInfo, roleInsidePerAttrDict))
|
| | | % (ChConfig.Def_CalcAttrFunc_RoleBase, ChConfig.FuncIndexName.get(ChConfig.Def_CalcAttrFunc_RoleBase, ""), roleBaseAttrInfo, roleInsidePerAttrDict), playerID)
|
| | | GameWorld.DebugLog("功能点属性: %s(%s), %s, 内层百分比附加: %s"
|
| | | % (ChConfig.Def_CalcAttrFunc_LingGenQuailty, ChConfig.FuncIndexName.get(ChConfig.Def_CalcAttrFunc_LingGenQuailty, ""), lingGenQualityAttrList, lingGenQualityInsidePerAttrDict))
|
| | | % (ChConfig.Def_CalcAttrFunc_LingGenQuailty, ChConfig.FuncIndexName.get(ChConfig.Def_CalcAttrFunc_LingGenQuailty, ""), lingGenQualityAttrList, lingGenQualityInsidePerAttrDict), playerID)
|
| | |
|
| | | #self.PrintAttr(curPlayer, "基础后")
|
| | | #self.PrintAttr(curPlayer, "基础后", playerID)
|
| | |
|
| | | # 3.计算战斗属性
|
| | | # 3.1 战斗属性层级交叉影响基值数值汇总
|
| | |
| | | funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LingGen],
|
| | | funcAttrInfoList[ChConfig.Def_CalcAttrFunc_LingGenQuailty],
|
| | | ])
|
| | | #GameWorld.DebugLog("基础层级: %s" % baseAttrList)
|
| | | #GameWorld.DebugLog("基础层级: %s" % baseAttrList, playerID)
|
| | |
|
| | | # 功能点交叉影响非线性层对应属性基值列表
|
| | | funcAttrPerInfo = {ChConfig.TYPE_Calc_BaseAtkAddPer:[baseAttrList],
|
| | |
| | | if not battleNoLineAttrDict:
|
| | | continue
|
| | | addAttrDict = {}
|
| | | #GameWorld.DebugLog("交叉功能点: i=%s,%s" % (i,battleNoLineAttrDict))
|
| | | #GameWorld.DebugLog("交叉功能点: i=%s,%s" % (i,battleNoLineAttrDict), playerID)
|
| | | for noLineAttrType, addAttrPer in battleNoLineAttrDict.items():
|
| | | if noLineAttrType not in funcAttrPerInfo or noLineAttrType not in ChConfig.FuncNoLinearAttrDict:
|
| | | continue
|
| | |
| | | # 如符文有个武器攻击百分比增加属性,增加的数值属于符文功能,不属于武器功能点的,只是基值使用了武器攻击
|
| | | funcCrossAttrPerInfoDict[i] = addAttrDict # 先都统计完后再累加到对应功能属性里,不然可能会导致功能基值变更
|
| | |
|
| | | GameWorld.DebugLog("交叉影响属性: %s" % funcCrossAttrPerInfoDict)
|
| | | GameWorld.DebugLog("交叉影响属性: %s" % funcCrossAttrPerInfoDict, playerID)
|
| | |
|
| | | # 3.3 统计所有功能固定属性影响累加
|
| | | allFixAttrDict = {} # 固定属性层级总属性基值
|
| | |
| | | addValueExDict[fixAttrType] = addValueEx
|
| | | fixAttrPerAddExDict[funcIndex] = addValueExDict
|
| | |
|
| | | GameWorld.DebugLog("固定属性总和: %s" % allFixAttrDict)
|
| | | GameWorld.DebugLog("固定百分比附加属性: %s" % fixAttrPerAddExDict)
|
| | | GameWorld.DebugLog("固定属性总和: %s" % allFixAttrDict, playerID)
|
| | | GameWorld.DebugLog("固定百分比附加属性: %s" % fixAttrPerAddExDict, playerID)
|
| | |
|
| | | # 4. 计算属性及战力, 需在计算buff层之前计算
|
| | | curLV = curPlayer.GetLV()
|
| | |
| | | elif mfpType == ShareDefine.Def_MFPType_Wash:
|
| | | OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_Wash, mfpTotal)
|
| | |
|
| | | #GameWorld.DebugLog("整体层级线性属性: %s" % allAttrList)
|
| | | #GameWorld.DebugLog("整体层级线性属性: %s" % allAttrList, playerID)
|
| | |
|
| | | # 5.被动技能附加属性,不算战力
|
| | | passiveSkillAttrList = [{} for _ in range(4)]
|
| | | SkillShell.CalcPassiveAttr_Effect(curPlayer, passiveSkillAttrList) # 属性类技能与buff同层
|
| | | for funcIndex in ChConfig.CalcAttrFuncSkillList:
|
| | | passiveSkillAttrList = AddAttrListValue([passiveSkillAttrList, funcAttrInfoList[funcIndex]])
|
| | | GameWorld.DebugLog("无战力被动属性: %s" % passiveSkillAttrList)
|
| | | GameWorld.DebugLog("无战力被动属性: %s" % passiveSkillAttrList, playerID)
|
| | |
|
| | | skillFixAttrExDict = {}
|
| | | skillFixAddPerDict = passiveSkillAttrList[ChConfig.CalcAttr_BattleNoline]
|
| | |
| | | while billFuncCnt > 0 and PyGameData.g_refreshAttrBillboardFunc:
|
| | | billFuncCnt -= 1
|
| | | billboardFunc = PyGameData.g_refreshAttrBillboardFunc.pop(0)
|
| | | GameWorld.DebugLog("回调排行榜: %s" % billboardFunc)
|
| | | GameWorld.DebugLog("回调排行榜: %s" % billboardFunc, playerID)
|
| | | billboardFunc(curPlayer, isForceUpdate=True)
|
| | |
|
| | | # 暂停刷新属性标志,必须被调用
|
| | | curPlayer.SetDict(ChConfig.Def_Player_RefreshAttr, 0)
|
| | | curPlayer.SetDict(ChConfig.Def_Player_RefreshAttrByBuff, 0)
|
| | | curPlayer.SetDict(ChConfig.Def_Player_HadRefreshAttr, 1)
|
| | | GameWorld.DebugLog("End RefreshPlayerAttrStateEx!!!")
|
| | | GameWorld.DebugLog("End RefreshPlayerAttrStateEx!!!", playerID)
|
| | | return True
|
| | |
|
| | |
|
| | |
| | | def __RefreshBuffAttr(self):
|
| | | ## 刷新buff层属性,该层属性只会改变玩家最终属性,不会影响战力等
|
| | | curPlayer = self.__Player
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | allAttrListBuffs = [{} for _ in range(4)]
|
| | | # 6.计算buff属性, buff层级的不算如战斗力
|
| | | # 算战斗力总值时该层影响的数值不统计,但刷属性时需计算
|
| | |
| | |
|
| | | # 刷新攻击速度
|
| | | self.__SetAtkInterval()
|
| | | GameWorld.DebugLog("Buff层属性: %s" % allAttrListBuffs)
|
| | | GameWorld.DebugLog("Buff层属性: %s" % allAttrListBuffs, playerID)
|
| | | return
|
| | |
|
| | | def __DoRefreshGMAttr(self):
|
| | |
| | | def SendModuleFightPowerPack(self, curPlayer, mfpDict):
|
| | | mfpDataList = []
|
| | | totalFightPower = 0
|
| | | GameWorld.DebugLog("战力功能点: %s" % ChConfig.MFPTypeAttrFuncIndexDict)
|
| | | GameWorld.DebugLog("模块战力: %s" % mfpDict)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("战力功能点: %s" % ChConfig.MFPTypeAttrFuncIndexDict, playerID)
|
| | | GameWorld.DebugLog("模块战力: %s" % mfpDict, playerID)
|
| | | for mfpType, fightPower in mfpDict.items():
|
| | | SetMFPFightPower(curPlayer, mfpType, fightPower)
|
| | | mfpData = ChPyNetSendPack.tagMCModuleFightPower()
|
| | |
| | | ChConfig.Def_PDictType_FightPower)
|
| | | NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FightPower_HighestEx, highestFightPower / ChConfig.Def_PerPointValue,
|
| | | ChConfig.Def_PDictType_FightPower)
|
| | | GameWorld.DebugLog("总战力: %s, 历史最高战力: %s, beforeFightPower=%s" % (totalFightPower, highestFightPower, beforeFightPower))
|
| | | GameWorld.DebugLog("总战力: %s, 历史最高战力: %s, beforeFightPower=%s" % (totalFightPower, highestFightPower, beforeFightPower), playerID)
|
| | | PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)
|
| | | # 记录开服活动数据,开服活动前X天理论上不会超过20E,暂不处理
|
| | | OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_FightPower, min(totalFightPower, ChConfig.Def_UpperLimit_DWord))
|
| | |
| | | def __RefreshMoveSpeed(self, allAttrListBuffs):
|
| | | ## 刷新移动速度
|
| | | curPlayer = self.__Player
|
| | | playerID = curPlayer.GetPlayerID()
|
| | |
|
| | | moveSpeedFormat = IpyGameDataPY.GetFuncCfg("MoveSpeed")
|
| | |
|
| | | if PlayerTruck.GetHaveAutoTruck(curPlayer):
|
| | | speed = IpyGameDataPY.GetFuncCfg("MoveSpeed", 3)
|
| | | GameWorld.DebugLog("运镖固定速度值: speed=%s" % speed)
|
| | | GameWorld.DebugLog("运镖固定速度值: speed=%s" % speed, playerID)
|
| | | else:
|
| | | speed = GetSpeedNotBuff(curPlayer)
|
| | | GameWorld.DebugLog("功能移动速度值: speed=%s" % speed)
|
| | | GameWorld.DebugLog("功能移动速度值: speed=%s" % speed, playerID)
|
| | |
|
| | | # 骑乘状态加上骑乘附加速度
|
| | | if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse:
|
| | | speedHorse = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SpeedHorse)
|
| | | speed += speedHorse
|
| | | GameWorld.DebugLog(" 骑乘状态附加值: %s, speed=%s" % (speedHorse, speed))
|
| | | GameWorld.DebugLog(" 骑乘状态附加值: %s, speed=%s" % (speedHorse, speed), playerID)
|
| | |
|
| | |
|
| | | buffBattleAttr = allAttrListBuffs[ChConfig.CalcAttr_Battle]
|
| | |
| | |
|
| | | if buffSpeed or buffSpeedPer:
|
| | | speed = int(speed * (ShareDefine.Def_MaxRateValue + buffSpeedPer) / float(ShareDefine.Def_MaxRateValue) + buffSpeed)
|
| | | GameWorld.DebugLog(" buff影响后速度值: speed=%s,buffSpeedPer=%s,buffSpeed=%s" % (speed, buffSpeedPer, buffSpeed))
|
| | | GameWorld.DebugLog(" buff影响后速度值: speed=%s,buffSpeedPer=%s,buffSpeed=%s" % (speed, buffSpeedPer, buffSpeed), playerID)
|
| | |
|
| | | speed = max(speed, 0) #防小于0错误
|
| | | if GetSpeedValue(curPlayer) != speed:
|
| | | SetSpeedValue(curPlayer, speed)
|
| | | moveSpeed = eval(FormulaControl.GetCompileFormula("MoveSpeed", moveSpeedFormat))
|
| | | curPlayer.SetSpeed(moveSpeed)
|
| | | GameWorld.DebugLog("公式计算后移动频率: moveSpeed=%s 毫秒/格" % moveSpeed)
|
| | | GameWorld.DebugLog("公式计算后移动频率: moveSpeed=%s 毫秒/格" % moveSpeed, playerID)
|
| | |
|
| | | fightPet = curPlayer.GetPetMgr().GetFightPet()
|
| | | #无出战宠物
|
| | |
| | | # @return 返回值无意义
|
| | | # @remarks 刷新玩家所有行为BUFF状态
|
| | | def RefreshPlayerActionState(self):
|
| | | GameWorld.DebugLog("Start RefreshPlayerActionState!!!")
|
| | | #curTime = time.clock()
|
| | | curPlayer = self.__Player
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("Start RefreshPlayerActionState!!!", playerID)
|
| | | #curTime = time.clock()
|
| | |
|
| | | #先清除所有状态
|
| | | OperControlManager.ClearObjActionState(curPlayer)
|
| | |
| | |
|
| | | #PlayerTJG.PlayerTJGReborn(curPlayer, tick)
|
| | | GameObj.ClearPyPlayerState(curPlayer)
|
| | | |
| | | MirrorAttack.OnPlayerDead(curPlayer)
|
| | | return
|
| | |
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerCostRebateAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.OnlineCount()):
|
| | | curPlayer = playerManager.OnlineAt(i)
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | #检查重置玩家信息
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerDailyGiftbagAction(curPlayer)
|
| | | return
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnDay(curPlayer)
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnDayEx(curPlayer)
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnHour(curPlayer)
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnWeek(curPlayer)
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnWeekEx(curPlayer)
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnMonth(curPlayer)
|
| | |
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnMonthEx(curPlayer)
|
| | |
| | | for i in range(0, playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | |
|
| | | PlayerOnYear(curPlayer)
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | ChPlayer.Sync_PyServerDataTimeToClient(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | PlayerWorldAverageLv.UpdatePlayerWorldAverageLv(curPlayer)
|
| | |
|
| | |
| | | import ShareDefine
|
| | | import GameFuncComm
|
| | | import FBHelpBattle
|
| | | import MirrorAttack
|
| | | import SkillShell
|
| | | import PyGameData
|
| | | import PetControl
|
| | |
| | | % (curMapID, curLineID), playerID)
|
| | | result = 0
|
| | | StartCustomSceneResult(curPlayer, mapID, lineID, result)
|
| | | return
|
| | | return result
|
| | |
|
| | | #进入副本通用检查
|
| | | if mapID:
|
| | |
| | | fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID)
|
| | | if PlayerControl.CheckMoveToFB(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData, tick) != ShareDefine.EntFBAskRet_OK:
|
| | | StartCustomSceneResult(curPlayer, mapID, lineID, 0)
|
| | | return
|
| | | return 0
|
| | |
|
| | | PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
|
| | |
|
| | |
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick, tick)
|
| | | PlayerControl.SetCustomMap(curPlayer, mapID, lineID)
|
| | | NPCCommon.ClearPriWoodPile(curPlayer)
|
| | | MirrorAttack.ClearMirrorBattleByPlayer(curPlayer)
|
| | | GameWorld.Log("玩家开始自定义场景!mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | if mapID:
|
| | | #PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | |
| | |
|
| | | #通知进入状态
|
| | | StartCustomSceneResult(curPlayer, mapID, lineID, 1)
|
| | | return
|
| | | return 1
|
| | |
|
| | | def StartCustomSceneResult(curPlayer, mapID, lineID, result):
|
| | | if result != 1:
|
| | |
| | | if mapID and FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) != ChConfig.CustomMapStep_Over:
|
| | | FBCommon.SetCustomMapStep(curPlayer, mapID, lineID, ChConfig.CustomMapStep_Over)
|
| | | NPCCommon.ClearPriWoodPile(curPlayer)
|
| | | MirrorAttack.ClearMirrorBattleByPlayer(curPlayer)
|
| | |
|
| | | #默认回满血
|
| | | if GameObj.GetHP(curPlayer) > 0 and curPlayer.GetPlayerAction() != IPY_GameWorld.paDie and GameObj.GetHP(curPlayer) < GameObj.GetMaxHP(curPlayer):
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFairyCeremonyAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if curPlayer.GetID() == 0: |
| | | if not GameWorld.IsNormalPlayer(curPlayer): |
| | | continue |
| | | |
| | | if familyID and curPlayer.GetFamilyID() != familyID: |
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFeastLoginAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.OnlineCount()):
|
| | | curPlayer = playerManager.OnlineAt(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFeastRedPacketAction(curPlayer)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFeastTravelAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFeastWeekPartyAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFeastWishAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerFlashGiftbagAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerflashSaleAction(curPlayer, actNum)
|
| | | return
|
| | |
| | |
|
| | | # 附加战力
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_GodWeapon, fightPowerEx)
|
| | | GameWorld.DebugLog("神兵属性:%s" % allAttrList)
|
| | | #GameWorld.DebugLog("神兵属性:%s" % allAttrList)
|
| | | # 保存计算值
|
| | | PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_GodWeapon, allAttrList)
|
| | | return
|
| | |
| | | ## 挂机定时处理收益
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | if curPlayer.GetRealPlayerID() != 0:
|
| | | return
|
| | | |
| | | if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Guaji):
|
| | | return
|
| | |
|
| | |
| | | curAwardSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiAwardSeconds)
|
| | | maxSeconds = GetGuajiSecondsMax(curPlayer)
|
| | | if curAwardSeconds >= maxSeconds:
|
| | | GameWorld.DebugLog("挂机收益时长已达上限: curAwardSeconds=%s >= %s" % (curAwardSeconds, maxSeconds), playerID)
|
| | | #GameWorld.DebugLog("挂机收益时长已达上限: curAwardSeconds=%s >= %s" % (curAwardSeconds, maxSeconds), playerID)
|
| | | return
|
| | |
|
| | | awardSeconds = min(maxSeconds - curAwardSeconds, awardSeconds)
|
| | |
| | |
|
| | | updAwardSeconds = curAwardSeconds + awardSeconds
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiAwardSeconds, updAwardSeconds)
|
| | | GameWorld.DebugLog("保存挂机累计收益: curAwardSeconds=%s,updAwardSeconds=%s,maxSeconds=%s" % (curAwardSeconds, updAwardSeconds, maxSeconds), playerID)
|
| | | #GameWorld.DebugLog("保存挂机累计收益: curAwardSeconds=%s,updAwardSeconds=%s,maxSeconds=%s" % (curAwardSeconds, updAwardSeconds, maxSeconds), playerID)
|
| | |
|
| | | # 经验
|
| | | exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiExpPoint) * ChConfig.Def_PerPointValue \
|
| | |
| | | updExp = exp % ChConfig.Def_PerPointValue
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiExpPoint, updExpPoint)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiExp, updExp)
|
| | | GameWorld.DebugLog(" 累计经验: %s亿%s" % (updExpPoint, updExp), playerID)
|
| | | #GameWorld.DebugLog(" 累计经验: %s亿%s" % (updExpPoint, updExp), playerID)
|
| | |
|
| | | # 货币
|
| | | for moneyType, addValue in giveMoneyDict.items():
|
| | |
| | | updMoney = min(moneyValue + addValue, ChConfig.Def_UpperLimit_DWord)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyType % saveNum, moneyType)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyValue % saveNum, updMoney)
|
| | | GameWorld.DebugLog(" 累计货币: moneyType=%s,updMoney=%s,saveNum=%s" % (moneyType, updMoney, saveNum), playerID)
|
| | | #GameWorld.DebugLog(" 累计货币: moneyType=%s,updMoney=%s,saveNum=%s" % (moneyType, updMoney, saveNum), playerID)
|
| | |
|
| | | # 物品
|
| | | for itemID, addCount in giveItemDict.items():
|
| | |
| | | updCount = min(curCount + addCount, ChConfig.Def_UpperLimit_DWord)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemID % saveNum, itemID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemCount % saveNum, updCount)
|
| | | GameWorld.DebugLog(" 累计物品: itemID=%s,updCount=%s,saveNum=%s" % (itemID, updCount, saveNum), playerID)
|
| | | #GameWorld.DebugLog(" 累计物品: itemID=%s,updCount=%s,saveNum=%s" % (itemID, updCount, saveNum), playerID)
|
| | |
|
| | | Sync_GuajiAward(curPlayer)
|
| | | return True
|
| | |
| | | lvIpyData = PlayerControl.GetPlayerLVIpyData(reLV)
|
| | | reExp = lvIpyData.GetReExp() if lvIpyData else 0
|
| | | worldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
|
| | | GameWorld.DebugLog("计算挂机收益: awardSeconds=%s,useUnsecond=%s,reLV=%s,reExp=%s,worldLV=%s" |
| | | % (awardSeconds, useUnsecond, reLV, reExp, worldLV), playerID)
|
| | | #GameWorld.DebugLog("计算挂机收益: awardSeconds=%s,useUnsecond=%s,reLV=%s,reExp=%s,worldLV=%s" |
| | | # % (awardSeconds, useUnsecond, reLV, reExp, worldLV), playerID)
|
| | |
|
| | | # 经验
|
| | | expRate = GetGuajiExpRate(curPlayer)
|
| | | secondBaseExp = int(eval(FormulaControl.GetCompileFormula("GuajiExp", IpyGameDataPY.GetFuncCfg("GuajiAward", 1))))
|
| | | secondExp = int(secondBaseExp * expRate / float(ChConfig.Def_MaxRateValue))
|
| | | addExp = awardSeconds * secondExp
|
| | | GameWorld.DebugLog(" 每秒经验: %s, addExp=%s,secondBaseExp=%s,expRate=%s" % (secondExp, addExp, secondBaseExp, expRate), playerID)
|
| | | #GameWorld.DebugLog(" 每秒经验: %s, addExp=%s,secondBaseExp=%s,expRate=%s" % (secondExp, addExp, secondBaseExp, expRate), playerID)
|
| | |
|
| | | # 每秒产出货币
|
| | | moneyDict = {}
|
| | |
| | | secondMoney = int(eval(FormulaControl.GetCompileFormula("GuajiMoney_%s" % moneyType, formula)))
|
| | | moneyValue = awardSeconds * secondMoney
|
| | | moneyDict[moneyType] = moneyValue
|
| | | GameWorld.DebugLog(" 每秒货币: moneyType=%s,secondMoney=%s,moneyValue=%s" % (moneyType, secondMoney, moneyValue), playerID)
|
| | | #GameWorld.DebugLog(" 每秒货币: moneyType=%s,secondMoney=%s,moneyValue=%s" % (moneyType, secondMoney, moneyValue), playerID)
|
| | |
|
| | | # 每x秒产出1货币
|
| | | perMoneyTimeFromulaDict = IpyGameDataPY.GetFuncEvalCfg("GuajiAward", 3, {}) # 每x秒获得1个货币公式 {货币类型:"x秒公式", ...}
|
| | |
| | | oneMoneyNeedSeconds = int(eval(FormulaControl.GetCompileFormula("GuajiMoney_%s" % moneyType, formula)))
|
| | | moneyValue = moneyAwardSeconds / oneMoneyNeedSeconds
|
| | | moneyDict[moneyType] = moneyValue
|
| | | GameWorld.DebugLog(" 每X秒货币: moneyType=%s,oneMoneyNeedSeconds=%s,moneyValue=%s,moneyAwardSeconds=%s" |
| | | % (moneyType, oneMoneyNeedSeconds, moneyValue, moneyAwardSeconds), playerID)
|
| | | #GameWorld.DebugLog(" 每X秒货币: moneyType=%s,oneMoneyNeedSeconds=%s,moneyValue=%s,moneyAwardSeconds=%s" |
| | | # % (moneyType, oneMoneyNeedSeconds, moneyValue, moneyAwardSeconds), playerID)
|
| | |
|
| | | if useUnsecond:
|
| | | unSeconds = moneyAwardSeconds % oneMoneyNeedSeconds
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyUnSeconds % moneyType, unSeconds)
|
| | | GameWorld.DebugLog(" moneyType=%s,unSeconds=%s" % (moneyType, unSeconds), playerID)
|
| | | #GameWorld.DebugLog(" moneyType=%s,unSeconds=%s" % (moneyType, unSeconds), playerID)
|
| | |
|
| | | # 物品
|
| | | giveItemSecondsSet = IpyGameDataPY.GetFuncCfg("GuajiAward", 4) # 每x秒获得一次随机物品机会
|
| | |
| | | itemAwardSeconds += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiItemUnSeconds)
|
| | |
|
| | | itemAwardTimes = itemAwardSeconds / giveItemSecondsSet # 给物品次数
|
| | | GameWorld.DebugLog(" 给物品次数: %s, itemAwardSeconds=%s,giveItemSecondsSet=%s" % (itemAwardTimes, itemAwardSeconds, giveItemSecondsSet), playerID)
|
| | | #GameWorld.DebugLog(" 给物品次数: %s, itemAwardSeconds=%s,giveItemSecondsSet=%s" % (itemAwardTimes, itemAwardSeconds, giveItemSecondsSet), playerID)
|
| | |
|
| | | if useUnsecond:
|
| | | unSeconds = itemAwardSeconds % giveItemSecondsSet
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemUnSeconds, unSeconds)
|
| | | GameWorld.DebugLog(" 给物品未处理秒数=%s" % unSeconds, playerID)
|
| | | #GameWorld.DebugLog(" 给物品未处理秒数=%s" % unSeconds, playerID)
|
| | |
|
| | | lvList = lvItemRateDict.keys()
|
| | | lvList.sort()
|
| | |
| | | dropCountTotal = 0
|
| | | itemDict = {}
|
| | | maxRate = itemRateList[-1][0]
|
| | | GameWorld.DebugLog(" itemRateList=%s,maxRate=%s" % (itemRateList, maxRate), playerID)
|
| | | #GameWorld.DebugLog(" itemRateList=%s,maxRate=%s" % (itemRateList, maxRate), playerID)
|
| | | if itemAwardTimes > 100: # 超过x次的,先进行批量处理
|
| | | preRate = 0
|
| | | for rateInfo in itemRateList:
|
| | |
| | | if GameWorld.CanHappen(rateEx, maxRate):
|
| | | dropCount += 1
|
| | | dropCountTotal += dropCount # 产出是是空物品也要算执行掉落次数
|
| | | GameWorld.DebugLog(" 挂机物品: itemInfo=%s,curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,dropCountTotal=%s" |
| | | % (itemInfo, curRate, totalRate, rateEx, dropCount, dropCountTotal), playerID)
|
| | | #GameWorld.DebugLog(" 挂机物品: itemInfo=%s,curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,dropCountTotal=%s" |
| | | # % (itemInfo, curRate, totalRate, rateEx, dropCount, dropCountTotal), playerID)
|
| | | if not dropCount:
|
| | | continue
|
| | |
|
| | |
| | | itemDict[itemID] = itemDict.get(itemID, 0) + itemCount * dropCount
|
| | |
|
| | | awardTimesEx = itemAwardTimes - dropCountTotal
|
| | | GameWorld.DebugLog(" awardTimesEx=%s" % awardTimesEx, playerID)
|
| | | #GameWorld.DebugLog(" awardTimesEx=%s" % awardTimesEx, playerID)
|
| | | if awardTimesEx > 0:
|
| | | for _ in range(awardTimesEx):
|
| | | itemInfo = GameWorld.GetResultByRandomList(itemRateList)
|
| | |
| | | for itemID, dropCount in giveGarbageItemList.items():
|
| | | itemDict[itemID] = itemDict.get(itemID, 0) + dropCount
|
| | |
|
| | | GameWorld.DebugLog(" itemDict=%s" % (itemDict), playerID)
|
| | | #GameWorld.DebugLog(" itemDict=%s" % (itemDict), playerID)
|
| | | return addExp, moneyDict, itemDict
|
| | |
|
| | | def GetGuajiExpRate(curPlayer):
|
| | |
| | | if isNotify:
|
| | | curPlayer.Sync_RideHorse()
|
| | |
|
| | | playerControl = PlayerControl.PlayerControl(curPlayer)
|
| | | playerControl.RefreshPlayerAttrByBuff()
|
| | | if refreshState:
|
| | | playerControl = PlayerControl.PlayerControl(curPlayer)
|
| | | playerControl.RefreshPlayerAttrByBuff()
|
| | | return True
|
| | |
|
| | | #=====================================================================
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckLuckyCloudBuyID(curPlayer)
|
| | | Sync_LuckyCloudBuyPlayerInfo(curPlayer) # 该功能收到就同步,不论有没有重置,因为可能由跨服关闭变为开启时的数据同步
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerLuckyTreasureAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerNewFairyCeremonyAction(curPlayer)
|
| | | return
|
| | |
| | |
|
| | | if not attrDict:
|
| | | continue
|
| | | GameWorld.DebugLog(' 刷符印属性 holeNum=%s, attrDict=%s' % (holeNum, attrDict))
|
| | | #GameWorld.DebugLog(' 刷符印属性 holeNum=%s, attrDict=%s' % (holeNum, attrDict))
|
| | | for attrID, attrValue in attrDict.items():
|
| | | PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
|
| | |
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerSpringSaleAction(curPlayer, actNum)
|
| | | return
|
| | |
| | | import PlayerYinji
|
| | | import PlayerActivity
|
| | | import PlayerBackup
|
| | | import MirrorAttack
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | #---------------------------------------------------------------------
|
| | |
| | | #GameWorld.Log("玩家还未初始化成功, 不处理")
|
| | | return
|
| | |
|
| | | #延迟回收镜像玩家
|
| | | if PlayerControl.OnDelayDeleteMirror(curPlayer, tick):
|
| | | return
|
| | | |
| | | #定时备档
|
| | | PlayerBackup.CheckPlayerBackup(curPlayer)
|
| | |
|
| | | #玩家镜像战斗AI
|
| | | MirrorAttack.ProcessPlayerMirrorAI(curPlayer, tick)
|
| | | |
| | | #被GM封状态响应
|
| | | ProcessGMOperLogic(curPlayer, tick)
|
| | |
|
| | |
| | | for attrID, attrValue in attrAwardDict.items():
|
| | | attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
|
| | |
|
| | | GameWorld.DebugLog(" 成就增加属性 attrDict=%s" % (attrDict)) |
| | | #GameWorld.DebugLog(" 成就增加属性 attrDict=%s" % (attrDict)) |
| | | for attrID, attrValue in attrDict.items():
|
| | | PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
|
| | |
|
| | |
| | | ##玩家下线同步
|
| | | UpdateGameServerPlayerCache(curPlayer, tick, True)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_EquipViewCacheState, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncState, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncFightPower, 0)
|
| | | return
|
| | |
|
| | | def ProcessCache(curPlayer, tick):
|
| | |
| | | UpdateGameServerPlayerCache(curPlayer, tick, False)
|
| | | return
|
| | |
|
| | | def GetSyncPlayerPackData(curPlayer, force=False):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | fightPower = curPlayer.GetFightPower()
|
| | | |
| | | if not force:
|
| | | syncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)
|
| | | if not syncState:
|
| | | GameWorld.DebugLog("不需要同步打包数据", playerID)
|
| | | return ""
|
| | | # 值判断求余部分即可
|
| | | syncFightPower = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncFightPower)
|
| | | if syncFightPower == fightPower:
|
| | | GameWorld.DebugLog("战力不变,不需要同步打包数据! syncFightPower=%s" % syncFightPower, playerID)
|
| | | return ""
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncFightPower, fightPower)
|
| | | packData = curPlayer.GetPackData()
|
| | | #GameWorld.DebugLog("packData=%s %s %s" % (type(packData), len(packData), packData), playerID)
|
| | | return packData
|
| | |
|
| | |
|
| | | ##更新玩家当前详细信息到GameServer
|
| | | # @param curPlayer, tick
|
| | | # @return None
|
| | | def UpdateGameServerPlayerCache(curPlayer, tick, IsLogouting=False):
|
| | | def UpdateGameServerPlayerCache(curPlayer, tick, IsLogouting=False, forcePackData=False, packMsg=None):
|
| | | if PlayerTJG.GetIsTJG(curPlayer):
|
| | | # 脱机不处理
|
| | | return
|
| | |
| | | for classLV, itemData in itemDataDict.items():
|
| | | setattr(sendPack, "ItemData%s" % classLV, itemData)
|
| | | setattr(sendPack, "ItemDataSize%s" % classLV, len(itemData))
|
| | | # 打包数据相关
|
| | | sendPack.PackDataSyncState = 11 if forcePackData else curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)
|
| | | sendPack.PackData = GetSyncPlayerPackData(curPlayer, forcePackData)
|
| | | sendPack.PackDataLen = len(sendPack.PackData)
|
| | | sendPack.PackMsg = str(packMsg) if packMsg else "{}"
|
| | | sendPack.PackMsgLen = len(sendPack.PackMsg)
|
| | | #GameWorld.DebugLog("同步缓存: %s" % sendPack.OutputString())
|
| | | NetPackCommon.SendPyPackToGameServer(sendPack)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerWeekPartyAction(curPlayer)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK():
|
| | | if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | continue
|
| | | __CheckPlayerWishingWellAction(curPlayer)
|
| | | return
|
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #---------------------------------------------------------------------
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | ##@package GY_Query_PlayerMirror
|
| | | ##@package Player.RemoteQuery.GY_Query_PlayerMirror
|
| | | #
|
| | | # @todo:玩家镜像打包数据
|
| | | # @author hxp
|
| | | # @date 2024-10-17
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 玩家镜像打包数据
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2024-10-17 15:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import PlayerEventCounter
|
| | | import ChPlayer
|
| | | import GameServerRefresh
|
| | | import MirrorAttack
|
| | | import PlayerViewCacheTube
|
| | | import PlayerControl
|
| | | import ChConfig
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | # @param query_Type 请求类型
|
| | |
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(query_ID)
|
| | | GameWorld.DebugLog("GY_Query_PlayerMirror DoLogic", query_ID)
|
| | | msgInfo, packDataDict = packCMDList
|
| | | msgType = msgInfo["msgType"]
|
| | | # 镜像战斗
|
| | | if msgType == "MirrorBattle":
|
| | | curPlayer = None
|
| | | playerID = msgInfo.get("playerID", 0)
|
| | | if playerID:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | return ''
|
| | | MirrorAttack.OnMirrorBattleInit(msgInfo, packDataDict, curPlayer)
|
| | | |
| | | # 其他功能
|
| | | elif msgType == "":
|
| | | pass
|
| | |
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | return ''
|
| | | playerData = packCMDList['playerData']
|
| | | # playerData为base64后的数据
|
| | | mirrorPlayer = GameWorld.GetGameWorld().CreateMirrorPlayer(playerData, curPlayer.GetPosX(), curPlayer.GetPosY())
|
| | | |
| | |
|
| | | #CreateMirrorPlayer 中会调用到 ChPlayer.PlayerLogin
|
| | | #是否镜像玩家 判断 mirrorPlayer.GetRealPlayerID()是否为0
|
| | | #python自己处理,以下逻辑,可以在DoPlayerLogin函数最后 判断是镜像玩家后统一处理
|
| | |
|
| | | index = mirrorPlayer.GetIndex()
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | PlayerEventCounter.GameServer_InitOK(index, tick)
|
| | | ChPlayer.LoadMapOK(index, tick)
|
| | | GameServerRefresh.GameSever_PlayerInitOK(index, tick)
|
| | | return ''
|
| | |
|
| | |
|
| | | def DoResult(curPlayer , callFunName , funResult , tick):
|
| | | GameWorld.DebugLog("GY_Query_PlayerMirror DoResult %s" % str(funResult), curPlayer.GetPlayerID())
|
| | | funResult = eval(funResult)
|
| | | if not funResult:
|
| | | return
|
| | | msgType = funResult[0]
|
| | | msgData = funResult[1]
|
| | | |
| | | if msgType == "PackDataSyncState":
|
| | | isCross, isNeed = msgData
|
| | | __UpdPackDataSyncState(curPlayer, isCross, isNeed)
|
| | | |
| | | elif msgType == "PullPlayerPackData":
|
| | | msgInfo = msgData
|
| | | __DoPullPlayerPackData(curPlayer, msgInfo, tick)
|
| | | |
| | | return
|
| | |
|
| | | def __UpdPackDataSyncState(curPlayer, isCross, isNeed):
|
| | | ## 更新打包数据同步状态,这里只更新状态即可,具体同步由定时同步处理
|
| | | syncState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PackDataSyncState)
|
| | | if isCross:
|
| | | updSyncState = (1 if isNeed else 0) * 10 + syncState % 10
|
| | | else:
|
| | | updSyncState = syncState / 10 + (1 if isNeed else 0)
|
| | | if syncState == updSyncState:
|
| | | return
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PackDataSyncState, syncState)
|
| | | GameWorld.DebugLog("更新打包数据同步状态: isCross=%s,isNeed=%s,syncState=%s,updSyncState=%s" |
| | | % (isCross, isNeed, syncState, updSyncState), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def __DoPullPlayerPackData(curPlayer, msgInfo, tick):
|
| | | pullFrom = msgInfo.get("pullFrom")
|
| | | isCross = False
|
| | | # 0 或 非本服代表跨服需要
|
| | | if pullFrom == 0 or (pullFrom > 0 and pullFrom != GameWorld.GetServerGroupID()):
|
| | | isCross = True
|
| | | __UpdPackDataSyncState(curPlayer, isCross, 1)
|
| | | PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True, packMsg=msgInfo)
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | |
| | | g_coupleInfo = {} # {playerID:[coupleID, coupleName], ...}
|
| | |
|
| | | g_playerPriWoodPileNPCDict = {} # {playerID:[npcObj, ...], ...}
|
| | | g_mirrorBattleDict = {} # {battleID:MirrorBattle, ...}
|
| | |
|
| | | g_familyZhenfaInfo = {} # 仙盟阵法信息{familyID:{zhenfaType:{k:v, }, ...}, ...}
|
| | |
|
| | |
| | | CrossServerMsg_Notify = "Notify" # 提示信息
|
| | | CrossServerMsg_ChatCrossWorld = "ChatCrossWorld" # 跨服世界聊天
|
| | | CrossServerMsg_ViewPlayerCacheRet = "ViewPlayerCacheRet"# 查看跨服玩家信息结果
|
| | | CrossServerMsg_PlayerPackDataState = "PlayerPackDataState"# 玩家打包数据同步状态
|
| | | CrossServerMsg_PullPlayerPackData = "PullPlayerPackData"# 拉取玩家打包数据
|
| | | CrossServerMsg_PushPlayerPackData = "PushPlayerPackData"# 推送玩家打包数据
|
| | | CrossServerMsg_PKMatchReqRet = "PKMatchReqRet" # 跨服PK匹配请求结果
|
| | | CrossServerMsg_PKMatchResult = "PKMatchResult" # 跨服PK匹配结果
|
| | | CrossServerMsg_PKReadyOKRoomList = "PKReadyOKRoomList" # 跨服PK已准备好的房间列表
|
| | |
| | | ClientServerMsg_ChatCrossWorld = "ChatCrossWorld" # 跨服世界聊天
|
| | | ClientServerMsg_GMCMD = "GMCMD" # GM命令
|
| | | ClientServerMsg_ViewPlayerCache = "ViewPlayerCache" # 查看跨服玩家信息
|
| | | ClientServerMsg_PullOtherPlayerPackData = "PullOtherPlayerPackData" # 拉其他服玩家打包数据
|
| | | ClientServerMsg_PlayerPackData = "PlayerPackData" # 玩家打包数据同步
|
| | | ClientServerMsg_PKMatch = "PKMatch" # 跨服PK匹配
|
| | | ClientServerMsg_PKRobotOver = "PKRobotOver" # 跨服PK机器人结算
|
| | | ClientServerMsg_PKCancel = "PKCancel" # 跨服PK取消匹配
|
| | |
| | | skillAim = GetSkillFireAim(curSkill)
|
| | | affectTag = GetSkillAffectTag(curSkill)
|
| | | skillID = curSkill.GetSkillID()
|
| | | GameWorld.DebugLog("释放被动触发技能 : atkID=%s,skillID=%s(%s)" % (attacker.GetID(), skillID, curSkill.GetSkillName()))
|
| | | GameWorld.DebugLog("释放被动触发技能 : atkID=%s,skillID=%s(%s)" % (attacker.GetID(), skillID, curSkill.GetSkillName()), attacker.GetID())
|
| | |
|
| | | if skillAim == ChConfig.Def_UseSkillAim_None:
|
| | | if curSkill.GetSkillType() in ChConfig.Def_CanAttackSkill_List and affectTag != ChConfig.Def_UseSkillTag_Self:
|
| | |
| | | # 指定目标为自己
|
| | | result = DoLogic_UseSkill(attacker, attacker, curSkill, tick, isEnhanceSkill=isEnhanceSkill)
|
| | |
|
| | | GameWorld.DebugLog("触发结果-----------skillID=%s, %s" % (skillID, result))
|
| | | GameWorld.DebugLog("触发结果-----------skillID=%s, %s" % (skillID, result), attacker.GetID())
|
| | | return result
|
| | |
|
| | |
|