10367 【越南】【英语】【BT】【砍树】仙盟攻城战-服务端(增加圣泉抽奖;积分总榜增加轮次积分明细记录;优化活动相关榜单排序规则,支持战斗阶段每分钟统计最新积分情况;优化轮次结算汇总信息;轮次支持升降级;)
| | |
| | | dict ScoreAwardEx; //达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...}
|
| | | };
|
| | |
|
| | | //仙盟攻城战圣泉表
|
| | |
|
| | | struct tagCrossActFamilyGCZSQ
|
| | | {
|
| | | DWORD _LayerNum; //层
|
| | | DWORD CostItemID; //消耗抽奖道具ID
|
| | | BYTE CostItemCnt; //消耗抽奖道具个数
|
| | | BYTE GridCnt; //格子数
|
| | | WORD PassRate; //过关万分率
|
| | | list GridWeightItemList; //格子物品权重随机库 [[权重,物品ID,个数], ...]
|
| | | list LayerAwardItemList; //通关该层固定奖励 [[物品ID,个数,是否拍品], ...]
|
| | | list LayerWeightItemList; //通关该层额外随机奖励 [[权重,物品ID,个数], ...]
|
| | | };
|
| | |
|
| | | //仙匣秘境活动时间表
|
| | |
|
| | | struct tagActXianXiaMJ
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 27 仙盟攻城战圣泉抽奖 #tagCMFamilyGCZSQ
|
| | |
|
| | | class tagCMFamilyGCZSQ(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("GridNum", c_ubyte), # 选中格子编号,1~n
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xC1
|
| | | self.SubCmd = 0x27
|
| | | 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 = 0xC1
|
| | | self.SubCmd = 0x27
|
| | | self.GridNum = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMFamilyGCZSQ)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C1 27 仙盟攻城战圣泉抽奖 //tagCMFamilyGCZSQ:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | GridNum:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.GridNum
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMFamilyGCZSQ=tagCMFamilyGCZSQ()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFamilyGCZSQ.Cmd,m_NAtagCMFamilyGCZSQ.SubCmd))] = m_NAtagCMFamilyGCZSQ
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 10 幸运云购购买 #tagCMLuckyCloudBuy
|
| | |
|
| | | class tagCMLuckyCloudBuy(Structure):
|
| | |
| | | GuessTemplateID = 0 #(WORD GuessTemplateID)// 竞猜奖励模版,对应H.活动竞猜表,前端自行读表展示
|
| | | PersonalTemplateID = 0 #(WORD PersonalTemplateID)// 个人伤害排行奖励模版,对应H.活动榜单奖励模版表,前端自行读表展示
|
| | | FamilyTemplateID = 0 #(WORD FamilyTemplateID)// 仙盟积分排行奖励模版,对应H.活动榜单奖励模版表,前端自行读表展示
|
| | | StateError = 0 #(BYTE StateError)// 活动流程状态是否异常,如果不为0代表活动已异常,前端自行决定是不显示活动还是活动页面做提示
|
| | | StateError = 0 #(DWORD StateError)// 活动流程状态是否异常,如果不为0代表活动已异常,前端自行决定是不显示活动还是活动页面做提示
|
| | | FamilyCount = 0 #(BYTE FamilyCount)
|
| | | ActFamilyList = list() #(vector<tagGCFamilyGCZActFamily> ActFamilyList)//本分区参与的仙盟名单
|
| | | data = None
|
| | |
| | | self.GuessTemplateID,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.PersonalTemplateID,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.FamilyTemplateID,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.StateError,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.StateError,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FamilyCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.FamilyCount):
|
| | | temActFamilyList = tagGCFamilyGCZActFamily()
|
| | |
| | | length += 2
|
| | | length += 2
|
| | | length += 2
|
| | | length += 1
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.FamilyCount):
|
| | | length += self.ActFamilyList[i].GetLength()
|
| | |
| | | data = CommFunc.WriteWORD(data, self.GuessTemplateID)
|
| | | data = CommFunc.WriteWORD(data, self.PersonalTemplateID)
|
| | | data = CommFunc.WriteWORD(data, self.FamilyTemplateID)
|
| | | data = CommFunc.WriteBYTE(data, self.StateError)
|
| | | data = CommFunc.WriteDWORD(data, self.StateError)
|
| | | data = CommFunc.WriteBYTE(data, self.FamilyCount)
|
| | | for i in range(self.FamilyCount):
|
| | | data = CommFunc.WriteString(data, self.ActFamilyList[i].GetLength(), self.ActFamilyList[i].GetBuffer())
|
| | |
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCFamilyGCZCampRound(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("RoundNum", c_ubyte), #轮次编号,从1开始
|
| | | ("BatType", c_ubyte), #所在战场类型
|
| | | ("GroupNum", c_ubyte), #所在分组编号
|
| | | ("Rank", c_ubyte), #本轮排名
|
| | | ("Score", c_ushort), #本轮积分,总积分为所有轮次累加
|
| | | ("UpdownState", c_ubyte), #本轮结算晋级降级状态:0-未处理,1-降级;2-保级;3-晋级,即本轮的晋降级状态决定下一轮的战场类型
|
| | | ]
|
| | |
|
| | | 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.RoundNum = 0
|
| | | self.BatType = 0
|
| | | self.GroupNum = 0
|
| | | self.Rank = 0
|
| | | self.Score = 0
|
| | | self.UpdownState = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagGCFamilyGCZCampRound)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C0 26 仙盟攻城战大本营信息 //tagGCFamilyGCZCampInfo:
|
| | | RoundNum:%d,
|
| | | BatType:%d,
|
| | | GroupNum:%d,
|
| | | Rank:%d,
|
| | | Score:%d,
|
| | | UpdownState:%d
|
| | | '''\
|
| | | %(
|
| | | self.RoundNum,
|
| | | self.BatType,
|
| | | self.GroupNum,
|
| | | self.Rank,
|
| | | self.Score,
|
| | | self.UpdownState
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCFamilyGCZCampInfo(Structure):
|
| | | Head = tagHead()
|
| | | FamilyID = 0 #(DWORD FamilyID)//所在活动仙盟ID,可能不是玩家当前的仙盟ID,活动以该ID为准
|
| | | Score = 0 #(WORD Score)//活动总积分,如果不在榜上则读该值
|
| | | CampLV = 0 #(WORD CampLV)//大本营当前等级
|
| | | CampExp = 0 #(DWORD CampExp)//大本营当前经验
|
| | | CityLV = 0 #(WORD CityLV)//城池属性等级,开战后可能与当前大本营等级不一样
|
| | |
| | | HPMaxEx = 0 #(DWORD HPMaxEx)//总大生命,整除亿部分
|
| | | HP = 0 #(DWORD HP)//剩余生命,求余亿部分
|
| | | HPEx = 0 #(DWORD HPEx)//剩余生命,整除亿部分
|
| | | RoundCnt = 0 #(BYTE RoundCnt)
|
| | | RoundInfoList = list() #(vector<tagGCFamilyGCZCampRound> RoundInfoList)//仙盟轮次汇总信息
|
| | | DefMemCnt = 0 #(BYTE DefMemCnt)
|
| | | DefMemList = list() #(vector<tagGCFamilyGCZCampMem> DefMemList)//防守成员列表,有同步则差异更新,没有在防守成员里的视为没有参与资格
|
| | | data = None
|
| | |
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Score,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.CampLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.CampExp,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CityLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | |
| | | self.HPMaxEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.HP,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.HPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.RoundCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.RoundCnt):
|
| | | temRoundInfoList = tagGCFamilyGCZCampRound()
|
| | | _pos = temRoundInfoList.ReadData(_lpData, _pos)
|
| | | self.RoundInfoList.append(temRoundInfoList)
|
| | | self.DefMemCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.DefMemCnt):
|
| | | temDefMemList = tagGCFamilyGCZCampMem()
|
| | |
| | | self.Head.Cmd = 0xC0
|
| | | self.Head.SubCmd = 0x26
|
| | | self.FamilyID = 0
|
| | | self.Score = 0
|
| | | self.CampLV = 0
|
| | | self.CampExp = 0
|
| | | self.CityLV = 0
|
| | |
| | | self.HPMaxEx = 0
|
| | | self.HP = 0
|
| | | self.HPEx = 0
|
| | | self.RoundCnt = 0
|
| | | self.RoundInfoList = list()
|
| | | self.DefMemCnt = 0
|
| | | self.DefMemList = list()
|
| | | return
|
| | |
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 4
|
| | | length += 2
|
| | | length += 2
|
| | | length += 4
|
| | | length += 2
|
| | |
| | | length += 4
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.RoundCnt):
|
| | | length += self.RoundInfoList[i].GetLength()
|
| | | length += 1
|
| | | for i in range(self.DefMemCnt):
|
| | | length += self.DefMemList[i].GetLength()
|
| | |
|
| | |
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteDWORD(data, self.FamilyID)
|
| | | data = CommFunc.WriteWORD(data, self.Score)
|
| | | data = CommFunc.WriteWORD(data, self.CampLV)
|
| | | data = CommFunc.WriteDWORD(data, self.CampExp)
|
| | | data = CommFunc.WriteWORD(data, self.CityLV)
|
| | |
| | | data = CommFunc.WriteDWORD(data, self.HPMaxEx)
|
| | | data = CommFunc.WriteDWORD(data, self.HP)
|
| | | data = CommFunc.WriteDWORD(data, self.HPEx)
|
| | | data = CommFunc.WriteBYTE(data, self.RoundCnt)
|
| | | for i in range(self.RoundCnt):
|
| | | data = CommFunc.WriteString(data, self.RoundInfoList[i].GetLength(), self.RoundInfoList[i].GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.DefMemCnt)
|
| | | for i in range(self.DefMemCnt):
|
| | | data = CommFunc.WriteString(data, self.DefMemList[i].GetLength(), self.DefMemList[i].GetBuffer())
|
| | |
| | | DumpString = '''
|
| | | Head:%s,
|
| | | FamilyID:%d,
|
| | | Score:%d,
|
| | | CampLV:%d,
|
| | | CampExp:%d,
|
| | | CityLV:%d,
|
| | |
| | | HPMaxEx:%d,
|
| | | HP:%d,
|
| | | HPEx:%d,
|
| | | RoundCnt:%d,
|
| | | RoundInfoList:%s,
|
| | | DefMemCnt:%d,
|
| | | DefMemList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.FamilyID,
|
| | | self.Score,
|
| | | self.CampLV,
|
| | | self.CampExp,
|
| | | self.CityLV,
|
| | |
| | | self.HPMaxEx,
|
| | | self.HP,
|
| | | self.HPEx,
|
| | | self.RoundCnt,
|
| | | "...",
|
| | | self.DefMemCnt,
|
| | | "..."
|
| | | )
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 11 仙盟攻城战圣泉信息 #tagMCFamilyGCZSQInfo
|
| | |
|
| | | class tagMCFamilyGCZSQGrid(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("GridNum", c_ubyte), # 格子编号,1~n |
| | | ("ItemID", c_int), # 抽中的物品ID,20亿时为过关标记
|
| | | ("ItemCount", c_ushort), # 物品数量
|
| | | ]
|
| | |
|
| | | 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.GridNum = 0
|
| | | self.ItemID = 0
|
| | | self.ItemCount = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCFamilyGCZSQGrid)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C1 11 仙盟攻城战圣泉信息 //tagMCFamilyGCZSQInfo:
|
| | | GridNum:%d,
|
| | | ItemID:%d,
|
| | | ItemCount:%d
|
| | | '''\
|
| | | %(
|
| | | self.GridNum,
|
| | | self.ItemID,
|
| | | self.ItemCount
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCFamilyGCZSQInfo(Structure):
|
| | | Head = tagHead()
|
| | | SQLayer = 0 #(BYTE SQLayer)// 当前所在圣泉层,从1开始
|
| | | SQGirdCnt = 0 #(BYTE SQGirdCnt)
|
| | | SQGridList = list() #(vector<tagMCFamilyGCZSQGrid> SQGridList)//圣泉当前层已抽格子信息,仅同步全部或变更的格子,前端进行差异更新,层数变更时重置本地记录
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xC1
|
| | | self.Head.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.SQLayer,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.SQGirdCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.SQGirdCnt):
|
| | | temSQGridList = tagMCFamilyGCZSQGrid()
|
| | | _pos = temSQGridList.ReadData(_lpData, _pos)
|
| | | self.SQGridList.append(temSQGridList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xC1
|
| | | self.Head.SubCmd = 0x11
|
| | | self.SQLayer = 0
|
| | | self.SQGirdCnt = 0
|
| | | self.SQGridList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.SQGirdCnt):
|
| | | length += self.SQGridList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.SQLayer)
|
| | | data = CommFunc.WriteBYTE(data, self.SQGirdCnt)
|
| | | for i in range(self.SQGirdCnt):
|
| | | data = CommFunc.WriteString(data, self.SQGridList[i].GetLength(), self.SQGridList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | SQLayer:%d,
|
| | | SQGirdCnt:%d,
|
| | | SQGridList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.SQLayer,
|
| | | self.SQGirdCnt,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCFamilyGCZSQInfo=tagMCFamilyGCZSQInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFamilyGCZSQInfo.Head.Cmd,m_NAtagMCFamilyGCZSQInfo.Head.SubCmd))] = m_NAtagMCFamilyGCZSQInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 08 幸运云购玩家信息 #tagMCLuckyCloudBuyPlayerInfo
|
| | |
|
| | | class tagMCLuckyCloudBuyPlayerInfo(Structure):
|
| | |
| | |
|
| | | import operator
|
| | | import time
|
| | | import json
|
| | |
|
| | | class CrossBillboardManager(object):
|
| | | ## 跨服排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
|
| | |
| | | billboardData.Value6 = kwargs.get("value6", 0)
|
| | | billboardData.Value7 = kwargs.get("value7", 0)
|
| | | billboardData.Value8 = kwargs.get("value8", 0)
|
| | | billboardData.UserData = kwargs.get("userData", "") |
| | | userData = kwargs.get("userData", "")
|
| | | if userData and not isinstance(userData, str):
|
| | | if isinstance(userData, dict) or isinstance(userData, list):
|
| | | userData = json.dumps(userData, ensure_ascii=False)
|
| | | userData = userData.replace(" ", "")
|
| | | billboardData.UserData = userData |
| | | billboardData.DataLen = len(billboardData.UserData)
|
| | | billboardData.CmpValue = cmpValue
|
| | | billboardData.CmpValue2 = cmpValue2
|
| | |
| | | import time
|
| | |
|
| | |
|
| | | ## 1-公示期;99-领奖期;轮次状态=轮次*10+轮次阶段;轮次阶段:1-分组战备;2-战斗;3-休战结算
|
| | | ## 1-公示期;99-领奖期;轮次状态=轮次*10+轮次阶段;轮次阶段:1-分组战备;2-战斗;3-休战
|
| | | FamilyGCZState_Publicity = 1 # 公示期
|
| | | FamilyGCZState_Award = 99 # 结束领奖期
|
| | |
|
| | | # 轮次状态信息
|
| | | FamilyGCZRoundState_Group = 1 # 分组+战备
|
| | | FamilyGCZRoundState_Fight = 2 # 战斗
|
| | | FamilyGCZRoundState_Over = 3 # 休战结算
|
| | | FamilyGCZRoundState_Over = 3 # 休战,该阶段可有可无,由策划配置决定,程序结算逻辑不依赖与此状态
|
| | |
|
| | | # 战场类型
|
| | | BatTypeList = (
|
| | |
| | | BatType_Middle, # 中级 2
|
| | | BatType_High, # 高级 3
|
| | | ) = range(1, 1 + 3)
|
| | |
|
| | | BatType_Min = BatType_Junior
|
| | | BatType_Max = BatType_High
|
| | |
|
| | | # 晋降级类型
|
| | | (
|
| | | UpdownState_None, # 未处理 0
|
| | | UpdownState_Down, # 降级 1
|
| | | UpdownState_Keep, # 保级 2
|
| | | UpdownState_Up, # 晋级 3
|
| | | ) = range(4)
|
| | |
|
| | | # 每组固定仙盟数
|
| | | Def_PerGroupFamilyCnt = 12
|
| | |
|
| | | # 攻击类型
|
| | | (
|
| | |
| | | self.groupNum = 0
|
| | | self.campLV = 1 # 大本营等级
|
| | | self.campExp = 0
|
| | | self.score = 0 # 活动总积分
|
| | | self.roundInfoDict = {} # 仙盟轮次信息汇总 {轮次:{k:v, ...}, ...} k-batType,groupNum,rank,score,updownState
|
| | | self.sortWeight = 0 # 榜单比较权值,用于平分或伤害相同时的比较权值
|
| | |
|
| | | self.familyName = ""
|
| | | self.lv = 0
|
| | |
| | | if isNotify:
|
| | | Sync_FamilyGCZCampInfo(self.zoneID, self.familyID)
|
| | | return isOK
|
| | | |
| | | def GetTotalScore(self):
|
| | | ## 获取仙盟当前总积分,所有轮次积分的总和
|
| | | totalScore = 0
|
| | | for info in self.roundInfoDict.values():
|
| | | totalScore += info.get("score", 0)
|
| | | return totalScore
|
| | |
|
| | | def AddCampExp(self, playerID, addCampExp, isNotify=True):
|
| | | ## 大本营加经验
|
| | |
| | | self.joinFamilyDict = {} # 参与仙盟对象信息 {familyID:FamilyGCZFamily, ...}
|
| | | self.joinMemberDict = {} # 参与玩家对象信息 {playerID:FamilyGCZMember, ...}
|
| | | self.roundGroupDict = {} # 当前轮次分组信息 {batType:{groupNum:FamilyGCZBatGroup, ...}, ...}
|
| | | self.roundNum = 0 # roundGroupDict 数据对应的轮次
|
| | | self.roundOver = 0 # roundNum轮次是否已结算了
|
| | | self.familyGuessDict = {} # 仙盟竞猜热度信息 {familyID:value, ...}
|
| | | self.playerGuessDict = {} # 玩家竞猜记录 {playerID:[familyID, ...], ...}
|
| | |
|
| | |
| | | self.inBatCityPlayerIDDict = {} # 在战斗城池中的玩家ID {(batType, groupNum, cityID):[playerID, ...], ...}
|
| | | return
|
| | |
|
| | | def OnRoundReset(self):
|
| | | def OnRoundReset(self, roundNum):
|
| | | ## 分区轮次重置
|
| | | self.roundNum = roundNum
|
| | | self.roundOver = 0
|
| | | self.roundGroupDict = {}
|
| | | self.inBatScenePlayerIDDict = {}
|
| | | self.inBatCityPlayerIDDict = {}
|
| | |
| | | zone.lockFamilyIDList = zoneDataDict.get("lockFamilyIDList", [])
|
| | | zone.familyGuessDict = zoneDataDict.get("familyGuessDict", {})
|
| | | zone.playerGuessDict = zoneDataDict.get("playerGuessDict", {})
|
| | | zone.roundNum = zoneDataDict.get("roundNum", 0)
|
| | | zone.roundOver = zoneDataDict.get("roundOver", 0)
|
| | | GameWorld.Log("加载分区记录! zoneID=%s,joinFamilyCnt=%s,lockCnt=%s,%s" % (zoneID, zone.joinFamilyCnt, len(zone.lockFamilyIDList), zone.lockFamilyIDList))
|
| | |
|
| | | familyRecList = gameRecMgr.GetGameRecDataList(ShareDefine.Def_GameRecType_FamilyGCZJoinFamily, zoneID)
|
| | |
| | | groupNum = familyRecData.GetValue3()
|
| | | campLV = familyRecData.GetValue4()
|
| | | campExp = familyRecData.GetValue5()
|
| | | score = familyRecData.GetValue6()
|
| | | familyDataDict = familyRecData.GetUserDataDict()
|
| | |
|
| | | joinFamily = zone.AddZoneJoinFamily(familyID)
|
| | |
| | | joinFamily.groupNum = groupNum
|
| | | joinFamily.campLV = campLV
|
| | | joinFamily.campExp = campExp
|
| | | joinFamily.score = score
|
| | | joinFamily.familyName = familyDataDict.get("familyName", "")
|
| | | joinFamily.leaderID = familyDataDict.get("leaderID", 0)
|
| | | joinFamily.leaderName = familyDataDict.get("leaderName", "")
|
| | |
| | | joinFamily.fightPowerTotal = familyDataDict.get("fightPowerTotal", 0)
|
| | | joinFamily.joinMemberIDList = familyDataDict.get("joinMemberIDList", [])
|
| | | joinFamily.memAddCampExpInfo = familyDataDict.get("memAddCampExpInfo", {})
|
| | | joinFamily.roundInfoDict = familyDataDict.get("roundInfoDict", {})
|
| | | joinFamily.sortWeight = familyDataDict.get("sortWeight", 0)
|
| | |
|
| | | GameWorld.Log(" 加载分区仙盟 zoneID=%s,%s,familyID=%s,campLV=%s-%s,score=%s,,memAddCampExpInfo=%s" |
| | | % (zoneID, fNum, familyID, joinFamily.campLV, joinFamily.campExp, joinFamily.score, joinFamily.memAddCampExpInfo))
|
| | | GameWorld.Log(" 加载分区仙盟 zoneID=%s,%s,familyID=%s,campLV=%s-%s,roundInfoDict=%s" |
| | | % (zoneID, fNum, familyID, joinFamily.campLV, joinFamily.campExp, joinFamily.roundInfoDict))
|
| | |
|
| | | memberRecList = gameRecMgr.GetGameRecDataList(ShareDefine.Def_GameRecType_FamilyGCZJoinMember, zoneID)
|
| | | for pNum, memberRecData in enumerate(memberRecList, 1):
|
| | |
| | | zoneRecData = gameRecMgr.AddGameRecData(ShareDefine.Def_GameRecType_FamilyGCZMgr, zoneID)
|
| | | zoneRecData.SetValue1(zone.joinFamilyCnt)
|
| | | lockFamilyIDList = zone.GetZoneLockFamilyIDList()
|
| | | zoneData = {"lockFamilyIDList":lockFamilyIDList, "familyGuessDict":zone.familyGuessDict, "playerGuessDict":zone.playerGuessDict}
|
| | | zoneData = {"lockFamilyIDList":lockFamilyIDList, "familyGuessDict":zone.familyGuessDict, "playerGuessDict":zone.playerGuessDict, |
| | | "roundNum":zone.roundNum, "roundOver":zone.roundOver}
|
| | | zoneRecData.SetUserData(zoneData)
|
| | |
|
| | | GameWorld.Log("----- zoneID=%s,joinFamilyCnt=%s,lockFamilyIDList=%s,%s" % (zoneID, zone.joinFamilyCnt, len(lockFamilyIDList), lockFamilyIDList))
|
| | |
| | | familyRecData.SetValue3(joinFamily.groupNum)
|
| | | familyRecData.SetValue4(joinFamily.campLV)
|
| | | familyRecData.SetValue5(joinFamily.campExp)
|
| | | familyRecData.SetValue6(joinFamily.score)
|
| | |
|
| | | familyData = {"familyName":joinFamily.familyName, "leaderID":joinFamily.leaderID, "leaderName":joinFamily.leaderName,
|
| | | "lv":joinFamily.lv, "emblemID":joinFamily.emblemID, "serverID":joinFamily.serverID, "fightPowerTotal":joinFamily.fightPowerTotal,
|
| | | "joinMemberIDList":joinFamily.joinMemberIDList, "memAddCampExpInfo":joinFamily.memAddCampExpInfo
|
| | | "joinMemberIDList":joinFamily.joinMemberIDList, "memAddCampExpInfo":joinFamily.memAddCampExpInfo, |
| | | "roundInfoDict":joinFamily.roundInfoDict, "sortWeight":joinFamily.sortWeight
|
| | | }
|
| | | familyRecData.SetUserData(familyData)
|
| | | GameWorld.Log(" 保存分区仙盟 zoneID=%s,%s,familyID=%s,campLV=%s-%s,score=%s," % (zoneID, fNum, familyID, joinFamily.campLV, joinFamily.campExp, joinFamily.score))
|
| | | GameWorld.Log(" 保存分区仙盟 zoneID=%s,%s,familyID=%s,campLV=%s-%s,roundInfoDict=%s" % (zoneID, fNum, familyID, joinFamily.campLV, joinFamily.campExp, joinFamily.roundInfoDict))
|
| | |
|
| | | for pNum, playerID in enumerate(joinFamily.joinMemberIDList, 1):
|
| | | joinMember = zone.GetZoneJoinMember(playerID)
|
| | |
| | | zone = gczMgr.GetActZone(zoneID)
|
| | | zone.OnRoundFightStart()
|
| | |
|
| | | # 结算
|
| | | # 结算,注:程序的结算流程不依赖与此状态,如果策划有配置,则直接在该阶段结算,如果没有配置则在分组时、活动领奖时之前校验上一轮结算
|
| | | elif roundState == FamilyGCZRoundState_Over:
|
| | | DoRoundOver(curRound, zoneID)
|
| | | DoRoundOver(zoneID)
|
| | |
|
| | | else:
|
| | | pass
|
| | |
| | | ## 执行轮次分组
|
| | |
|
| | | GameWorld.Log("========== 仙盟攻城战轮次分组: zoneID=%s,curRound=%s,joinFamilyCnt=%s" % (zoneID, curRound, joinFamilyCnt))
|
| | | # 参与仙盟数对应分组及晋级规则 {参与仙盟数:{轮次:{战场类型:[组数, 前x名晋级, x名开始降级], ...}, ...}, ...}
|
| | | DoRoundOver(zoneID)
|
| | | # 参与仙盟数对应分组及晋级规则 {参与仙盟数:{轮次:{战场类型:[组数, 前x名晋级, 后x名降级], ...}, ...}, ...}
|
| | | FamilyGCZGroupSet = IpyGameDataPY.GetFuncEvalCfg("FamilyGCZGroupSet", 1, {})
|
| | | if joinFamilyCnt not in FamilyGCZGroupSet:
|
| | | return
|
| | |
| | | batTypeDict = roundSetDict[curRound]
|
| | |
|
| | | groupValue1 = zoneID
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | gczMgr = GetFamilyGCZMgr()
|
| | | zone = gczMgr.GetActZone(zoneID)
|
| | | |
| | | # 先处理上一轮晋级、保级、降级,需在重置前处理
|
| | | nextBatTypeFamilyInfo = {} # 下一轮战场仙盟ID分配信息 {batType:[familyID, ...], ....}
|
| | | preRound = curRound - 1
|
| | | preBatTypeDict = roundSetDict.get(preRound, {})
|
| | | for batType in BatTypeList: # 按战场类型顺序遍历处理
|
| | | if batType not in zone.roundGroupDict:
|
| | | continue
|
| | | groupDict = zone.roundGroupDict[batType]
|
| | | groupNumList = groupDict.keys()
|
| | | groupNumList.sort()
|
| | | preRoundSet = preBatTypeDict.get(batType, [0, 0])
|
| | | upRank = preRoundSet[1] # 前x晋级
|
| | | downRank = preRoundSet[2] if len(preRoundSet) > 2 else 0 # 大于等于x名降级,为0时不降级
|
| | | GameWorld.Log("上轮战场类型分组: preRound=%s,batType=%s,upRank=%s,downRank=%s,%s" % (preRound, batType, upRank, downRank, groupNumList))
|
| | | for groupNum in groupNumList:
|
| | | groupValue2 = GetRoundHurtGroupID(batType, groupNum)
|
| | | billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZRoundHurt, groupValue1, groupValue2)
|
| | | billboardObj.SortData()
|
| | | upFamilyIDList, keepFamilyIDList, downFamilyIDList = [], [], []
|
| | | for bIndex in range(billboardObj.GetCount()):
|
| | | billData = billboardObj.At(bIndex)
|
| | | familyID = billData.ID
|
| | | rank = bIndex + 1
|
| | | if rank <= upRank:
|
| | | nextBatType = min(BatType_High, batType + 1)
|
| | | upFamilyIDList.append(familyID)
|
| | | elif downRank and rank >= downRank:
|
| | | nextBatType = max(BatType_Junior, batType - 1)
|
| | | downFamilyIDList.append(familyID)
|
| | | # 除了升降级的就是保级
|
| | | else:
|
| | | nextBatType = batType
|
| | | keepFamilyIDList.append(familyID)
|
| | | |
| | | if nextBatType not in nextBatTypeFamilyInfo:
|
| | | nextBatTypeFamilyInfo[nextBatType] = []
|
| | | familyIDList = nextBatTypeFamilyInfo[nextBatType]
|
| | | if familyID not in familyIDList:
|
| | | familyIDList.append(familyID)
|
| | | GameWorld.Log(" 升保降级zoneID=%s,batType=%s,groupNum=%s,up:%s,keep:%s,down:%s,%s" |
| | | % (zoneID, batType, groupNum, upFamilyIDList, keepFamilyIDList, downFamilyIDList, nextBatTypeFamilyInfo))
|
| | | |
| | | |
| | | #汇总上一轮升降级明细
|
| | | nextBatTypeFamilyInfo = {} # 根据上一轮结算的升降级状态汇总出的本轮仙盟ID战场归组
|
| | | if curRound > 1:
|
| | | preRound = curRound - 1
|
| | | lockFamilyIDList = zone.GetZoneLockFamilyIDList()
|
| | | for familyID in lockFamilyIDList:
|
| | | joinFamily = zone.GetZoneJoinFamily(familyID)
|
| | | if not joinFamily:
|
| | | continue
|
| | | roundInfo = joinFamily.roundInfoDict.get(preRound, {})
|
| | | batType = roundInfo.get("batType", BatType_Min) # 默认最低级
|
| | | updownState = roundInfo.get("updownState", UpdownState_Keep) # 默认保级
|
| | | if updownState == UpdownState_Up:
|
| | | nextBatType = min(batType + 1, BatType_Max)
|
| | | elif updownState == UpdownState_Down:
|
| | | nextBatType = max(batType - 1, BatType_Min)
|
| | | else:
|
| | | nextBatType = batType
|
| | | if nextBatType not in nextBatTypeFamilyInfo:
|
| | | nextBatTypeFamilyInfo[nextBatType] = []
|
| | | batFamilyIDList = nextBatTypeFamilyInfo[nextBatType]
|
| | | if familyID not in batFamilyIDList:
|
| | | batFamilyIDList.append(familyID)
|
| | | GameWorld.Log("上一轮升降级结算汇总: %s" % nextBatTypeFamilyInfo)
|
| | | |
| | | #每轮重新分组时,重置该分区下的轮次伤害相关榜单
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardMgr.ClearBillboard(ShareDefine.Def_CBT_FamilyGCZRoundHurt, groupValue1)
|
| | | zone.OnRoundReset()
|
| | | zone.OnRoundReset(curRound)
|
| | |
|
| | | for batType in BatTypeList: # 按战场类型顺序遍历处理
|
| | | if batType not in batTypeDict:
|
| | |
| | | if not joinFamily:
|
| | | continue
|
| | | groupFamilySortList.append(joinFamily)
|
| | | groupFamilyDict[familyID] = [joinFamily.fightPowerTotal, joinFamily.score]
|
| | | groupFamilyDict[familyID] = [joinFamily.fightPowerTotal, joinFamily.GetTotalScore()]
|
| | |
|
| | | # 先按总战力倒序,可扩展积分等
|
| | | groupFamilySortList.sort(key=lambda f: (f.fightPowerTotal, f.score), reverse=True)
|
| | | groupFamilySortList.sort(key=lambda f: (f.fightPowerTotal, f.GetTotalScore()), reverse=True)
|
| | | groupFamilyIDSortList = [f.familyID for f in groupFamilySortList]
|
| | | |
| | | GameWorld.Log("开始分组按排序后的顺序循环插入每组! 仙盟数:%s, %s, %s" % (len(groupFamilyIDSortList), groupFamilyIDSortList, groupFamilyDict))
|
| | | groupFamilyIDCnt = len(groupFamilyIDSortList)
|
| | | GameWorld.Log("开始分组按排序后的顺序循环插入每组! 仙盟数:%s, %s, %s" % (groupFamilyIDCnt, groupFamilyIDSortList, groupFamilyDict))
|
| | |
|
| | | groupNum = 0
|
| | | for familyID in groupFamilyIDSortList:
|
| | | for index, familyID in enumerate(groupFamilyIDSortList):
|
| | | groupNum += 1
|
| | | if groupNum > groupCnt:
|
| | | groupNum = 1
|
| | |
| | | if not joinFamily:
|
| | | GameWorld.ErrLog("仙盟分配到战斗分组失败! zoneID=%s,batType=%s,groupNum=%s,familyID=%s" % (zoneID, batType, groupNum, familyID))
|
| | | continue
|
| | | joinFamily.sortWeight = batType * 10000 + (100 - groupNum) * 100 + (groupFamilyIDCnt - index)
|
| | | UndFamilyRoundHurtBillboard(joinFamily)
|
| | | GameWorld.Log(" 仙盟ID分组: zoneID=%s,curRound=%s,batType=%s,groupNum=%s,familyID=%s,%s" % (zoneID, curRound, batType, groupNum, familyID, groupFamilyDict[familyID]))
|
| | |
|
| | | Sync_FamilyGCZBatGroupInfo(zoneID)
|
| | | RefreshFamilyGCZBillboard(zoneID, True) # 分组完毕后,有新轮次数据了,强制刷新一次榜单,更新新一轮的积分
|
| | | return
|
| | |
|
| | | def UndFamilyRoundHurtBillboard(joinFamily):
|
| | |
| | | roundTotalHurt = sum(joinFamily.cityWall.fighterHurtDict.values())
|
| | | cmpValue = roundTotalHurt / ChConfig.Def_PerPointValue
|
| | | cmpValue2 = roundTotalHurt % ChConfig.Def_PerPointValue
|
| | | cmpValue3 = joinFamily.sortWeight
|
| | | CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_FamilyGCZRoundHurt, groupValue1, dataID, name1, name2, type2, value1, value2,
|
| | | cmpValue, cmpValue2, groupValue2=groupValue2, id2=id2, autoSort=True, value3=value3, value5=value5)
|
| | | cmpValue, cmpValue2, cmpValue3, groupValue2=groupValue2, id2=id2, autoSort=True, value3=value3, value5=value5)
|
| | | return
|
| | |
|
| | | def DoRoundOver(curRound, zoneID):
|
| | | ## 执行轮次结算
|
| | | def OnMinuteProcess(curMinute):
|
| | | ## 每分钟处理
|
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | gczMgr = GetFamilyGCZMgr()
|
| | | zoneIDList = gczMgr.zoneDict.keys()
|
| | | if not zoneIDList:
|
| | | return
|
| | | |
| | | for zoneID in zoneIDList:
|
| | | if not zoneID:
|
| | | continue
|
| | | RefreshFamilyGCZBillboard(zoneID)
|
| | | |
| | | return
|
| | |
|
| | | def RefreshFamilyGCZBillboard(zoneID, force=False):
|
| | | ## 刷新并排序当前活动相关榜单
|
| | | |
| | | # 非强制刷新的,仅战斗阶段定时刷新
|
| | | if not force:
|
| | | actInfo = CrossActionControl.GetCrossActInfoByZoneID(ShareDefine.CrossActName_FamilyGCZ, zoneID)
|
| | | if not actInfo:
|
| | | return
|
| | | state = actInfo.get(ShareDefine.ActKey_State)
|
| | | if not state:
|
| | | return
|
| | | curRound, roundState = GetRoundState(state)
|
| | | # 仅轮次战斗阶段需要定时刷新
|
| | | if not curRound or roundState != FamilyGCZRoundState_Fight:
|
| | | return
|
| | | |
| | | gczMgr = GetFamilyGCZMgr()
|
| | | zone = gczMgr.GetActZone(zoneID)
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | batTypeScoreInfo = IpyGameDataPY.GetFuncEvalCfg("FamilyGCZGroupSet", 2, {})
|
| | | GameWorld.Log("========== 仙盟攻城战轮次结算: zoneID=%s,curRound=%s" % (zoneID, curRound))
|
| | | if zone.roundOver:
|
| | | # 轮次数据已经结算过了,不需要再处理
|
| | | return
|
| | | roundNum = zone.roundNum
|
| | | if not roundNum:
|
| | | return
|
| | | GameWorld.DebugLog("仙盟攻城战榜单排序! zoneID=%s,roundNum=%s,force=%s" % (zoneID, roundNum, force))
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager() |
| | | playerHurtBillObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZPlayerHurt, zoneID)
|
| | | playerHurtBillObj.SortData()
|
| | | |
| | | batTypeScoreInfo = IpyGameDataPY.GetFuncEvalCfg("FamilyGCZGroupSet", 2, {}) # 不同战场类型仙盟排名对应积分 {"战场类型":{"名次":积分, ...}, ...}
|
| | | for batType, groupDict in zone.roundGroupDict.items():
|
| | | rankScoreInfo = batTypeScoreInfo.get(str(batType), {})
|
| | | if not rankScoreInfo:
|
| | | GameWorld.ErrLog("仙盟攻城战战场类型没有配置名次积分! batType=%s" % batType)
|
| | | rankScoreDict = {int(k):v for k, v in rankScoreInfo.items()}
|
| | | groupNumList = groupDict.keys()
|
| | | GameWorld.Log("zoneID=%s,batType=%s,groupCnt=%s,rankScoreDict=%s" % (zoneID, batType, len(groupNumList), rankScoreDict))
|
| | | for groupNum in groupNumList:
|
| | | batGroup = zone.GetBatGroup(batType, groupNum)
|
| | | if not batGroup:
|
| | | continue
|
| | | groupValue2 = GetRoundHurtGroupID(batType, groupNum)
|
| | | roundBillboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZRoundHurt, zoneID, groupValue2)
|
| | | roundBillboardObj.SortData()
|
| | | for bIndex in range(roundBillboardObj.GetCount()):
|
| | | billData = roundBillboardObj.At(bIndex)
|
| | | familyID = billData.ID
|
| | | rank = bIndex + 1
|
| | | score = GameWorld.GetOrderValueByDict(rankScoreDict, rank, False, 0)
|
| | | joinFamily = zone.GetZoneJoinFamily(familyID)
|
| | | if not joinFamily:
|
| | | continue
|
| | | roundInfo = joinFamily.roundInfoDict.get(roundNum, {})
|
| | | roundInfo.update({"batType":batType, "groupNum":groupNum, "rank":rank, "score":score})
|
| | | joinFamily.roundInfoDict[roundNum] = roundInfo
|
| | | |
| | | lockFamilyIDList = zone.GetZoneLockFamilyIDList()
|
| | | for familyID in lockFamilyIDList:
|
| | | joinFamily = zone.GetZoneJoinFamily(familyID)
|
| | | if not joinFamily:
|
| | | continue
|
| | | dataID = joinFamily.familyID
|
| | | name1 = joinFamily.familyName
|
| | | id2 = joinFamily.leaderID
|
| | | name2 = joinFamily.leaderName
|
| | | type2, value1, value2 = 0, 0, 0
|
| | | value3 = joinFamily.emblemID
|
| | | value5 = joinFamily.serverID
|
| | | cmpValue = joinFamily.GetTotalScore()
|
| | | cmpValue2 = joinFamily.sortWeight
|
| | | CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_FamilyGCZScore, zoneID, dataID, name1, name2, type2, value1, value2,
|
| | | cmpValue, cmpValue2=cmpValue2, id2=id2, autoSort=False, value3=value3, value5=value5, userData=joinFamily.roundInfoDict)
|
| | | |
| | | familyScoreBillObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZScore, zoneID)
|
| | | familyScoreBillObj.SortData()
|
| | | return
|
| | |
|
| | | def DoRoundOver(zoneID):
|
| | | ## 执行轮次结算,这里可以不用管是第几轮,对于结算来说只对当前的轮次数据做结算
|
| | | gczMgr = GetFamilyGCZMgr()
|
| | | zone = gczMgr.GetActZone(zoneID)
|
| | | if zone.roundOver:
|
| | | # 已经结算过了,不重复结算
|
| | | return
|
| | | roundNum = zone.roundNum
|
| | | if not roundNum:
|
| | | # 还没有轮次不处理
|
| | | return
|
| | | RefreshFamilyGCZBillboard(zoneID, True) # 强制刷新一次榜单
|
| | | |
| | | joinFamilyCnt = zone.joinFamilyCnt
|
| | | # 参与仙盟数对应分组及晋级规则 {参与仙盟数:{轮次:{战场类型:[组数, 前x名晋级, 后x名降级], ...}, ...}, ...}
|
| | | FamilyGCZGroupSet = IpyGameDataPY.GetFuncEvalCfg("FamilyGCZGroupSet", 1, {})
|
| | | if joinFamilyCnt not in FamilyGCZGroupSet:
|
| | | return
|
| | | roundSetDict = FamilyGCZGroupSet[joinFamilyCnt]
|
| | | if roundNum not in roundSetDict:
|
| | | return
|
| | | batTypeDict = roundSetDict[roundNum]
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | GameWorld.Log("========== 仙盟攻城战轮次结算: zoneID=%s,roundNum=%s" % (zoneID, roundNum))
|
| | | for batType, groupDict in zone.roundGroupDict.items():
|
| | | if batType not in batTypeDict:
|
| | | continue
|
| | | batTypeSet = batTypeDict[batType]
|
| | | upRank = batTypeSet[1] # 前x晋级
|
| | | downRank = batTypeSet[2] if len(batTypeSet) > 2 else 0 # 后x名降级,为0时不降级
|
| | | groupNumList = groupDict.keys()
|
| | | GameWorld.Log("zoneID=%s,batType=%s,upRank=%s,downRank=%s,groupNumList=%s" % (zoneID, batType, upRank, downRank, groupNumList))
|
| | | for groupNum in groupNumList:
|
| | | batGroup = zone.GetBatGroup(batType, groupNum)
|
| | | if not batGroup:
|
| | |
| | |
|
| | | groupValue2 = GetRoundHurtGroupID(batType, groupNum)
|
| | | billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZRoundHurt, zoneID, groupValue2)
|
| | | billboardObj.SortData()
|
| | | GameWorld.Log("zoneID=%s,batType=%s,groupNum=%s,roundHurtFamilyCnt=%s" % (zoneID, batType, groupNum, billboardObj.GetCount()))
|
| | | GameWorld.Log("zoneID=%s,batType=%s,groupNum=%s,groupFamilyCnt=%s" % (zoneID, batType, groupNum, billboardObj.GetCount()))
|
| | | for bIndex in range(billboardObj.GetCount()):
|
| | | billData = billboardObj.At(bIndex)
|
| | | familyID = billData.ID
|
| | | hurtValue = billData.CmpValue
|
| | | hurtValueEx = billData.CmpValue2
|
| | | hurtValueTotal = hurtValue * ChConfig.Def_PerPointValue + hurtValueEx
|
| | | cmpValue = billData.CmpValue
|
| | | cmpValue2 = billData.CmpValue2
|
| | | hurtValueTotal = cmpValue * ChConfig.Def_PerPointValue + cmpValue2
|
| | | rank = bIndex + 1
|
| | | addScore = GameWorld.GetOrderValueByDict(rankScoreDict, rank, False, 0)
|
| | | |
| | | updownState = UpdownState_Keep # 本轮结算晋级降级状态:0-未处理,1-降级;2-保级;3-晋级,即本轮的晋降级状态决定下一轮的战场类型
|
| | | if rank <= upRank and batType < BatType_Max:
|
| | | updownState = UpdownState_Up
|
| | | elif downRank and rank > (Def_PerGroupFamilyCnt - downRank) and batType > BatType_Min:
|
| | | updownState = UpdownState_Down
|
| | | |
| | | joinFamily = zone.GetZoneJoinFamily(familyID)
|
| | | if not joinFamily:
|
| | | continue
|
| | | joinFamily.score += addScore
|
| | | GameWorld.Log(" zoneID=%s,batType=%s,groupNum=%s,rank=%s,familyID=%s,addScore=%s,updScore=%s,hurtValueTotal=%s" |
| | | % (zoneID, batType, groupNum, rank, familyID, addScore, joinFamily.score, hurtValueTotal))
|
| | | roundInfo = joinFamily.roundInfoDict.get(roundNum, {})
|
| | | roundInfo.update({"updownState":updownState})
|
| | | joinFamily.roundInfoDict[roundNum] = roundInfo
|
| | |
|
| | | dataID = joinFamily.familyID
|
| | | name1 = joinFamily.familyName
|
| | | id2 = joinFamily.leaderID
|
| | | name2 = joinFamily.leaderName
|
| | | type2, value1, value2 = 0, 0, 0
|
| | | value3 = joinFamily.emblemID
|
| | | value5 = joinFamily.serverID
|
| | | cmpValue = joinFamily.score
|
| | | CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_FamilyGCZScore, zoneID, dataID, name1, name2, type2, value1, value2,
|
| | | cmpValue, id2=id2, autoSort=False, value3=value3, value5=value5)
|
| | | GameWorld.Log(" 升保降级zoneID=%s,batType=%s,groupNum=%s,rank=%s,familyID=%s,updownState=%s,hurtValueTotal=%s" |
| | | % (zoneID, batType, groupNum, rank, familyID, updownState, hurtValueTotal))
|
| | | Sync_FamilyGCZCampInfo(zoneID, familyID)
|
| | |
|
| | | # 都加完积分后统一排序
|
| | | familyScoreBillObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZScore, zoneID)
|
| | | familyScoreBillObj.SortData()
|
| | | |
| | | playerHurtBillObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZPlayerHurt, zoneID)
|
| | | playerHurtBillObj.SortData()
|
| | | zone.roundOver = 1 # 标记已结算
|
| | | return
|
| | |
|
| | | def DoGenerateGuess(zoneID, state):
|
| | |
| | |
|
| | | def DoStartAward(zoneID):
|
| | | ## 开始领奖
|
| | | |
| | | DoRoundOver(zoneID)
|
| | |
|
| | | # 下发竞猜统计结果
|
| | | Sync_FamilyGCZGuessInfo(zoneID)
|
| | |
| | | guessCountMax = IpyGameDataPY.GetFuncCfg("FamilyGCZGuess", 3)
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | scoreBillObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZScore, zoneID)
|
| | | for index in range(guessCountMax):
|
| | | for index in range(scoreBillObj.GetCount()):
|
| | | billData = scoreBillObj.At(index)
|
| | | finalFamilyIDList.append(billData.ID)
|
| | | if len(finalFamilyIDList) >= guessCountMax:
|
| | | break
|
| | |
|
| | | # 统计竞猜结果
|
| | | rightRankAwardIDDict = GameWorld.GetActGuessRightRankAwardIDDict(guessTemplateID)
|
| | |
| | | return
|
| | |
|
| | | clientPack = ChPyNetSendPack.tagGCFamilyGCZBatGroupInfo()
|
| | | clientPack.RoundNum = curRound
|
| | | clientPack.RoundNum = zone.roundNum
|
| | | clientPack.BatList = []
|
| | | for batType, groupNumDict in zone.roundGroupDict.items():
|
| | | batInfo = ChPyNetSendPack.tagGCFamilyGCZBat()
|
| | |
| | | clientPack = ChPyNetSendPack.tagGCFamilyGCZCampInfo()
|
| | | clientPack.Clear()
|
| | | clientPack.FamilyID = familyID
|
| | | clientPack.Score = joinFamily.score
|
| | | clientPack.CampLV = joinFamily.campLV
|
| | | clientPack.CampExp = joinFamily.campExp
|
| | | clientPack.CityLV = joinFamily.cityWall.cityLV
|
| | |
| | | clientPack.HPMaxEx = joinFamily.cityWall.hpMax / ChConfig.Def_PerPointValue
|
| | | clientPack.HP = joinFamily.cityWall.hp % ChConfig.Def_PerPointValue
|
| | | clientPack.HPEx = joinFamily.cityWall.hp / ChConfig.Def_PerPointValue
|
| | | clientPack.RoundInfoList = []
|
| | | for roundNum, info in joinFamily.roundInfoDict.items():
|
| | | roundObj = ChPyNetSendPack.tagGCFamilyGCZCampRound()
|
| | | roundObj.RoundNum = roundNum
|
| | | roundObj.BatType = info.get("batType", 0)
|
| | | roundObj.GroupNum = info.get("groupNum", 0)
|
| | | roundObj.Rank = info.get("rank", 0)
|
| | | roundObj.Score = info.get("score", 0)
|
| | | roundObj.UpdownState = info.get("updownState", 0)
|
| | | clientPack.RoundInfoList.append(roundObj)
|
| | | clientPack.RoundCnt = len(clientPack.RoundInfoList)
|
| | | clientPack.DefMemList = []
|
| | | for playerID in joinFamily.joinMemberIDList:
|
| | | if defMemIDList != None and playerID not in defMemIDList:
|
| | |
| | | #import ReloadModule
|
| | | import CrossRealmPK
|
| | | import CrossRealmMsg
|
| | | import CrossFamilyGCZ
|
| | | import CrossRealmPlayer
|
| | | import CrossBattlefield
|
| | | import CrossActionControl
|
| | |
| | | #跨服排位
|
| | | CrossChampionship.OnMinuteProcess(curMinute)
|
| | | CrossBattlefield.OnMinuteProcess()
|
| | | #仙盟攻城战
|
| | | CrossFamilyGCZ.OnMinuteProcess(curMinute)
|
| | | #处理重开服务器后, 活动继续开启逻辑根据天数
|
| | | #GameWorldActionControl.Dispose_Action_GoOn_ByDay(tick)
|
| | | #触发世界等级
|
| | |
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 3
|
| | | RegisterPackCount = 4
|
| | |
|
| | | PacketCMD_1=0xC1
|
| | | PacketSubCMD_1=0x24
|
| | |
| | | PacketCMD_3=0xC1
|
| | | PacketSubCMD_3=0x26
|
| | | PacketCallFunc_3=OnFamilyGCZGuess
|
| | |
|
| | | PacketCMD_4=0xC1
|
| | | PacketSubCMD_4=0x27
|
| | | PacketCallFunc_4=OnFamilyGCZSQ
|
| | |
|
| | |
| | | Def_PDict_FamilyGCZEnergy = "FamilyGCZEnergy" # 进攻剩余体力
|
| | | Def_PDict_FamilyGCZEnergyTime = "FamilyGCZEnergyTime" # 上次恢复体力时间戳,为0时不再恢复
|
| | | Def_PDict_FamilyGCZAwardState = "FamilyGCZAwardState" # 活动奖励领取状态,按二进制位判断是否已领取,0-竞猜奖励;1-个人排行奖励;2-仙盟排名奖励;
|
| | | Def_PDict_FamilyGCZSQLayer = "FamilyGCZSQLayer" # 当前圣泉所在层级
|
| | | Def_PDict_FamilyGCZSQGridItemID = "FamilyGCZSQItemID_%s" # 圣泉当前层格子抽中物品ID,参数(格子编号)
|
| | | Def_PDict_FamilyGCZSQGridItemCnt = "FamilyGCZSQItemCnt_%s" # 圣泉当前层格子抽中物品个数,参数(格子编号)
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | #开服活动,Def_PDictType_OpenServerCampaign
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 27 仙盟攻城战圣泉抽奖 #tagCMFamilyGCZSQ
|
| | |
|
| | | class tagCMFamilyGCZSQ(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("GridNum", c_ubyte), # 选中格子编号,1~n
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xC1
|
| | | self.SubCmd = 0x27
|
| | | 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 = 0xC1
|
| | | self.SubCmd = 0x27
|
| | | self.GridNum = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMFamilyGCZSQ)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C1 27 仙盟攻城战圣泉抽奖 //tagCMFamilyGCZSQ:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | GridNum:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.GridNum
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMFamilyGCZSQ=tagCMFamilyGCZSQ()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMFamilyGCZSQ.Cmd,m_NAtagCMFamilyGCZSQ.SubCmd))] = m_NAtagCMFamilyGCZSQ
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 10 幸运云购购买 #tagCMLuckyCloudBuy
|
| | |
|
| | | class tagCMLuckyCloudBuy(Structure):
|
| | |
| | | GuessTemplateID = 0 #(WORD GuessTemplateID)// 竞猜奖励模版,对应H.活动竞猜表,前端自行读表展示
|
| | | PersonalTemplateID = 0 #(WORD PersonalTemplateID)// 个人伤害排行奖励模版,对应H.活动榜单奖励模版表,前端自行读表展示
|
| | | FamilyTemplateID = 0 #(WORD FamilyTemplateID)// 仙盟积分排行奖励模版,对应H.活动榜单奖励模版表,前端自行读表展示
|
| | | StateError = 0 #(BYTE StateError)// 活动流程状态是否异常,如果不为0代表活动已异常,前端自行决定是不显示活动还是活动页面做提示
|
| | | StateError = 0 #(DWORD StateError)// 活动流程状态是否异常,如果不为0代表活动已异常,前端自行决定是不显示活动还是活动页面做提示
|
| | | FamilyCount = 0 #(BYTE FamilyCount)
|
| | | ActFamilyList = list() #(vector<tagGCFamilyGCZActFamily> ActFamilyList)//本分区参与的仙盟名单
|
| | | data = None
|
| | |
| | | self.GuessTemplateID,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.PersonalTemplateID,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.FamilyTemplateID,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.StateError,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.StateError,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FamilyCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.FamilyCount):
|
| | | temActFamilyList = tagGCFamilyGCZActFamily()
|
| | |
| | | length += 2
|
| | | length += 2
|
| | | length += 2
|
| | | length += 1
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.FamilyCount):
|
| | | length += self.ActFamilyList[i].GetLength()
|
| | |
| | | data = CommFunc.WriteWORD(data, self.GuessTemplateID)
|
| | | data = CommFunc.WriteWORD(data, self.PersonalTemplateID)
|
| | | data = CommFunc.WriteWORD(data, self.FamilyTemplateID)
|
| | | data = CommFunc.WriteBYTE(data, self.StateError)
|
| | | data = CommFunc.WriteDWORD(data, self.StateError)
|
| | | data = CommFunc.WriteBYTE(data, self.FamilyCount)
|
| | | for i in range(self.FamilyCount):
|
| | | data = CommFunc.WriteString(data, self.ActFamilyList[i].GetLength(), self.ActFamilyList[i].GetBuffer())
|
| | |
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCFamilyGCZCampRound(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("RoundNum", c_ubyte), #轮次编号,从1开始
|
| | | ("BatType", c_ubyte), #所在战场类型
|
| | | ("GroupNum", c_ubyte), #所在分组编号
|
| | | ("Rank", c_ubyte), #本轮排名
|
| | | ("Score", c_ushort), #本轮积分,总积分为所有轮次累加
|
| | | ("UpdownState", c_ubyte), #本轮结算晋级降级状态:0-未处理,1-降级;2-保级;3-晋级,即本轮的晋降级状态决定下一轮的战场类型
|
| | | ]
|
| | |
|
| | | 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.RoundNum = 0
|
| | | self.BatType = 0
|
| | | self.GroupNum = 0
|
| | | self.Rank = 0
|
| | | self.Score = 0
|
| | | self.UpdownState = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagGCFamilyGCZCampRound)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C0 26 仙盟攻城战大本营信息 //tagGCFamilyGCZCampInfo:
|
| | | RoundNum:%d,
|
| | | BatType:%d,
|
| | | GroupNum:%d,
|
| | | Rank:%d,
|
| | | Score:%d,
|
| | | UpdownState:%d
|
| | | '''\
|
| | | %(
|
| | | self.RoundNum,
|
| | | self.BatType,
|
| | | self.GroupNum,
|
| | | self.Rank,
|
| | | self.Score,
|
| | | self.UpdownState
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCFamilyGCZCampInfo(Structure):
|
| | | Head = tagHead()
|
| | | FamilyID = 0 #(DWORD FamilyID)//所在活动仙盟ID,可能不是玩家当前的仙盟ID,活动以该ID为准
|
| | | Score = 0 #(WORD Score)//活动总积分,如果不在榜上则读该值
|
| | | CampLV = 0 #(WORD CampLV)//大本营当前等级
|
| | | CampExp = 0 #(DWORD CampExp)//大本营当前经验
|
| | | CityLV = 0 #(WORD CityLV)//城池属性等级,开战后可能与当前大本营等级不一样
|
| | |
| | | HPMaxEx = 0 #(DWORD HPMaxEx)//总大生命,整除亿部分
|
| | | HP = 0 #(DWORD HP)//剩余生命,求余亿部分
|
| | | HPEx = 0 #(DWORD HPEx)//剩余生命,整除亿部分
|
| | | RoundCnt = 0 #(BYTE RoundCnt)
|
| | | RoundInfoList = list() #(vector<tagGCFamilyGCZCampRound> RoundInfoList)//仙盟轮次汇总信息
|
| | | DefMemCnt = 0 #(BYTE DefMemCnt)
|
| | | DefMemList = list() #(vector<tagGCFamilyGCZCampMem> DefMemList)//防守成员列表,有同步则差异更新,没有在防守成员里的视为没有参与资格
|
| | | data = None
|
| | |
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Score,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.CampLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.CampExp,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CityLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | |
| | | self.HPMaxEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.HP,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.HPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.RoundCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.RoundCnt):
|
| | | temRoundInfoList = tagGCFamilyGCZCampRound()
|
| | | _pos = temRoundInfoList.ReadData(_lpData, _pos)
|
| | | self.RoundInfoList.append(temRoundInfoList)
|
| | | self.DefMemCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.DefMemCnt):
|
| | | temDefMemList = tagGCFamilyGCZCampMem()
|
| | |
| | | self.Head.Cmd = 0xC0
|
| | | self.Head.SubCmd = 0x26
|
| | | self.FamilyID = 0
|
| | | self.Score = 0
|
| | | self.CampLV = 0
|
| | | self.CampExp = 0
|
| | | self.CityLV = 0
|
| | |
| | | self.HPMaxEx = 0
|
| | | self.HP = 0
|
| | | self.HPEx = 0
|
| | | self.RoundCnt = 0
|
| | | self.RoundInfoList = list()
|
| | | self.DefMemCnt = 0
|
| | | self.DefMemList = list()
|
| | | return
|
| | |
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 4
|
| | | length += 2
|
| | | length += 2
|
| | | length += 4
|
| | | length += 2
|
| | |
| | | length += 4
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.RoundCnt):
|
| | | length += self.RoundInfoList[i].GetLength()
|
| | | length += 1
|
| | | for i in range(self.DefMemCnt):
|
| | | length += self.DefMemList[i].GetLength()
|
| | |
|
| | |
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteDWORD(data, self.FamilyID)
|
| | | data = CommFunc.WriteWORD(data, self.Score)
|
| | | data = CommFunc.WriteWORD(data, self.CampLV)
|
| | | data = CommFunc.WriteDWORD(data, self.CampExp)
|
| | | data = CommFunc.WriteWORD(data, self.CityLV)
|
| | |
| | | data = CommFunc.WriteDWORD(data, self.HPMaxEx)
|
| | | data = CommFunc.WriteDWORD(data, self.HP)
|
| | | data = CommFunc.WriteDWORD(data, self.HPEx)
|
| | | data = CommFunc.WriteBYTE(data, self.RoundCnt)
|
| | | for i in range(self.RoundCnt):
|
| | | data = CommFunc.WriteString(data, self.RoundInfoList[i].GetLength(), self.RoundInfoList[i].GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.DefMemCnt)
|
| | | for i in range(self.DefMemCnt):
|
| | | data = CommFunc.WriteString(data, self.DefMemList[i].GetLength(), self.DefMemList[i].GetBuffer())
|
| | |
| | | DumpString = '''
|
| | | Head:%s,
|
| | | FamilyID:%d,
|
| | | Score:%d,
|
| | | CampLV:%d,
|
| | | CampExp:%d,
|
| | | CityLV:%d,
|
| | |
| | | HPMaxEx:%d,
|
| | | HP:%d,
|
| | | HPEx:%d,
|
| | | RoundCnt:%d,
|
| | | RoundInfoList:%s,
|
| | | DefMemCnt:%d,
|
| | | DefMemList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.FamilyID,
|
| | | self.Score,
|
| | | self.CampLV,
|
| | | self.CampExp,
|
| | | self.CityLV,
|
| | |
| | | self.HPMaxEx,
|
| | | self.HP,
|
| | | self.HPEx,
|
| | | self.RoundCnt,
|
| | | "...",
|
| | | self.DefMemCnt,
|
| | | "..."
|
| | | )
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 11 仙盟攻城战圣泉信息 #tagMCFamilyGCZSQInfo
|
| | |
|
| | | class tagMCFamilyGCZSQGrid(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("GridNum", c_ubyte), # 格子编号,1~n |
| | | ("ItemID", c_int), # 抽中的物品ID,20亿时为过关标记
|
| | | ("ItemCount", c_ushort), # 物品数量
|
| | | ]
|
| | |
|
| | | 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.GridNum = 0
|
| | | self.ItemID = 0
|
| | | self.ItemCount = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCFamilyGCZSQGrid)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C1 11 仙盟攻城战圣泉信息 //tagMCFamilyGCZSQInfo:
|
| | | GridNum:%d,
|
| | | ItemID:%d,
|
| | | ItemCount:%d
|
| | | '''\
|
| | | %(
|
| | | self.GridNum,
|
| | | self.ItemID,
|
| | | self.ItemCount
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCFamilyGCZSQInfo(Structure):
|
| | | Head = tagHead()
|
| | | SQLayer = 0 #(BYTE SQLayer)// 当前所在圣泉层,从1开始
|
| | | SQGirdCnt = 0 #(BYTE SQGirdCnt)
|
| | | SQGridList = list() #(vector<tagMCFamilyGCZSQGrid> SQGridList)//圣泉当前层已抽格子信息,仅同步全部或变更的格子,前端进行差异更新,层数变更时重置本地记录
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xC1
|
| | | self.Head.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.SQLayer,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.SQGirdCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.SQGirdCnt):
|
| | | temSQGridList = tagMCFamilyGCZSQGrid()
|
| | | _pos = temSQGridList.ReadData(_lpData, _pos)
|
| | | self.SQGridList.append(temSQGridList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xC1
|
| | | self.Head.SubCmd = 0x11
|
| | | self.SQLayer = 0
|
| | | self.SQGirdCnt = 0
|
| | | self.SQGridList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.SQGirdCnt):
|
| | | length += self.SQGridList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.SQLayer)
|
| | | data = CommFunc.WriteBYTE(data, self.SQGirdCnt)
|
| | | for i in range(self.SQGirdCnt):
|
| | | data = CommFunc.WriteString(data, self.SQGridList[i].GetLength(), self.SQGridList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | SQLayer:%d,
|
| | | SQGirdCnt:%d,
|
| | | SQGridList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.SQLayer,
|
| | | self.SQGirdCnt,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCFamilyGCZSQInfo=tagMCFamilyGCZSQInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFamilyGCZSQInfo.Head.Cmd,m_NAtagMCFamilyGCZSQInfo.Head.SubCmd))] = m_NAtagMCFamilyGCZSQInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C1 08 幸运云购玩家信息 #tagMCLuckyCloudBuyPlayerInfo
|
| | |
|
| | | class tagMCLuckyCloudBuyPlayerInfo(Structure):
|
| | |
| | | ("dict", "ScoreAwardEx", 0),
|
| | | ),
|
| | |
|
| | | "CrossActFamilyGCZSQ":(
|
| | | ("DWORD", "LayerNum", 1),
|
| | | ("DWORD", "CostItemID", 0),
|
| | | ("BYTE", "CostItemCnt", 0),
|
| | | ("BYTE", "GridCnt", 0),
|
| | | ("WORD", "PassRate", 0),
|
| | | ("list", "GridWeightItemList", 0),
|
| | | ("list", "LayerAwardItemList", 0),
|
| | | ("list", "LayerWeightItemList", 0),
|
| | | ),
|
| | |
|
| | | "ActXianXiaMJ":(
|
| | | ("DWORD", "CfgID", 1),
|
| | | ("char", "StartDate", 0),
|
| | |
| | | def GetNeedScore(self): return self.attrTuple[3] # 上榜所需积分 DWORD
|
| | | def GetScoreAwardEx(self): return self.attrTuple[4] # 达标积分额外奖励 {积分:[[物品ID,个数,是否拍品], ...], ...} dict |
| | | |
| | | # 仙盟攻城战圣泉表 |
| | | class IPY_CrossActFamilyGCZSQ(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetLayerNum(self): return self.attrTuple[0] # 层 DWORD
|
| | | def GetCostItemID(self): return self.attrTuple[1] # 消耗抽奖道具ID DWORD
|
| | | def GetCostItemCnt(self): return self.attrTuple[2] # 消耗抽奖道具个数 BYTE
|
| | | def GetGridCnt(self): return self.attrTuple[3] # 格子数 BYTE
|
| | | def GetPassRate(self): return self.attrTuple[4] # 过关万分率 WORD
|
| | | def GetGridWeightItemList(self): return self.attrTuple[5] # 格子物品权重随机库 [[权重,物品ID,个数], ...] list
|
| | | def GetLayerAwardItemList(self): return self.attrTuple[6] # 通关该层固定奖励 [[物品ID,个数,是否拍品], ...] list
|
| | | def GetLayerWeightItemList(self): return self.attrTuple[7] # 通关该层额外随机奖励 [[权重,物品ID,个数], ...] list |
| | | |
| | | # 仙匣秘境活动时间表 |
| | | class IPY_ActXianXiaMJ(): |
| | | |
| | |
| | | self.__LoadFileData("ActGubao", onlyCheck)
|
| | | self.__LoadFileData("ActGubaoBillTemp", onlyCheck)
|
| | | self.__LoadFileData("ActLianqiBillTemp", onlyCheck)
|
| | | self.__LoadFileData("CrossActFamilyGCZSQ", onlyCheck)
|
| | | self.__LoadFileData("ActXianXiaMJ", onlyCheck)
|
| | | self.__LoadFileData("ActXianXiaMJBillTemp", onlyCheck)
|
| | | self.__LoadFileData("ActXianXiaMJAward", onlyCheck)
|
| | |
| | | self.CheckLoadData("ActLianqiBillTemp") |
| | | return self.ipyActLianqiBillTempCache[index]
|
| | | |
| | | def GetCrossActFamilyGCZSQCount(self): |
| | | self.CheckLoadData("CrossActFamilyGCZSQ") |
| | | return self.ipyCrossActFamilyGCZSQLen
|
| | | def GetCrossActFamilyGCZSQByIndex(self, index): |
| | | self.CheckLoadData("CrossActFamilyGCZSQ") |
| | | return self.ipyCrossActFamilyGCZSQCache[index]
|
| | | |
| | | def GetActXianXiaMJCount(self): |
| | | self.CheckLoadData("ActXianXiaMJ") |
| | | return self.ipyActXianXiaMJLen
|
| | |
| | | AtkType_SkillArea, # 技能群攻 3
|
| | | ) = range(1, 1 + 3)
|
| | |
|
| | | # 圣泉过关标记物品ID
|
| | | SQPass_ItemID = 2000000000
|
| | |
|
| | | def GetRoundState(state):
|
| | | ## 获取轮次、状态信息
|
| | | if state < 10 or state == FamilyGCZState_Award:
|
| | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZFamilyID, familyID)
|
| | | if state:
|
| | | Sync_FamilyGCZPlayerInfo(curPlayer)
|
| | | Sync_FamilyGCZSQInfo(curPlayer)
|
| | | return
|
| | |
|
| | | GameWorld.DebugLog("仙盟攻城战活动玩家重置! zoneID=%s,actID=%s,playerZoneID=%s,playerActID=%s"
|
| | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZEnergyTime, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZAwardState, 0)
|
| | |
|
| | | # 重置圣泉
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQLayer, 0)
|
| | | gridCntMax = 0
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetCrossActFamilyGCZSQCount()):
|
| | | ipyData = ipyDataMgr.GetCrossActFamilyGCZSQByIndex(index)
|
| | | gridCntMax = max(0, ipyData.GetGridCnt())
|
| | | for gridNum in range(1, gridCntMax + 1):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemID % gridNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemCnt % gridNum, 0)
|
| | | |
| | | # # 回收道具
|
| | | # for itemID in IpyGameDataPY.GetFuncEvalCfg("LianqiUseItem", 5):
|
| | | # ItemControler.RecycleItem(curPlayer, itemID, "ActLianqiRecycleItem")
|
| | |
| | | if state:
|
| | | maxEnergy = IpyGameDataPY.GetFuncCfg("FamilyGCZEnergy", 1)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZEnergy, maxEnergy)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQLayer, 1)
|
| | | Sync_FamilyGCZPlayerInfo(curPlayer)
|
| | | Sync_FamilyGCZSQInfo(curPlayer)
|
| | |
|
| | | return True
|
| | |
|
| | |
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["FamilyGCZAward", True, drDict])
|
| | | return
|
| | |
|
| | |
|
| | | #// C1 27 仙盟攻城战圣泉抽奖 #tagCMFamilyGCZSQ
|
| | | #
|
| | | #struct tagCMFamilyGCZSQ
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE GridNum; // 选中格子编号,1~n
|
| | | #};
|
| | | def OnFamilyGCZSQ(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | gridNum = clientData.GridNum
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | layerNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZSQLayer)
|
| | | if not layerNum:
|
| | | layerNum = 1
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQLayer, 1)
|
| | | |
| | | ipyData = IpyGameDataPY.GetIpyGameData("CrossActFamilyGCZSQ", layerNum)
|
| | | if not ipyData:
|
| | | return
|
| | | gridCnt = ipyData.GetGridCnt()
|
| | | if gridNum < 1 or gridNum > gridCnt:
|
| | | GameWorld.DebugLog("圣泉抽奖不存在该格子编号! layerNum=%s, gridNum=%s" % (layerNum, gridNum), playerID)
|
| | | return
|
| | | |
| | | if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZSQGridItemID % gridNum):
|
| | | Sync_FamilyGCZSQInfo(curPlayer, gridNum)
|
| | | return
|
| | | |
| | | costItemID = ipyData.GetCostItemID()
|
| | | costItemCount = ipyData.GetCostItemCnt()
|
| | | if not costItemID or not costItemCount:
|
| | | return
|
| | | |
| | | itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
|
| | | hasEnough, itemIndexList = ItemCommon.GetItem_FromPack_ByID(costItemID, itemPack, costItemCount)
|
| | | if not hasEnough:
|
| | | GameWorld.DebugLog("圣泉抽奖道具不足! costItemID=%s, costItemCount=%s" % (costItemID, costItemCount), playerID)
|
| | | return
|
| | | |
| | | emptyCnt = 0 |
| | | for gNum in range(1, gridCnt + 1):
|
| | | if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZSQGridItemID % gNum):
|
| | | continue
|
| | | emptyCnt += 1
|
| | | if emptyCnt > 1:
|
| | | break
|
| | | |
| | | if emptyCnt > 1:
|
| | | isPass = GameWorld.CanHappen(ipyData.GetPassRate())
|
| | | else:
|
| | | isPass = 1
|
| | | GameWorld.DebugLog("仙盟攻城战圣泉抽奖最后一格必过关! layerNum=%s" % layerNum, playerID)
|
| | | |
| | | if not isPass:
|
| | | randItem = GameWorld.GetResultByWeightList(ipyData.GetGridWeightItemList())
|
| | | GameWorld.DebugLog("仙盟攻城战圣泉抽奖未过关! layerNum=%s,gridNum=%s,randItem=%s" % (layerNum, gridNum, randItem), playerID)
|
| | | if not randItem:
|
| | | return
|
| | | itemID, itemCount = randItem
|
| | | if not itemID or not itemCount:
|
| | | return
|
| | | |
| | | ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, costItemCount, True, "FamilyGCZSQ")
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemID % gridNum, itemID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemCnt % gridNum, itemCount)
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, [[itemID, itemCount]], event=["FamilyGCZSQGrid", False, {}])
|
| | | Sync_FamilyGCZSQInfo(curPlayer, gridNum)
|
| | | return
|
| | | |
| | | # 过关
|
| | | ItemCommon.ReduceItem(curPlayer, itemPack, itemIndexList, costItemCount, True, "FamilyGCZSQ")
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemID % gridNum, SQPass_ItemID)
|
| | | passAwardItemList = ipyData.GetLayerAwardItemList() # 过关奖励
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, passAwardItemList, event=["FamilyGCZSQPass", False, {}])
|
| | | Sync_FamilyGCZSQInfo(curPlayer, gridNum)
|
| | | GameWorld.DebugLog("仙盟攻城战圣泉抽奖过关! layerNum=%s,gridNum=%s,passAwardItemList=%s" |
| | | % (layerNum, gridNum, passAwardItemList), playerID)
|
| | | |
| | | #重置格子记录
|
| | | for gridNum in range(1, ipyData.GetGridCnt() + 1):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemID % gridNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQGridItemCnt % gridNum, 0)
|
| | | |
| | | nextLayerNum = layerNum + 1
|
| | | #下一层
|
| | | if IpyGameDataPY.GetIpyGameDataNotLog("CrossActFamilyGCZSQ", nextLayerNum):
|
| | | GameWorld.DebugLog(" 下一层! nextLayerNum=%s" % (nextLayerNum), playerID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQLayer, nextLayerNum)
|
| | | Sync_FamilyGCZSQInfo(curPlayer)
|
| | | return
|
| | | |
| | | #通关,从头开始
|
| | | weightItemList = ipyData.GetLayerWeightItemList() # 通关随机奖励
|
| | | awardItemEx = GameWorld.GetResultByWeightList(weightItemList)
|
| | | if awardItemEx and len(awardItemEx) == 2:
|
| | | itemID, itemCount = awardItemEx
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, [[itemID, itemCount]], event=["FamilyGCZSQPassAll", False, {}])
|
| | | |
| | | GameWorld.DebugLog(" 没有下一层了,从头开始! awardItemEx=%s" % str(awardItemEx), playerID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyGCZSQLayer, 1)
|
| | | Sync_FamilyGCZSQInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def Sync_FamilyGCZPlayerInfo(curPlayer):
|
| | | clientPack = ChPyNetSendPack.tagMCFamilyGCZPlayerInfo()
|
| | | clientPack.ContributionCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZContributionCnt)
|
| | |
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | def Sync_FamilyGCZSQInfo(curPlayer, gridNum=0):
|
| | | layerNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZSQLayer)
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("CrossActFamilyGCZSQ", layerNum)
|
| | | if not ipyData:
|
| | | return
|
| | | clientPack = ChPyNetSendPack.tagMCFamilyGCZSQInfo()
|
| | | clientPack.SQLayer = layerNum
|
| | | if gridNum:
|
| | | syncGridList = [gridNum]
|
| | | else:
|
| | | syncGridList = range(1, ipyData.GetGridCnt() + 1)
|
| | | clientPack.SQGridList = []
|
| | | for gNum in syncGridList:
|
| | | grid = ChPyNetSendPack.tagMCFamilyGCZSQGrid()
|
| | | grid.GridNum = gNum
|
| | | grid.ItemID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZSQGridItemID % gNum)
|
| | | grid.ItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyGCZSQGridItemCnt % gNum)
|
| | | clientPack.SQGridList.append(grid)
|
| | | clientPack.SQGirdCnt = len(clientPack.SQGridList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|