From daedb61b798873f6fc475172583ad9f8c8b3408d Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 23 五月 2022 18:03:58 +0800
Subject: [PATCH] 9480 【BT6】【后端】炼体系统

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLianTi.py         |  259 +++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                 |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                 |  104 ++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py             |   56 ++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                      |  104 ++++++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                  |   56 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                         |   16 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py               |   44 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py             |    4 
 PySysDB/PySysDBPY.h                                                                                |   16 +
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                      |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LianTi.py          |   59 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py         |    2 
 14 files changed, 728 insertions(+), 2 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index b49da21..dc47456 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -69,6 +69,22 @@
 	BYTE		AddFreePoint;	//增加自由属性点
 };
 
+//境界炼体属性表
+
+struct tagLianTi
+{
+	BYTE		_LianTiLV;	//炼体等级
+	list		FixedAttrType;	//固定属性类型(非累积)
+	list		FixedAttrValue;	//固定属性值(非累积)
+	list		PlusAttrType;	//增强属性类型(非累积)
+	list		PlusAttrRate;	//增强属性万分率(非累积)
+	list		EatItemAttrType;	//每x个培养丹增加属性类型,x=UpEatItemPerCount
+	list		EatItemAttrValue;	//每x个培养丹增加属性值,x=UpEatItemPerCount
+	WORD		NeedEatCount;	//升级所需个数(非累计)
+	WORD		EatPerCount;	//每次培养消耗x个
+	list		LVUpCostItemInfo;	//突破等级道具ID|个数
+};
+
 //神兵表 #tagGodWeapon
 
 struct	tagGodWeapon
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 69dec41..0482b74 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -11510,6 +11510,110 @@
 
 
 #------------------------------------------------------
+# A5 34 炼体突破 #tagCMLianTiLVUp
+
+class  tagCMLianTiLVUp(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0x34
+        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 = 0xA5
+        self.SubCmd = 0x34
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMLianTiLVUp)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 34 炼体突破 //tagCMLianTiLVUp:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMLianTiLVUp=tagCMLianTiLVUp()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMLianTiLVUp.Cmd,m_NAtagCMLianTiLVUp.SubCmd))] = m_NAtagCMLianTiLVUp
+
+
+#------------------------------------------------------
+# A5 33 炼体提升 #tagCMLianTiUp
+
+class  tagCMLianTiUp(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("UseItemCnt", c_int),    #消耗材料个数
+                  ("IsAutoBuy", c_ubyte),    #是否自动购买
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0x33
+        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 = 0xA5
+        self.SubCmd = 0x33
+        self.UseItemCnt = 0
+        self.IsAutoBuy = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMLianTiUp)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 33 炼体提升 //tagCMLianTiUp:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                UseItemCnt:%d,
+                                IsAutoBuy:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.UseItemCnt,
+                                self.IsAutoBuy
+                                )
+        return DumpString
+
+
+m_NAtagCMLianTiUp=tagCMLianTiUp()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMLianTiUp.Cmd,m_NAtagCMLianTiUp.SubCmd))] = m_NAtagCMLianTiUp
+
+
+#------------------------------------------------------
 # A5 15 提升法宝等级 #tagCMMagicWeaponUp
 
 class  tagCMMagicWeaponUp(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index aaff9fe..14ebe55 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -19339,6 +19339,62 @@
 
 
 #------------------------------------------------------
+# A3 55 炼体信息 #tagMCLianTiInfo
+
+class  tagMCLianTiInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("LianTiLV", c_ubyte),    #炼体等级
+                  ("EatItemCount", c_int),    #当前等级已吃丹个数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA3
+        self.SubCmd = 0x55
+        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 = 0xA3
+        self.SubCmd = 0x55
+        self.LianTiLV = 0
+        self.EatItemCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCLianTiInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A3 55 炼体信息 //tagMCLianTiInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                LianTiLV:%d,
+                                EatItemCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.LianTiLV,
+                                self.EatItemCount
+                                )
+        return DumpString
+
+
+m_NAtagMCLianTiInfo=tagMCLianTiInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCLianTiInfo.Cmd,m_NAtagMCLianTiInfo.SubCmd))] = m_NAtagMCLianTiInfo
+
+
+#------------------------------------------------------
 # A3 52 法宝等级信息 #tagMCMagicWeaponLVInfo
 
 class  tagMCMagicWeaponInfo(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 5920276..77015ad 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1092,6 +1092,7 @@
 GameFuncID_ZhuXianBoss = 163    # 诛仙BOSS
 GameFuncID_Arena = 195          # 竞技场
 GameFuncID_FaQi = 199           # 法器
+GameFuncID_LianTi = 207         # 炼体
 # 以下为暂时无用的
 GameFuncID_Truck = 33           # 运镖
 GameFuncID_RunDaily = 34        # 日常跑环
@@ -1521,7 +1522,7 @@
 )=range(5)
 
 # 战斗力模块类型
-Def_MFPType_Max = 28
+Def_MFPType_Max = 29
 ModuleFightPowerTypeList = (
 Def_MFPType_Role, # 角色 0
 Def_MFPType_Equip, # 装备(装备本身) 1
@@ -1550,6 +1551,7 @@
 Def_MFPType_Coat, # 时装 24
 Def_MFPType_Love, # 情缘 25
 Def_MFPType_Charm, # 魅力 26
+Def_MFPType_LianTi, # 炼体 27
 Def_MFPType_Other, # 其他
 ) = range(Def_MFPType_Max)
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 8d8ad16..d4769e7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -562,6 +562,22 @@
 PacketSubCMD_3 = 0x23
 PacketCallFunc_3 = DoRealmLVUp
 
+;炼体
+[PlayerLianTi]
+ScriptName = Player\PlayerLianTi.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 2
+
+PacketCMD_1 = 0xA5
+PacketSubCMD_1 = 0x33
+PacketCallFunc_1 = OnLianTiUp
+
+PacketCMD_2 = 0xA5
+PacketSubCMD_2 = 0x34
+PacketCallFunc_2 = OnLianTiLVUp
+
 ;累计登陆礼
 [PlayerLoginDayAward]
 ScriptName = Player\PlayerLoginDayAward.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 69dec41..0482b74 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -11510,6 +11510,110 @@
 
 
 #------------------------------------------------------
+# A5 34 炼体突破 #tagCMLianTiLVUp
+
+class  tagCMLianTiLVUp(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0x34
+        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 = 0xA5
+        self.SubCmd = 0x34
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMLianTiLVUp)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 34 炼体突破 //tagCMLianTiLVUp:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMLianTiLVUp=tagCMLianTiLVUp()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMLianTiLVUp.Cmd,m_NAtagCMLianTiLVUp.SubCmd))] = m_NAtagCMLianTiLVUp
+
+
+#------------------------------------------------------
+# A5 33 炼体提升 #tagCMLianTiUp
+
+class  tagCMLianTiUp(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("UseItemCnt", c_int),    #消耗材料个数
+                  ("IsAutoBuy", c_ubyte),    #是否自动购买
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0x33
+        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 = 0xA5
+        self.SubCmd = 0x33
+        self.UseItemCnt = 0
+        self.IsAutoBuy = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMLianTiUp)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 33 炼体提升 //tagCMLianTiUp:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                UseItemCnt:%d,
+                                IsAutoBuy:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.UseItemCnt,
+                                self.IsAutoBuy
+                                )
+        return DumpString
+
+
+m_NAtagCMLianTiUp=tagCMLianTiUp()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMLianTiUp.Cmd,m_NAtagCMLianTiUp.SubCmd))] = m_NAtagCMLianTiUp
+
+
+#------------------------------------------------------
 # A5 15 提升法宝等级 #tagCMMagicWeaponUp
 
 class  tagCMMagicWeaponUp(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index aaff9fe..14ebe55 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -19339,6 +19339,62 @@
 
 
 #------------------------------------------------------
+# A3 55 炼体信息 #tagMCLianTiInfo
+
+class  tagMCLianTiInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("LianTiLV", c_ubyte),    #炼体等级
+                  ("EatItemCount", c_int),    #当前等级已吃丹个数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA3
+        self.SubCmd = 0x55
+        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 = 0xA3
+        self.SubCmd = 0x55
+        self.LianTiLV = 0
+        self.EatItemCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCLianTiInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A3 55 炼体信息 //tagMCLianTiInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                LianTiLV:%d,
+                                EatItemCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.LianTiLV,
+                                self.EatItemCount
+                                )
+        return DumpString
+
+
+m_NAtagMCLianTiInfo=tagMCLianTiInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCLianTiInfo.Cmd,m_NAtagMCLianTiInfo.SubCmd))] = m_NAtagMCLianTiInfo
+
+
+#------------------------------------------------------
 # A3 52 法宝等级信息 #tagMCMagicWeaponLVInfo
 
 class  tagMCMagicWeaponInfo(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LianTi.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LianTi.py
new file mode 100644
index 0000000..6c67215
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LianTi.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.LianTi
+#
+# @todo:炼体
+# @author hxp
+# @date 2022-22-23
+# @version 1.0
+#
+# 详细描述: 炼体
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-22-23 15:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import GameWorld
+import PlayerControl
+import PlayerLianTi
+
+#---------------------------------------------------------------------
+#逻辑实现
+
+## GM命令执行入口
+#  @param curPlayer 当前玩家
+#  @param msgList 参数列表
+#  @return None
+#  @remarks 函数详细说明.
+def OnExec(curPlayer, msgList):
+    
+    if not msgList:
+        GameWorld.DebugAnswer(curPlayer, "重置炼体: LianTi 0")
+        GameWorld.DebugAnswer(curPlayer, "设置炼体: LianTi 等级 本级已吃丹数")
+        return
+    
+    if len(msgList) == 1:
+        if msgList[0] == 0:
+            if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiLV):
+                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiLV, 1)
+                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiEatItemCount, 0)
+            
+    elif len(msgList) == 2:
+        lv, eatItemCount = msgList
+        if lv < 1:
+            GameWorld.DebugAnswer(curPlayer, "等级不能小于1")
+            return
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiLV, lv)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiEatItemCount, eatItemCount)
+        
+    else:
+        return
+    
+    PlayerLianTi.RefreshLianTiAttr(curPlayer)
+    PlayerLianTi.SyncLianTiInfo(curPlayer)
+    return
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py
index c1c4bfb..c231e02 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py
@@ -55,6 +55,7 @@
                    ShareDefine.Def_MFPType_Coat:"时装",
                    ShareDefine.Def_MFPType_Love:"情缘",
                    ShareDefine.Def_MFPType_Charm:"魅力",
+                   ShareDefine.Def_MFPType_LianTi:"炼体",
                    ShareDefine.Def_MFPType_Other:"其他",
                    }
     
@@ -105,6 +106,7 @@
                      ChConfig.Def_CalcAttrFunc_LoveRing:"情戒基础",
                      ChConfig.Def_CalcAttrFunc_LoveRingCouple:"情戒仙侣",
                      ChConfig.Def_CalcAttrFunc_Charm:"魅力",
+                     ChConfig.Def_CalcAttrFunc_LianTi:"炼体",
                      }
     
     GameWorld.DebugAnswer(curPlayer, "PrintFightPower 模块类型(可选)")
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 66a9f49..885a61d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -88,6 +88,19 @@
                         ("BYTE", "AddFreePoint", 0),
                         ),
 
+                "LianTi":(
+                        ("BYTE", "LianTiLV", 1),
+                        ("list", "FixedAttrType", 0),
+                        ("list", "FixedAttrValue", 0),
+                        ("list", "PlusAttrType", 0),
+                        ("list", "PlusAttrRate", 0),
+                        ("list", "EatItemAttrType", 0),
+                        ("list", "EatItemAttrValue", 0),
+                        ("WORD", "NeedEatCount", 0),
+                        ("WORD", "EatPerCount", 0),
+                        ("list", "LVUpCostItemInfo", 0),
+                        ),
+
                 "GodWeapon":(
                         ("WORD", "Type", 1),
                         ("WORD", "LV", 1),
@@ -2076,6 +2089,33 @@
     def GetExpLimit(self): return self.ExpLimit # 修为池经验上限
     def GetLearnSkillIDInfo(self): return self.LearnSkillIDInfo # 学习技能ID信息 {"职业":[技能ID, ...], ...}
     def GetAddFreePoint(self): return self.AddFreePoint # 增加自由属性点
+
+# 境界炼体属性表
+class IPY_LianTi():
+    
+    def __init__(self):
+        self.LianTiLV = 0
+        self.FixedAttrType = []
+        self.FixedAttrValue = []
+        self.PlusAttrType = []
+        self.PlusAttrRate = []
+        self.EatItemAttrType = []
+        self.EatItemAttrValue = []
+        self.NeedEatCount = 0
+        self.EatPerCount = 0
+        self.LVUpCostItemInfo = []
+        return
+        
+    def GetLianTiLV(self): return self.LianTiLV # 炼体等级
+    def GetFixedAttrType(self): return self.FixedAttrType # 固定属性类型(非累积)
+    def GetFixedAttrValue(self): return self.FixedAttrValue # 固定属性值(非累积)
+    def GetPlusAttrType(self): return self.PlusAttrType # 增强属性类型(非累积)
+    def GetPlusAttrRate(self): return self.PlusAttrRate # 增强属性万分率(非累积)
+    def GetEatItemAttrType(self): return self.EatItemAttrType # 每x个培养丹增加属性类型,x=UpEatItemPerCount
+    def GetEatItemAttrValue(self): return self.EatItemAttrValue # 每x个培养丹增加属性值,x=UpEatItemPerCount
+    def GetNeedEatCount(self): return self.NeedEatCount # 升级所需个数(非累计)
+    def GetEatPerCount(self): return self.EatPerCount # 每次培养消耗x个
+    def GetLVUpCostItemInfo(self): return self.LVUpCostItemInfo # 突破等级道具ID|个数
 
 # 神兵表
 class IPY_GodWeapon():
@@ -6046,6 +6086,8 @@
         self.ipyLingQiTrainLen = len(self.ipyLingQiTrainCache)
         self.ipyRealmCache = self.__LoadFileData("Realm", IPY_Realm)
         self.ipyRealmLen = len(self.ipyRealmCache)
+        self.ipyLianTiCache = self.__LoadFileData("LianTi", IPY_LianTi)
+        self.ipyLianTiLen = len(self.ipyLianTiCache)
         self.ipyGodWeaponCache = self.__LoadFileData("GodWeapon", IPY_GodWeapon)
         self.ipyGodWeaponLen = len(self.ipyGodWeaponCache)
         self.ipyFuncConfigCache = self.__LoadFileData("FuncConfig", IPY_FuncConfig)
@@ -6612,6 +6654,8 @@
     def GetLingQiTrainByIndex(self, index): return self.ipyLingQiTrainCache[index]
     def GetRealmCount(self): return self.ipyRealmLen
     def GetRealmByIndex(self, index): return self.ipyRealmCache[index]
+    def GetLianTiCount(self): return self.ipyLianTiLen
+    def GetLianTiByIndex(self, index): return self.ipyLianTiCache[index]
     def GetGodWeaponCount(self): return self.ipyGodWeaponLen
     def GetGodWeaponByIndex(self, index): return self.ipyGodWeaponCache[index]
     def GetFuncConfigCount(self): return self.ipyFuncConfigLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index b78c037..cdf62cb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -138,6 +138,7 @@
 import PlayerFB
 import PlayerFaQi
 import SkillShell
+import PlayerLianTi
 import PlayerYinji
 import PlayerLove
 import GameObj
@@ -659,6 +660,9 @@
     # 法器
     PlayerFaQi.PlayerFaQiLogin(curPlayer)
     
+    # 炼体
+    PlayerLianTi.OnPlayerLogin(curPlayer)
+    
     PlayerTreasure.OnTreasureLogin(curPlayer)
     
     # 通知累计登陆礼
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
index aff9a98..7151799 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
@@ -44,6 +44,7 @@
 import IPY_GameWorld
 import ItemCommon
 import ItemControler
+import PlayerLianTi
 import PlayerArena
 import PlayerFaQi
 import PlayerTJG
@@ -69,6 +70,7 @@
                      ShareDefine.GameFuncID_TJG:lambda curObj:PlayerTJG.DoTJGOpen(curObj),
                      ShareDefine.GameFuncID_Arena:lambda curObj:PlayerArena.DoArenaOpen(curObj),
                      ShareDefine.GameFuncID_FaQi:lambda curObj:PlayerFaQi.DoFaQiOpen(curObj),
+                     ShareDefine.GameFuncID_LianTi:lambda curObj:PlayerLianTi.DoLianTiOpen(curObj),
                      #ShareDefine.GameFuncID_RunDaily:lambda curObj:FBCommon.DoFuncOpen_RunDaily(curObj),
                      #ShareDefine.GameFuncID_RunFamily:lambda curObj:FBCommon.DoFuncOpen_RunFamily(curObj),
                      #ShareDefine.GameFuncID_RefineExp:lambda curObj:Operate_PlayerBuyZhenQi.DoFuncOpen_RefineExp(curObj),
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLianTi.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLianTi.py
new file mode 100644
index 0000000..6280826
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLianTi.py
@@ -0,0 +1,259 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerLianTi
+#
+# @todo:炼体
+# @author hxp
+# @date 2022-22-23
+# @version 1.0
+#
+# 详细描述: 炼体
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-22-23 15:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import IpyGameDataPY
+import PlayerControl
+import FunctionNPCCommon
+import ChPyNetSendPack
+import NetPackCommon
+import ItemCommon
+import ChConfig
+
+def DoLianTiOpen(curPlayer):
+    ## 功能开启
+    lianTiLV = 1
+    ipyData = IpyGameDataPY.GetIpyGameData("LianTi", lianTiLV)
+    if not ipyData:
+        return
+    
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiLV, lianTiLV)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiEatItemCount, 0)
+    
+    GameWorld.DebugLog("炼体功能开启! lianTiLV=%s" % lianTiLV)
+    SyncLianTiInfo(curPlayer)
+    RefreshLianTiAttr(curPlayer)
+    return True
+
+def OnPlayerLogin(curPlayer):
+    if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiLV):
+        return
+    SyncLianTiInfo(curPlayer)
+    return
+
+#// A5 33 炼体提升 #tagCMLianTiUp
+#
+#struct    tagCMLianTiUp
+#{
+#    tagHead        Head;
+#    DWORD        UseItemCnt;    //消耗材料个数
+#    BYTE        IsAutoBuy;    //是否自动购买
+#};
+def OnLianTiUp(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    costItemCount = clientData.UseItemCnt # 消耗材料个数
+    isAutoBuy = clientData.IsAutoBuy # 是否自动购买
+    
+    lianTiLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiLV)
+    curEatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiEatItemCount)
+    
+    if not lianTiLV:
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("LianTi", lianTiLV)
+    if not ipyData:
+        return
+    
+    needEatCount = ipyData.GetNeedEatCount()
+    if not needEatCount:
+        GameWorld.DebugLog("炼体已满级! lianTiLV=%s" % lianTiLV)
+        return
+        
+    if curEatItemCount >= needEatCount:
+        GameWorld.DebugLog("本级已吃满! lianTiLV=%s,curEatItemCount=%s >= %s" % (lianTiLV, curEatItemCount, needEatCount))
+        return
+    
+    costItemID = IpyGameDataPY.GetFuncCfg("LianTiUpItem", 1)
+    if not costItemID or not costItemCount:
+        return
+    
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)
+    lackCnt = costItemCount - bindCnt - unBindCnt
+    if lackCnt > 0 and not isAutoBuy:
+        GameWorld.DebugLog("道具不足,无法提升炼体! costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s" 
+                           % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))
+        return
+    
+    delCnt = costItemCount
+    if lackCnt > 0:
+        autoBuyMoneyType = IpyGameDataPY.GetFuncCfg("LianTiUpItem", 2)
+        if not autoBuyMoneyType:
+            return
+        infoDict = {ChConfig.Def_Cost_Reason_SonKey:costItemID}
+        if not FunctionNPCCommon.PayAutoBuyItem(curPlayer, {costItemID:lackCnt}, autoBuyMoneyType, ChConfig.Def_Cost_LianTi, infoDict):
+            return
+        delCnt -= lackCnt
+        
+    # 扣除消耗
+    if delCnt:
+        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, ChConfig.ItemDel_LianTi)
+        
+    updEatItemCount = curEatItemCount + costItemCount
+    GameWorld.DebugLog("炼体提升: lianTiLV=%s,curEatItemCount=%s,costItemCount=%s,updEatItemCount=%s,needEatCount=%s" 
+                       % (lianTiLV, curEatItemCount, costItemCount, updEatItemCount, needEatCount))
+    
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiEatItemCount, updEatItemCount)
+    
+    SyncLianTiInfo(curPlayer)
+    RefreshLianTiAttr(curPlayer)
+    return
+
+#// A5 34 炼体突破 #tagCMLianTiLVUp
+#
+#struct    tagCMLianTiLVUp
+#{
+#    tagHead        Head;
+#};
+def OnLianTiLVUp(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+        
+    lianTiLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiLV)
+    curEatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiEatItemCount)
+    
+    if not lianTiLV:
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("LianTi", lianTiLV)
+    if not ipyData:
+        return
+    
+    needEatCount = ipyData.GetNeedEatCount()
+    if not needEatCount:
+        GameWorld.DebugLog("炼体已满级! lianTiLV=%s" % lianTiLV)
+        return
+    
+    if curEatItemCount < needEatCount:
+        GameWorld.DebugLog("炼体培养物品个数不足,无法突破! lianTiLV=%s,curEatItemCount=%s < %s" % (lianTiLV, curEatItemCount, needEatCount))
+        return
+    
+    costItemInfo = ipyData.GetLVUpCostItemInfo()
+    if not costItemInfo or len(costItemInfo) != 2:
+        return
+    costItemID, costItemCount = costItemInfo
+    if not costItemID or not costItemCount:
+        return
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)
+    lackCnt = costItemCount - bindCnt - unBindCnt
+    if lackCnt > 0:
+        GameWorld.DebugLog("道具不足,无法突破炼体! costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s" 
+                           % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))
+        return
+    
+    nextLianTiLv = lianTiLV + 1
+    nextIpyData = IpyGameDataPY.GetIpyGameDataNotLog("LianTi", nextLianTiLv)
+    if not nextIpyData:
+        return
+    
+    curRealmLV = curPlayer.GetOfficialRank()
+    if nextLianTiLv > curRealmLV:
+        GameWorld.DebugLog("炼体突破不能超过当前境界! nextLianTiLv=%s > curRealmLV(%s)" % (nextLianTiLv, curRealmLV))
+        return
+    
+    # 扣除消耗
+    ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCount, ChConfig.ItemDel_LianTi)
+    
+    updEatItemCount = curEatItemCount - needEatCount
+    GameWorld.DebugLog("炼体突破: lianTiLV=%s,curEatItemCount=%s,needEatCount=%s,updEatItemCount=%s,nextLianTiLv=%s" 
+                       % (lianTiLV, curEatItemCount, needEatCount, updEatItemCount, nextLianTiLv))
+    
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiLV, nextLianTiLv)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LianTiEatItemCount, updEatItemCount)
+    
+    SyncLianTiInfo(curPlayer)
+    RefreshLianTiAttr(curPlayer)
+    return
+
+def RefreshLianTiAttr(curPlayer):
+    CalcLianTiAttr(curPlayer)
+    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
+    return
+
+def CalcLianTiAttr(curPlayer):
+    
+    lianTiLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiLV)
+    if not lianTiLV:
+        return
+    
+    allAttrList = [{} for _ in range(4)]
+    plusAttrRateDict = {}
+    lianTiAttrDict = {}
+    
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in xrange(ipyDataMgr.GetLianTiCount()):
+        lvupIpyData = ipyDataMgr.GetLianTiByIndex(index)
+        dataLV = lvupIpyData.GetLianTiLV()
+        if dataLV > lianTiLV:
+            break
+        
+        upItemCount = lvupIpyData.GetNeedEatCount()
+        if dataLV == lianTiLV:
+            upItemCount = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiEatItemCount), upItemCount)
+        #GameWorld.DebugLog("dataLV=%s,upItemCount=%s" % (dataLV, upItemCount))
+        
+        # 固定属性
+        fixedAttrTypeList = lvupIpyData.GetFixedAttrType()
+        fixedAttrValueList = lvupIpyData.GetFixedAttrValue()
+        for i, attrID in enumerate(fixedAttrTypeList):
+            attrValue = fixedAttrValueList[i] if len(fixedAttrValueList) > i else 0
+            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
+            lianTiAttrDict[attrID] = lianTiAttrDict.get(attrID, 0) + attrValue
+            #GameWorld.DebugLog("    %s, attrID=%s,attrValue=%s,%s" % (i, attrID, attrValue, lianTiAttrDict))
+            
+        # 培养丹增加属性
+        upItemPerCount = lvupIpyData.GetEatPerCount()
+        if upItemCount and upItemPerCount:
+            upItemAttrTypeList = lvupIpyData.GetEatItemAttrType()
+            upItemAttrValueList = lvupIpyData.GetEatItemAttrValue()
+            attrMultiple = upItemCount / upItemPerCount
+            #GameWorld.DebugLog("    upItemCount=%s,upItemPerCount=%s,attrMultiple=%s" % (upItemCount, upItemPerCount, attrMultiple))
+            for i, attrID in enumerate(upItemAttrTypeList):
+                attrValue = upItemAttrValueList[i] if len(upItemAttrValueList) > i else 0
+                attrValue *= attrMultiple
+                PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
+                lianTiAttrDict[attrID] = lianTiAttrDict.get(attrID, 0) + attrValue
+                #GameWorld.DebugLog("    %s, attrID=%s,attrValue=%s,%s" % (i, attrID, attrValue, lianTiAttrDict))
+                
+        # 增强属性万分率累加
+        plusAttrTypeList = lvupIpyData.GetPlusAttrType()
+        plusAttrRateList = lvupIpyData.GetPlusAttrRate()
+        for i, attrID in enumerate(plusAttrTypeList):
+            plusRate = plusAttrRateList[i] if len(plusAttrRateList) > i else 0
+            plusAttrRateDict[attrID] = plusAttrRateDict.get(attrID, 0) + plusRate
+            
+    #GameWorld.DebugLog("    lianTiAttrDict=%s" % lianTiAttrDict)
+    #GameWorld.DebugLog("    plusAttrRateDict=%s" % plusAttrRateDict)
+    
+    # 固定属性增强值计算
+    for attrID, plusRate in plusAttrRateDict.items():
+        if attrID not in lianTiAttrDict:
+            continue
+        attrValue = lianTiAttrDict[attrID]
+        plusValue = int(attrValue * plusRate / 10000.0)
+        PlayerControl.CalcAttrDict_Type(attrID, plusValue, allAttrList)
+        #GameWorld.DebugLog("    plus: attrID=%s,attrValue=%s,plusRate=%s,plusValue=%s" % (attrID, attrValue, plusRate, plusValue))
+        
+    #GameWorld.DebugLog("    allAttrList=%s" % allAttrList)
+    # 保存计算值
+    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_LianTi, allAttrList)
+    return
+
+def SyncLianTiInfo(curPlayer):
+    clientPack = ChPyNetSendPack.tagMCLianTiInfo()
+    clientPack.LianTiLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiLV)
+    clientPack.EatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LianTiEatItemCount)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 5920276..77015ad 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1092,6 +1092,7 @@
 GameFuncID_ZhuXianBoss = 163    # 诛仙BOSS
 GameFuncID_Arena = 195          # 竞技场
 GameFuncID_FaQi = 199           # 法器
+GameFuncID_LianTi = 207         # 炼体
 # 以下为暂时无用的
 GameFuncID_Truck = 33           # 运镖
 GameFuncID_RunDaily = 34        # 日常跑环
@@ -1521,7 +1522,7 @@
 )=range(5)
 
 # 战斗力模块类型
-Def_MFPType_Max = 28
+Def_MFPType_Max = 29
 ModuleFightPowerTypeList = (
 Def_MFPType_Role, # 角色 0
 Def_MFPType_Equip, # 装备(装备本身) 1
@@ -1550,6 +1551,7 @@
 Def_MFPType_Coat, # 时装 24
 Def_MFPType_Love, # 情缘 25
 Def_MFPType_Charm, # 魅力 26
+Def_MFPType_LianTi, # 炼体 27
 Def_MFPType_Other, # 其他
 ) = range(Def_MFPType_Max)
 

--
Gitblit v1.8.0