412 【挑战】定军阁-服务端(效果属性暂时无效;)
| | |
| | | list RandWeightItemList; //宝箱随机物品权重列表,[[权重,物品ID,数量], ...]
|
| | | };
|
| | |
|
| | | //定军阁关卡表
|
| | | struct FBDJGLevel
|
| | | {
|
| | | WORD _LayerNum; //层数
|
| | | BYTE _LevelNum; //关卡编号
|
| | | list PassAwardList; // 过关奖励列表,[[物品ID,个数], ...]
|
| | | list AwardList; // 挑战奖励,[[物品ID,个数], ...]
|
| | | list LineupIDList; // 阵容ID列表,小队1阵容ID|小队2阵容ID|...
|
| | | WORD NPCLV; //NPC等级
|
| | | float Difficulty; //难度系数
|
| | | };
|
| | |
|
| | | //定军阁速战奖励表
|
| | | struct FBDJGQuick
|
| | | {
|
| | | WORD _NeedLayer; //所需层数
|
| | | list QuickAwardList; // 速战奖励列表,[[物品ID,个数], ...]
|
| | | };
|
| | |
|
| | | //定军阁效果表
|
| | | struct FBDJGEffect
|
| | | {
|
| | | DWORD _EffID; //效果ID
|
| | | BYTE EffQuality; // 效果品质
|
| | | BYTE AttrID; // 属性ID
|
| | | DWORD AttrValue; // 属性值
|
| | | DWORD RandWeight; // 随机权重
|
| | | };
|
| | |
|
| | | //广告奖励表
|
| | |
|
| | | struct ADAward
|
| | |
| | | PacketSubCMD_1=0x15
|
| | | PacketCallFunc_1=OnMainDropItemOP
|
| | |
|
| | | ;定军阁
|
| | | [GameLogic_Dingjunge]
|
| | | ScriptName = GameWorldLogic\FBProcess\GameLogic_Dingjunge.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 2
|
| | |
|
| | | PacketCMD_1=0xB1
|
| | | PacketSubCMD_1=0x01
|
| | | PacketCallFunc_1=OnDingjungeEffSet
|
| | |
|
| | | PacketCMD_2=0xB1
|
| | | PacketSubCMD_2=0x02
|
| | | PacketCallFunc_2=OnDingjungeEffSelect
|
| | |
|
| | | ;回合攻击
|
| | | [TurnAttack]
|
| | | ScriptName = Attack\TurnAttack.py
|
| | |
| | | if not reqRet:
|
| | | return
|
| | | funcLineID = reqRet[1] if len(reqRet) > 1 else funcLineID
|
| | | GameWorld.DebugLogEx(" funcLineID=%s", funcLineID, playerID)
|
| | |
|
| | | fbIpyData = FBCommon.GetFBIpyData(mapID)
|
| | | fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, funcLineID, False)
|
| | | if fbIpyData:
|
| | | if not fbLineIpyData:
|
| | | GameWorld.DebugLogEx("不存在该副本功能线路! mapID=%s,funcLineID=%s", mapID, funcLineID)
|
| | | return
|
| | | #if not fbLineIpyData:
|
| | | # GameWorld.DebugLogEx("不存在该副本功能线路! mapID=%s,funcLineID=%s", mapID, funcLineID)
|
| | | # return
|
| | | if FBCommon.CheckCanEnterFBComm(curPlayer, mapID, funcLineID, fbIpyData, fbLineIpyData) != ShareDefine.EntFBAskRet_OK:
|
| | | return
|
| | |
|
| | |
| | |
|
| | | for index, lineupID in enumerate(npcLineupIDList):
|
| | | turnFight.lineupIndex = index
|
| | | GameWorld.DebugLogEx("对战NPC阵容: index=%s, lineupID=%s", index, lineupID)
|
| | | GameWorld.DebugLogEx("对战NPC阵容: mapID=%s,funcLineID=%s,index=%s,lineupID=%s", mapID, funcLineID, index, lineupID)
|
| | | if index > 0:
|
| | | turnFight.nextTurnFight()
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, strongerLV, difficulty)})
|
| | |
| | |
|
| | | Def_FBMapID_Zhanchui = 30010 # 白骨盈野/战锤秘境
|
| | | Def_FBMapID_Tianzi = 30020 # 天子考验
|
| | | Def_FBMapID_Dingjunge = 30030 # 定军阁
|
| | |
|
| | | #线路未过关时免费的地图
|
| | | UnPassFreeMapIDList = [Def_FBMapID_Zhanchui]
|
| | | UnPassFreeMapIDList = [Def_FBMapID_Zhanchui, Def_FBMapID_Dingjunge]
|
| | | #按星级记录过关的地图
|
| | | PassByStarMapIDList = []
|
| | | #扫荡不需要检查是否已过关的地图
|
| | |
| | | #固定玩家获胜的地图
|
| | | PlayerWinMapIDList = [Def_FBMapID_Tianzi]
|
| | | #需要汇报中心副本过关进度的地图
|
| | | ReportCenterMapIDList = [Def_FBMapID_Zhanchui]
|
| | | ReportCenterMapIDList = [Def_FBMapID_Zhanchui, Def_FBMapID_Dingjunge]
|
| | |
|
| | | #注册上传跨服服务器数据后直接进入跨服服务器的地图
|
| | | RegisterEnter_CrossServerMapIDList = []
|
| | |
| | | 'Arena':[Def_FBMapID_ArenaBattle],
|
| | | 'Zhanchui':[Def_FBMapID_Zhanchui],
|
| | | 'Tianzi':[Def_FBMapID_Tianzi],
|
| | | 'Dingjunge':[Def_FBMapID_Dingjunge],
|
| | | }
|
| | |
|
| | | #特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
|
| | |
| | | Def_PDict_TianziHisHurtEx = "TianziHisHurtEx_%s" # 历史最高伤害,整除亿部分,参数(bossID)
|
| | | Def_PDict_TianziTodayHurt = "TianziTodayHurt" # 今日最高伤害,求余亿部分
|
| | | Def_PDict_TianziTodayHurtEx = "TianziTodayHurtEx" # 今日最高伤害,整除亿部分
|
| | |
|
| | | #定军阁
|
| | | Def_PDict_DJGLineID = "DJGLineID" # 今日已过关的线路ID 层 * 100 + 关卡编号
|
| | | Def_PDict_DJGEffect = "DJGEff_%s" # 已生效的加成效果,参数(index) effID * 100 + 效果等级
|
| | | Def_PDict_DJGSelectEffect = "DJGSelectEff_%s" # 当前待选择的加成效果,参数(index) effID
|
| | | Def_PDict_DJGUnSelectCnt = "DJGUnSelectCnt" # 还有几个未选择的效果
|
| | | Def_PDict_DJGEffAuto = "DJGEffAuto" # 是否自动选择效果
|
| | | Def_PDict_DJGEffSet = "DJGEffSet_%s" # 预设优先选择属性ID,参数(优先index)
|
| | |
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | #物品效果(ID或指定类型)对应的属性计算信息 {效果(ID/指定类型):[[属性索引, ...], 是否基础属性,(非)线性]}
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B1 02 定军阁效果选择 #tagCSDingjungeEffSelect
|
| | |
|
| | | class tagCSDingjungeEffSelect(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("SelectType", c_ubyte), #0-手动选择,1-放弃本次选择,2-一键选择(仅开启了自动选择时有效)
|
| | | ("SelectIndex", c_ubyte), #手动选择索引 0~n
|
| | | ("ReplaceHole", c_ubyte), #手动选择替换槽位 1~n,槽位=槽索引+1,升级时可直接发0
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xB1
|
| | | self.SubCmd = 0x02
|
| | | 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 = 0xB1
|
| | | self.SubCmd = 0x02
|
| | | self.SelectType = 0
|
| | | self.SelectIndex = 0
|
| | | self.ReplaceHole = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCSDingjungeEffSelect)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// B1 02 定军阁效果选择 //tagCSDingjungeEffSelect:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | SelectType:%d,
|
| | | SelectIndex:%d,
|
| | | ReplaceHole:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.SelectType,
|
| | | self.SelectIndex,
|
| | | self.ReplaceHole
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCSDingjungeEffSelect=tagCSDingjungeEffSelect()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSDingjungeEffSelect.Cmd,m_NAtagCSDingjungeEffSelect.SubCmd))] = m_NAtagCSDingjungeEffSelect
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B1 01 定军阁效果预设 #tagCSDingjungeEffSet
|
| | |
|
| | | class tagCSDingjungeEffSet(Structure):
|
| | | Head = tagHead()
|
| | | SelectAuto = 0 #(BYTE SelectAuto)//是否启用自动选择
|
| | | SelectSetCnt = 0 #(BYTE SelectSetCnt)
|
| | | SelectSetAttrIDList = list() #(vector<WORD> SelectSetAttrIDList)//预设优先选择属性ID列表 [优先级1属性ID, ...]
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB1
|
| | | self.Head.SubCmd = 0x01
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.SelectAuto,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.SelectSetCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.SelectSetCnt):
|
| | | value,_pos=CommFunc.ReadWORD(_lpData,_pos)
|
| | | self.SelectSetAttrIDList.append(value)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB1
|
| | | self.Head.SubCmd = 0x01
|
| | | self.SelectAuto = 0
|
| | | self.SelectSetCnt = 0
|
| | | self.SelectSetAttrIDList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += 2 * self.SelectSetCnt
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.SelectAuto)
|
| | | data = CommFunc.WriteBYTE(data, self.SelectSetCnt)
|
| | | for i in range(self.SelectSetCnt):
|
| | | data = CommFunc.WriteWORD(data, self.SelectSetAttrIDList[i])
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | SelectAuto:%d,
|
| | | SelectSetCnt:%d,
|
| | | SelectSetAttrIDList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.SelectAuto,
|
| | | self.SelectSetCnt,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCSDingjungeEffSet=tagCSDingjungeEffSet()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSDingjungeEffSet.Head.Cmd,m_NAtagCSDingjungeEffSet.Head.SubCmd))] = m_NAtagCSDingjungeEffSet
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B1 08 快速一键过关副本 #tagCMFBQuickPass
|
| | |
|
| | | class tagCMFBQuickPass(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B2 02 定军阁信息 #tagSCDingjungeInfo
|
| | |
|
| | | class tagSCDingjungeEff(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("EffIndex", c_ubyte), #槽索引,0~n
|
| | | ("EffID", c_ushort), |
| | | ("EffLV", 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.EffIndex = 0
|
| | | self.EffID = 0
|
| | | self.EffLV = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagSCDingjungeEff)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// B2 02 定军阁信息 //tagSCDingjungeInfo:
|
| | | EffIndex:%d,
|
| | | EffID:%d,
|
| | | EffLV:%d
|
| | | '''\
|
| | | %(
|
| | | self.EffIndex,
|
| | | self.EffID,
|
| | | self.EffLV
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagSCDingjungeInfo(Structure):
|
| | | Head = tagHead()
|
| | | TodayPass = 0 #(DWORD TodayPass)//今日过关进度 层*100+关卡编号,历史最高过关记录取A320中的PassLineID
|
| | | EffCnt = 0 #(BYTE EffCnt)
|
| | | EffList = list() #(vector<tagSCDingjungeEff> EffList)//已生效的效果列表
|
| | | SelectEffCnt = 0 #(BYTE SelectEffCnt)
|
| | | SelectEffList = list() #(vector<DWORD> SelectEffList)//待手动选择的效果ID列表
|
| | | UnSelectCnt = 0 #(WORD UnSelectCnt)//还有几个未选择的效果
|
| | | SelectAuto = 0 #(BYTE SelectAuto)//是否启用自动选择
|
| | | SelectSetCnt = 0 #(BYTE SelectSetCnt)
|
| | | SelectSetAttrIDList = list() #(vector<WORD> SelectSetAttrIDList)//预设优先选择属性ID列表 [优先级1属性ID, ...]
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xB2
|
| | | self.Head.SubCmd = 0x02
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.TodayPass,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.EffCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.EffCnt):
|
| | | temEffList = tagSCDingjungeEff()
|
| | | _pos = temEffList.ReadData(_lpData, _pos)
|
| | | self.EffList.append(temEffList)
|
| | | self.SelectEffCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.SelectEffCnt):
|
| | | value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
|
| | | self.SelectEffList.append(value)
|
| | | self.UnSelectCnt,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.SelectAuto,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.SelectSetCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.SelectSetCnt):
|
| | | value,_pos=CommFunc.ReadWORD(_lpData,_pos)
|
| | | self.SelectSetAttrIDList.append(value)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xB2
|
| | | self.Head.SubCmd = 0x02
|
| | | self.TodayPass = 0
|
| | | self.EffCnt = 0
|
| | | self.EffList = list()
|
| | | self.SelectEffCnt = 0
|
| | | self.SelectEffList = list()
|
| | | self.UnSelectCnt = 0
|
| | | self.SelectAuto = 0
|
| | | self.SelectSetCnt = 0
|
| | | self.SelectSetAttrIDList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.EffCnt):
|
| | | length += self.EffList[i].GetLength()
|
| | | length += 1
|
| | | length += 4 * self.SelectEffCnt
|
| | | length += 2
|
| | | length += 1
|
| | | length += 1
|
| | | length += 2 * self.SelectSetCnt
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteDWORD(data, self.TodayPass)
|
| | | data = CommFunc.WriteBYTE(data, self.EffCnt)
|
| | | for i in range(self.EffCnt):
|
| | | data = CommFunc.WriteString(data, self.EffList[i].GetLength(), self.EffList[i].GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.SelectEffCnt)
|
| | | for i in range(self.SelectEffCnt):
|
| | | data = CommFunc.WriteDWORD(data, self.SelectEffList[i])
|
| | | data = CommFunc.WriteWORD(data, self.UnSelectCnt)
|
| | | data = CommFunc.WriteBYTE(data, self.SelectAuto)
|
| | | data = CommFunc.WriteBYTE(data, self.SelectSetCnt)
|
| | | for i in range(self.SelectSetCnt):
|
| | | data = CommFunc.WriteWORD(data, self.SelectSetAttrIDList[i])
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | TodayPass:%d,
|
| | | EffCnt:%d,
|
| | | EffList:%s,
|
| | | SelectEffCnt:%d,
|
| | | SelectEffList:%s,
|
| | | UnSelectCnt:%d,
|
| | | SelectAuto:%d,
|
| | | SelectSetCnt:%d,
|
| | | SelectSetAttrIDList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.TodayPass,
|
| | | self.EffCnt,
|
| | | "...",
|
| | | self.SelectEffCnt,
|
| | | "...",
|
| | | self.UnSelectCnt,
|
| | | self.SelectAuto,
|
| | | self.SelectSetCnt,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagSCDingjungeInfo=tagSCDingjungeInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCDingjungeInfo.Head.Cmd,m_NAtagSCDingjungeInfo.Head.SubCmd))] = m_NAtagSCDingjungeInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B2 01 天子考验信息 #tagSCTianziKYInfo
|
| | |
|
| | | class tagSCTianziKYInfo(Structure):
|
| New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.Dingjunge
|
| | | #
|
| | | # @todo:定军阁
|
| | | # @author hxp
|
| | | # @date 2026-01-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 定军阁
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2026-01-06 13:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import FBCommon
|
| | | import GameWorld
|
| | | import IpyGameDataPY
|
| | | import GameLogic_Dingjunge
|
| | | import PlayerControl
|
| | | import ChConfig
|
| | |
|
| | | def OnExec(curPlayer, paramList):
|
| | | |
| | | if not paramList:
|
| | | GameWorld.DebugAnswer(curPlayer, "定军阁进度: Dingjunge 今日关卡ID 历史关卡ID")
|
| | | GameWorld.DebugAnswer(curPlayer, "增加效果数: Dingjunge e 增加效果次数")
|
| | | GameWorld.DebugAnswer(curPlayer, "待选择效果: Dingjunge s 效果ID [效果ID ...]")
|
| | | return
|
| | | mapID = ChConfig.Def_FBMapID_Dingjunge
|
| | | value1 = paramList[0]
|
| | | |
| | | if value1 == "e":
|
| | | addEffCnt = paramList[1] if len(paramList) > 1 else 1
|
| | | GameLogic_Dingjunge.GivePassLayerEff(curPlayer, addEffCnt)
|
| | | elif value1 == "s":
|
| | | setEffIDList = paramList[1:]
|
| | | sEffIDList = []
|
| | | for sIndex in range(IpyGameDataPY.GetFuncCfg("DingjungeEff", 3)):
|
| | | effID = setEffIDList[sIndex] if len(setEffIDList) > sIndex else 0
|
| | | if effID and not IpyGameDataPY.GetIpyGameDataNotLog("FBDJGEffect", effID):
|
| | | GameWorld.DebugAnswer(curPlayer, "效果ID不存在:%s" % effID)
|
| | | effID = 0
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGSelectEffect % sIndex, effID)
|
| | | sEffIDList.append(effID)
|
| | | GameWorld.DebugAnswer(curPlayer, "待选效果ID:%s" % sEffIDList)
|
| | | else:
|
| | | todayLineID = value1
|
| | | highestLineID = paramList[1] if len(paramList) > 1 else None
|
| | | if not highestLineID:
|
| | | highestLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
|
| | | |
| | | layerNum, levelNum = todayLineID / 100, todayLineID % 100
|
| | | ipyData = IpyGameDataPY.GetIpyGameDataNotLog("FBDJGLevel", layerNum, levelNum)
|
| | | if not ipyData:
|
| | | GameWorld.DebugAnswer(curPlayer, "不存在该层关卡:%s-%s" % (layerNum, levelNum))
|
| | | return
|
| | | |
| | | if highestLineID:
|
| | | if todayLineID > highestLineID:
|
| | | highestLineID = todayLineID
|
| | | hLayerNum, hLevelNum = highestLineID / 100, highestLineID % 100
|
| | | if not IpyGameDataPY.GetIpyGameDataNotLog("FBDJGLevel", hLayerNum, hLevelNum):
|
| | | GameWorld.DebugAnswer(curPlayer, "不存在该层关:%s-%s" % (hLayerNum, hLevelNum))
|
| | | return
|
| | | |
| | | GameWorld.DebugAnswer(curPlayer, "历史最高层关:%s-%s" % (hLayerNum, hLevelNum))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FBPassLineID % mapID, highestLineID)
|
| | | FBCommon.Sync_FBPlayerFBInfoData(curPlayer, mapID)
|
| | | |
| | | GameWorld.DebugAnswer(curPlayer, "今日层关:%s-%s" % (layerNum, levelNum))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGLineID, todayLineID)
|
| | | |
| | | GameLogic_Dingjunge.SyncDingjungeInfo(curPlayer)
|
| | | return
|
| | |
| | | def OnPlayerFBQuickPass(curPlayer, mapID, lineID):
|
| | | '''副本快速过关验证
|
| | | @param mapID: 数据地图ID
|
| | | @param lineID: 目标关卡线路ID,可一次性跳多关,由前端发包决定
|
| | | @return: (bossID, quickCnt) 或 None
|
| | | @note: bossID 目标NPCID - 目标关卡所需要挑战的主NPCID,一般是boss,用于验证战力是否满足快速过关
|
| | | @note: quickCnt 本次总共跳过几关 - 默认1
|
| | | @param lineID: 目标关卡线路ID,可一次性跳多关,根据功能由前端发包决定或后端直接决定
|
| | | @return: (lineID, quickCnt, quickFightPower, quickData) 或 None
|
| | | @note: lineID 由后端决定的快速过关到哪,如果前端决定的则直接返回 lineID
|
| | | @note: quickCnt 本次总共跳过几关 |
| | | @note: quickFightPower 目标阵容战力,用于验证战力是否满足快速过关
|
| | | @note: quickData 扩展数据,功能自定义,传给 OnPlayerFBQuickPassResult
|
| | | '''
|
| | | do_FBLogic_ID = __GetFBLogic_MapID(mapID)
|
| | |
|
| | |
| | |
|
| | | return callFunc(curPlayer, mapID, lineID)
|
| | |
|
| | | def OnPlayerFBQuickPassResult(curPlayer, mapID, lineID):
|
| | | def OnPlayerFBQuickPassResult(curPlayer, mapID, lineID, quickData):
|
| | | '''副本快速过关结果
|
| | | '''
|
| | | do_FBLogic_ID = __GetFBLogic_MapID(mapID)
|
| | |
| | | if callFunc == None:
|
| | | return
|
| | |
|
| | | return callFunc(curPlayer, mapID, lineID)
|
| | | return callFunc(curPlayer, mapID, lineID, quickData)
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
|
| New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GameWorldLogic.FBProcess.GameLogic_Dingjunge
|
| | | #
|
| | | # @todo:定军阁
|
| | | # @author hxp
|
| | | # @date 2026-01-06
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 定军阁
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2026-01-06 13:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import FBCommon
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import PlayerBillboard
|
| | | import ChPyNetSendPack
|
| | | import ItemControler
|
| | | import IpyGameDataPY
|
| | | import NetPackCommon
|
| | | import ChConfig
|
| | |
|
| | | # 自动选择排序优先级索引
|
| | | (
|
| | | Priority_InSet, # 0
|
| | | Priority_EffQuality, # 1
|
| | | Priority_SetPriority, # 2
|
| | | Priority_EIndex, # 3
|
| | | Priority_EffInfo, # 4
|
| | | Priority_EffID, # 5
|
| | | Priority_AttrID, # 6
|
| | | ) = range(7)
|
| | |
|
| | | def OnFBPlayerOnLogin(curPlayer):
|
| | | SyncDingjungeInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def OnFBPlayerOnDay(curPlayer):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGLineID, 0)
|
| | | for eIndex in range(len(IpyGameDataPY.GetFuncEvalCfg("DingjungeEff", 1))):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % eIndex, 0)
|
| | | for sIndex in range(IpyGameDataPY.GetFuncCfg("DingjungeEff", 3)):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGSelectEffect % sIndex, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGUnSelectCnt, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffAuto, 0) # 每日重置自动开关
|
| | | SyncDingjungeInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def GetNextIpyData(curPlayer):
|
| | | ## 获取下一关ipyData
|
| | | todayLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGLineID)
|
| | | layerNum, levelNum = todayLineID / 100, todayLineID % 100
|
| | | if not layerNum:
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("FBDJGLevel", 1, 1)
|
| | | elif not levelNum:
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("FBDJGLevel", layerNum, 1)
|
| | | else:
|
| | | nextLayerNum = layerNum
|
| | | nextLevelNum = levelNum + 1 # 下一关
|
| | | ipyData = IpyGameDataPY.GetIpyGameDataNotLog("FBDJGLevel", nextLayerNum, nextLevelNum)
|
| | | if not ipyData:# 没有下一关取下一层
|
| | | nextLayerNum = layerNum + 1
|
| | | nextLevelNum = 1
|
| | | ipyData = IpyGameDataPY.GetIpyGameDataNotLog("FBDJGLevel", nextLayerNum, nextLevelNum)
|
| | | if ipyData:
|
| | | return ipyData
|
| | | GameWorld.DebugLog("已通关或找不到下一关数据! layerNum=%s,levelNum=%s" % (layerNum, levelNum))
|
| | | return
|
| | |
|
| | | def GetPassLayerMax(curPlayer):
|
| | | ## 获取已通关的最大层级
|
| | | mapID = ChConfig.Def_FBMapID_Dingjunge
|
| | | highestLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
|
| | | hLayerNum, hLevelNum = highestLineID / 100, highestLineID % 100
|
| | | passLayerMax = max(0, hLayerNum - 1) # 默认通关的是上一层
|
| | | # 如果过关记录在本层,且没有下一关了,也算通关了本层
|
| | | if hLayerNum and hLevelNum and not IpyGameDataPY.GetIpyGameDataNotLog("FBDJGLevel", hLayerNum, hLevelNum + 1):
|
| | | passLayerMax = hLayerNum
|
| | | return passLayerMax
|
| | |
|
| | | def GetQuickStartLayer(curPlayer):
|
| | | ## 获取快速挑战的起始层级
|
| | | # @return: >1-可快速挑战的起始层级
|
| | | passLayerMax = GetPassLayerMax(curPlayer)
|
| | | backLayers = IpyGameDataPY.GetFuncCfg("Dingjunge", 1)
|
| | | quickStartLayer = passLayerMax + 1 - backLayers # 需要+1层
|
| | | if quickStartLayer > 1:
|
| | | return quickStartLayer
|
| | | return 0
|
| | |
|
| | | def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagType, tagID, valueList):
|
| | | ## 回合战斗请求 |
| | | highestLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
|
| | | quickStartLayer = GetQuickStartLayer(curPlayer)
|
| | | if quickStartLayer:
|
| | | todayLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGLineID)
|
| | | if not todayLineID:
|
| | | GameWorld.DebugLog("今日还未快速战斗无法手动挑战! highestLineID=%s,quickStartLayer=%s" % (highestLineID, quickStartLayer))
|
| | | return
|
| | | nextIpyData = GetNextIpyData(curPlayer)
|
| | | if not nextIpyData:
|
| | | return
|
| | | layerNum = nextIpyData.GetLayerNum()
|
| | | levelNum = nextIpyData.GetLevelNum()
|
| | | funcLineID = layerNum * 100 + levelNum
|
| | | return True, funcLineID
|
| | |
|
| | | def GetFBNPCLineupInfo(curPlayer, mapID, funcLineID):
|
| | | ## 获取NPC阵容相关
|
| | | # @return: npcLineupIDList, strongerLV, difficulty
|
| | | |
| | | layerNum, levelNum = funcLineID / 100, funcLineID % 100
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("FBDJGLevel", layerNum, levelNum)
|
| | | if not ipyData:
|
| | | return
|
| | | |
| | | npcLineupIDList = ipyData.GetLineupIDList()
|
| | | strongerLV = ipyData.GetNPCLV()
|
| | | difficulty = ipyData.GetDifficulty()
|
| | | |
| | | return npcLineupIDList, strongerLV, difficulty
|
| | |
|
| | | def OnTurnFightAward(curPlayer, guid, mapID, funcLineID, winFaction, statMsg, dateStr, reqData, awardDict):
|
| | | ## 回合战斗结算奖励
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | isWin = winFaction == ChConfig.Def_FactionA
|
| | | |
| | | if not isWin:
|
| | | return
|
| | | |
| | | todayLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGLineID)
|
| | | GameWorld.DebugLog("定军阁结算: funcLineID=%s,todayLineID=%s" % (funcLineID, todayLineID))
|
| | | if todayLineID >= funcLineID:
|
| | | GameWorld.DebugLog("今日已过关的不重复结算奖励! todayLineID=%s >= %s" % (todayLineID, funcLineID))
|
| | | return
|
| | | |
| | | layerNum, levelNum = funcLineID / 100, funcLineID % 100
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("FBDJGLevel", layerNum, levelNum)
|
| | | if not ipyData:
|
| | | return
|
| | | |
| | | awardItemList = []
|
| | | highestLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
|
| | | # 首通
|
| | | if funcLineID > highestLineID:
|
| | | firstPassAwardList = ipyData.GetPassAwardList()
|
| | | awardItemList += firstPassAwardList
|
| | | GameWorld.DebugLog("首次过关: highestLineID=%s,firstPassAwardList=%s" % (highestLineID, firstPassAwardList))
|
| | | FBCommon.SetFBPass(curPlayer, mapID, funcLineID)
|
| | | PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_Dingjunge, funcLineID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGLineID, funcLineID)
|
| | | |
| | | awardItemList += ipyData.GetAwardList() # 挑战奖励
|
| | | GameWorld.DebugLog("最终奖励: mapID=%s,layerNum=%s,levelNum=%s,awardItemList=%s" % (mapID, layerNum, levelNum, awardItemList))
|
| | | awardDict.update({FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(awardItemList)})
|
| | | |
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Dingjunge", False, {}], isNotifyAward=False)
|
| | | |
| | | if not IpyGameDataPY.GetIpyGameDataNotLog("FBDJGLevel", layerNum, levelNum + 1):
|
| | | GameWorld.DebugLog("本层没有下一关了,通关本层!: layerNum=%s,levelNum=%s" % (layerNum, levelNum))
|
| | | GivePassLayerEff(curPlayer, 1)
|
| | | |
| | | SyncDingjungeInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def OnPlayerFBQuickPass(curPlayer, mapID, lineID):
|
| | | '''副本快速过关验证
|
| | | @param mapID: 数据地图ID
|
| | | @param lineID: 目标关卡线路ID,可一次性跳多关,根据功能由前端发包决定或后端直接决定
|
| | | @return: (lineID, quickCnt, quickFightPower, quickData) 或 None
|
| | | @note: lineID 由后端决定的快速过关到哪,如果前端决定的则直接返回 lineID
|
| | | @note: quickCnt 本次总共跳过几关 |
| | | @note: quickFightPower 目标阵容战力,用于验证战力是否满足快速过关
|
| | | @note: quickData 扩展数据,功能自定义,传给 OnPlayerFBQuickPassResult
|
| | | '''
|
| | | |
| | | todayLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGLineID)
|
| | | if todayLineID:
|
| | | GameWorld.DebugLog("今日已经在手动战斗了,无法快速挑战! todayLineID=%s" % (todayLineID))
|
| | | return
|
| | | |
| | | highestLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
|
| | | quickStartLayer = GetQuickStartLayer(curPlayer)
|
| | | if not quickStartLayer:
|
| | | GameWorld.DebugLog("还未达到可快速挑战的层级! highestLineID=%s" % (highestLineID))
|
| | | return
|
| | | quickData = [highestLineID, quickStartLayer]
|
| | | quickCnt = 0
|
| | | quickFightPower = 0
|
| | | return lineID, quickCnt, quickFightPower, quickData
|
| | |
|
| | | def OnPlayerFBQuickPassResult(curPlayer, mapID, lineID, quickData):
|
| | | ## 副本快速过关结果
|
| | | |
| | | highestLineID, quickStartLayer = quickData
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | passLayerMax = GetPassLayerMax(curPlayer) # 历史最大过关层级
|
| | | todayLineID = quickStartLayer * 100 + 0 # 先设置已过到起始层第0关,前端如果有问题再设置为上一层最后一关
|
| | | GameWorld.DebugLog("定军阁快速战斗: highestLineID=%s,passLayerMax=%s,quickStartLayer=%s,todayLineID=%s" |
| | | % (highestLineID, passLayerMax, quickStartLayer, todayLineID), playerID)
|
| | | |
| | | # 快速过关奖励按历史最大过关层级领取
|
| | | awardItemDict = {}
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetFBDJGQuickCount()):
|
| | | quickIpyData = ipyDataMgr.GetFBDJGQuickByIndex(index)
|
| | | needLayer = quickIpyData.GetNeedLayer()
|
| | | if needLayer > passLayerMax:
|
| | | break
|
| | | quickItemList = quickIpyData.GetQuickAwardList()
|
| | | for itemInfo in quickItemList:
|
| | | itemID, itemCount = itemInfo[:2]
|
| | | awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount
|
| | | awardItemList = [[itemID, itemCount] for itemID, itemCount in awardItemDict.items()]
|
| | | |
| | | # 设置起始层关卡
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGLineID, todayLineID)
|
| | | |
| | | addEffCnt = quickStartLayer - 1 # -1是代表加成效果结算到起始的上一层,每过1层+1次
|
| | | GivePassLayerEff(curPlayer, addEffCnt)
|
| | | SyncDingjungeInfo(curPlayer)
|
| | | |
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Dingjunge", False, {}])
|
| | | return
|
| | |
|
| | | def GivePassLayerEff(curPlayer, addEffCnt=1):
|
| | | unSelectCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGUnSelectCnt) + addEffCnt
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGUnSelectCnt, unSelectCnt)
|
| | | GameWorld.DebugLog("增加效果加成次数: addEffCnt=%s,unSelectCnt=%s" % (addEffCnt, unSelectCnt))
|
| | | if not __doAutoSelectAll(curPlayer):
|
| | | __randSelectEff(curPlayer)
|
| | | return
|
| | |
|
| | | #// B1 01 定军阁效果预设 #tagCSDingjungeEffSet
|
| | | #
|
| | | #struct tagCSDingjungeEffSet
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE SelectAuto; //是否启用自动选择
|
| | | # BYTE SelectSetCnt;
|
| | | # WORD SelectSetAttrIDList[SelectSetCnt]; //预设优先选择属性ID列表 [优先级1属性ID, ...]
|
| | | #};
|
| | | def OnDingjungeEffSet(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | selectAuto = 1 if clientData.SelectAuto else 0
|
| | | selectSetAttrIDList = clientData.SelectSetAttrIDList
|
| | | |
| | | canSetAttrIDList = []
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetFBDJGEffectCount()):
|
| | | ipyData = ipyDataMgr.GetFBDJGEffectByIndex(index)
|
| | | attrID = ipyData.GetAttrID()
|
| | | if attrID not in canSetAttrIDList:
|
| | | canSetAttrIDList.append(attrID)
|
| | | canSetAttrIDList.sort()
|
| | | |
| | | GameWorld.DebugLog("效果预设: selectAuto=%s,selectSetAttrIDList=%s,canSetAttrIDList=%s" % (selectAuto, selectSetAttrIDList, canSetAttrIDList))
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffAuto, selectAuto)
|
| | | for ssIndex in range(IpyGameDataPY.GetFuncCfg("DingjungeEff", 4)):
|
| | | attrID = selectSetAttrIDList[ssIndex] if len(selectSetAttrIDList) > ssIndex else 0
|
| | | if attrID not in canSetAttrIDList:
|
| | | attrID = 0
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffSet % ssIndex, attrID)
|
| | | SyncDingjungeInfo(curPlayer)
|
| | | return
|
| | |
|
| | | #// B1 02 定军阁效果选择 #tagCSDingjungeEffSelect
|
| | | #
|
| | | #struct tagCSDingjungeEffSelect
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE SelectType; //0-手动选择,1-放弃本次选择,2-一键选择(仅开启了自动选择时有效)
|
| | | # BYTE SelectIndex; //手动选择索引 0~n
|
| | | # BYTE ReplaceHole; //手动选择替换槽位 1~n,槽位=槽索引+1,升级时可直接发0
|
| | | #};
|
| | | def OnDingjungeEffSelect(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | selectType = clientData.SelectType
|
| | | selectIndex = clientData.SelectIndex
|
| | | replaceHole = clientData.ReplaceHole
|
| | | |
| | | if selectType == 2:
|
| | | __doAutoSelectAll(curPlayer)
|
| | | elif selectType == 1:
|
| | | __randSelectEff(curPlayer, isReset=True)
|
| | | else:
|
| | | if __doSelectEff(curPlayer, selectIndex, replaceHole):
|
| | | __randSelectEff(curPlayer, isReset=True)
|
| | | |
| | | SyncDingjungeInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def __doAutoSelectAll(curPlayer):
|
| | | if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffAuto):
|
| | | GameWorld.DebugLog("未开启自动选择!")
|
| | | return
|
| | | unSelectCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGUnSelectCnt)
|
| | | |
| | | selectSetAttrIDList = [] # 效果选择预设
|
| | | for ssIndex in range(IpyGameDataPY.GetFuncCfg("DingjungeEff", 4)):
|
| | | attrID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffSet % ssIndex)
|
| | | if attrID:
|
| | | selectSetAttrIDList.append(attrID)
|
| | | |
| | | effHoleCnt = __getUnlockEffHoleCnt(curPlayer)
|
| | | |
| | | GameWorld.DebugLog("执行一键选择加成效果: unSelectCnt=%s,effHoleCnt=%s,selectSetAttrIDList=%s" % (unSelectCnt, effHoleCnt, selectSetAttrIDList))
|
| | | |
| | | randEffCnt = IpyGameDataPY.GetFuncCfg("DingjungeEff", 3)
|
| | | for _ in range(unSelectCnt):
|
| | | effIDList = __randSelectEff(curPlayer, randEffCnt)
|
| | | if not effIDList:
|
| | | break
|
| | | if not __doAutoSelectEff(curPlayer, effIDList, selectSetAttrIDList, effHoleCnt):
|
| | | # 不需要自动选择,直接退出,玩家手动选择
|
| | | break
|
| | | # 自动选择后重置
|
| | | for sIndex in range(randEffCnt):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGSelectEffect % sIndex, 0)
|
| | | return True
|
| | |
|
| | | def __getUnlockEffHoleCnt(curPlayer):
|
| | | ## 获取已解锁的效果槽数
|
| | | todayLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGLineID)
|
| | | effHoleNeedLVIDList = IpyGameDataPY.GetFuncEvalCfg("DingjungeEff", 1)
|
| | | effHoleCnt = 0 # 已解锁的效果槽数
|
| | | for needLVID in effHoleNeedLVIDList:
|
| | | if todayLineID >= needLVID:
|
| | | effHoleCnt += 1
|
| | | return effHoleCnt
|
| | |
|
| | | def __randSelectEff(curPlayer, randEffCnt=0, isReset=False):
|
| | | ## 随机生成待选择加成效果
|
| | | unSelectCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGUnSelectCnt)
|
| | | if unSelectCnt <= 0:
|
| | | GameWorld.DebugLog("没有未处理的加成效果次数了")
|
| | | return
|
| | | if not randEffCnt:
|
| | | randEffCnt = IpyGameDataPY.GetFuncCfg("DingjungeEff", 3)
|
| | | effIDList = []
|
| | | if isReset:
|
| | | # 重置
|
| | | for sIndex in range(randEffCnt):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGSelectEffect % sIndex, 0)
|
| | | else:
|
| | | for sIndex in range(randEffCnt):
|
| | | effID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGSelectEffect % sIndex)
|
| | | if not effID:
|
| | | break
|
| | | effIDList.append(effID)
|
| | | if effIDList:
|
| | | GameWorld.DebugLog("已存在未选择的加成效果等选择后再生成: effIDList=%s,unSelectCnt=%s" % (effIDList, unSelectCnt))
|
| | | return effIDList
|
| | | |
| | | fullLVEffIDList = [] # 已满级的效果ID列表
|
| | | effMaxLV = IpyGameDataPY.GetFuncCfg("DingjungeEff", 2)
|
| | | for eIndex in range(len(IpyGameDataPY.GetFuncEvalCfg("DingjungeEff", 1))):
|
| | | effInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffect % eIndex)
|
| | | if not effInfo:
|
| | | break
|
| | | effID, effLV = effInfo / 100, effInfo % 100
|
| | | if effLV >= effMaxLV:
|
| | | fullLVEffIDList.append(effID)
|
| | | |
| | | randWeightList = []
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetFBDJGEffectCount()):
|
| | | ipyData = ipyDataMgr.GetFBDJGEffectByIndex(index)
|
| | | effID = ipyData.GetEffID()
|
| | | if effID in fullLVEffIDList:
|
| | | # 排除满级的
|
| | | continue
|
| | | randWeight = ipyData.GetRandWeight()
|
| | | if randWeight:
|
| | | randWeightList.append([randWeight, effID])
|
| | | |
| | | # 随机效果,不重复
|
| | | randCnt = 200
|
| | | while len(effIDList) < randEffCnt and randCnt > 0:
|
| | | randCnt -= 1
|
| | | randEffID = GameWorld.GetResultByWeightList(randWeightList)
|
| | | if randEffID not in effIDList:
|
| | | effIDList.append(randEffID)
|
| | | |
| | | unSelectCnt -= 1
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGUnSelectCnt, unSelectCnt)
|
| | | for sIndex in range(randEffCnt):
|
| | | effID = effIDList[sIndex] if len(effIDList) > sIndex else 0
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGSelectEffect % sIndex, effID)
|
| | | #GameWorld.DebugLog("随机生成加成效果: effIDList=%s,unSelectCnt=%s,fullLVEffIDList=%s" % (effIDList, unSelectCnt, fullLVEffIDList))
|
| | | return effIDList
|
| | |
|
| | | def __doAutoSelectEff(curPlayer, selectEffIDList, selectSetAttrIDList, effHoleCnt):
|
| | | ## 自动选择加成
|
| | | |
| | | # 若随机出了多种预设内的的属性,则优先选择品质高的,只出现单种预设内属性的话,则预设优先
|
| | | priorityEffList = [] # 品质优先
|
| | | for effID in selectEffIDList:
|
| | | effIpyData = IpyGameDataPY.GetIpyGameData("FBDJGEffect", effID)
|
| | | if not effIpyData:
|
| | | continue
|
| | | effQuality = effIpyData.GetEffQuality()
|
| | | attrID = effIpyData.GetAttrID()
|
| | | inSet = 0 # 预设优先,但多个预设同时出现时,先品质优先,再预设优先级
|
| | | setPriority = 0 # 预设排序优先级
|
| | | if attrID in selectSetAttrIDList:
|
| | | inSet = 1
|
| | | setPriority = len(selectSetAttrIDList) - selectSetAttrIDList.index(attrID)
|
| | | |
| | | effLV = 1 # 初始1级
|
| | | effInfo = effID * 100 + effLV
|
| | | eIndex = -1 # 生效索引,设为-1,比已生效的低
|
| | | priorityEffList.append([inSet, effQuality, setPriority, eIndex, effInfo, effID, attrID])
|
| | | |
| | | priorityEffList.sort(reverse=True)
|
| | | if not priorityEffList:
|
| | | return
|
| | | #GameWorld.DebugLog(" 排序优先级: [inSet, effQuality, setPriority, eIndex, effInfo, effID, attrID]")
|
| | | #GameWorld.DebugLog(" 待选择排序: %s" % priorityEffList)
|
| | | selectEff = priorityEffList[0] # 自动选择第一个
|
| | | #selectAttrID = selectEff[Priority_AttrID]
|
| | | selectEffID = selectEff[Priority_EffID]
|
| | | selectEffInfo = selectEff[Priority_EffInfo]
|
| | | |
| | | effMaxLV = IpyGameDataPY.GetFuncCfg("DingjungeEff", 2)
|
| | | emptyIndex = -1
|
| | | effList = [] # 已生效的效果
|
| | | for eIndex in range(effHoleCnt):
|
| | | effInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffect % eIndex)
|
| | | if not effInfo:
|
| | | if emptyIndex == -1:
|
| | | #GameWorld.DebugLog(" 还有空槽: eIndex=%s" % eIndex)
|
| | | emptyIndex = eIndex
|
| | | continue
|
| | | |
| | | effID, effLV = effInfo / 100, effInfo % 100
|
| | | |
| | | effIpyData = IpyGameDataPY.GetIpyGameData("FBDJGEffect", effID)
|
| | | if not effIpyData:
|
| | | continue
|
| | | effQuality = effIpyData.GetEffQuality()
|
| | | attrID = effIpyData.GetAttrID()
|
| | | |
| | | # 已存在,升级
|
| | | if effID == selectEffID and effLV < effMaxLV:
|
| | | effLV += 1
|
| | | effInfo = effID * 100 + effLV
|
| | | #GameWorld.DebugLog(" 已存在该效果直接升级: eIndex=%s,effID=%s,effLV=%s,attrID=%s" % (eIndex, effID, effLV, attrID))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % eIndex, effInfo)
|
| | | return True
|
| | | |
| | | inSet = 0 # 预设优先,但多个预设同时出现时,先品质优先,再预设优先级
|
| | | setPriority = 0 # 预设排序优先级
|
| | | if attrID in selectSetAttrIDList:
|
| | | inSet = 1
|
| | | setPriority = len(selectSetAttrIDList) - selectSetAttrIDList.index(attrID)
|
| | | |
| | | effList.append([inSet, effQuality, setPriority, eIndex, effInfo, effID, attrID])
|
| | | |
| | | # 空槽
|
| | | if emptyIndex != -1:
|
| | | eIndex = emptyIndex
|
| | | effID = selectEffID
|
| | | effLV = 1
|
| | | effInfo = effID * 100 + effLV
|
| | | #GameWorld.DebugLog(" 空槽直接设置: emptyIndex=%s,effID=%s,effLV=%s,attrID=%s,effList=%s" % (eIndex, effID, effLV, selectAttrID, effList))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % eIndex, effInfo)
|
| | | return True
|
| | | |
| | | # 替换逻辑
|
| | | effList.append(selectEff) # 选择项再与生效的一起排序
|
| | | effList.sort(reverse=True)
|
| | | |
| | | lastEff = effList[-1]
|
| | | lastEIndex = lastEff[Priority_EIndex]
|
| | | #lastEffID = lastEff[Priority_EffID]
|
| | | #lastAttrID = lastEff[Priority_AttrID]
|
| | | if lastEIndex == -1:
|
| | | pass
|
| | | #GameWorld.DebugLog(" 优先级比已生效的低,直接舍弃! lastEIndex=%s,lastEffID=%s,lastAttrID=%s,effList=%s" % (lastEIndex, lastEffID, lastAttrID, effList))
|
| | | else:
|
| | | replaceIndex = lastEIndex
|
| | | effInfo = selectEffInfo
|
| | | #GameWorld.DebugLog(" 优先级比已生效的高,直接替换! replaceIndex=%s,selectAttrID=%s,effInfo=%s,effList=%s" % (replaceIndex, selectAttrID, effInfo, effList))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % replaceIndex, effInfo)
|
| | | |
| | | return True
|
| | |
|
| | | def __doSelectEff(curPlayer, selectIndex, replaceHole):
|
| | | ## 手动选择效果
|
| | | selectEffID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGSelectEffect % selectIndex)
|
| | | GameWorld.DebugLog("手动选择效果: selectIndex=%s,selectEffID=%s,replaceHole=%s" % (selectIndex, selectEffID, replaceHole))
|
| | | if not selectEffID:
|
| | | return
|
| | | effHoleCnt = __getUnlockEffHoleCnt(curPlayer)
|
| | | effMaxLV = IpyGameDataPY.GetFuncCfg("DingjungeEff", 2)
|
| | | emptyIndex = -1
|
| | | for eIndex in range(effHoleCnt):
|
| | | effInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffect % eIndex)
|
| | | if not effInfo:
|
| | | if emptyIndex == -1:
|
| | | GameWorld.DebugLog(" 还有空槽: eIndex=%s" % eIndex)
|
| | | emptyIndex = eIndex
|
| | | continue
|
| | | effID, effLV = effInfo / 100, effInfo % 100
|
| | | # 已存在,升级
|
| | | if effID == selectEffID:
|
| | | if effLV >= effMaxLV:
|
| | | GameWorld.DebugLog(" 已存在该效果且已满级: eIndex=%s,effID=%s,effLV=%s" % (eIndex, effID, effLV))
|
| | | return
|
| | | effLV += 1
|
| | | effInfo = effID * 100 + effLV
|
| | | GameWorld.DebugLog(" 已存在该效果直接升级: eIndex=%s,effID=%s,effLV=%s" % (eIndex, effID, effLV))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % eIndex, effInfo)
|
| | | return True
|
| | | |
| | | # 空槽
|
| | | if emptyIndex != -1:
|
| | | eIndex = emptyIndex
|
| | | effID = selectEffID
|
| | | effLV = 1
|
| | | effInfo = effID * 100 + effLV
|
| | | GameWorld.DebugLog(" 空槽直接设置: emptyIndex=%s,effID=%s,effLV=%s" % (eIndex, effID, effLV))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % eIndex, effInfo)
|
| | | return True
|
| | | |
| | | # 替换逻辑
|
| | | if replaceHole < 1 or replaceHole > effHoleCnt:
|
| | | GameWorld.DebugLog(" 替换的目标槽位不可用: replaceHole=%s,effHoleCnt=%s" % (replaceHole, effHoleCnt))
|
| | | return
|
| | | |
| | | effLV = 1
|
| | | selectEffInfo = selectEffID * 100 + effLV
|
| | | replaceIndex = replaceHole - 1
|
| | | effInfo = selectEffInfo
|
| | | GameWorld.DebugLog(" 手动选择替换! replaceIndex=%s,effInfo=%s" % (replaceIndex, effInfo))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DJGEffect % replaceIndex, effInfo)
|
| | | return True
|
| | |
|
| | | def SyncDingjungeInfo(curPlayer):
|
| | | clientPack = ChPyNetSendPack.tagSCDingjungeInfo()
|
| | | clientPack.TodayPass = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGLineID)
|
| | | effList = [] # 已生效的效果
|
| | | for eIndex in range(len(IpyGameDataPY.GetFuncEvalCfg("DingjungeEff", 1))):
|
| | | effInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffect % eIndex)
|
| | | if not effInfo:
|
| | | break
|
| | | effID, effLV = effInfo / 100, effInfo % 100
|
| | | eff = ChPyNetSendPack.tagSCDingjungeEff()
|
| | | eff.EffIndex = eIndex
|
| | | eff.EffID = effID
|
| | | eff.EffLV = effLV
|
| | | effList.append(eff)
|
| | | clientPack.EffList = effList
|
| | | clientPack.EffCnt = len(clientPack.EffList)
|
| | | selectEffList = [] # 待选择的效果
|
| | | for sIndex in range(IpyGameDataPY.GetFuncCfg("DingjungeEff", 3)):
|
| | | effID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGSelectEffect % sIndex)
|
| | | if not effID:
|
| | | break
|
| | | selectEffList.append(effID)
|
| | | clientPack.SelectEffList = selectEffList
|
| | | clientPack.SelectEffCnt = len(clientPack.SelectEffList)
|
| | | clientPack.UnSelectCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGUnSelectCnt)
|
| | | clientPack.SelectAuto = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffAuto)
|
| | | selectSetAttrIDList = [] # 效果选择预设
|
| | | for ssIndex in range(IpyGameDataPY.GetFuncCfg("DingjungeEff", 4)):
|
| | | attrID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DJGEffSet % ssIndex)
|
| | | selectSetAttrIDList.append(attrID)
|
| | | clientPack.SelectSetAttrIDList = selectSetAttrIDList
|
| | | clientPack.SelectSetCnt = len(clientPack.SelectSetAttrIDList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
| | | ("list", "RandWeightItemList", 0),
|
| | | ),
|
| | |
|
| | | "FBDJGLevel":(
|
| | | ("WORD", "LayerNum", 1),
|
| | | ("BYTE", "LevelNum", 1),
|
| | | ("list", "PassAwardList", 0),
|
| | | ("list", "AwardList", 0),
|
| | | ("list", "LineupIDList", 0),
|
| | | ("WORD", "NPCLV", 0),
|
| | | ("float", "Difficulty", 0),
|
| | | ),
|
| | |
|
| | | "FBDJGQuick":(
|
| | | ("WORD", "NeedLayer", 1),
|
| | | ("list", "QuickAwardList", 0),
|
| | | ),
|
| | |
|
| | | "FBDJGEffect":(
|
| | | ("DWORD", "EffID", 1),
|
| | | ("BYTE", "EffQuality", 0),
|
| | | ("BYTE", "AttrID", 0),
|
| | | ("DWORD", "AttrValue", 0),
|
| | | ("DWORD", "RandWeight", 0),
|
| | | ),
|
| | |
|
| | | "ADAward":(
|
| | | ("DWORD", "ADID", 1),
|
| | | ("BYTE", "ADCntMax", 0),
|
| | |
| | | def GetOtherAttrDict(self): return self.attrTuple[5] # 其他属性 {attrID:attrValue, ...} dict
|
| | | def GetRandWeightItemList(self): return self.attrTuple[6] # 宝箱随机物品权重列表,[[权重,物品ID,数量], ...] list |
| | | |
| | | # 定军阁关卡表 |
| | | class IPY_FBDJGLevel(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetLayerNum(self): return self.attrTuple[0] # 层数 WORD
|
| | | def GetLevelNum(self): return self.attrTuple[1] # 关卡编号 BYTE
|
| | | def GetPassAwardList(self): return self.attrTuple[2] # 过关奖励列表,[[物品ID,个数], ...] list
|
| | | def GetAwardList(self): return self.attrTuple[3] # 挑战奖励,[[物品ID,个数], ...] list
|
| | | def GetLineupIDList(self): return self.attrTuple[4] # 阵容ID列表,小队1阵容ID|小队2阵容ID|... list
|
| | | def GetNPCLV(self): return self.attrTuple[5] # NPC等级 WORD
|
| | | def GetDifficulty(self): return self.attrTuple[6] # 难度系数 float |
| | | |
| | | # 定军阁速战奖励表 |
| | | class IPY_FBDJGQuick(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetNeedLayer(self): return self.attrTuple[0] # 所需层数 WORD
|
| | | def GetQuickAwardList(self): return self.attrTuple[1] # 速战奖励列表,[[物品ID,个数], ...] list |
| | | |
| | | # 定军阁效果表 |
| | | class IPY_FBDJGEffect(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetEffID(self): return self.attrTuple[0] # 效果ID DWORD
|
| | | def GetEffQuality(self): return self.attrTuple[1] # 效果品质 BYTE
|
| | | def GetAttrID(self): return self.attrTuple[2] # 属性ID BYTE
|
| | | def GetAttrValue(self): return self.attrTuple[3] # 属性值 DWORD
|
| | | def GetRandWeight(self): return self.attrTuple[4] # 随机权重 DWORD |
| | | |
| | | # 广告奖励表 |
| | | class IPY_ADAward(): |
| | | |
| | |
| | | self.__LoadFileData("FBFunc", onlyCheck)
|
| | | self.__LoadFileData("FBLine", onlyCheck)
|
| | | self.__LoadFileData("Tianzi", onlyCheck)
|
| | | self.__LoadFileData("FBDJGLevel", onlyCheck)
|
| | | self.__LoadFileData("FBDJGQuick", onlyCheck)
|
| | | self.__LoadFileData("FBDJGEffect", onlyCheck)
|
| | | self.__LoadFileData("ADAward", onlyCheck)
|
| | | self.__LoadFileData("Success", onlyCheck)
|
| | | self.__LoadFileData("TongTianLV", onlyCheck)
|
| | |
| | | self.CheckLoadData("Tianzi") |
| | | return self.ipyTianziCache[index]
|
| | | |
| | | def GetFBDJGLevelCount(self): |
| | | self.CheckLoadData("FBDJGLevel") |
| | | return self.ipyFBDJGLevelLen
|
| | | def GetFBDJGLevelByIndex(self, index): |
| | | self.CheckLoadData("FBDJGLevel") |
| | | return self.ipyFBDJGLevelCache[index]
|
| | | |
| | | def GetFBDJGQuickCount(self): |
| | | self.CheckLoadData("FBDJGQuick") |
| | | return self.ipyFBDJGQuickLen
|
| | | def GetFBDJGQuickByIndex(self, index): |
| | | self.CheckLoadData("FBDJGQuick") |
| | | return self.ipyFBDJGQuickCache[index]
|
| | | |
| | | def GetFBDJGEffectCount(self): |
| | | self.CheckLoadData("FBDJGEffect") |
| | | return self.ipyFBDJGEffectLen
|
| | | def GetFBDJGEffectByIndex(self, index): |
| | | self.CheckLoadData("FBDJGEffect") |
| | | return self.ipyFBDJGEffectCache[index]
|
| | | |
| | | def GetADAwardCount(self): |
| | | self.CheckLoadData("ADAward") |
| | | return self.ipyADAwardLen
|
| | |
| | | import FBLogic
|
| | | import IpyGameDataPY
|
| | | import ShareDefine
|
| | | import NPCCommon
|
| | | import ChConfig
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | return
|
| | |
|
| | | reqRet = FBLogic.OnPlayerFBQuickPass(curPlayer, mapID, lineID)
|
| | | if not reqRet or len(reqRet) != 2:
|
| | | if not reqRet:
|
| | | GameWorld.DebugLog("无法一键过关副本: mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | return
|
| | | bossID, quickCnt = reqRet
|
| | | if bossID:
|
| | | npcData = GameWorld.GetGameData().FindNPCDataByID(bossID)
|
| | | if not npcData:
|
| | | return
|
| | | npcFightPower = NPCCommon.GetSuppressFightPower(npcData)
|
| | | lineID = reqRet[0]
|
| | | quickCnt = reqRet[1] if len(reqRet) > 1 else 0
|
| | | quickFightPower = reqRet[2] if len(reqRet) > 2 else 0
|
| | | quickData = reqRet[3] if len(reqRet) > 3 else []
|
| | | if quickFightPower:
|
| | | quickNeedRatio = IpyGameDataPY.GetFuncCfg("FBQuickPass", 1)
|
| | | quickNeedFightPower = int(npcFightPower * quickNeedRatio)
|
| | | quickNeedFightPower = int(quickFightPower * quickNeedRatio)
|
| | | curFightPower = PlayerControl.GetFightPower(curPlayer)
|
| | | if quickNeedFightPower and curFightPower < quickNeedFightPower:
|
| | | GameWorld.DebugLog("无法一键过关副本! 战力限制: mapID=%s,lineID=%s,bossID=%s,npcFightPower=%s,quickNeedFightPower=%s > %s" |
| | | % (mapID, lineID, bossID, npcFightPower, quickNeedFightPower, curFightPower), playerID)
|
| | | GameWorld.DebugLog("无法一键过关副本! 战力限制: mapID=%s,lineID=%s,quickFightPower=%s,quickNeedFightPower=%s > %s" |
| | | % (mapID, lineID, quickFightPower, quickNeedFightPower, curFightPower), playerID)
|
| | | PlayerControl.NotifyCode(curPlayer, 'TaskFeedback4')
|
| | | return
|
| | |
|
| | |
| | | FBCommon.AddEnterFBCount(curPlayer, mapID, quickCnt)
|
| | |
|
| | | #扫荡结果给奖励等
|
| | | FBLogic.OnPlayerFBQuickPassResult(curPlayer, mapID, lineID)
|
| | | FBLogic.OnPlayerFBQuickPassResult(curPlayer, mapID, lineID, quickData)
|
| | | return
|
| | |
|
| | |
| | | Def_BT_Tianzi, # 天子考验伤害榜 2
|
| | | Def_BT_OSA_MainLevel, # 开服关卡榜 3
|
| | | Def_BT_OSA_HeroCall, # 开服招募榜 4
|
| | | ) = range(0, 5) |
| | | Def_BT_Dingjunge, # 定军阁过关榜 5
|
| | | ) = range(0, 6) |
| | |
|
| | | ''' 跨服排行榜类型, 从 150 开始,最大条数在功能配置表 CrossBillboardSet 配置,没配默认100
|
| | | 与本服榜单存储的是不一样的数据库表格,理论上类型可以和本服榜单类型重复,为了做下区分防误导,跨服榜单从 150 开始
|
| | |
| | | BillboardTypeAllList = BillboardTypeList + CrossBillboardTypeList
|
| | |
|
| | | BillboardNameDict = {Def_BT_MainLevel:"主线过关榜", Def_BT_Arena:"演武场积分周榜", Def_BT_Tianzi:"天子考验伤害榜",
|
| | | Def_BT_OSA_MainLevel:"开服关卡榜", Def_BT_OSA_HeroCall:"开服招募榜"}
|
| | | Def_BT_OSA_MainLevel:"开服关卡榜", Def_BT_OSA_HeroCall:"开服招募榜", Def_BT_Dingjunge:"定军阁过关榜"}
|
| | |
|
| | | #仙盟榜单类型
|
| | | FamilyBillboardList = []
|