From e326cb341ae3562edd549b13bd654102cad29aba Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 31 十二月 2025 16:05:49 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(等级参考值支持多个模版,原等级表参考值去除改为配置在等级参考值表;阵容表增加对应的等级参考值模版ID字段;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py     |   65 ++++++++++++++++++++++----------
 PySysDB/PySysDBPY.h                                                                      |    9 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py |   33 ++++++++--------
 3 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 6e03d75..802b26e 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -373,6 +373,7 @@
 	BYTE		BossPosView;	//Boss通知站位
 	list		SkillIDExList;	// boss附加技能列表
 	BYTE		SkillExCnt;	//随机附加技能数,0为所有
+	WORD		ReModelID;	//等级参考值模版
 };
 
 //称号表
@@ -1055,6 +1056,14 @@
 	DWORD		MaxHP;	//生命
 	DWORD		Atk;	//攻击
 	DWORD		Def;	//防御
+};
+
+//等级参考值
+
+struct LVReValue
+{
+	WORD		_ModelID;	//模版ID
+	WORD		_LV;	//玩家等级
 	BYTE		ReHeroStar;	//参考星级
 	BYTE		ReHeroBreakLV;	//参考突破等级
 	BYTE		ReHeroAwakeLV;	//参考觉醒等级
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 7b0a141..5dda203 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -786,19 +786,20 @@
     npcLV = npcData.GetLV()
     star, breakLV, awakeLV = 0, 0, 0
     
-    lvIpyData = None
+    reModelID = lineupIpyData.GetReModelID()
+    lvReIpyData = None
     heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None
     npcStronger = IpyGameDataPY.GetIpyGameDataNotLog("NPCStronger", npcID)
     if npcStronger and strongerLV:
-        lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", strongerLV)
-        if lvIpyData:
+        lvReIpyData = IpyGameDataPY.GetIpyGameData("LVReValue", reModelID, strongerLV)
+        if lvReIpyData:
             npcLV = strongerLV
-    if not lvIpyData:
-        lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", npcLV)
-    if lvIpyData:
-        star = lvIpyData.GetReHeroStar()
-        breakLV = lvIpyData.GetReHeroBreakLV()
-        awakeLV = lvIpyData.GetReHeroAwakeLV()
+    if not lvReIpyData:
+        lvReIpyData = IpyGameDataPY.GetIpyGameData("LVReValue", reModelID, npcLV)
+    if lvReIpyData:
+        star = lvReIpyData.GetReHeroStar()
+        breakLV = lvReIpyData.GetReHeroBreakLV()
+        awakeLV = lvReIpyData.GetReHeroAwakeLV()
     if heroIpyData:
         skinIDList = heroIpyData.GetSkinIDList()
         skinID = skinIDList[0] if skinIDList else 0
@@ -822,7 +823,7 @@
             GameWorld.DebugLogEx("阵容boss技能: %s, 随机附加技能: %s", skillIDList, randSkillIDExList)
             
     # 成长怪属性
-    batAttrDict = GetNPCStrongerAttrDict(npcID, lvIpyData, npcStronger, difficulty)
+    batAttrDict = GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty)
     if not batAttrDict:
         batAttrDict = {ChConfig.AttrID_Atk:npcData.GetAtk(), ChConfig.AttrID_Def:npcData.GetDef(), ChConfig.AttrID_MaxHP:npcData.GetMaxHP(), 
                        ChConfig.AttrID_FinalDamPer:npcData.GetFinalDamPer(), ChConfig.AttrID_FinalDamPerDef:npcData.GetFinalDamPerDef(), 
@@ -849,7 +850,7 @@
                   "SkillIDList":skillIDList,
                   }
     
-    GameWorld.DebugLogEx("GetNPCBattleDict npcID=%s,strongerLV=%s,difficulty=%s,%s", npcID, strongerLV, difficulty, battleDict)
+    GameWorld.DebugLogEx("GetNPCBattleDict npcID=%s,strongerLV=%s,difficulty=%s,reModelID=%s,%s", npcID, strongerLV, difficulty, reModelID, battleDict)
     return battleDict
 
 def GetNPCHeroSkillIDList(heroID, heroIpyData, breakLV, awakeLV):
@@ -878,23 +879,23 @@
                 
     return skillIDList
 
-def GetNPCStrongerAttrDict(npcID, lvIpyData, npcStronger, difficulty):
+def GetNPCStrongerAttrDict(npcID, lvReIpyData, npcStronger, difficulty):
     ## 获取NPC成长属性
     # @param strongerLV: 成长等级
     # @param difficulty: 难度系数
     
     batAttrDict = {}
-    if not lvIpyData or not npcStronger or not difficulty:
+    if not lvReIpyData or not npcStronger or not difficulty:
         return batAttrDict
-    lv = lvIpyData.GetLV()
+    lv = lvReIpyData.GetLV()
     for attrID in ChConfig.CalcBattleAttrIDList:
         attrIpyData = IpyGameDataPY.GetIpyGameData("PlayerAttr", attrID)
         if not attrIpyData:
             continue
         attrName = attrIpyData.GetParameter()
-        if not hasattr(lvIpyData, "GetRe%s" % attrName):
+        if not hasattr(lvReIpyData, "GetRe%s" % attrName):
             continue
-        reValue = getattr(lvIpyData, "GetRe%s" % attrName)() # 基础参考值
+        reValue = getattr(lvReIpyData, "GetRe%s" % attrName)() # 基础参考值
         ratio = getattr(npcStronger, "Get%sRatio" % attrName)() if hasattr(npcStronger, "Get%sRatio" % attrName) else 1 # 属性系数
         attrValue = int(reValue * ratio * difficulty)
         batAttrDict[attrID] = attrValue
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 64e95be..ab8a339 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -357,6 +357,7 @@
                         ("BYTE", "BossPosView", 0),
                         ("list", "SkillIDExList", 0),
                         ("BYTE", "SkillExCnt", 0),
+                        ("WORD", "ReModelID", 0),
                         ),
 
                 "Title":(
@@ -873,6 +874,11 @@
                         ("DWORD", "MaxHP", 0),
                         ("DWORD", "Atk", 0),
                         ("DWORD", "Def", 0),
+                        ),
+
+                "LVReValue":(
+                        ("WORD", "ModelID", 1),
+                        ("WORD", "LV", 1),
                         ("BYTE", "ReHeroStar", 0),
                         ("BYTE", "ReHeroBreakLV", 0),
                         ("BYTE", "ReHeroAwakeLV", 0),
@@ -2666,7 +2672,8 @@
     def GetBossID(self): return self.attrTuple[7] #  本阵容的BossID,没有boss时为0 DWORD
     def GetBossPosView(self): return self.attrTuple[8] # Boss通知站位 BYTE
     def GetSkillIDExList(self): return self.attrTuple[9] #  boss附加技能列表 list
-    def GetSkillExCnt(self): return self.attrTuple[10] # 随机附加技能数,0为所有 BYTE
+    def GetSkillExCnt(self): return self.attrTuple[10] # 随机附加技能数,0为所有 BYTE
+    def GetReModelID(self): return self.attrTuple[11] # 等级参考值模版 WORD
 
 # 称号表
 class IPY_Title():
@@ -3447,25 +3454,35 @@
     def GetExp(self): return self.attrTuple[1] # 升级所需经验 DWORD
     def GetMaxHP(self): return self.attrTuple[2] # 生命 DWORD
     def GetAtk(self): return self.attrTuple[3] # 攻击 DWORD
-    def GetDef(self): return self.attrTuple[4] # 防御 DWORD
-    def GetReHeroStar(self): return self.attrTuple[5] # 参考星级 BYTE
-    def GetReHeroBreakLV(self): return self.attrTuple[6] # 参考突破等级 BYTE
-    def GetReHeroAwakeLV(self): return self.attrTuple[7] # 参考觉醒等级 BYTE
-    def GetReAtk(self): return self.attrTuple[8] # 参考攻击 DWORD
-    def GetReDef(self): return self.attrTuple[9] # 防御 DWORD
-    def GetReMaxHP(self): return self.attrTuple[10] # 生命 DWORD
-    def GetReStunRate(self): return self.attrTuple[11] # DWORD
-    def GetReSuperHitRate(self): return self.attrTuple[12] # DWORD
-    def GetReComboRate(self): return self.attrTuple[13] # DWORD
-    def GetReMissRate(self): return self.attrTuple[14] # DWORD
-    def GetReParryRate(self): return self.attrTuple[15] # DWORD
-    def GetReSuckHPPer(self): return self.attrTuple[16] # DWORD
-    def GetReStunRateDef(self): return self.attrTuple[17] # DWORD
-    def GetReSuperHitRateDef(self): return self.attrTuple[18] # DWORD
-    def GetReComboRateDef(self): return self.attrTuple[19] # DWORD
-    def GetReMissRateDef(self): return self.attrTuple[20] # DWORD
-    def GetReParryRateDef(self): return self.attrTuple[21] # DWORD
-    def GetReSuckHPPerDef(self): return self.attrTuple[22] # DWORD
+    def GetDef(self): return self.attrTuple[4] # 防御 DWORD
+
+# 等级参考值
+class IPY_LVReValue():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetModelID(self): return self.attrTuple[0] # 模版ID WORD
+    def GetLV(self): return self.attrTuple[1] # 玩家等级 WORD
+    def GetReHeroStar(self): return self.attrTuple[2] # 参考星级 BYTE
+    def GetReHeroBreakLV(self): return self.attrTuple[3] # 参考突破等级 BYTE
+    def GetReHeroAwakeLV(self): return self.attrTuple[4] # 参考觉醒等级 BYTE
+    def GetReAtk(self): return self.attrTuple[5] # 参考攻击 DWORD
+    def GetReDef(self): return self.attrTuple[6] # 防御 DWORD
+    def GetReMaxHP(self): return self.attrTuple[7] # 生命 DWORD
+    def GetReStunRate(self): return self.attrTuple[8] # DWORD
+    def GetReSuperHitRate(self): return self.attrTuple[9] # DWORD
+    def GetReComboRate(self): return self.attrTuple[10] # DWORD
+    def GetReMissRate(self): return self.attrTuple[11] # DWORD
+    def GetReParryRate(self): return self.attrTuple[12] # DWORD
+    def GetReSuckHPPer(self): return self.attrTuple[13] # DWORD
+    def GetReStunRateDef(self): return self.attrTuple[14] # DWORD
+    def GetReSuperHitRateDef(self): return self.attrTuple[15] # DWORD
+    def GetReComboRateDef(self): return self.attrTuple[16] # DWORD
+    def GetReMissRateDef(self): return self.attrTuple[17] # DWORD
+    def GetReParryRateDef(self): return self.attrTuple[18] # DWORD
+    def GetReSuckHPPerDef(self): return self.attrTuple[19] # DWORD
 
 # 特殊地图玩家属性公式表
 class IPY_SpecMapPlayerAttrFormat():
@@ -5649,6 +5666,7 @@
         self.__LoadFileData("TravelEvent", onlyCheck)
         self.__LoadFileData("TravelScenery", onlyCheck)
         self.__LoadFileData("PlayerLV", onlyCheck)
+        self.__LoadFileData("LVReValue", onlyCheck)
         self.__LoadFileData("SpecMapPlayerAttrFormat", onlyCheck)
         self.__LoadFileData("GMAttr", onlyCheck)
         self.__LoadFileData("RuneTower", onlyCheck)
@@ -6558,6 +6576,13 @@
         self.CheckLoadData("PlayerLV")
         return self.ipyPlayerLVCache[index]
 
+    def GetLVReValueCount(self):
+        self.CheckLoadData("LVReValue")
+        return self.ipyLVReValueLen
+    def GetLVReValueByIndex(self, index):
+        self.CheckLoadData("LVReValue")
+        return self.ipyLVReValueCache[index]
+
     def GetSpecMapPlayerAttrFormatCount(self):
         self.CheckLoadData("SpecMapPlayerAttrFormat")
         return self.ipySpecMapPlayerAttrFormatLen

--
Gitblit v1.8.0