From 34520d2b2a4ac78f832169b7ea120651b7f43c26 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 06 一月 2026 13:02:05 +0800
Subject: [PATCH] 412 【挑战】定军阁-服务端(效果属性暂时无效;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py | 22
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py | 14
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini | 16
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py | 134 ++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 167 ++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 85 ++++
PySysDB/PySysDBPY.h | 29 +
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Dingjunge.py | 77 +++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 9
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Dingjunge.py | 582 +++++++++++++++++++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 15
12 files changed, 1,129 insertions(+), 26 deletions(-)
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 802b26e..6e63716 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -1171,6 +1171,35 @@
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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 29922f9..8419b3a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1183,6 +1183,22 @@
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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
index 3a0d9a0..8b292e4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -1087,13 +1087,14 @@
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
@@ -1277,7 +1278,7 @@
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)})
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 133bd9d..0e906ee 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1897,9 +1897,10 @@
Def_FBMapID_Zhanchui = 30010 # 白骨盈野/战锤秘境
Def_FBMapID_Tianzi = 30020 # 天子考验
+Def_FBMapID_Dingjunge = 30030 # 定军阁
#线路未过关时免费的地图
-UnPassFreeMapIDList = [Def_FBMapID_Zhanchui]
+UnPassFreeMapIDList = [Def_FBMapID_Zhanchui, Def_FBMapID_Dingjunge]
#按星级记录过关的地图
PassByStarMapIDList = []
#扫荡不需要检查是否已过关的地图
@@ -1907,7 +1908,7 @@
#固定玩家获胜的地图
PlayerWinMapIDList = [Def_FBMapID_Tianzi]
#需要汇报中心副本过关进度的地图
-ReportCenterMapIDList = [Def_FBMapID_Zhanchui]
+ReportCenterMapIDList = [Def_FBMapID_Zhanchui, Def_FBMapID_Dingjunge]
#注册上传跨服服务器数据后直接进入跨服服务器的地图
RegisterEnter_CrossServerMapIDList = []
@@ -1981,6 +1982,7 @@
'Arena':[Def_FBMapID_ArenaBattle],
'Zhanchui':[Def_FBMapID_Zhanchui],
'Tianzi':[Def_FBMapID_Tianzi],
+ 'Dingjunge':[Def_FBMapID_Dingjunge],
}
#特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
@@ -3885,6 +3887,15 @@
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/指定类型):[[属性索引, ...], 是否基础属性,(非)线性]}
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 664f69a..4aacc12 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -10984,6 +10984,140 @@
#------------------------------------------------------
+# 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):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index b7fb943..edb273c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -33232,6 +33232,173 @@
#------------------------------------------------------
+# 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):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Dingjunge.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Dingjunge.py
new file mode 100644
index 0000000..41143e0
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Dingjunge.py
@@ -0,0 +1,77 @@
+#!/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
index 20c26fb..1e4d80c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -1549,10 +1549,12 @@
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)
@@ -1564,7 +1566,7 @@
return callFunc(curPlayer, mapID, lineID)
-def OnPlayerFBQuickPassResult(curPlayer, mapID, lineID):
+def OnPlayerFBQuickPassResult(curPlayer, mapID, lineID, quickData):
'''副本快速过关结果
'''
do_FBLogic_ID = __GetFBLogic_MapID(mapID)
@@ -1574,7 +1576,7 @@
if callFunc == None:
return
- return callFunc(curPlayer, mapID, lineID)
+ return callFunc(curPlayer, mapID, lineID, quickData)
#---------------------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Dingjunge.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Dingjunge.py
new file mode 100644
index 0000000..069562e
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Dingjunge.py
@@ -0,0 +1,582 @@
+#!/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index ab8a339..9f0122e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -964,6 +964,29 @@
("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),
@@ -3584,6 +3607,44 @@
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():
@@ -5674,6 +5735,9 @@
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)
@@ -6632,6 +6696,27 @@
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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
index 1a9ca69..b370c04 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFB.py
@@ -29,7 +29,6 @@
import FBLogic
import IpyGameDataPY
import ShareDefine
-import NPCCommon
import ChConfig
#---------------------------------------------------------------------
@@ -120,21 +119,20 @@
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
@@ -146,6 +144,6 @@
FBCommon.AddEnterFBCount(curPlayer, mapID, quickCnt)
#扫荡结果给奖励等
- FBLogic.OnPlayerFBQuickPassResult(curPlayer, mapID, lineID)
+ FBLogic.OnPlayerFBQuickPassResult(curPlayer, mapID, lineID, quickData)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 3d10148..082dd5b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -433,7 +433,8 @@
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 开始
@@ -447,7 +448,7 @@
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 = []
--
Gitblit v1.8.0