From c5731326acc36a3cfc6870ddb51ce2cc86e2cdc5 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 09 一月 2025 17:00:16 +0800 Subject: [PATCH] 10361 【越南】【英语】【BT】【砍树】仙匠大会 - 服务端 --- ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py | 66 + ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerZhanling.py | 15 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 7 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py | 9 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py | 64 + ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 428 +++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Lianqi.py | 134 +++ ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py | 64 + ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py | 428 +++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py | 3 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py | 2 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py | 4 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLianqi.py | 635 ++++++++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini | 12 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 27 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py | 9 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py | 3 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActLianqi.py | 264 ++++++ PySysDB/PySysDBPY.h | 10 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py | 7 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py | 4 PySysDB/PySysDBG.h | 26 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 11 23 files changed, 2,224 insertions(+), 8 deletions(-) diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h index e3e29c3..91dd292 100644 --- a/PySysDB/PySysDBG.h +++ b/PySysDB/PySysDBG.h @@ -754,6 +754,32 @@ WORD XiangongID; //晋升仙宫ID }; +//炼器活动跨服表 + +struct tagCrossActLianqi +{ + DWORD _CfgID; //配置ID + char ActGroupName; //活动组名(同组活动的名字需相同) + BYTE ZoneID; //组内分组编号 + list ServerIDRangeList; //活动的账号服务器ID范围列表 [[serverIDA, serverIDB], ...] + char StartDate; //开启日期 + char EndDate; //结束日期 + char JoinStartTime; //参与开始时间点 + char JoinEndTime; //参与结束时间点 + WORD LVLimit; //限制等级 + WORD PersonalTemplateID; //个人排行模板编号 +}; + +//炼器榜单模版表 + +struct tagActLianqiBillTemp +{ + DWORD _TemplateID; //模板编号 + BYTE Rank; //名次 + list AwardItemList; //奖励物品列表[[物品ID,个数,是否拍品], ...] + DWORD NeedScore; //上榜所需积分 +}; + //仙匣秘境活动时间表 struct tagActXianXiaMJ diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h index a9f83f4..057d032 100644 --- a/PySysDB/PySysDBPY.h +++ b/PySysDB/PySysDBPY.h @@ -2034,6 +2034,16 @@ dict ScoreAwardEx; //达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} }; +//炼器榜单模版表 + +struct tagActLianqiBillTemp +{ + DWORD _TemplateID; //模板编号 + BYTE Rank; //名次 + list AwardItemList; //奖励物品列表[[物品ID,个数,是否拍品], ...] + DWORD NeedScore; //上榜所需积分 +}; + //仙匣秘境活动时间表 struct tagActXianXiaMJ diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py index 6dc84f0..323ab1f 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py @@ -16711,6 +16711,70 @@ #------------------------------------------------------ +# AA 25 炼器操作 #tagCMActLianqiOP + +class tagCMActLianqiOP(Structure): + _pack_ = 1 + _fields_ = [ + ("Cmd", c_ubyte), + ("SubCmd", c_ubyte), + ("OPType", c_ubyte), # 1-移动;2-使用道具;3-重新开始;4-领取等级奖励 + ("OPValue", c_int), # 移动时-发1上2下3左4右;使用道具时-发使用个数*10+道具ID所在配置索引;等级奖励时-发领取的奖励等级 + ("OPValue2", c_int), # 使用道具时-发选中格子A的行列值 行*10+列 + ("OPValue3", c_int), # 使用道具时-发选中格子B的行列值 行*10+列 + ] + + def __init__(self): + self.Clear() + self.Cmd = 0xAA + self.SubCmd = 0x25 + 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 = 0xAA + self.SubCmd = 0x25 + self.OPType = 0 + self.OPValue = 0 + self.OPValue2 = 0 + self.OPValue3 = 0 + return + + def GetLength(self): + return sizeof(tagCMActLianqiOP) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AA 25 炼器操作 //tagCMActLianqiOP: + Cmd:%s, + SubCmd:%s, + OPType:%d, + OPValue:%d, + OPValue2:%d, + OPValue3:%d + '''\ + %( + self.Cmd, + self.SubCmd, + self.OPType, + self.OPValue, + self.OPValue2, + self.OPValue3 + ) + return DumpString + + +m_NAtagCMActLianqiOP=tagCMActLianqiOP() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMActLianqiOP.Cmd,m_NAtagCMActLianqiOP.SubCmd))] = m_NAtagCMActLianqiOP + + +#------------------------------------------------------ # AA 12 选择转盘活动物品 #tagCMActTurntableChooseItem class tagCMActTurntableChooseItem(Structure): diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py index 7484eb3..80940a3 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py @@ -44354,6 +44354,434 @@ #------------------------------------------------------ +# AA 90 炼器跨服活动信息 #tagMCCrossActLianqiInfo + +class tagMCCrossActLianqiItem(Structure): + _pack_ = 1 + _fields_ = [ + ("ItemID", c_int), + ("ItemCount", c_ushort), + ("IsBind", c_ubyte), + ] + + def __init__(self): + self.Clear() + 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.ItemID = 0 + self.ItemCount = 0 + self.IsBind = 0 + return + + def GetLength(self): + return sizeof(tagMCCrossActLianqiItem) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AA 90 炼器跨服活动信息 //tagMCCrossActLianqiInfo: + ItemID:%d, + ItemCount:%d, + IsBind:%d + '''\ + %( + self.ItemID, + self.ItemCount, + self.IsBind + ) + return DumpString + + +class tagMCCrossActLianqiBillard(Structure): + Rank = 0 #(DWORD Rank)// 名次,1-代表第一名;支持夸段,如1,3 代表第1名,第2~3名 + Count = 0 #(BYTE Count)// 奖励物品数 + AwardItemList = list() #(vector<tagMCCrossActLianqiItem> AwardItemList)// 奖励物品列表 + NeedScore = 0 #(DWORD NeedScore)// 上榜所需积分 + data = None + + def __init__(self): + self.Clear() + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + self.Rank,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.Count): + temAwardItemList = tagMCCrossActLianqiItem() + _pos = temAwardItemList.ReadData(_lpData, _pos) + self.AwardItemList.append(temAwardItemList) + self.NeedScore,_pos = CommFunc.ReadDWORD(_lpData, _pos) + return _pos + + def Clear(self): + self.Rank = 0 + self.Count = 0 + self.AwardItemList = list() + self.NeedScore = 0 + return + + def GetLength(self): + length = 0 + length += 4 + length += 1 + for i in range(self.Count): + length += self.AwardItemList[i].GetLength() + length += 4 + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteDWORD(data, self.Rank) + data = CommFunc.WriteBYTE(data, self.Count) + for i in range(self.Count): + data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer()) + data = CommFunc.WriteDWORD(data, self.NeedScore) + return data + + def OutputString(self): + DumpString = ''' + Rank:%d, + Count:%d, + AwardItemList:%s, + NeedScore:%d + '''\ + %( + self.Rank, + self.Count, + "...", + self.NeedScore + ) + return DumpString + + +class tagMCCrossActLianqiInfo(Structure): + Head = tagHead() + ServerInfoLen = 0 #(BYTE ServerInfoLen) + ServerIDRangeInfo = "" #(String ServerIDRangeInfo)//开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服 + GroupValue1 = 0 #(BYTE GroupValue1)// 活动榜单分组值1,用于查询对应榜单 + StartDate = "" #(char StartDate[10])// 开始日期 y-m-d + EndtDate = "" #(char EndtDate[10])// 结束日期 y-m-d + JoinStartTime = "" #(char JoinStartTime[5])// 参与开始时间点 mm:ss + JoinEndTime = "" #(char JoinEndTime[5])// 参与结束时间点 mm:ss + LimitLV = 0 #(WORD LimitLV)// 限制等级 + PersonalBillCount = 0 #(BYTE PersonalBillCount) + PersonalBillboardInfoList = list() #(vector<tagMCCrossActLianqiBillard> PersonalBillboardInfoList)// 个人榜单奖励信息列表,如果没有代表本次活动没有该榜奖励 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x90 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.ServerInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.ServerIDRangeInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ServerInfoLen) + self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10) + self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10) + self.JoinStartTime,_pos = CommFunc.ReadString(_lpData, _pos,5) + self.JoinEndTime,_pos = CommFunc.ReadString(_lpData, _pos,5) + self.LimitLV,_pos = CommFunc.ReadWORD(_lpData, _pos) + self.PersonalBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.PersonalBillCount): + temPersonalBillboardInfoList = tagMCCrossActLianqiBillard() + _pos = temPersonalBillboardInfoList.ReadData(_lpData, _pos) + self.PersonalBillboardInfoList.append(temPersonalBillboardInfoList) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x90 + self.ServerInfoLen = 0 + self.ServerIDRangeInfo = "" + self.GroupValue1 = 0 + self.StartDate = "" + self.EndtDate = "" + self.JoinStartTime = "" + self.JoinEndTime = "" + self.LimitLV = 0 + self.PersonalBillCount = 0 + self.PersonalBillboardInfoList = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 1 + length += len(self.ServerIDRangeInfo) + length += 1 + length += 10 + length += 10 + length += 5 + length += 5 + length += 2 + length += 1 + for i in range(self.PersonalBillCount): + length += self.PersonalBillboardInfoList[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteBYTE(data, self.ServerInfoLen) + data = CommFunc.WriteString(data, self.ServerInfoLen, self.ServerIDRangeInfo) + data = CommFunc.WriteBYTE(data, self.GroupValue1) + data = CommFunc.WriteString(data, 10, self.StartDate) + data = CommFunc.WriteString(data, 10, self.EndtDate) + data = CommFunc.WriteString(data, 5, self.JoinStartTime) + data = CommFunc.WriteString(data, 5, self.JoinEndTime) + data = CommFunc.WriteWORD(data, self.LimitLV) + data = CommFunc.WriteBYTE(data, self.PersonalBillCount) + for i in range(self.PersonalBillCount): + data = CommFunc.WriteString(data, self.PersonalBillboardInfoList[i].GetLength(), self.PersonalBillboardInfoList[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + ServerInfoLen:%d, + ServerIDRangeInfo:%s, + GroupValue1:%d, + StartDate:%s, + EndtDate:%s, + JoinStartTime:%s, + JoinEndTime:%s, + LimitLV:%d, + PersonalBillCount:%d, + PersonalBillboardInfoList:%s + '''\ + %( + self.Head.OutputString(), + self.ServerInfoLen, + self.ServerIDRangeInfo, + self.GroupValue1, + self.StartDate, + self.EndtDate, + self.JoinStartTime, + self.JoinEndTime, + self.LimitLV, + self.PersonalBillCount, + "..." + ) + return DumpString + + +m_NAtagMCCrossActLianqiInfo=tagMCCrossActLianqiInfo() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCrossActLianqiInfo.Head.Cmd,m_NAtagMCCrossActLianqiInfo.Head.SubCmd))] = m_NAtagMCCrossActLianqiInfo + + +#------------------------------------------------------ +# AA 91 炼器活动玩家信息 #tagMCActLianqiPlayerInfo + +class tagMCActLianqiTileMove(Structure): + _pack_ = 1 + _fields_ = [ + ("Row", c_ubyte), # 行,0为第1行 + ("Col", c_ubyte), # 列,0为第1列 + ("ToRow", c_ubyte), # 移动到目标行 + ("ToCol", c_ubyte), # 移动到目标列 + ] + + def __init__(self): + self.Clear() + 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.Row = 0 + self.Col = 0 + self.ToRow = 0 + self.ToCol = 0 + return + + def GetLength(self): + return sizeof(tagMCActLianqiTileMove) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AA 91 炼器活动玩家信息 //tagMCActLianqiPlayerInfo: + Row:%d, + Col:%d, + ToRow:%d, + ToCol:%d + '''\ + %( + self.Row, + self.Col, + self.ToRow, + self.ToCol + ) + return DumpString + + +class tagMCActLianqiPlayerInfo(Structure): + Head = tagHead() + Score = 0 #(DWORD Score)// 当前活动积分 + ScoreHighest = 0 #(DWORD ScoreHighest)// 当前活动最高积分,即上榜积分 + Energy = 0 #(WORD Energy)// 当前体力 + EnergyTime = 0 #(DWORD EnergyTime)// 上次恢复体力时间戳,为0时不用处理倒计时 + LVAwardMax = 0 #(DWORD LVAwardMax)// 已激活的最大合成奖励等级 + LVAwardState = 0 #(DWORD LVAwardState)// 最大合成等级奖励领取记录,按等级二进制位存储是否已领取 + UseItemLen = 0 #(BYTE UseItemLen) + UseItemCntList = list() #(vector<WORD> UseItemCntList)// 本局已使用辅助道具次数 [辅助道具1使用次数, ...] + GridDataLen = 0 #(BYTE GridDataLen)// 格子数据长度 + GridData = "" #(String GridData)// 格子二维行列数据,一定会同步,直接替换,行从上往下排 [[第1行格子1,格子2, ...], ...] + OPType = 0 #(BYTE OPType)// 0-无(如初始化,GM等后端直接设置);1-移动;2-使用道具;3-重新开始;如果是因为操作引起的格子数据变化,则在相关操作表现完毕后再展示最新行列数据,否则直接变更 + MoveCount = 0 #(BYTE MoveCount) + MoveList = list() #(vector<tagMCActLianqiTileMove> MoveList)// 图块移动列表,可能没有数据,有的话先表现移动 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x91 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.Score,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.ScoreHighest,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.Energy,_pos = CommFunc.ReadWORD(_lpData, _pos) + self.EnergyTime,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.LVAwardMax,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.LVAwardState,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.UseItemLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.UseItemLen): + value,_pos=CommFunc.ReadWORD(_lpData,_pos) + self.UseItemCntList.append(value) + self.GridDataLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.GridData,_pos = CommFunc.ReadString(_lpData, _pos,self.GridDataLen) + self.OPType,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.MoveCount,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.MoveCount): + temMoveList = tagMCActLianqiTileMove() + _pos = temMoveList.ReadData(_lpData, _pos) + self.MoveList.append(temMoveList) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x91 + self.Score = 0 + self.ScoreHighest = 0 + self.Energy = 0 + self.EnergyTime = 0 + self.LVAwardMax = 0 + self.LVAwardState = 0 + self.UseItemLen = 0 + self.UseItemCntList = list() + self.GridDataLen = 0 + self.GridData = "" + self.OPType = 0 + self.MoveCount = 0 + self.MoveList = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 4 + length += 4 + length += 2 + length += 4 + length += 4 + length += 4 + length += 1 + length += 2 * self.UseItemLen + length += 1 + length += len(self.GridData) + length += 1 + length += 1 + for i in range(self.MoveCount): + length += self.MoveList[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteDWORD(data, self.Score) + data = CommFunc.WriteDWORD(data, self.ScoreHighest) + data = CommFunc.WriteWORD(data, self.Energy) + data = CommFunc.WriteDWORD(data, self.EnergyTime) + data = CommFunc.WriteDWORD(data, self.LVAwardMax) + data = CommFunc.WriteDWORD(data, self.LVAwardState) + data = CommFunc.WriteBYTE(data, self.UseItemLen) + for i in range(self.UseItemLen): + data = CommFunc.WriteWORD(data, self.UseItemCntList[i]) + data = CommFunc.WriteBYTE(data, self.GridDataLen) + data = CommFunc.WriteString(data, self.GridDataLen, self.GridData) + data = CommFunc.WriteBYTE(data, self.OPType) + data = CommFunc.WriteBYTE(data, self.MoveCount) + for i in range(self.MoveCount): + data = CommFunc.WriteString(data, self.MoveList[i].GetLength(), self.MoveList[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + Score:%d, + ScoreHighest:%d, + Energy:%d, + EnergyTime:%d, + LVAwardMax:%d, + LVAwardState:%d, + UseItemLen:%d, + UseItemCntList:%s, + GridDataLen:%d, + GridData:%s, + OPType:%d, + MoveCount:%d, + MoveList:%s + '''\ + %( + self.Head.OutputString(), + self.Score, + self.ScoreHighest, + self.Energy, + self.EnergyTime, + self.LVAwardMax, + self.LVAwardState, + self.UseItemLen, + "...", + self.GridDataLen, + self.GridData, + self.OPType, + self.MoveCount, + "..." + ) + return DumpString + + +m_NAtagMCActLianqiPlayerInfo=tagMCActLianqiPlayerInfo() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCActLianqiPlayerInfo.Head.Cmd,m_NAtagMCActLianqiPlayerInfo.Head.SubCmd))] = m_NAtagMCActLianqiPlayerInfo + + +#------------------------------------------------------ # AA 80 仙匣秘境跨服活动信息 #tagMCCrossActXianXiaMJInfo class tagMCCrossActXianXiaMJItem(Structure): diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py index 7315f7a..ce7e55d 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossActionControl.py @@ -26,6 +26,7 @@ import PlayerActXianXiaMJ import PlayerActGubao import PlayerActHorsePetTrain +import PlayerActLianqi import CrossRealmMsg import PyGameData import PlayerFB @@ -637,6 +638,9 @@ elif actName == ShareDefine.CrossActName_HorsePetTrain: PlayerActHorsePetTrain.OnCrossActIDChange(cfgID, zoneID, ipyData, state) + elif actName == ShareDefine.CrossActName_Lianqi: + PlayerActLianqi.OnCrossActIDChange(cfgID, zoneID, ipyData, state) + else: actChangeList.append([actName, ipyData, state, cfgID, groupName, zoneID, dbActID, actID, forceReset, dbTemplateID]) @@ -660,6 +664,8 @@ PlayerActGubao.OnCrossActInStateRefresh(cfgID, zoneID, ipyData) elif actName == ShareDefine.CrossActName_HorsePetTrain: PlayerActHorsePetTrain.OnCrossActInStateRefresh(cfgID, zoneID, ipyData) + elif actName == ShareDefine.CrossActName_Lianqi: + PlayerActLianqi.OnCrossActInStateRefresh(cfgID, zoneID, ipyData) # 仅活动有配置参与时间段的会触发 if actID and dbActID == actID and dbStateJoin != stateJoin: @@ -681,6 +687,9 @@ elif actName == ShareDefine.CrossActName_HorsePetTrain: PlayerActHorsePetTrain.OnCrossActJoinEnd(cfgID, zoneID, ipyData) + elif actName == ShareDefine.CrossActName_Lianqi: + PlayerActLianqi.OnCrossActJoinEnd(cfgID, zoneID, ipyData) + GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossActInfo % actName, crossActInfoDict[actName]) # 非活动中的处理完关闭后,最后删除 if not state and isEnd: diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py index befda4a..2a75c24 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py @@ -30,6 +30,7 @@ import PlayerActXianXiaMJ import PlayerActGubao import PlayerActHorsePetTrain +import PlayerActLianqi import CrossActionControl import CrossActAllRecharge import CrossFamilyFlagwar @@ -199,6 +200,9 @@ elif msgType == ShareDefine.ClientServerMsg_HorsePetTrainScore: PlayerActHorsePetTrain.ClientServerMsg_HorsePetTrainScore(serverGroupID, msgData) + elif msgType == ShareDefine.ClientServerMsg_LianqiScore: + PlayerActLianqi.ClientServerMsg_LianqiScore(serverGroupID, msgData) + elif msgType == ShareDefine.ClientServerMsg_CreateFuncTeam: PlayerFuncTeam.ClientServerMsg_CreateFuncTeam(serverGroupID, msgData) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py index 618c5d7..40b6f87 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py @@ -617,6 +617,26 @@ ("WORD", "XiangongID", 0), ), + "CrossActLianqi":( + ("DWORD", "CfgID", 1), + ("char", "ActGroupName", 0), + ("BYTE", "ZoneID", 0), + ("list", "ServerIDRangeList", 0), + ("char", "StartDate", 0), + ("char", "EndDate", 0), + ("char", "JoinStartTime", 0), + ("char", "JoinEndTime", 0), + ("WORD", "LVLimit", 0), + ("WORD", "PersonalTemplateID", 0), + ), + + "ActLianqiBillTemp":( + ("DWORD", "TemplateID", 1), + ("BYTE", "Rank", 0), + ("list", "AwardItemList", 0), + ("DWORD", "NeedScore", 0), + ), + "ActXianXiaMJ":( ("DWORD", "CfgID", 1), ("list", "PlatformList", 0), @@ -2075,6 +2095,36 @@ def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict def GetXiangongID(self): return self.attrTuple[5] # 晋升仙宫ID WORD +# 炼器活动跨服表 +class IPY_CrossActLianqi(): + + def __init__(self): + self.attrTuple = None + return + + def GetCfgID(self): return self.attrTuple[0] # 配置ID DWORD + def GetActGroupName(self): return self.attrTuple[1] # 活动组名(同组活动的名字需相同) char + def GetZoneID(self): return self.attrTuple[2] # 组内分组编号 BYTE + def GetServerIDRangeList(self): return self.attrTuple[3] # 活动的账号服务器ID范围列表 [[serverIDA, serverIDB], ...] list + def GetStartDate(self): return self.attrTuple[4] # 开启日期 char + def GetEndDate(self): return self.attrTuple[5] # 结束日期 char + def GetJoinStartTime(self): return self.attrTuple[6] # 参与开始时间点 char + def GetJoinEndTime(self): return self.attrTuple[7] # 参与结束时间点 char + def GetLVLimit(self): return self.attrTuple[8] # 限制等级 WORD + def GetPersonalTemplateID(self): return self.attrTuple[9] # 个人排行模板编号 WORD + +# 炼器榜单模版表 +class IPY_ActLianqiBillTemp(): + + def __init__(self): + self.attrTuple = None + return + + def GetTemplateID(self): return self.attrTuple[0] # 模板编号 DWORD + def GetRank(self): return self.attrTuple[1] # 名次 BYTE + def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] list + def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD + # 仙匣秘境活动时间表 class IPY_ActXianXiaMJ(): @@ -3054,6 +3104,8 @@ self.__LoadFileData("ActGubao", onlyCheck) self.__LoadFileData("CrossActGubao", onlyCheck) self.__LoadFileData("ActGubaoBillTemp", onlyCheck) + self.__LoadFileData("CrossActLianqi", onlyCheck) + self.__LoadFileData("ActLianqiBillTemp", onlyCheck) self.__LoadFileData("ActXianXiaMJ", onlyCheck) self.__LoadFileData("CrossActXianXiaMJ", onlyCheck) self.__LoadFileData("ActXianXiaMJBillTemp", onlyCheck) @@ -3718,6 +3770,20 @@ self.CheckLoadData("ActGubaoBillTemp") return self.ipyActGubaoBillTempCache[index] + def GetCrossActLianqiCount(self): + self.CheckLoadData("CrossActLianqi") + return self.ipyCrossActLianqiLen + def GetCrossActLianqiByIndex(self, index): + self.CheckLoadData("CrossActLianqi") + return self.ipyCrossActLianqiCache[index] + + def GetActLianqiBillTempCount(self): + self.CheckLoadData("ActLianqiBillTemp") + return self.ipyActLianqiBillTempLen + def GetActLianqiBillTempByIndex(self, index): + self.CheckLoadData("ActLianqiBillTemp") + return self.ipyActLianqiBillTempCache[index] + def GetActXianXiaMJCount(self): self.CheckLoadData("ActXianXiaMJ") return self.ipyActXianXiaMJLen diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActLianqi.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActLianqi.py new file mode 100644 index 0000000..d5fb400 --- /dev/null +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerActLianqi.py @@ -0,0 +1,264 @@ +#!/usr/bin/python +# -*- coding: GBK -*- +#------------------------------------------------------------------------------- +# +##@package PlayerActLianqi +# +# @todo:炼器活动 +# @author hxp +# @date 2025-01-09 +# @version 1.0 +# +# 详细描述: 炼器活动 +# +#------------------------------------------------------------------------------- +#"""Version = 2025-01-09 17:30""" +#------------------------------------------------------------------------------- + +import ShareDefine +import IpyGameDataPY +import PlayerDBGSEvent +import PlayerCompensation +import CrossActionControl +import CrossBillboard +import PyDataManager +import CrossRealmMsg +import GameWorld + +def MapServer_Lianqi(curPlayer, msgList): + mapID = curPlayer.GetRealMapID() + playerID = curPlayer.GetPlayerID() + GameWorld.DebugLog("MapServer_Lianqi mapID=%s,msgList=%s" % (mapID, msgList), playerID) + if not msgList: + return + + msgType, dataMsg = msgList + ret = None + + if msgType == "ScoreHighest": + ret = __OnLianqiScoreHighest(curPlayer, dataMsg) + + if ret == None: + return + return msgList + (ret if isinstance(ret, list) else [ret]) + +def __OnLianqiScoreHighest(curPlayer, dataMsg): + ## 地图同步最高积分记录 + playerID = curPlayer.GetPlayerID() + accID = curPlayer.GetAccID() + playerName = curPlayer.GetName() + job = curPlayer.GetJob() + face = curPlayer.GetFace() + facePic = curPlayer.GetFacePic() + realmLV = curPlayer.GetOfficialRank() + scoreHighest, lvHighest = dataMsg + isRelationCrossAct = True + + if isRelationCrossAct: + #同步跨服 + playerInfo = {"playerID":playerID, "playerName":playerName, "accID":accID, "job":job, "realmLV":realmLV, + "scoreHighest":scoreHighest, "lvHighest":lvHighest, "face":face, "facePic":facePic} + SyncLianqiToCrossServer(curPlayer, playerInfo) + return + +def SyncLianqiToCrossServer(curPlayer, playerInfo): + ## 同步到跨服服务器 + actInfo = CrossActionControl.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_Lianqi) + if not actInfo.get(ShareDefine.ActKey_State): + return + cfgID = actInfo.get(ShareDefine.ActKey_CfgID) + ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {}) + if not ipyDataDict: + return + zoneID = ipyDataDict.get("ZoneID") + if not cfgID or not zoneID: + return + + dataMsg = {"cfgID":cfgID, "zoneID":zoneID, "playerInfo":playerInfo} + CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_LianqiScore, dataMsg) + return + +##------------------------------------------ 跨服炼器活动 --------------------------------------- +def ClientServerMsg_LianqiScore(serverGroupID, msgData): + ## 收到子服 - 同步积分 + + cfgID = msgData["cfgID"] + zoneID = msgData["zoneID"] + playerInfo = msgData["playerInfo"] + + actInfo = CrossActionControl.GetCrossActInfoByCfgID(ShareDefine.CrossActName_Lianqi, cfgID, zoneID) + if not actInfo or not actInfo[ShareDefine.ActKey_State]: + GameWorld.ErrLog("跨服炼器非活动中,无法更新! cfgID=%s, zoneID=%s" % (cfgID, zoneID)) + return + if actInfo[ShareDefine.ActKey_StateJoin] != ShareDefine.ActStateJoin_Start: + GameWorld.ErrLog("跨服炼器非可参与状态,无法更新! cfgID=%s, zoneID=%s" % (cfgID, zoneID)) + return + ipyData = IpyGameDataPY.GetIpyGameData("CrossActLianqi", cfgID) + if not ipyData: + return + PersonalTemplateID = ipyData.GetPersonalTemplateID() + rankIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLianqiBillTemp", PersonalTemplateID) + if not rankIpyDataList: + return + lastRankIpyData = rankIpyDataList[-1] # 取最后一个为最低上榜积分限制 + personlLimit = lastRankIpyData.GetNeedScore() + + playerID = playerInfo["playerID"] + playerName = playerInfo["playerName"] + job = playerInfo["job"] + accID = playerInfo["accID"] + realmLV = playerInfo["realmLV"] + face = playerInfo.get("face", 0) + facePic = playerInfo.get("facePic", 0) + scoreHighest = playerInfo["scoreHighest"] + lvHighest = playerInfo["lvHighest"] + + groupValue1 = zoneID + + if scoreHighest >= personlLimit: + name2, type2, value1, value2 = accID, job, realmLV, 0 + CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_LianqiScore, groupValue1, playerID, playerName, + name2, type2, value1, value2, scoreHighest, cmpValue2=lvHighest, autoSort=False, value3=face, value4=facePic) + return + +def OnCrossActIDChange(cfgID, zoneID, ipyData, state): + ## 跨服活动ID变更 + if state: + OnCrossActStart(cfgID, zoneID, ipyData) + else: + OnCrossActEnd(cfgID, zoneID, ipyData) + return + +def OnCrossActStart(cfgID, zoneID, ipyData): + ## 跨服活动开启 + + PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ActLianqiAwardC % zoneID, 0) + + groupValue1 = zoneID + billboardMgr = PyDataManager.GetCrossBillboardManager() + billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_LianqiScore, groupValue1) + billboardObj.ClearData() # 新活动重置榜单数据 + return + +def OnCrossActEnd(cfgID, zoneID, ipyData): + ## 跨服活动结束 + + groupValue1 = zoneID + GameWorld.Log("=== 跨服炼器活动结束! === cfgID=%s,zoneID=%s" % (cfgID, zoneID)) + __OnCrossEndAward(cfgID, zoneID, ipyData) + + # 备份、清除榜单数据 + billboardMgr = PyDataManager.GetCrossBillboardManager() + billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_LianqiScore, groupValue1) + billboardObj.ClearData() + + GameWorld.Log("=================================================================================") + return + +def OnCrossActInStateRefresh(cfgID, zoneID, ipyData): + ## 活动中刷新,每次都需要刷新的逻辑,包含重读配置等 + if not ipyData: + return + PersonalTemplateID = ipyData.GetPersonalTemplateID() + orderRuleList = GetOrderRuleList(PersonalTemplateID) + + groupValue1 = zoneID + billboardMgr = PyDataManager.GetCrossBillboardManager() + billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_LianqiScore, groupValue1) + billboardObj.SetOrderRuleList(orderRuleList) + return + +def GetOrderRuleList(templateID): + orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLianqiBillTemp", templateID) + if not orderIpyDataList: + return + orderRuleList = [] + for ipyData in orderIpyDataList: + orderRuleList.append([ipyData.GetRank(), ipyData.GetNeedScore()]) + return orderRuleList + +def OnCrossActJoinEnd(cfgID, zoneID, ipyData): + ## 跨服活动参与结束 + __OnCrossEndAward(cfgID, zoneID, ipyData) + return + +def __OnCrossEndAward(cfgID, zoneID, ipyData): + ## 结算跨服奖励 + awardState = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ActLianqiAwardC % zoneID) + if awardState: + #已经结算过该活动 + GameWorld.Log("跨服炼器活动已经结算过奖励了! cfgID=%s,zoneID=%s" % (cfgID, zoneID)) + return + PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ActLianqiAwardC % zoneID, 1) + + GameWorld.Log("=== 跨服炼器活动发放榜单奖励! === cfgID=%s,zoneID=%s" % (cfgID, zoneID)) + + PersonalTemplateID = ipyData.GetPersonalTemplateID() + serverIDRangeList = ipyData.GetServerIDRangeList() + + __GiveCrossOrderAwardPersonal(cfgID, zoneID, PersonalTemplateID, ShareDefine.Def_CBT_LianqiScore, serverIDRangeList) + GameWorld.Log("=================================================================================") + return + +def __GiveCrossOrderAwardPersonal(cfgID, zoneID, templateID, billboardType, serverIDRangeList): + + groupValue1 = zoneID + billboardMgr = PyDataManager.GetCrossBillboardManager() + billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1) + billboardDataCount = billboardObj.GetCount() + if not billboardDataCount: + GameWorld.Log("跨服炼器个人排行数据为空! billboardType=%s,zoneID=%s,cfgID=%s,templateID=%s" % (billboardType, zoneID, cfgID, templateID)) + return + + # 结算时排序并保存榜单数据流向 + billboardObj.SortData() + billboardObj.SaveDRData("Award", {"cfgID":cfgID, "zoneID":zoneID}) + + GameWorld.Log("结算跨服炼器个人排行奖励: billboardType=%s,zoneID=%s,cfgID=%s,templateID=%s,billboardDataCount=%s" + % (billboardType, zoneID, cfgID, templateID, billboardDataCount)) + + orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLianqiBillTemp", templateID) + if not orderIpyDataList: + return + + rankPre = 0 + billboardIndex = 0 + for ipyData in orderIpyDataList: + rank = ipyData.GetRank() + needScore = ipyData.GetNeedScore() + scoreAwardEx = {} #ipyData.GetScoreAwardEx() + scoreAwardExList = scoreAwardEx.keys() + scoreAwardExList.sort() + awardItemList = ipyData.GetAwardItemList() + orderCountTotal = rank - rankPre # 奖励名次数量 + rankPre = rank + + for index in xrange(billboardIndex, billboardDataCount): + if orderCountTotal <= 0: + break + + billboardData = billboardObj.At(index) + playerID = billboardData.ID + name2 = billboardData.Name2 + cmpValue = billboardData.CmpValue + if cmpValue < needScore: + GameWorld.Log(" 积分不足该榜单所需积分,跳过该名次: index=%s,rank=%s,playerID=%s,cmpValue=%s < %s" % (index, rank, playerID, cmpValue, needScore)) + break + + awardItemExList = [] + for scoreEx in scoreAwardExList: + if cmpValue < scoreEx: + break + awardItemExList = scoreAwardEx[scoreEx] # 取最大满足条件的一档 + finalAwardItemList = awardItemList + awardItemExList + + playerRank = rank - orderCountTotal + 1 + GameWorld.Log(" 发放炼器个人榜单奖励: index=%s,rank=%s,playerRank=%s,playerID=%s,cmpValue=%s,awardItemList=%s,scoreAwardEx=%s,finalAwardItemList=%s, %s" + % (index, rank, playerRank, playerID, cmpValue, awardItemList, scoreAwardEx, finalAwardItemList, name2)) + PlayerCompensation.SendMailByKey("ActLianqiCrossPlayer", [playerID], finalAwardItemList, [playerRank], crossMail=True) + + orderCountTotal -= 1 + billboardIndex += 1 + + return + diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py index 980c8fa..fa6239e 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerDBGSEvent.py @@ -190,6 +190,8 @@ Def_ActHorsePetTrainAward = "ActHorsePetTrainAward_%s" #跨服骑宠养成结算状态,参数(zoneID) Def_ActHorsePetTrainAwardC = "ActHorsePetTrainAwardC_%s" +#跨服炼器结算状态,参数(zoneID) +Def_ActLianqiAwardC = "ActLianqiAwardC_%s" def SetInitOpenServerTime(initTime): openDatetime = GameWorld.ChangeTimeNumToDatetime(initTime) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py index edc8d7a..d8a4074 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py @@ -80,6 +80,7 @@ import CrossActAllRecharge import PlayerActGubao import PlayerActHorsePetTrain +import PlayerActLianqi import PlayerActXianXiaMJ import PlayerActBossTrial import PlayerActFamilyCTGAssist @@ -714,6 +715,14 @@ PlayerActHorsePetTrain.MapServer_HorsePetTrain(curPlayer, eval(resultName)) return + # 炼器 + if callName == "ActLianqi": + curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID) + if not curPlayer: + return + PlayerActLianqi.MapServer_Lianqi(curPlayer, eval(resultName)) + return + #py喇叭聊天 if callName == 'PYSpeaker': curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py index 366b69a..620f00f 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py @@ -363,10 +363,11 @@ CrossActName_XianXiaMJ = "CrossActXianXiaMJ" # 仙匣秘境 - 跨服 CrossActName_Gubao = "CrossActGubao" # 古宝养成 - 跨服 CrossActName_HorsePetTrain = "CrossActHorsePetTrain" # 骑宠养成 - 跨服 +CrossActName_Lianqi = "CrossActLianqi" # 炼器 - 跨服 #跨服运营活动列表 CrossActNameList = [CrossActName_CTGBillboard, CrossActName_AllRecharge, CrossActName_LuckyCloudBuy, CrossActName_BossTrial, - CrossActName_XianXiaMJ, CrossActName_Gubao, CrossActName_HorsePetTrain] + CrossActName_XianXiaMJ, CrossActName_Gubao, CrossActName_HorsePetTrain, CrossActName_Lianqi] #需要锁定活动分区分配直到活动结束的跨服运营活动,即使热更分区配置,也不会改变正在活动中的分区设定,直到活动结束 CrossActLockServerGroupIDList = [CrossActName_CTGBillboard, CrossActName_AllRecharge] @@ -902,7 +903,8 @@ Def_CBT_GubaoScore, # 古宝养成积分 - 个人榜 163 Def_CBT_HorsePetTrainScore, # 骑宠养成积分 - 个人榜 164 Def_CBT_CrossRealmPK, # 跨服PK竞技场 165 -) = range(150, 165 + 1) +Def_CBT_LianqiScore, # 炼器积分 - 个人榜 166 +) = range(150, 166 + 1) #职业对应战力排行榜类型 JobFightPowerBillboardDict = { @@ -1725,6 +1727,7 @@ ClientServerMsg_GubaoScore = "GubaoScore" # 古宝养成积分 ClientServerMsg_HorsePetTrainScore = "HorsePetTrainScore" # 骑宠养成积分 ClientServerMsg_QueryXiangong = "QueryXiangong" # 查看仙宫仙名录 +ClientServerMsg_LianqiScore = "LianqiScore" # 炼器积分 #跨服广播类型定义 CrossNotify_CrossAct = "CrossAct" diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini index 4538b16..f02f4c0 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini @@ -1677,6 +1677,18 @@ PacketSubCMD_3=0x22 PacketCallFunc_3=OnActGodGiftReset +;炼器活动 +[PlayerActLianqi] +ScriptName = Player\PlayerActLianqi.py +Writer = hxp +Releaser = hxp +RegType = 0 +RegisterPackCount = 1 + +PacketCMD_1=0xAA +PacketSubCMD_1=0x25 +PacketCallFunc_1=OnActLianqiOP + ;集字活动 [PlayerActCollectWords] ScriptName = Player\PlayerActCollectWords.py diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py index 375d770..69f3c74 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py @@ -4156,6 +4156,17 @@ Def_PDict_ActHorsePetTrainID = "ActHorsePetTrainID_%s" # 玩家身上的活动ID,唯一标识,取活动开始日期time值,参数:(活动编号) Def_PDict_ActHorsePetTrainScore = "ActHorsePetTrainScore_%s" # 累计获得活动养成积分,参数:(活动编号) +#炼器活动 +Def_PDict_CA_LianqiID = "CA_LianqiID" # 玩家身上的活动ID,唯一标识,取活动开始日期time值 +Def_PDict_LianqiScore = "LianqiScore" # 当前积分 +Def_PDict_LianqiScoreHighest = "LianqiScoreHighest" # 本次最高分(上榜分取该分) +Def_PDict_LianqiEnergy = "LianqiEnergy" # 当前体力 +Def_PDict_LianqiEnergyTime = "LianqiEnergyTime" # 上次恢复体力时间戳 +Def_PDict_LianqiRowData = "LianqiRowData_%s" # 行数据,最大支持每行4格,每格存两位,参数:(key编号) +Def_PDict_LianqiItemUse = "LianqiItemUse_%s" # 辅助道具单局已使用次数,参数:(物品ID) +Def_PDict_LianqiLVAwardMax = "LianqiLVAwardMax" # 激活的最大合成奖励等级 +Def_PDict_LianqiLVAwardState = "LianqiLVAwardState" # 最大合成等级奖励领取记录,按二进制位存储是否已领取 + #天帝礼包活动 Def_PDict_GodGiftID = "ActGodGiftID_%s" # 玩家身上的活动ID,唯一标识,取活动开始日期time值,参数:(活动编号) Def_PDict_GodGiftWorldLV = "ActGodGiftWorldLV_%s" #玩家身上的活动世界等级,参数:(活动编号) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py index 6dc84f0..323ab1f 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py @@ -16711,6 +16711,70 @@ #------------------------------------------------------ +# AA 25 炼器操作 #tagCMActLianqiOP + +class tagCMActLianqiOP(Structure): + _pack_ = 1 + _fields_ = [ + ("Cmd", c_ubyte), + ("SubCmd", c_ubyte), + ("OPType", c_ubyte), # 1-移动;2-使用道具;3-重新开始;4-领取等级奖励 + ("OPValue", c_int), # 移动时-发1上2下3左4右;使用道具时-发使用个数*10+道具ID所在配置索引;等级奖励时-发领取的奖励等级 + ("OPValue2", c_int), # 使用道具时-发选中格子A的行列值 行*10+列 + ("OPValue3", c_int), # 使用道具时-发选中格子B的行列值 行*10+列 + ] + + def __init__(self): + self.Clear() + self.Cmd = 0xAA + self.SubCmd = 0x25 + 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 = 0xAA + self.SubCmd = 0x25 + self.OPType = 0 + self.OPValue = 0 + self.OPValue2 = 0 + self.OPValue3 = 0 + return + + def GetLength(self): + return sizeof(tagCMActLianqiOP) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AA 25 炼器操作 //tagCMActLianqiOP: + Cmd:%s, + SubCmd:%s, + OPType:%d, + OPValue:%d, + OPValue2:%d, + OPValue3:%d + '''\ + %( + self.Cmd, + self.SubCmd, + self.OPType, + self.OPValue, + self.OPValue2, + self.OPValue3 + ) + return DumpString + + +m_NAtagCMActLianqiOP=tagCMActLianqiOP() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMActLianqiOP.Cmd,m_NAtagCMActLianqiOP.SubCmd))] = m_NAtagCMActLianqiOP + + +#------------------------------------------------------ # AA 12 选择转盘活动物品 #tagCMActTurntableChooseItem class tagCMActTurntableChooseItem(Structure): diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py index 7484eb3..80940a3 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py @@ -44354,6 +44354,434 @@ #------------------------------------------------------ +# AA 90 炼器跨服活动信息 #tagMCCrossActLianqiInfo + +class tagMCCrossActLianqiItem(Structure): + _pack_ = 1 + _fields_ = [ + ("ItemID", c_int), + ("ItemCount", c_ushort), + ("IsBind", c_ubyte), + ] + + def __init__(self): + self.Clear() + 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.ItemID = 0 + self.ItemCount = 0 + self.IsBind = 0 + return + + def GetLength(self): + return sizeof(tagMCCrossActLianqiItem) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AA 90 炼器跨服活动信息 //tagMCCrossActLianqiInfo: + ItemID:%d, + ItemCount:%d, + IsBind:%d + '''\ + %( + self.ItemID, + self.ItemCount, + self.IsBind + ) + return DumpString + + +class tagMCCrossActLianqiBillard(Structure): + Rank = 0 #(DWORD Rank)// 名次,1-代表第一名;支持夸段,如1,3 代表第1名,第2~3名 + Count = 0 #(BYTE Count)// 奖励物品数 + AwardItemList = list() #(vector<tagMCCrossActLianqiItem> AwardItemList)// 奖励物品列表 + NeedScore = 0 #(DWORD NeedScore)// 上榜所需积分 + data = None + + def __init__(self): + self.Clear() + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + self.Rank,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.Count): + temAwardItemList = tagMCCrossActLianqiItem() + _pos = temAwardItemList.ReadData(_lpData, _pos) + self.AwardItemList.append(temAwardItemList) + self.NeedScore,_pos = CommFunc.ReadDWORD(_lpData, _pos) + return _pos + + def Clear(self): + self.Rank = 0 + self.Count = 0 + self.AwardItemList = list() + self.NeedScore = 0 + return + + def GetLength(self): + length = 0 + length += 4 + length += 1 + for i in range(self.Count): + length += self.AwardItemList[i].GetLength() + length += 4 + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteDWORD(data, self.Rank) + data = CommFunc.WriteBYTE(data, self.Count) + for i in range(self.Count): + data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer()) + data = CommFunc.WriteDWORD(data, self.NeedScore) + return data + + def OutputString(self): + DumpString = ''' + Rank:%d, + Count:%d, + AwardItemList:%s, + NeedScore:%d + '''\ + %( + self.Rank, + self.Count, + "...", + self.NeedScore + ) + return DumpString + + +class tagMCCrossActLianqiInfo(Structure): + Head = tagHead() + ServerInfoLen = 0 #(BYTE ServerInfoLen) + ServerIDRangeInfo = "" #(String ServerIDRangeInfo)//开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服 + GroupValue1 = 0 #(BYTE GroupValue1)// 活动榜单分组值1,用于查询对应榜单 + StartDate = "" #(char StartDate[10])// 开始日期 y-m-d + EndtDate = "" #(char EndtDate[10])// 结束日期 y-m-d + JoinStartTime = "" #(char JoinStartTime[5])// 参与开始时间点 mm:ss + JoinEndTime = "" #(char JoinEndTime[5])// 参与结束时间点 mm:ss + LimitLV = 0 #(WORD LimitLV)// 限制等级 + PersonalBillCount = 0 #(BYTE PersonalBillCount) + PersonalBillboardInfoList = list() #(vector<tagMCCrossActLianqiBillard> PersonalBillboardInfoList)// 个人榜单奖励信息列表,如果没有代表本次活动没有该榜奖励 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x90 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.ServerInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.ServerIDRangeInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ServerInfoLen) + self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10) + self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10) + self.JoinStartTime,_pos = CommFunc.ReadString(_lpData, _pos,5) + self.JoinEndTime,_pos = CommFunc.ReadString(_lpData, _pos,5) + self.LimitLV,_pos = CommFunc.ReadWORD(_lpData, _pos) + self.PersonalBillCount,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.PersonalBillCount): + temPersonalBillboardInfoList = tagMCCrossActLianqiBillard() + _pos = temPersonalBillboardInfoList.ReadData(_lpData, _pos) + self.PersonalBillboardInfoList.append(temPersonalBillboardInfoList) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x90 + self.ServerInfoLen = 0 + self.ServerIDRangeInfo = "" + self.GroupValue1 = 0 + self.StartDate = "" + self.EndtDate = "" + self.JoinStartTime = "" + self.JoinEndTime = "" + self.LimitLV = 0 + self.PersonalBillCount = 0 + self.PersonalBillboardInfoList = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 1 + length += len(self.ServerIDRangeInfo) + length += 1 + length += 10 + length += 10 + length += 5 + length += 5 + length += 2 + length += 1 + for i in range(self.PersonalBillCount): + length += self.PersonalBillboardInfoList[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteBYTE(data, self.ServerInfoLen) + data = CommFunc.WriteString(data, self.ServerInfoLen, self.ServerIDRangeInfo) + data = CommFunc.WriteBYTE(data, self.GroupValue1) + data = CommFunc.WriteString(data, 10, self.StartDate) + data = CommFunc.WriteString(data, 10, self.EndtDate) + data = CommFunc.WriteString(data, 5, self.JoinStartTime) + data = CommFunc.WriteString(data, 5, self.JoinEndTime) + data = CommFunc.WriteWORD(data, self.LimitLV) + data = CommFunc.WriteBYTE(data, self.PersonalBillCount) + for i in range(self.PersonalBillCount): + data = CommFunc.WriteString(data, self.PersonalBillboardInfoList[i].GetLength(), self.PersonalBillboardInfoList[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + ServerInfoLen:%d, + ServerIDRangeInfo:%s, + GroupValue1:%d, + StartDate:%s, + EndtDate:%s, + JoinStartTime:%s, + JoinEndTime:%s, + LimitLV:%d, + PersonalBillCount:%d, + PersonalBillboardInfoList:%s + '''\ + %( + self.Head.OutputString(), + self.ServerInfoLen, + self.ServerIDRangeInfo, + self.GroupValue1, + self.StartDate, + self.EndtDate, + self.JoinStartTime, + self.JoinEndTime, + self.LimitLV, + self.PersonalBillCount, + "..." + ) + return DumpString + + +m_NAtagMCCrossActLianqiInfo=tagMCCrossActLianqiInfo() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCrossActLianqiInfo.Head.Cmd,m_NAtagMCCrossActLianqiInfo.Head.SubCmd))] = m_NAtagMCCrossActLianqiInfo + + +#------------------------------------------------------ +# AA 91 炼器活动玩家信息 #tagMCActLianqiPlayerInfo + +class tagMCActLianqiTileMove(Structure): + _pack_ = 1 + _fields_ = [ + ("Row", c_ubyte), # 行,0为第1行 + ("Col", c_ubyte), # 列,0为第1列 + ("ToRow", c_ubyte), # 移动到目标行 + ("ToCol", c_ubyte), # 移动到目标列 + ] + + def __init__(self): + self.Clear() + 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.Row = 0 + self.Col = 0 + self.ToRow = 0 + self.ToCol = 0 + return + + def GetLength(self): + return sizeof(tagMCActLianqiTileMove) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AA 91 炼器活动玩家信息 //tagMCActLianqiPlayerInfo: + Row:%d, + Col:%d, + ToRow:%d, + ToCol:%d + '''\ + %( + self.Row, + self.Col, + self.ToRow, + self.ToCol + ) + return DumpString + + +class tagMCActLianqiPlayerInfo(Structure): + Head = tagHead() + Score = 0 #(DWORD Score)// 当前活动积分 + ScoreHighest = 0 #(DWORD ScoreHighest)// 当前活动最高积分,即上榜积分 + Energy = 0 #(WORD Energy)// 当前体力 + EnergyTime = 0 #(DWORD EnergyTime)// 上次恢复体力时间戳,为0时不用处理倒计时 + LVAwardMax = 0 #(DWORD LVAwardMax)// 已激活的最大合成奖励等级 + LVAwardState = 0 #(DWORD LVAwardState)// 最大合成等级奖励领取记录,按等级二进制位存储是否已领取 + UseItemLen = 0 #(BYTE UseItemLen) + UseItemCntList = list() #(vector<WORD> UseItemCntList)// 本局已使用辅助道具次数 [辅助道具1使用次数, ...] + GridDataLen = 0 #(BYTE GridDataLen)// 格子数据长度 + GridData = "" #(String GridData)// 格子二维行列数据,一定会同步,直接替换,行从上往下排 [[第1行格子1,格子2, ...], ...] + OPType = 0 #(BYTE OPType)// 0-无(如初始化,GM等后端直接设置);1-移动;2-使用道具;3-重新开始;如果是因为操作引起的格子数据变化,则在相关操作表现完毕后再展示最新行列数据,否则直接变更 + MoveCount = 0 #(BYTE MoveCount) + MoveList = list() #(vector<tagMCActLianqiTileMove> MoveList)// 图块移动列表,可能没有数据,有的话先表现移动 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x91 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.Score,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.ScoreHighest,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.Energy,_pos = CommFunc.ReadWORD(_lpData, _pos) + self.EnergyTime,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.LVAwardMax,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.LVAwardState,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.UseItemLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.UseItemLen): + value,_pos=CommFunc.ReadWORD(_lpData,_pos) + self.UseItemCntList.append(value) + self.GridDataLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.GridData,_pos = CommFunc.ReadString(_lpData, _pos,self.GridDataLen) + self.OPType,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.MoveCount,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.MoveCount): + temMoveList = tagMCActLianqiTileMove() + _pos = temMoveList.ReadData(_lpData, _pos) + self.MoveList.append(temMoveList) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xAA + self.Head.SubCmd = 0x91 + self.Score = 0 + self.ScoreHighest = 0 + self.Energy = 0 + self.EnergyTime = 0 + self.LVAwardMax = 0 + self.LVAwardState = 0 + self.UseItemLen = 0 + self.UseItemCntList = list() + self.GridDataLen = 0 + self.GridData = "" + self.OPType = 0 + self.MoveCount = 0 + self.MoveList = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 4 + length += 4 + length += 2 + length += 4 + length += 4 + length += 4 + length += 1 + length += 2 * self.UseItemLen + length += 1 + length += len(self.GridData) + length += 1 + length += 1 + for i in range(self.MoveCount): + length += self.MoveList[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteDWORD(data, self.Score) + data = CommFunc.WriteDWORD(data, self.ScoreHighest) + data = CommFunc.WriteWORD(data, self.Energy) + data = CommFunc.WriteDWORD(data, self.EnergyTime) + data = CommFunc.WriteDWORD(data, self.LVAwardMax) + data = CommFunc.WriteDWORD(data, self.LVAwardState) + data = CommFunc.WriteBYTE(data, self.UseItemLen) + for i in range(self.UseItemLen): + data = CommFunc.WriteWORD(data, self.UseItemCntList[i]) + data = CommFunc.WriteBYTE(data, self.GridDataLen) + data = CommFunc.WriteString(data, self.GridDataLen, self.GridData) + data = CommFunc.WriteBYTE(data, self.OPType) + data = CommFunc.WriteBYTE(data, self.MoveCount) + for i in range(self.MoveCount): + data = CommFunc.WriteString(data, self.MoveList[i].GetLength(), self.MoveList[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + Score:%d, + ScoreHighest:%d, + Energy:%d, + EnergyTime:%d, + LVAwardMax:%d, + LVAwardState:%d, + UseItemLen:%d, + UseItemCntList:%s, + GridDataLen:%d, + GridData:%s, + OPType:%d, + MoveCount:%d, + MoveList:%s + '''\ + %( + self.Head.OutputString(), + self.Score, + self.ScoreHighest, + self.Energy, + self.EnergyTime, + self.LVAwardMax, + self.LVAwardState, + self.UseItemLen, + "...", + self.GridDataLen, + self.GridData, + self.OPType, + self.MoveCount, + "..." + ) + return DumpString + + +m_NAtagMCActLianqiPlayerInfo=tagMCActLianqiPlayerInfo() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCActLianqiPlayerInfo.Head.Cmd,m_NAtagMCActLianqiPlayerInfo.Head.SubCmd))] = m_NAtagMCActLianqiPlayerInfo + + +#------------------------------------------------------ # AA 80 仙匣秘境跨服活动信息 #tagMCCrossActXianXiaMJInfo class tagMCCrossActXianXiaMJItem(Structure): diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Lianqi.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Lianqi.py new file mode 100644 index 0000000..8581f12 --- /dev/null +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Lianqi.py @@ -0,0 +1,134 @@ +#!/usr/bin/python +# -*- coding: GBK -*- +#------------------------------------------------------------------------------- +# +##@package GM.Commands.Lianqi +# +# @todo:炼器活动 +# @author hxp +# @date 2025-01-09 +# @version 1.0 +# +# 详细描述: 炼器活动 +# +#------------------------------------------------------------------------------- +#"""Version = 2025-01-09 17:30""" +#------------------------------------------------------------------------------- + +import GameWorld +import PlayerControl +import PlayerZhanling +import PlayerActLianqi +import IpyGameDataPY +import ChConfig + +#--------------------------------------------------------------------- +#逻辑实现 + +## GM命令执行入口 +# @param curPlayer 当前玩家 +# @param msgList 参数列表 +# @return None +# @remarks 函数详细说明. +def OnExec(curPlayer, msgList): + if not msgList: + GameWorld.DebugAnswer(curPlayer, "重置炼器数据: Lianqi 0") + GameWorld.DebugAnswer(curPlayer, "重新开始游戏: Lianqi 1") + GameWorld.DebugAnswer(curPlayer, "设置辅助道具: Lianqi w ID索引 已用次数") + GameWorld.DebugAnswer(curPlayer, "设置当前体力: Lianqi e 体力值") + GameWorld.DebugAnswer(curPlayer, "设置当前积分: Lianqi s 积分") + GameWorld.DebugAnswer(curPlayer, "设置网格等级: Lianqi g 行 列 等级") + GameWorld.DebugAnswer(curPlayer, "输出棋盘数据: Lianqi p") + GameWorld.DebugAnswer(curPlayer, "设置棋盘数据: Lianqi c 行列等级1 ...") + GameWorld.DebugAnswer(curPlayer, "棋盘行列从行0~3列0~3开始总16格,不足的值默认0") + return + + if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_LianqiID): + GameWorld.DebugAnswer(curPlayer, "炼器非活动中") + return + + value1 = msgList[0] + if value1 == 0: + PlayerZhanling.ResetZhanling(curPlayer, PlayerZhanling.ZhanlingType_Lianqi) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScore, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScoreHighest, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiLVAwardMax, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiLVAwardState, 0) + PlayerActLianqi.SetLianqiEnergy(curPlayer, IpyGameDataPY.GetFuncCfg("LianqiSet", 1)) + PlayerActLianqi.ReStartGame(curPlayer, isNotify=False) + GameWorld.DebugAnswer(curPlayer, "重置炼器OK!") + + elif value1 == 1: + PlayerActLianqi.ReStartGame(curPlayer, isNotify=False) + GameWorld.DebugAnswer(curPlayer, "重新开始炼器OK!") + + elif value1 == "e": + energy = msgList[1] if len(msgList) > 1 else 0 + updEnergy = PlayerActLianqi.SetLianqiEnergy(curPlayer, energy) + GameWorld.DebugAnswer(curPlayer, "设置体力: %s" % updEnergy) + + elif value1 == "s": + score = msgList[1] if len(msgList) > 1 else 0 + updScore = PlayerActLianqi.SetLianqiScore(curPlayer, score) + GameWorld.DebugAnswer(curPlayer, "设置积分: %s" % updScore) + + elif value1 == "g": + r = msgList[1] if len(msgList) > 1 else 0 + c = msgList[2] if len(msgList) > 2 else 0 + lv = msgList[3] if len(msgList) > 3 else 0 + gridDataList = PlayerActLianqi.GetGridDataList(curPlayer) + rcLV = PlayerActLianqi.GetGridLV(r, c, gridDataList) + if rcLV == None: + GameWorld.DebugAnswer(curPlayer, "该行列不存在!行:%s,列:%s" % (r, c)) + return + lv = min(lv, PlayerActLianqi.Def_MaxLV) + gridDataList[r][c] = lv + PlayerActLianqi.SaveGridData(curPlayer, gridDataList) + GameWorld.DebugAnswer(curPlayer, "设置行:%s,列:%s,等级:%s" % (r, c, lv)) + __PrintGrid(curPlayer) + + elif value1 == "p": + __PrintGrid(curPlayer) + + elif value1 == "c": + rcvList = msgList[1:] + gridMax = PlayerActLianqi.Def_Size *PlayerActLianqi.Def_Size + if len(rcvList) < gridMax: + rcvList += [0] * (gridMax - len(rcvList)) + gridDataList = PlayerActLianqi.GetGridDataList(curPlayer) + for r in range(PlayerActLianqi.Def_Size): + for c in range(PlayerActLianqi.Def_Size): + lv = rcvList.pop(0) + gridDataList[r][c] = min(lv, PlayerActLianqi.Def_MaxLV) + PlayerActLianqi.SaveGridData(curPlayer, gridDataList) + GameWorld.DebugAnswer(curPlayer, "设置棋盘OK!") + __PrintGrid(curPlayer) + + elif value1 == "w": + idIndex = msgList[1] if len(msgList) > 1 else 0 + usedCnt = msgList[2] if len(msgList) > 2 else 0 + itemIDList = IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 1) + if idIndex < 0 or idIndex >= len(itemIDList): + GameWorld.DebugAnswer(curPlayer, "非辅助道具ID索引:%s,%s" % (idIndex, range(len(itemIDList)))) + return + itemID = itemIDList[idIndex] + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiItemUse % itemID, usedCnt) + GameWorld.DebugAnswer(curPlayer, "设置物品ID:%s,使用次数:%s" % (itemID, usedCnt)) + + PlayerActLianqi.Sync_LianqiPlayerInfo(curPlayer) + return + +def __PrintGrid(curPlayer): + gridDataList = PlayerActLianqi.GetGridDataList(curPlayer) + for rowData in gridDataList: + rowStr = "" + for lv in rowData: + if rowStr: + rowStr += ", " + if lv < 10: + rowStr += " " + rowStr += str(lv) + GameWorld.DebugAnswer(curPlayer, "[%s]" % rowStr) + return + + diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py index eb13988..40f9520 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py @@ -1606,6 +1606,13 @@ ("dict", "ScoreAwardEx", 0), ), + "ActLianqiBillTemp":( + ("DWORD", "TemplateID", 1), + ("BYTE", "Rank", 0), + ("list", "AwardItemList", 0), + ("DWORD", "NeedScore", 0), + ), + "ActXianXiaMJ":( ("DWORD", "CfgID", 1), ("char", "StartDate", 0), @@ -4888,6 +4895,18 @@ def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict +# 炼器榜单模版表 +class IPY_ActLianqiBillTemp(): + + def __init__(self): + self.attrTuple = None + return + + def GetTemplateID(self): return self.attrTuple[0] # 模板编号 DWORD + def GetRank(self): return self.attrTuple[1] # 名次 BYTE + def GetAwardItemList(self): return self.attrTuple[2] # 奖励物品列表[[物品ID,个数,是否拍品], ...] list + def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD + # 仙匣秘境活动时间表 class IPY_ActXianXiaMJ(): @@ -6610,6 +6629,7 @@ self.__LoadFileData("ActHorsePetTrainBillTemp", onlyCheck) self.__LoadFileData("ActGubao", onlyCheck) self.__LoadFileData("ActGubaoBillTemp", onlyCheck) + self.__LoadFileData("ActLianqiBillTemp", onlyCheck) self.__LoadFileData("ActXianXiaMJ", onlyCheck) self.__LoadFileData("ActXianXiaMJBillTemp", onlyCheck) self.__LoadFileData("ActXianXiaMJAward", onlyCheck) @@ -7981,6 +8001,13 @@ self.CheckLoadData("ActGubaoBillTemp") return self.ipyActGubaoBillTempCache[index] + def GetActLianqiBillTempCount(self): + self.CheckLoadData("ActLianqiBillTemp") + return self.ipyActLianqiBillTempLen + def GetActLianqiBillTempByIndex(self, index): + self.CheckLoadData("ActLianqiBillTemp") + return self.ipyActLianqiBillTempCache[index] + def GetActXianXiaMJCount(self): self.CheckLoadData("ActXianXiaMJ") return self.ipyActXianXiaMJLen diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py index b5e90ed..49f1ccf 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py @@ -115,6 +115,7 @@ import PlayerActXianXiaMJ import PlayerActGubao import PlayerActHorsePetTrain +import PlayerActLianqi import PlayerActGodGift import PlayerActFamilyCTGAssist import PlayerActRechargeRebateGold @@ -908,6 +909,8 @@ PlayerActGubao.OnPlayerLogin(curPlayer) # 骑宠养成活动 PlayerActHorsePetTrain.OnPlayerLogin(curPlayer) + # 炼器活动 + PlayerActLianqi.OnPlayerLogin(curPlayer) # 天帝礼包活动 PlayerActGodGift.OnPlayerLogin(curPlayer) # 多日连充活动 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLianqi.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLianqi.py new file mode 100644 index 0000000..89c4f52 --- /dev/null +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActLianqi.py @@ -0,0 +1,635 @@ +#!/usr/bin/python +# -*- coding: GBK -*- +#------------------------------------------------------------------------------- +# +##@package Player.PlayerActLianqi +# +# @todo:炼器活动 +# @author hxp +# @date 2025-01-09 +# @version 1.0 +# +# 详细描述: 炼器活动 +# +#------------------------------------------------------------------------------- +#"""Version = 2025-01-09 17:30""" +#------------------------------------------------------------------------------- + +import ShareDefine +import PlayerControl +import IpyGameDataPY +import NetPackCommon +import ChPyNetSendPack +import CrossRealmPlayer +import PlayerZhanling +import ItemControler +import ItemCommon +import GameWorld +import ChConfig + +import random +import time + +Def_Size = 4 # 行列数 +Def_MaxLV = 11 # 最大等级,2048 + +def OnPlayerLogin(curPlayer): + + if not __CheckPlayerCrossActLianqi(curPlayer): + Sync_CrossActLianqiActionInfo(curPlayer) + Sync_LianqiPlayerInfo(curPlayer) + + return + +def RefreshCrossActLianqiInfo(): + ## 收到GameServer同步的活动信息,刷新活动信息 + playerManager = GameWorld.GetPlayerManager() + for index in xrange(playerManager.GetPlayerCount()): + curPlayer = playerManager.GetPlayerByIndex(index) + if not GameWorld.IsNormalPlayer(curPlayer): + continue + __CheckPlayerCrossActLianqi(curPlayer) + + return + +def __CheckPlayerCrossActLianqi(curPlayer): + + playerID = curPlayer.GetPlayerID() + + actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_Lianqi) + cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0) + actID = actInfo.get(ShareDefine.ActKey_ID, 0) + state = actInfo.get(ShareDefine.ActKey_State, 0) + + playerActID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_LianqiID) # 玩家身上的活动ID + + # 活动ID 相同的话不处理 + if actID == playerActID: + GameWorld.DebugLog("跨服炼器活动ID不变,不处理!cfgID=%s,actID=%s" % (cfgID, actID), playerID) + return + GameWorld.DebugLog("跨服炼器活动重置! cfgID=%s,actID=%s,playerActID=%s,state=%s" % (cfgID, actID, playerActID, state), playerID) + PlayerZhanling.ResetZhanling(curPlayer, PlayerZhanling.ZhanlingType_Lianqi) + + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_LianqiID, actID) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScore, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScoreHighest, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergy, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergyTime, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiLVAwardMax, 0) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiLVAwardState, 0) + for row in range(Def_Size): + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiRowData % row, 0) + for itemID in IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 1): + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiItemUse % itemID, 0) + # 回收道具 + for itemID in IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 5): + ItemControler.RecycleItem(curPlayer, itemID, "ActLianqiRecycleItem") + + if state: + SetLianqiEnergy(curPlayer, IpyGameDataPY.GetFuncCfg("LianqiSet", 1)) + ReStartGame(curPlayer, isNotify=False) + Sync_CrossActLianqiActionInfo(curPlayer) + Sync_LianqiPlayerInfo(curPlayer) + else: + CrossRealmPlayer.NotifyCrossActEnd(curPlayer, ShareDefine.CrossActName_Lianqi) + + return True + +def ReStartGame(curPlayer, opType=0, isNotify=True): + ## 重新开始游戏 + + # 重置积分 + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScore, 0) + + # 重置单局使用道具次数 + for itemID in IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 1): + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiItemUse % itemID, 0) + + # 初始化棋盘 + initRandCount = IpyGameDataPY.GetFuncCfg("LianqiRand", 1) + randList = range(Def_Size * Def_Size) + random.shuffle(randList) + randList = randList[:initRandCount] + gridDataList = [] + for row in range(Def_Size): + rowDataList = [] + for col in range(Def_Size): + lv = 1 if (row * Def_Size + col) in randList else 0 + rowDataList.append(lv) + gridDataList.append(rowDataList) + PrintGridData(curPlayer, gridDataList, "重新开始炼器: %s" % randList) + SaveGridData(curPlayer, gridDataList) + + if isNotify: + Sync_LianqiPlayerInfo(curPlayer, opType) + return + +def GetGridDataList(curPlayer): + ## 获取行列数据列表 + gridDataList = [] + for row in range(Def_Size): + rowDataValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiRowData % row) + rowDataList = [] + for _ in range(Def_Size): + colValue = rowDataValue % 100 + rowDataValue = rowDataValue / 100 + rowDataList.insert(0, colValue) + gridDataList.append(rowDataList) + return gridDataList + +def PrintGridData(curPlayer, gridDataList, printTitle): + GameWorld.DebugLog("%s" % printTitle, curPlayer.GetPlayerID()) + for rowData in gridDataList: + rowStr = "" + for lv in rowData: + if rowStr: + rowStr += ", " + if lv < 10: + rowStr += " " + rowStr += str(lv) + GameWorld.DebugLog("[%s]" % rowStr, curPlayer.GetPlayerID()) + return + +def SaveGridData(curPlayer, gridDataList): + ## 保存行列数据 + for row in range(Def_Size): + rowDataStr = "" + for col in range(Def_Size): + rowDataStr += "%02d" % gridDataList[row][col] + rowDataValue = int(rowDataStr) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiRowData % row, rowDataValue) + return + +#// AA 25 炼器操作 #tagCMActLianqiOP +# +#struct tagCMActLianqiOP +#{ +# tagHead Head; +# BYTE OPType; // 1-移动;2-使用道具;3-重新开始;4-领取等级奖励 +# DWORD OPValue; // 移动时-发1上2下3左4右;使用道具时-发使用个数*10+道具ID所在配置索引;等级奖励时-发领取的奖励等级 +# DWORD OPValue2; // 使用道具时-发选中格子A的行列值 行*10+列 +# DWORD OPValue3; // 使用道具时-发选中格子B的行列值 行*10+列 +#}; +def OnActLianqiOP(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + playerID = curPlayer.GetPlayerID() + OPType = clientData.OPType + OPValue = clientData.OPValue + OPValue2 = clientData.OPValue2 + OPValue3 = clientData.OPValue3 + + if OPType not in [4]: + actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_Lianqi) + if not actInfo: + GameWorld.DebugLog("非炼器活动中,无法操作! OPType=%s" % OPType, playerID) + return + if actInfo.get(ShareDefine.ActKey_StateJoin) != ShareDefine.ActStateJoin_Start: + GameWorld.DebugLog("非炼器活动参与中,无法操作! OPType=%s" % OPType, playerID) + return + + if OPType == 1: + OnMove(curPlayer, OPType, OPValue) + elif OPType == 2: + OnUseItem(curPlayer, OPType, OPValue, OPValue2, OPValue3) + elif OPType == 3: + ReStartGame(curPlayer, OPType) + elif OPType == 4: + OnGetLVAward(curPlayer, OPType, OPValue) + return + +def GetGridLV(r, c, gridDataList): + ## 获取格子中的图块等级 + # @return: None-越界;0-空位置;>0-对应等级 + if 0 <= r < len(gridDataList) and 0 <= c < len(gridDataList[r]): + lv = gridDataList[r][c] + return lv + return + +def OnMove(curPlayer, opType, moveDir): + ## 移动 + playerID = curPlayer.GetPlayerID() + + curEnergy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergy) + if not curEnergy: + GameWorld.DebugLog("炼器无体力,无法移动!", playerID) + return + + moveDirCn = "" + v = [] # 移动行列向量 + if moveDir == 1: # 上 + v = (-1, 0) + moveDirCn = "上" + elif moveDir == 2: # 下 + v = (1, 0) + moveDirCn = "下" + elif moveDir == 3: # 左 + v = (0, -1) + moveDirCn = "左" + elif moveDir == 4: # 右 + v = (0, 1) + moveDirCn = "右" + else: + GameWorld.DebugLog("炼器方向错误,无法移动! moveDir=%s" % moveDir, playerID) + return + + GameWorld.DebugLog("炼器移动: moveDir=%s%s,v=%s,curEnergy=%s" % (moveDir, moveDirCn, v, curEnergy), playerID) + gridDataList = GetGridDataList(curPlayer) + PrintGridData(curPlayer, gridDataList, "移动前") + vr, vc = v + loopList = range(Def_Size) if (vr < 0 or vc < 0) else range(Def_Size)[::-1] + lvUPRCList = [] # 已经升级过的位置列表,每次移动单个位置只能升级一次 + moveList = [] # 移动信息 + addScoreTotal = 0 + for r in loopList: + for c in loopList: + lv = GetGridLV(r, c, gridDataList) + moveTo = [] + if not lv: + #空位置 + continue + toR, toC = r, c + isUp = False + for _ in range(Def_Size): + toR += vr + toC += vc + if [toR, toC] in lvUPRCList: + # 已经升级过的位置视为障碍点, toR, toC + break + lvTo = GetGridLV(toR, toC, gridDataList) + if lvTo == None: + # 超出边界了, toR, toC + break + if not lvTo: + moveTo = [toR, toC] + isUp = False + # 空位置直接替换, toR, toC + elif lv == lvTo and lv < Def_MaxLV: + moveTo = [toR, toC] + isUp = True + # 可升级, toR, toC + else: + # 其他情况均视为障碍点,被堵住了, toR, toC + break + + if moveTo: + toR, toC = moveTo + gridDataList[r][c] = 0 # 原位置置空 + if isUp: + lv += 1 + addScore = pow(2, lv) + addScoreTotal += addScore + GameWorld.DebugLog("合成等级: %s,addScore=%s,addScoreTotal=%s, RC(%s,%s) to (%s,%s)" + % (lv, addScore, addScoreTotal, r, c, toR, toC), playerID) + lvUPRCList.append([toR, toC]) + gridDataList[toR][toC] = lv # 替换到新位置 + moveList.append([r, c, toR, toC]) + + GameWorld.DebugLog("移动队列: %s" % moveList, playerID) + if not moveList: + PlayerControl.NotifyCode(curPlayer, "LianqiMoveUnable") + return + + # 随机生成新图块 + maxLVNow = 0 + emptyGridList = [] + for row in range(Def_Size): + for col in range(Def_Size): + lv = gridDataList[row][col] + if not lv: + emptyGridList.append([row, col]) + else: + if lv >= Def_MaxLV and maxLVNow >= Def_MaxLV: + maxLVNow += 1 + else: + maxLVNow = max(lv, maxLVNow) + + if emptyGridList: + row, col = random.choice(emptyGridList) + randRateList = [] + randRateDict = IpyGameDataPY.GetFuncEvalCfg("LianqiRand", 2, {}) + for lvRange in randRateDict.keys(): + if isinstance(lvRange, tuple) and len(lvRange) == 2 and lvRange[0] <= maxLVNow <= lvRange[1]: + randRateList = randRateDict[lvRange] + randLV = GameWorld.GetResultByRandomList(randRateList, 1) + gridDataList[row][col] = randLV + GameWorld.DebugLog("随机添加: maxLVNow=%s,row=%s,col=%s,randLV=%s, %s" % (maxLVNow, row, col, randLV, randRateList), playerID) + + PrintGridData(curPlayer, gridDataList, "移动后") + SetLianqiEnergy(curPlayer, curEnergy - 1) + AddLianqiScore(curPlayer, addScoreTotal, maxLVNow) + SaveGridData(curPlayer, gridDataList) + Sync_LianqiPlayerInfo(curPlayer, opType, moveList) + return True + +def OnUseItem(curPlayer, opType, useInfo, opValue2, opValue3): + ## 使用辅助道具 + + playerID = curPlayer.GetPlayerID() + itemIDList = IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 1) + useItemCount = max(1, useInfo / 10) # 至少1个 + useIndex = useInfo % 10 + if useIndex < 0 or useIndex >= len(itemIDList): + GameWorld.DebugLog("炼器辅助道具索引不存在! useIndex=%s" % (useIndex), playerID) + return + itemID = itemIDList[useIndex] + useLimitDict = IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 2) + limitCnt = useLimitDict.get(str(itemID), 0) + alreadyUsedCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiItemUse % itemID) + if limitCnt > 0 and alreadyUsedCnt >= limitCnt: + GameWorld.DebugLog("炼器单局使用该道具次数已达上限! useIndex=%s,itemID=%s,alreadyUsedCnt=%s >= %s" % (useIndex, itemID, alreadyUsedCnt, limitCnt), playerID) + return + + costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, itemID, useItemCount) + lackCount = max(0, useItemCount - bindCnt - unBindCnt) + if lackCount > 0: + GameWorld.DebugLog("炼器辅助道具不足! useIndex=%s,itemID=%s,lackCount=%s" % (useIndex, itemID, lackCount), playerID) + return + + rA, cA = opValue2 / 10, opValue2 % 10 + rB, cB = opValue3 / 10, opValue3 % 10 + gridDataList = GetGridDataList(curPlayer) + + # 碎天锤,消除任意位置,且不减分 + if useIndex == 0: + lvA = GetGridLV(rA, cA, gridDataList) + if not lvA: + GameWorld.DebugLog("炼器当前格子不存在或为空,无需使用该道具! useIndex=%s,itemID=%s,rA=%s,cA=%s,lvA=%s" % (useIndex, itemID, rA, cA, lvA), playerID) + return + GameWorld.DebugLog("炼器使用消除任意位置道具! useIndex=%s,itemID=%s,rA=%s,cA=%s,lvA=%s" % (useIndex, itemID, rA, cA, lvA), playerID) + PrintGridData(curPlayer, gridDataList, "使用前") + gridDataList[rA][cA] = 0 + SaveGridData(curPlayer, gridDataList) + PrintGridData(curPlayer, gridDataList, "使用后") + + # 造化灵玉,交换任意两个位置 + elif useIndex == 1: + lvA = GetGridLV(rA, cA, gridDataList) + lvB = GetGridLV(rB, cB, gridDataList) + if not lvA or not lvB: + GameWorld.DebugLog("炼器A或B格子不存在或为空,无需使用该道具! useIndex=%s,itemID=%s,rA=%s,cA=%s,lvA=%s,rB=%s,cB=%s,lvB=%s" + % (useIndex, itemID, rA, cA, lvA, rB, cB, lvB), playerID) + return + GameWorld.DebugLog("炼器使用交换任意两个位置道具! useIndex=%s,itemID=%s,rA=%s,cA=%s,lvA=%s,rB=%s,cB=%s,lvB=%s" + % (useIndex, itemID, rA, cA, lvA, rB, cB, lvB), playerID) + PrintGridData(curPlayer, gridDataList, "使用前") + gridDataList[rA][cA] = lvB + gridDataList[rB][cB] = lvA + SaveGridData(curPlayer, gridDataList) + PrintGridData(curPlayer, gridDataList, "使用后") + + # 九天陨铁,将任意1个7阶以下进阶,并获得积分及解锁等级奖励 + elif useIndex == 2: + lvA = GetGridLV(rA, cA, gridDataList) + lvLimit = IpyGameDataPY.GetFuncCfg("LianqiUseItem", 3) + if not lvA or lvA >= lvLimit: + GameWorld.DebugLog("炼器当前格子不满足使用等级,无需使用该道具! useIndex=%s,itemID=%s,rA=%s,cA=%s,lvA=%s,lvLimit=%s" % (useIndex, itemID, rA, cA, lvA, lvLimit), playerID) + return + GameWorld.DebugLog("炼器使用进阶道具! useIndex=%s,itemID=%s,rA=%s,cA=%s,lvA=%s" % (useIndex, itemID, rA, cA, lvA), playerID) + PrintGridData(curPlayer, gridDataList, "使用前") + lvA += 1 + gridDataList[rA][cA] = lvA + SaveGridData(curPlayer, gridDataList) + PrintGridData(curPlayer, gridDataList, "使用后") + addScore = pow(2, lvA) + AddLianqiScore(curPlayer, addScore, lvA) + + # 甘露仙液,体力加15 + elif useIndex == 3: + curEnergy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergy) + energyMax = IpyGameDataPY.GetFuncCfg("LianqiSet", 1) + if curEnergy >= energyMax: + GameWorld.DebugLog("炼器体力已满,无需使用该道具! useIndex=%s,itemID=%s,curEnergy=%s >= %s" % (useIndex, itemID, curEnergy, energyMax), playerID) + return + addEnergy = IpyGameDataPY.GetFuncCfg("LianqiUseItem", 4) * useItemCount + updEnergy = curEnergy + addEnergy + updEnergy = SetLianqiEnergy(curPlayer, updEnergy) + GameWorld.DebugLog("炼器使用体力道具! useIndex=%s,itemID=%s,useItemCount=%s,addEnergy=%s,curEnergy=%s,updEnergy=%s" + % (useIndex, itemID, useItemCount, addEnergy, curEnergy, updEnergy), playerID) + + ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, useItemCount, "Lianqi") + updUseCnt = alreadyUsedCnt + useItemCount + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiItemUse % itemID, updUseCnt) + GameWorld.DebugLog("更新单局道具使用次数: useIndex=%s,itemID=%s,updUseCnt=%s" % (useIndex, itemID, updUseCnt), playerID) + Sync_LianqiPlayerInfo(curPlayer, opType) + return + +def OnProcess(curPlayer): + if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_LianqiID): + return + curEnergy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergy) + energyMax = IpyGameDataPY.GetFuncCfg("LianqiSet", 1) + if curEnergy >= energyMax: + #GameWorld.DebugLog("炼器体力已满,无需恢复! curEnergy=%s >= %s" % (curEnergy, energyMax), curPlayer.GetPlayerID()) + return + needSeconds = IpyGameDataPY.GetFuncCfg("LianqiSet", 2) + if not needSeconds: + return + curTime = int(time.time()) + lastTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergyTime) + if not lastTime: + lastTime = curTime + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergyTime, lastTime) + return + passTime = curTime - lastTime + addEnergy = passTime / needSeconds + if addEnergy <= 0: + return + GameWorld.DebugLog("时间恢复炼器体力: passTime=%s(%s-%s),addEnergy=%s" % (passTime, curTime, lastTime, addEnergy), curPlayer.GetPlayerID()) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergyTime, curTime) + SetLianqiEnergy(curPlayer, min(curEnergy + addEnergy, energyMax)) + Sync_LianqiPlayerInfo(curPlayer) + return + +def SetLianqiEnergy(curPlayer, setEnergy): + ## 设置炼器体力 + # @param byTime: 由时间恢复的,传入的是当前时间戳 + + curEnergy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergy) + updEnergy = min(65000, setEnergy) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergy, updEnergy) + + energyMax = IpyGameDataPY.GetFuncCfg("LianqiSet", 1) + if updEnergy >= energyMax: + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergyTime, 0) + elif curEnergy >= energyMax and updEnergy < energyMax: + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiEnergyTime, int(time.time())) + + return updEnergy + +def AddLianqiScore(curPlayer, addScore, actLV=0): + ## 增加炼器积分 + if addScore <= 0: + return + curScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiScore) + GameWorld.DebugLog("炼器活动积分增加: curScore=%s,addScore=%s,actLV=%s" % (curScore, addScore, actLV), curPlayer.GetPlayerID()) + SetLianqiScore(curPlayer, curScore + addScore, actLV) + PlayerZhanling.AddZhanlingValue(curPlayer, PlayerZhanling.ZhanlingType_Lianqi, addScore) + return + +def SetLianqiScore(curPlayer, setScore, actLV=0): + ## 设置炼器积分 + # @param actLV: 激活的合成等级 + + updBillboard = False + lvHighest = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiLVAwardMax) + if actLV > lvHighest: + lvHighest = actLV + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiLVAwardMax, lvHighest) + updBillboard = True + + updScore = min(setScore, ChConfig.Def_UpperLimit_DWord) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScore, updScore) + + scoreHighest = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiScoreHighest) + if updScore > scoreHighest: + scoreHighest = updScore + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiScoreHighest, scoreHighest) + updBillboard = True + + GameWorld.DebugLog("炼器活动积分更新: updScore=%s,scoreHighest=%s,lvHighest=%s" + % (updScore, scoreHighest, lvHighest), curPlayer.GetPlayerID()) + if updBillboard: + SendToGameServer_Lianqi(curPlayer, "ScoreHighest", [scoreHighest, lvHighest]) + return updScore + +def SendToGameServer_Lianqi(curPlayer, msgType, dataMsg=""): + playerID = curPlayer.GetPlayerID() + msgList = str([msgType, dataMsg]) + GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "ActLianqi", msgList, len(msgList)) + GameWorld.Log("炼器活动发送GameServer: %s, %s" % (msgType, dataMsg), playerID) + return + +def OnGetLVAward(curPlayer, opType, awardLV): + ## 领取炼器等级奖励 + playerID = curPlayer.GetPlayerID() + curAwardLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiLVAwardMax) + if curAwardLV < awardLV: + GameWorld.DebugLog("炼器奖励等级不足! curAwardLV=%s < %s" % (curAwardLV, awardLV), playerID) + return + lvAwardItemDict = IpyGameDataPY.GetFuncEvalCfg("LianqiSet", 3, {}) + if str(awardLV) not in lvAwardItemDict: + return + awardItemList = lvAwardItemDict[str(awardLV)] + awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiLVAwardState) + if awardState&pow(2, awardLV): + GameWorld.DebugLog("炼器奖励等级已领取! awardLV=%s,awardState=%s" % (awardLV, awardState), playerID) + return + ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Lianqi", False, {}]) + updAwardState = awardState|pow(2, awardLV) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianqiLVAwardState, updAwardState) + GameWorld.DebugLog("炼器领取奖励等级! awardLV=%s,awardState=%s,updAwardState=%s,%s" + % (awardLV, awardState, updAwardState, awardItemList), playerID) + Sync_LianqiPlayerInfo(curPlayer, opType) + return + +def Sync_LianqiPlayerInfo(curPlayer, opType=0, moveList=[]): + + if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_LianqiID): + return + + clientPack = ChPyNetSendPack.tagMCActLianqiPlayerInfo() + clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiScore) + clientPack.ScoreHighest = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiScoreHighest) + clientPack.Energy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergy) + clientPack.EnergyTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiEnergyTime) + clientPack.LVAwardMax = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiLVAwardMax) + clientPack.LVAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiLVAwardState) + + clientPack.UseItemCntList = [] + for itemID in IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 1): + clientPack.UseItemCntList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianqiItemUse % itemID)) + clientPack.UseItemLen = len(clientPack.UseItemCntList) + + clientPack.GridData = str(GetGridDataList(curPlayer)).replace(" ", "") + clientPack.GridDataLen = len(clientPack.GridData) + clientPack.MoveList = [] + for moveInfo in moveList: + if not isinstance(moveInfo, list) or len(moveInfo) != 4: + continue + tileMove = ChPyNetSendPack.tagMCActLianqiTileMove() + row, col, toRow, toCol = moveInfo + tileMove.Row = row + tileMove.Col = col + tileMove.ToRow = toRow + tileMove.ToCol = toCol + clientPack.MoveList.append(tileMove) + clientPack.OPType = opType + clientPack.MoveCount = len(clientPack.MoveList) + NetPackCommon.SendFakePack(curPlayer, clientPack) + return + +def Sync_CrossActLianqiActionInfo(curPlayer): + ## 通知活动信息 + actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_Lianqi) + if not actInfo: + return + + if not actInfo.get(ShareDefine.ActKey_State): + return + + ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {}) + if not ipyDataDict: + return + + personalTempID = ipyDataDict.get("PersonalTemplateID", 0) + personalTempIpyDataList = IpyGameDataPY.GetIpyGameDataList("ActLianqiBillTemp", personalTempID) if personalTempID else [] + + clientPack = ChPyNetSendPack.tagMCCrossActLianqiInfo() + clientPack.ServerIDRangeInfo = str(actInfo.get(ShareDefine.ActKey_ServerIDRangeList, [])) + clientPack.ServerInfoLen = len(clientPack.ServerIDRangeInfo) + clientPack.GroupValue1 = ipyDataDict.get("ZoneID", 0) + clientPack.StartDate = ipyDataDict.get("StartDate", "") + clientPack.EndtDate = ipyDataDict.get("EndDate", "") + clientPack.JoinStartTime = ipyDataDict.get("JoinStartTime", "") + clientPack.JoinEndTime = ipyDataDict.get("JoinEndTime", "") + clientPack.LimitLV = ipyDataDict.get("LimitLV", 0) + + clientPack.PersonalBillboardInfoList = __GetTempRankBillPackList(personalTempIpyDataList) + clientPack.PersonalBillCount = len(clientPack.PersonalBillboardInfoList) + + NetPackCommon.SendFakePack(curPlayer, clientPack) + return + +def __GetTempRankBillPackList(ipyDataList): + packBillList = [] + if not ipyDataList: + return packBillList + for tempIpyData in ipyDataList: + rankInfo = ChPyNetSendPack.tagMCCrossActLianqiBillard() + rankInfo.Rank = tempIpyData.GetRank() + + rankInfo.AwardItemList = [] + awardItemList = tempIpyData.GetAwardItemList() + for itemID, itemCount, isAuctionItem in awardItemList: + item = ChPyNetSendPack.tagMCCrossActLianqiItem() + item.Clear() + item.ItemID = itemID + item.ItemCount = itemCount + item.IsBind = isAuctionItem + rankInfo.AwardItemList.append(item) + rankInfo.Count = len(rankInfo.AwardItemList) + rankInfo.NeedScore = tempIpyData.GetNeedScore() + +# rankInfo.AwardItemExList = [] +# scoreAwardEx = tempIpyData.GetScoreAwardEx() +# scoreExList = scoreAwardEx.keys() +# scoreExList.sort() +# for scoreEx in scoreExList: +# itemExList = scoreAwardEx[scoreEx] +# awardEx = ChPyNetSendPack.tagMCActLianqiAwardEx() +# awardEx.NeedScore = scoreEx +# awardEx.AwardItemList = [] +# for itemID, itemCount, isAuctionItem in itemExList: +# item = ChPyNetSendPack.tagMCActLianqiItem() +# item.Clear() +# item.ItemID = itemID +# item.ItemCount = itemCount +# item.IsBind = isAuctionItem +# awardEx.AwardItemList.append(item) +# awardEx.Count = len(awardEx.AwardItemList) +# +# rankInfo.AwardItemExList.append(awardEx) +# rankInfo.CountEx = len(rankInfo.AwardItemExList) + + packBillList.append(rankInfo) + return packBillList diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py index 5f78ef0..01ffe12 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py @@ -84,6 +84,7 @@ import PlayerActXianXiaMJ import PlayerActGubao import PlayerActHorsePetTrain +import PlayerActLianqi import PlayerActGodGift import PlayerActFamilyCTGAssist import PlayerActRechargeRebateGold @@ -1575,6 +1576,9 @@ elif actionName == ShareDefine.CrossActName_HorsePetTrain: PlayerActHorsePetTrain.RefreshCrossActHorsePetTrainInfo() + elif actionName == ShareDefine.CrossActName_Lianqi: + PlayerActLianqi.RefreshCrossActLianqiInfo() + return if key == ShareDefine.Def_Notify_WorldKey_CrossZoneName: diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py index 8c89276..d4cce3b 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py @@ -54,6 +54,7 @@ import FunctionNPCCommon import FormulaControl import PlayerGoldGift +import PlayerActLianqi import PlayerFlashSale import PlayerChatBox import PlayerFace @@ -1297,6 +1298,8 @@ PlayerActivity.ProcessActivityPlace(curPlayer) #自定义场景 FBLogic.OnCustomSceneProcess(curPlayer, tick) + #炼器 + PlayerActLianqi.OnProcess(curPlayer) #跨服数据同步,放最后 CrossPlayerData.ProcessCrossPlayer(curPlayer, tick) return diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerZhanling.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerZhanling.py index 08c32eb..56b6284 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerZhanling.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerZhanling.py @@ -42,7 +42,11 @@ ZhanlingType_GubaoTrain, # 古宝养成 8 ZhanlingType_Xianyuan, # 仙缘 9 ZhanlingType_Huanjingge, # 幻境阁 10 -) = range(1, 1 + 10) +ZhanlingType_Lianqi, # 炼器 11 +) = range(1, 1 + 11) + +# 用Value1记录进度的战令类型 +ZhanlingValue1TypeList = [ZhanlingType_Huanjingge, ZhanlingType_Lianqi] def OnPlayerLogin(curPlayer): for zhanlingType in ZhanlingTypeList: @@ -102,6 +106,9 @@ if zhanlingType == ZhanlingType_Xianyuan: backValue = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_XianyuanScore) PlayerControl.SetMoney(curPlayer, ShareDefine.TYPE_Price_XianyuanScore, 0) + elif zhanlingType in ZhanlingValue1TypeList: + backValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhanlingValue1 % zhanlingType) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ZhanlingValue1 % zhanlingType, 0) GameWorld.Log("重置战令: zhanlingType=%s,backValue=%s,state=(%s to %s) stateH=(%s to %s)" % (zhanlingType, backValue, state, updState, stateH, updStateH), curPlayer.GetPlayerID()) @@ -161,7 +168,7 @@ return def AddZhanlingValue(curPlayer, zhanlingType, addValue=1): - if zhanlingType not in [ZhanlingType_Huanjingge]: + if zhanlingType not in ZhanlingValue1TypeList: return curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhanlingValue1 % zhanlingType) updValue = min(ChConfig.Def_UpperLimit_DWord, curValue + addValue) @@ -172,7 +179,7 @@ return updValue def SetZhanlingValue(curPlayer, zhanlingType, value1): - if zhanlingType not in [ZhanlingType_Huanjingge]: + if zhanlingType not in ZhanlingValue1TypeList: return PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ZhanlingValue1 % zhanlingType, value1) GameWorld.DebugLog("设置战令进度: zhanlingType=%s,value1=%s" % (zhanlingType, value1), curPlayer.GetPlayerID()) @@ -211,7 +218,7 @@ curValue = PlayerActGubao.GetActGubaoTrainScore(curPlayer) elif zhanlingType == ZhanlingType_Xianyuan: curValue = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_XianyuanScore) - elif zhanlingType == ZhanlingType_Huanjingge: + elif zhanlingType == ZhanlingValue1TypeList: curValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhanlingValue1 % zhanlingType) else: return diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py index 366b69a..620f00f 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py @@ -363,10 +363,11 @@ CrossActName_XianXiaMJ = "CrossActXianXiaMJ" # 仙匣秘境 - 跨服 CrossActName_Gubao = "CrossActGubao" # 古宝养成 - 跨服 CrossActName_HorsePetTrain = "CrossActHorsePetTrain" # 骑宠养成 - 跨服 +CrossActName_Lianqi = "CrossActLianqi" # 炼器 - 跨服 #跨服运营活动列表 CrossActNameList = [CrossActName_CTGBillboard, CrossActName_AllRecharge, CrossActName_LuckyCloudBuy, CrossActName_BossTrial, - CrossActName_XianXiaMJ, CrossActName_Gubao, CrossActName_HorsePetTrain] + CrossActName_XianXiaMJ, CrossActName_Gubao, CrossActName_HorsePetTrain, CrossActName_Lianqi] #需要锁定活动分区分配直到活动结束的跨服运营活动,即使热更分区配置,也不会改变正在活动中的分区设定,直到活动结束 CrossActLockServerGroupIDList = [CrossActName_CTGBillboard, CrossActName_AllRecharge] @@ -902,7 +903,8 @@ Def_CBT_GubaoScore, # 古宝养成积分 - 个人榜 163 Def_CBT_HorsePetTrainScore, # 骑宠养成积分 - 个人榜 164 Def_CBT_CrossRealmPK, # 跨服PK竞技场 165 -) = range(150, 165 + 1) +Def_CBT_LianqiScore, # 炼器积分 - 个人榜 166 +) = range(150, 166 + 1) #职业对应战力排行榜类型 JobFightPowerBillboardDict = { @@ -1725,6 +1727,7 @@ ClientServerMsg_GubaoScore = "GubaoScore" # 古宝养成积分 ClientServerMsg_HorsePetTrainScore = "HorsePetTrainScore" # 骑宠养成积分 ClientServerMsg_QueryXiangong = "QueryXiangong" # 查看仙宫仙名录 +ClientServerMsg_LianqiScore = "LianqiScore" # 炼器积分 #跨服广播类型定义 CrossNotify_CrossAct = "CrossAct" -- Gitblit v1.8.0