From 09c67573ee3759802de4d40ea70813d2ce71be0c Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 13 一月 2026 10:27:16 +0800
Subject: [PATCH] 423 【内政】命格系统-服务端(初版不含属性;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMingge.py     |  358 ++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearPack.py   |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py      |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py             |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py             |  504 +++++++++-----------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py         |   60 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mingge.py      |   55 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini               |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py     |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                     |   24 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py |  116 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py           |  208 ++++++-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py         |    6 
 PySysDB/PySysDBPY.h                                                                            |   46 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py     |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                |   25 +
 16 files changed, 1,099 insertions(+), 332 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 7fe30a5..810c29f 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -293,6 +293,7 @@
 	float		AtkRatio;	//攻击系数
 	float		MaxHPRatio;
 	float		DefRatio;
+	float		AtkSpeedRatio;
 	float		StunRateRatio;
 	float		SuperHitRateRatio;
 	float		ComboRateRatio;
@@ -693,6 +694,51 @@
 	list		LegendAttrValue;	//传奇属性值
 };
 
+//感悟等级表
+
+struct MGGanwuLV
+{
+	BYTE		_GanwuLV;	//感悟等级
+	DWORD		NextNeedExp;	//升到下一级所需经验
+	DWORD		AtkBase;	//攻击基础值
+	DWORD		DefBase;	//防御基础值
+	DWORD		HPBase;	//生命基础值
+	DWORD		AtkSpeedBase;	//先攻基础值
+};
+
+//卦玉品质表
+
+struct MGGuayuQuality
+{
+	BYTE		_ItemColor;	//品质
+	float		AtkPlus;	//攻击加成
+	float		DefPlus;	//防御加成
+	float		HPPlus;	//生命加成
+	float		AtkSpeedPlus;	//先攻加成
+	BYTE		AttrLibCnt;	//库属性条数
+	list		AttrRange;	//通用属性范围,下限|上限
+	dict		AttrRangeDict;	//指定属性范围字典,{指定属性ID:[范围下限, 上限], ...}
+};
+
+//卦玉类型表
+
+struct MGGuayuType
+{
+	BYTE		_ItemType;	//类型
+	BYTE		EquipPlace;	//装备位
+	float		BaseAttrProportion;	//基础四维属性占比
+	DWORD		FixedAttrID;	//固定属性ID
+	list		AttrIDLib;	//随机属性ID库,[属性ID, ...]
+};
+
+//灵应品质表
+
+struct MGLingyingQuality
+{
+	DWORD		_Lingying;	//灵应段值
+	list		ItemColorWeightList;	//品质权重列表
+};
+
 //装备传奇属性条数表
 
 struct tagEquipLegendAttrCount
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini
index 54f95df..cdaacd1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/MapServerConfig.ini
@@ -1,7 +1,7 @@
 [RolePackConfig]
 ;2000///<所有背包总量限制
 ;玩家背包配置
-PackTypeCnt=36
+PackTypeCnt=38
 
 ;已删除物品rptDeleted//已无用
 PackCnt00=0
@@ -74,4 +74,8 @@
 ;垃圾分类背包
 PackCnt34=0
 ;武将英雄背包
-PackCnt35=500
\ No newline at end of file
+PackCnt35=500
+;命格卦玉背包
+PackCnt36=36
+;命格推演背包
+PackCnt37=10
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 52ab244..d69c45b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1287,6 +1287,30 @@
 PacketSubCMD_4=0x27
 PacketCallFunc_4=OnFamilyGCZSQ
 
+;命格
+[PlayerMingge]
+ScriptName = GameWorldLogic\FBProcess\PlayerMingge.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 4
+
+PacketCMD_1=0xB2
+PacketSubCMD_1=0x50
+PacketCallFunc_1=OnMinggeTuiyan
+
+PacketCMD_2=0xB2
+PacketSubCMD_2=0x51
+PacketCallFunc_2=OnMinggeDecompose
+
+PacketCMD_3=0xB2
+PacketSubCMD_3=0x52
+PacketCallFunc_3=OnMinggeEquip
+
+PacketCMD_4=0xB2
+PacketSubCMD_4=0x53
+PacketCallFunc_4=OnMinggeQiling
+
 ;武将
 [PlayerHero]
 ScriptName = Player\PlayerHero.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 0f729e4..160fd7a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -185,7 +185,7 @@
 ) = range(1, 1 + 80)
 
 # 需要计算的武将战斗属性ID列表
-CalcBattleAttrIDList = [AttrID_Atk, AttrID_Def, AttrID_MaxHP, AttrID_StunRate, AttrID_StunRateDef, 
+CalcBattleAttrIDList = [AttrID_Atk, AttrID_Def, AttrID_MaxHP, AttrID_AtkSpeed, AttrID_StunRate, AttrID_StunRateDef, 
                         AttrID_SuperHitRate, AttrID_SuperHitRateDef, AttrID_ComboRate, AttrID_ComboRateDef,
                         AttrID_MissRate, AttrID_MissRateDef, AttrID_ParryRate, AttrID_ParryRateDef,
                         AttrID_SuckHPPer, AttrID_SuckHPPerDef, AttrID_FinalDamPer, AttrID_FinalDamPerDef,
@@ -561,6 +561,19 @@
 
 Def_ItemType_Hero = 150 # 武将英雄
 
+Def_ItemType_GY_Taiyang = 201       # 太阳 注意修改装备列表配置 Def_MGGuayuType
+Def_ItemType_GY_Shaoyang = 202      # 少阳
+Def_ItemType_GY_Taiyin = 203        # 太阴
+Def_ItemType_GY_Shaoyin = 204       # 少阴
+Def_ItemType_GY_Qian = 205          # 乾(qián):代表天,位于西北方
+Def_ItemType_GY_Kun = 206           # 坤(kūn):代表地,位于西南方。
+Def_ItemType_GY_Zhen = 207          # 震(zhèn):代表雷,位于正东方。
+Def_ItemType_GY_Xun = 208           # 巽(xùn):代表风,位于东南方。
+Def_ItemType_GY_Kan = 209           # 坎(kǎn):代表水,位于正北方。
+Def_ItemType_GY_Li = 210            # 离(lí):代表火,位于正南方。
+Def_ItemType_GY_Gen = 211           # 艮(gèn):代表山,位于东北方。
+Def_ItemType_GY_Dui = 212           # 兑(duì):代表泽,位于正西方。
+
 #虚拟背包最大格子数 功能配置表对应的key
 Def_VPackCnt_Dict = {
                      #ShareDefine.rptRune:'RunePackageNum',
@@ -924,6 +937,9 @@
 #主线装备类型
 Def_MainEquipType = range(Def_ItemType_retWeapon, Def_ItemType_retAmulet + 1)
 
+#命格卦玉类型
+Def_MGGuayuType = range(Def_ItemType_GY_Taiyang, Def_ItemType_GY_Dui + 1)
+
 #神兽装备类型
 Def_DogzEquiipType = xrange(Def_ItemType_DogzEquipHorn, Def_ItemType_DogzEquipScute + 1)
 
@@ -1193,6 +1209,8 @@
                                     #ShareDefine.rptDogzEquip,
                                     #ShareDefine.rptGarbage,
                                     ShareDefine.rptHero,
+                                    ShareDefine.rptMGGuayu,
+                                    ShareDefine.rptMGTuiyan,
                                     ]
 
 #装备可强化背包列表
@@ -3845,6 +3863,11 @@
 Def_PDict_DJGEffAuto = "DJGEffAuto"  # 是否自动选择效果
 Def_PDict_DJGEffSet = "DJGEffSet_%s"  # 预设优先选择属性ID,参数(优先index)
 
+#命格
+Def_PDict_MGGanwuLV = "MGGanwuLV"  # 感悟等级
+Def_PDict_MGGanwuExp = "MGGanwuExp"  # 当前感悟等级对应的经验
+Def_PDict_MGLingying = "MGLingying"  # 当前灵应值
+
 #-------------------------------------------------------------------------------
 
 #物品效果(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 5345c6c..9cd7499 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -4769,227 +4769,6 @@
 
 
 #------------------------------------------------------
-# A5 71 命格分解 #tagCMBirthChartDecompose
-
-class  tagCMBirthChartDecompose(Structure):
-    Head = tagHead()
-    IsAll = 0    #(BYTE IsAll)// 是否全部分解,优先级最高,锁定除外
-    QualityCnt = 0    #(BYTE QualityCnt)// 按全部分解品质数
-    QualityList = list()    #(vector<BYTE> QualityList)// 全部分解的品质列表,发送的品质会全部分解,锁定除外
-    Count = 0    #(BYTE Count)// 指定批量分解数,最大不超过50个
-    PlaceIndexList = list()    #(vector<WORD> PlaceIndexList)// 批量分解位置索引列表
-    data = None
-
-    def __init__(self):
-        self.Clear()
-        self.Head.Cmd = 0xA5
-        self.Head.SubCmd = 0x71
-        return
-
-    def ReadData(self, _lpData, _pos=0, _Len=0):
-        self.Clear()
-        _pos = self.Head.ReadData(_lpData, _pos)
-        self.IsAll,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        self.QualityCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        for i in range(self.QualityCnt):
-            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
-            self.QualityList.append(value)
-        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        for i in range(self.Count):
-            value,_pos=CommFunc.ReadWORD(_lpData,_pos)
-            self.PlaceIndexList.append(value)
-        return _pos
-
-    def Clear(self):
-        self.Head = tagHead()
-        self.Head.Clear()
-        self.Head.Cmd = 0xA5
-        self.Head.SubCmd = 0x71
-        self.IsAll = 0
-        self.QualityCnt = 0
-        self.QualityList = list()
-        self.Count = 0
-        self.PlaceIndexList = list()
-        return
-
-    def GetLength(self):
-        length = 0
-        length += self.Head.GetLength()
-        length += 1
-        length += 1
-        length += 1 * self.QualityCnt
-        length += 1
-        length += 2 * self.Count
-
-        return length
-
-    def GetBuffer(self):
-        data = ''
-        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
-        data = CommFunc.WriteBYTE(data, self.IsAll)
-        data = CommFunc.WriteBYTE(data, self.QualityCnt)
-        for i in range(self.QualityCnt):
-            data = CommFunc.WriteBYTE(data, self.QualityList[i])
-        data = CommFunc.WriteBYTE(data, self.Count)
-        for i in range(self.Count):
-            data = CommFunc.WriteWORD(data, self.PlaceIndexList[i])
-        return data
-
-    def OutputString(self):
-        DumpString = '''
-                                Head:%s,
-                                IsAll:%d,
-                                QualityCnt:%d,
-                                QualityList:%s,
-                                Count:%d,
-                                PlaceIndexList:%s
-                                '''\
-                                %(
-                                self.Head.OutputString(),
-                                self.IsAll,
-                                self.QualityCnt,
-                                "...",
-                                self.Count,
-                                "..."
-                                )
-        return DumpString
-
-
-m_NAtagCMBirthChartDecompose=tagCMBirthChartDecompose()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMBirthChartDecompose.Head.Cmd,m_NAtagCMBirthChartDecompose.Head.SubCmd))] = m_NAtagCMBirthChartDecompose
-
-
-#------------------------------------------------------
-# A5 72 命格锁定状态变更 #tagCMBirthChartLock
-
-class  tagCMBirthChartLock(Structure):
-    Head = tagHead()
-    LockState = 0    #(BYTE LockState)// 锁定状态, 0-锁定,1-解锁
-    Count = 0    #(BYTE Count)// 批量操作数,最大不超过50个
-    PlaceIndexList = list()    #(vector<WORD> PlaceIndexList)// 批量操作位置索引列表
-    data = None
-
-    def __init__(self):
-        self.Clear()
-        self.Head.Cmd = 0xA5
-        self.Head.SubCmd = 0x72
-        return
-
-    def ReadData(self, _lpData, _pos=0, _Len=0):
-        self.Clear()
-        _pos = self.Head.ReadData(_lpData, _pos)
-        self.LockState,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
-        for i in range(self.Count):
-            value,_pos=CommFunc.ReadWORD(_lpData,_pos)
-            self.PlaceIndexList.append(value)
-        return _pos
-
-    def Clear(self):
-        self.Head = tagHead()
-        self.Head.Clear()
-        self.Head.Cmd = 0xA5
-        self.Head.SubCmd = 0x72
-        self.LockState = 0
-        self.Count = 0
-        self.PlaceIndexList = list()
-        return
-
-    def GetLength(self):
-        length = 0
-        length += self.Head.GetLength()
-        length += 1
-        length += 1
-        length += 2 * self.Count
-
-        return length
-
-    def GetBuffer(self):
-        data = ''
-        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
-        data = CommFunc.WriteBYTE(data, self.LockState)
-        data = CommFunc.WriteBYTE(data, self.Count)
-        for i in range(self.Count):
-            data = CommFunc.WriteWORD(data, self.PlaceIndexList[i])
-        return data
-
-    def OutputString(self):
-        DumpString = '''
-                                Head:%s,
-                                LockState:%d,
-                                Count:%d,
-                                PlaceIndexList:%s
-                                '''\
-                                %(
-                                self.Head.OutputString(),
-                                self.LockState,
-                                self.Count,
-                                "..."
-                                )
-        return DumpString
-
-
-m_NAtagCMBirthChartLock=tagCMBirthChartLock()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMBirthChartLock.Head.Cmd,m_NAtagCMBirthChartLock.Head.SubCmd))] = m_NAtagCMBirthChartLock
-
-
-#------------------------------------------------------
-# A5 70 命格升级 #tagCMBirthChartUp
-
-class  tagCMBirthChartUp(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ("PlaceType", c_ubyte),    # 位置类型;0-命格背包,1-命格孔
-                  ("PlaceIndex", c_ushort),    # 位置索引
-                  ]
-
-    def __init__(self):
-        self.Clear()
-        self.Cmd = 0xA5
-        self.SubCmd = 0x70
-        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 = 0x70
-        self.PlaceType = 0
-        self.PlaceIndex = 0
-        return
-
-    def GetLength(self):
-        return sizeof(tagCMBirthChartUp)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A5 70 命格升级 //tagCMBirthChartUp:
-                                Cmd:%s,
-                                SubCmd:%s,
-                                PlaceType:%d,
-                                PlaceIndex:%d
-                                '''\
-                                %(
-                                self.Cmd,
-                                self.SubCmd,
-                                self.PlaceType,
-                                self.PlaceIndex
-                                )
-        return DumpString
-
-
-m_NAtagCMBirthChartUp=tagCMBirthChartUp()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMBirthChartUp.Cmd,m_NAtagCMBirthChartUp.SubCmd))] = m_NAtagCMBirthChartUp
-
-
-#------------------------------------------------------
 # A5 52 购买功能NPC采集次数 #tagCMBuyCollectionCnt
 
 class  tagCMBuyCollectionCnt(Structure):
@@ -7371,58 +7150,6 @@
 
 m_NAtagCSTreasureWishSelect=tagCSTreasureWishSelect()
 ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSTreasureWishSelect.Head.Cmd,m_NAtagCSTreasureWishSelect.Head.SubCmd))] = m_NAtagCSTreasureWishSelect
-
-
-#------------------------------------------------------
-# A5 73 解锁命格孔 #tagCMUnLockBirthChartHole
-
-class  tagCMUnLockBirthChartHole(Structure):
-    _pack_ = 1
-    _fields_ = [
-                  ("Cmd", c_ubyte),
-                  ("SubCmd", c_ubyte),
-                  ("BirthChartIndex", c_ubyte),    # 孔索引
-                  ]
-
-    def __init__(self):
-        self.Clear()
-        self.Cmd = 0xA5
-        self.SubCmd = 0x73
-        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 = 0x73
-        self.BirthChartIndex = 0
-        return
-
-    def GetLength(self):
-        return sizeof(tagCMUnLockBirthChartHole)
-
-    def GetBuffer(self):
-        return string_at(addressof(self), self.GetLength())
-
-    def OutputString(self):
-        DumpString = '''// A5 73 解锁命格孔 //tagCMUnLockBirthChartHole:
-                                Cmd:%s,
-                                SubCmd:%s,
-                                BirthChartIndex:%d
-                                '''\
-                                %(
-                                self.Cmd,
-                                self.SubCmd,
-                                self.BirthChartIndex
-                                )
-        return DumpString
-
-
-m_NAtagCMUnLockBirthChartHole=tagCMUnLockBirthChartHole()
-ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMUnLockBirthChartHole.Cmd,m_NAtagCMUnLockBirthChartHole.SubCmd))] = m_NAtagCMUnLockBirthChartHole
 
 
 #------------------------------------------------------
@@ -12699,6 +12426,237 @@
 
 
 #------------------------------------------------------
+# B2 51 命格分解 #tagCSMinggeDecompose
+
+class  tagCSMinggeDecompose(Structure):
+    Head = tagHead()
+    Count = 0    #(BYTE Count)
+    IndexList = list()    #(vector<BYTE> IndexList)// 推演背包中的物品格子索引列表
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB2
+        self.Head.SubCmd = 0x51
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.Count):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.IndexList.append(value)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB2
+        self.Head.SubCmd = 0x51
+        self.Count = 0
+        self.IndexList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 1 * self.Count
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.Count)
+        for i in range(self.Count):
+            data = CommFunc.WriteBYTE(data, self.IndexList[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                Count:%d,
+                                IndexList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.Count,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagCSMinggeDecompose=tagCSMinggeDecompose()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSMinggeDecompose.Head.Cmd,m_NAtagCSMinggeDecompose.Head.SubCmd))] = m_NAtagCSMinggeDecompose
+
+
+#------------------------------------------------------
+# B2 52 命格装备替换 #tagCSMinggeEquip
+
+class  tagCSMinggeEquip(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("MGNum", c_ubyte),    # 装到哪一套命格,目前支持3套,从1开始
+                  ("Index", c_ubyte),    # 推演背包中的物品格子索引
+                  ("AutoDec", c_ubyte),    # 是否自动分解
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB2
+        self.SubCmd = 0x52
+        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 = 0xB2
+        self.SubCmd = 0x52
+        self.MGNum = 0
+        self.Index = 0
+        self.AutoDec = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSMinggeEquip)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 52 命格装备替换 //tagCSMinggeEquip:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                MGNum:%d,
+                                Index:%d,
+                                AutoDec:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.MGNum,
+                                self.Index,
+                                self.AutoDec
+                                )
+        return DumpString
+
+
+m_NAtagCSMinggeEquip=tagCSMinggeEquip()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSMinggeEquip.Cmd,m_NAtagCSMinggeEquip.SubCmd))] = m_NAtagCSMinggeEquip
+
+
+#------------------------------------------------------
+# B2 53 命格祈灵#tagCSMinggeQiling
+
+class  tagCSMinggeQiling(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("UseCount", c_int),    #使用个数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB2
+        self.SubCmd = 0x53
+        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 = 0xB2
+        self.SubCmd = 0x53
+        self.UseCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSMinggeQiling)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 53 命格祈灵//tagCSMinggeQiling:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                UseCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.UseCount
+                                )
+        return DumpString
+
+
+m_NAtagCSMinggeQiling=tagCSMinggeQiling()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSMinggeQiling.Cmd,m_NAtagCSMinggeQiling.SubCmd))] = m_NAtagCSMinggeQiling
+
+
+#------------------------------------------------------
+# B2 50 命格推演 #tagCSMinggeTuiyan
+
+class  tagCSMinggeTuiyan(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("Count", c_ubyte),    #推演个数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB2
+        self.SubCmd = 0x50
+        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 = 0xB2
+        self.SubCmd = 0x50
+        self.Count = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCSMinggeTuiyan)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B2 50 命格推演 //tagCSMinggeTuiyan:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                Count:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.Count
+                                )
+        return DumpString
+
+
+m_NAtagCSMinggeTuiyan=tagCSMinggeTuiyan()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSMinggeTuiyan.Cmd,m_NAtagCSMinggeTuiyan.SubCmd))] = m_NAtagCSMinggeTuiyan
+
+
+#------------------------------------------------------
 # B2 07 重置加点 #tagCMResetAttrPoint
 
 class  tagCMResetAttrPoint(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 6740488..b525881 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -31772,6 +31772,66 @@
 
 
 #------------------------------------------------------
+# B1 32 命格信息 #tagSCMinggeInfo
+
+class  tagSCMinggeInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("GanwuLV", c_ushort),    #感悟等级,从1开始
+                  ("GanwuExp", c_int),    #当前感悟等级经验,每级从0开始
+                  ("Lingying", c_int),    #当前灵应值
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB1
+        self.SubCmd = 0x32
+        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 = 0x32
+        self.GanwuLV = 0
+        self.GanwuExp = 0
+        self.Lingying = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagSCMinggeInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B1 32 命格信息 //tagSCMinggeInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                GanwuLV:%d,
+                                GanwuExp:%d,
+                                Lingying:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.GanwuLV,
+                                self.GanwuExp,
+                                self.Lingying
+                                )
+        return DumpString
+
+
+m_NAtagSCMinggeInfo=tagSCMinggeInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCMinggeInfo.Cmd,m_NAtagSCMinggeInfo.SubCmd))] = m_NAtagSCMinggeInfo
+
+
+#------------------------------------------------------
 # B1 19 形象信息 #tagSCModelInfo
 
 class  tagSCModel(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearPack.py
index 0d28f0c..2d6ea4f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearPack.py
@@ -26,7 +26,7 @@
 #  @remarks 函数详细说明.
 def OnExec(curPlayer, playerList):
     if not playerList:
-        GameWorld.DebugAnswer(curPlayer, "背包类型:1-装备;2-背包;5-仓库;30-寻宝;32-神兽;33-神兽装备;34-垃圾收集")
+        GameWorld.DebugAnswer(curPlayer, "背包类型:1-装备;2-背包;8-主线掉落;35-武将;36-命格;37-推演")
         return
     
     if len(playerList) == 1:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mingge.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mingge.py
new file mode 100644
index 0000000..2aad2b7
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Mingge.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.Mingge
+#
+# @todo:命格
+# @author hxp
+# @date 2026-01-13
+# @version 1.0
+#
+# 详细描述: 命格
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2026-01-13 11:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import ShareDefine
+import PlayerMingge
+import IpyGameDataPY
+import PlayerControl
+import ClearPack
+import ChConfig
+
+def OnExec(curPlayer, msgList):
+    
+    if not msgList:
+        GameWorld.DebugAnswer(curPlayer, "重置命格: Mingge 0 [是否重置卦玉]")
+        GameWorld.DebugAnswer(curPlayer, "设置感悟: Mingge 感悟等级 [经验 灵应值]")
+        return
+    
+    value1 = msgList[0]
+    if value1 == 0:
+        isResetItem = msgList[1] if len(msgList) > 1 else 0
+        PlayerMingge.DoMinggeOpen(curPlayer)
+        if isResetItem:
+            ClearPack.OnExec(curPlayer, [ShareDefine.rptMGGuayu])
+            ClearPack.OnExec(curPlayer, [ShareDefine.rptMGTuiyan])
+        GameWorld.DebugAnswer(curPlayer, "重置命格!")
+    elif value1 > 0:
+        ipyDataMgr = IpyGameDataPY.IPY_Data()
+        maxGWLV = ipyDataMgr.GetMGGanwuLVByIndex(ipyDataMgr.GetMGGanwuLVCount() - 1).GetGanwuLV()
+        gwLV = min(max(1, value1), maxGWLV)
+        gwExp = msgList[1] if len(msgList) > 1 else curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGGanwuExp)
+        lingying = msgList[2] if len(msgList) > 2 else curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGLingying)
+        
+        gwLV = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGGanwuLV, gwLV)
+        gwExp = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGGanwuExp, gwExp)
+        lingying = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGLingying, lingying)
+        GameWorld.DebugAnswer(curPlayer, "设置感悟LV=%s,Exp=%s,灵应=%s" % (gwLV, gwExp, lingying))
+        
+    PlayerMingge.RefreshMinggeAttr(curPlayer)
+    PlayerMingge.Sync_MinggeInfo(curPlayer)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 707ea02..b901fcf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -283,6 +283,7 @@
                         ("float", "AtkRatio", 0),
                         ("float", "MaxHPRatio", 0),
                         ("float", "DefRatio", 0),
+                        ("float", "AtkSpeedRatio", 0),
                         ("float", "StunRateRatio", 0),
                         ("float", "SuperHitRateRatio", 0),
                         ("float", "ComboRateRatio", 0),
@@ -601,6 +602,39 @@
                         ("list", "BaseAttrValue", 0),
                         ("list", "LegendAttrID", 0),
                         ("list", "LegendAttrValue", 0),
+                        ),
+
+                "MGGanwuLV":(
+                        ("BYTE", "GanwuLV", 1),
+                        ("DWORD", "NextNeedExp", 0),
+                        ("DWORD", "AtkBase", 0),
+                        ("DWORD", "DefBase", 0),
+                        ("DWORD", "HPBase", 0),
+                        ("DWORD", "AtkSpeedBase", 0),
+                        ),
+
+                "MGGuayuQuality":(
+                        ("BYTE", "ItemColor", 1),
+                        ("float", "AtkPlus", 0),
+                        ("float", "DefPlus", 0),
+                        ("float", "HPPlus", 0),
+                        ("float", "AtkSpeedPlus", 0),
+                        ("BYTE", "AttrLibCnt", 0),
+                        ("list", "AttrRange", 0),
+                        ("dict", "AttrRangeDict", 0),
+                        ),
+
+                "MGGuayuType":(
+                        ("BYTE", "ItemType", 1),
+                        ("BYTE", "EquipPlace", 0),
+                        ("float", "BaseAttrProportion", 0),
+                        ("DWORD", "FixedAttrID", 0),
+                        ("list", "AttrIDLib", 0),
+                        ),
+
+                "MGLingyingQuality":(
+                        ("DWORD", "Lingying", 1),
+                        ("list", "ItemColorWeightList", 0),
                         ),
 
                 "EquipLegendAttrCount":(
@@ -2623,50 +2657,51 @@
     def GetAtkRatio(self): return self.attrTuple[1] # 攻击系数 float
     def GetMaxHPRatio(self): return self.attrTuple[2] # float
     def GetDefRatio(self): return self.attrTuple[3] # float
-    def GetStunRateRatio(self): return self.attrTuple[4] # float
-    def GetSuperHitRateRatio(self): return self.attrTuple[5] # float
-    def GetComboRateRatio(self): return self.attrTuple[6] # float
-    def GetMissRateRatio(self): return self.attrTuple[7] # float
-    def GetParryRateRatio(self): return self.attrTuple[8] # float
-    def GetSuckHPPerRatio(self): return self.attrTuple[9] # float
-    def GetStunRateDefRatio(self): return self.attrTuple[10] # float
-    def GetSuperHitRateDefRatio(self): return self.attrTuple[11] # float
-    def GetComboRateDefRatio(self): return self.attrTuple[12] # float
-    def GetMissRateDefRatio(self): return self.attrTuple[13] # float
-    def GetParryRateDefRatio(self): return self.attrTuple[14] # float
-    def GetSuckHPPerDefRatio(self): return self.attrTuple[15] # float
-    def GetFinalDamPerRatio(self): return self.attrTuple[16] # float
-    def GetFinalDamPerDefRatio(self): return self.attrTuple[17] # float
-    def GetPhyDamPerRatio(self): return self.attrTuple[18] # float
-    def GetPhyDamPerDefRatio(self): return self.attrTuple[19] # float
-    def GetMagDamPerRatio(self): return self.attrTuple[20] # float
-    def GetMagDamPerDefRatio(self): return self.attrTuple[21] # float
-    def GetNormalSkillPerRatio(self): return self.attrTuple[22] # float
-    def GetNormalSkillPerDefRatio(self): return self.attrTuple[23] # float
-    def GetAngerSkillPerRatio(self): return self.attrTuple[24] # float
-    def GetAngerSkillPerDefRatio(self): return self.attrTuple[25] # float
-    def GetSuperDamPerRatio(self): return self.attrTuple[26] # float
-    def GetSuperDamPerDefRatio(self): return self.attrTuple[27] # float
-    def GetCurePerRatio(self): return self.attrTuple[28] # float
-    def GetCurePerDefRatio(self): return self.attrTuple[29] # float
-    def GetShieldPerRatio(self): return self.attrTuple[30] # float
-    def GetShieldPerDefRatio(self): return self.attrTuple[31] # float
-    def GetDOTPerRatio(self): return self.attrTuple[32] # float
-    def GetDOTPerDefRatio(self): return self.attrTuple[33] # float
-    def GetWeiFinalDamPerRatio(self): return self.attrTuple[34] # float
-    def GetWeiFinalDamPerDefRatio(self): return self.attrTuple[35] # float
-    def GetShuFinalDamPerRatio(self): return self.attrTuple[36] # float
-    def GetShuFinalDamPerDefRatio(self): return self.attrTuple[37] # float
-    def GetWuFinalDamPerRatio(self): return self.attrTuple[38] # float
-    def GetWuFinalDamPerDefRatio(self): return self.attrTuple[39] # float
-    def GetQunFinalDamPerRatio(self): return self.attrTuple[40] # float
-    def GetQunFinalDamPerDefRatio(self): return self.attrTuple[41] # float
-    def GetPVPDamPerRatio(self): return self.attrTuple[42] # float
-    def GetPVPDamPerDefRatio(self): return self.attrTuple[43] # float
-    def GetGuanchuanRatio(self): return self.attrTuple[44] # float
-    def GetGuanchuanDefRatio(self): return self.attrTuple[45] # float
-    def GetZhaojiaRatio(self): return self.attrTuple[46] # float
-    def GetZhaojiaDefRatio(self): return self.attrTuple[47] # float
+    def GetAtkSpeedRatio(self): return self.attrTuple[4] # float
+    def GetStunRateRatio(self): return self.attrTuple[5] # float
+    def GetSuperHitRateRatio(self): return self.attrTuple[6] # float
+    def GetComboRateRatio(self): return self.attrTuple[7] # float
+    def GetMissRateRatio(self): return self.attrTuple[8] # float
+    def GetParryRateRatio(self): return self.attrTuple[9] # float
+    def GetSuckHPPerRatio(self): return self.attrTuple[10] # float
+    def GetStunRateDefRatio(self): return self.attrTuple[11] # float
+    def GetSuperHitRateDefRatio(self): return self.attrTuple[12] # float
+    def GetComboRateDefRatio(self): return self.attrTuple[13] # float
+    def GetMissRateDefRatio(self): return self.attrTuple[14] # float
+    def GetParryRateDefRatio(self): return self.attrTuple[15] # float
+    def GetSuckHPPerDefRatio(self): return self.attrTuple[16] # float
+    def GetFinalDamPerRatio(self): return self.attrTuple[17] # float
+    def GetFinalDamPerDefRatio(self): return self.attrTuple[18] # float
+    def GetPhyDamPerRatio(self): return self.attrTuple[19] # float
+    def GetPhyDamPerDefRatio(self): return self.attrTuple[20] # float
+    def GetMagDamPerRatio(self): return self.attrTuple[21] # float
+    def GetMagDamPerDefRatio(self): return self.attrTuple[22] # float
+    def GetNormalSkillPerRatio(self): return self.attrTuple[23] # float
+    def GetNormalSkillPerDefRatio(self): return self.attrTuple[24] # float
+    def GetAngerSkillPerRatio(self): return self.attrTuple[25] # float
+    def GetAngerSkillPerDefRatio(self): return self.attrTuple[26] # float
+    def GetSuperDamPerRatio(self): return self.attrTuple[27] # float
+    def GetSuperDamPerDefRatio(self): return self.attrTuple[28] # float
+    def GetCurePerRatio(self): return self.attrTuple[29] # float
+    def GetCurePerDefRatio(self): return self.attrTuple[30] # float
+    def GetShieldPerRatio(self): return self.attrTuple[31] # float
+    def GetShieldPerDefRatio(self): return self.attrTuple[32] # float
+    def GetDOTPerRatio(self): return self.attrTuple[33] # float
+    def GetDOTPerDefRatio(self): return self.attrTuple[34] # float
+    def GetWeiFinalDamPerRatio(self): return self.attrTuple[35] # float
+    def GetWeiFinalDamPerDefRatio(self): return self.attrTuple[36] # float
+    def GetShuFinalDamPerRatio(self): return self.attrTuple[37] # float
+    def GetShuFinalDamPerDefRatio(self): return self.attrTuple[38] # float
+    def GetWuFinalDamPerRatio(self): return self.attrTuple[39] # float
+    def GetWuFinalDamPerDefRatio(self): return self.attrTuple[40] # float
+    def GetQunFinalDamPerRatio(self): return self.attrTuple[41] # float
+    def GetQunFinalDamPerDefRatio(self): return self.attrTuple[42] # float
+    def GetPVPDamPerRatio(self): return self.attrTuple[43] # float
+    def GetPVPDamPerDefRatio(self): return self.attrTuple[44] # float
+    def GetGuanchuanRatio(self): return self.attrTuple[45] # float
+    def GetGuanchuanDefRatio(self): return self.attrTuple[46] # float
+    def GetZhaojiaRatio(self): return self.attrTuple[47] # float
+    def GetZhaojiaDefRatio(self): return self.attrTuple[48] # float
 
 # 主线章节表
 class IPY_MainChapter():
@@ -3076,6 +3111,59 @@
     def GetBaseAttrValue(self): return self.attrTuple[4] # 基础属性值 list
     def GetLegendAttrID(self): return self.attrTuple[5] # 传奇属性ID list
     def GetLegendAttrValue(self): return self.attrTuple[6] # 传奇属性值 list
+
+# 感悟等级表
+class IPY_MGGanwuLV():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetGanwuLV(self): return self.attrTuple[0] # 感悟等级 BYTE
+    def GetNextNeedExp(self): return self.attrTuple[1] # 升到下一级所需经验 DWORD
+    def GetAtkBase(self): return self.attrTuple[2] # 攻击基础值 DWORD
+    def GetDefBase(self): return self.attrTuple[3] # 防御基础值 DWORD
+    def GetHPBase(self): return self.attrTuple[4] # 生命基础值 DWORD
+    def GetAtkSpeedBase(self): return self.attrTuple[5] # 先攻基础值 DWORD
+
+# 卦玉品质表
+class IPY_MGGuayuQuality():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetItemColor(self): return self.attrTuple[0] # 品质 BYTE
+    def GetAtkPlus(self): return self.attrTuple[1] # 攻击加成 float
+    def GetDefPlus(self): return self.attrTuple[2] # 防御加成 float
+    def GetHPPlus(self): return self.attrTuple[3] # 生命加成 float
+    def GetAtkSpeedPlus(self): return self.attrTuple[4] # 先攻加成 float
+    def GetAttrLibCnt(self): return self.attrTuple[5] # 库属性条数 BYTE
+    def GetAttrRange(self): return self.attrTuple[6] # 通用属性范围,下限|上限 list
+    def GetAttrRangeDict(self): return self.attrTuple[7] # 指定属性范围字典,{指定属性ID:[范围下限, 上限], ...} dict
+
+# 卦玉类型表
+class IPY_MGGuayuType():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetItemType(self): return self.attrTuple[0] # 类型 BYTE
+    def GetEquipPlace(self): return self.attrTuple[1] # 装备位 BYTE
+    def GetBaseAttrProportion(self): return self.attrTuple[2] # 基础四维属性占比 float
+    def GetFixedAttrID(self): return self.attrTuple[3] # 固定属性ID DWORD
+    def GetAttrIDLib(self): return self.attrTuple[4] # 随机属性ID库,[属性ID, ...] list
+
+# 灵应品质表
+class IPY_MGLingyingQuality():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetLingying(self): return self.attrTuple[0] # 灵应段值 DWORD
+    def GetItemColorWeightList(self): return self.attrTuple[1] # 品质权重列表 list
 
 # 装备传奇属性条数表
 class IPY_EquipLegendAttrCount():
@@ -5735,6 +5823,10 @@
         self.__LoadFileData("EquipColor", onlyCheck)
         self.__LoadFileData("EquipPlace", onlyCheck)
         self.__LoadFileData("AppointItem", onlyCheck)
+        self.__LoadFileData("MGGanwuLV", onlyCheck)
+        self.__LoadFileData("MGGuayuQuality", onlyCheck)
+        self.__LoadFileData("MGGuayuType", onlyCheck)
+        self.__LoadFileData("MGLingyingQuality", onlyCheck)
         self.__LoadFileData("EquipLegendAttrCount", onlyCheck)
         self.__LoadFileData("EquipLegendAttrType", onlyCheck)
         self.__LoadFileData("EquipLegendAttrLib", onlyCheck)
@@ -6475,6 +6567,34 @@
         self.CheckLoadData("AppointItem")
         return self.ipyAppointItemCache[index]
 
+    def GetMGGanwuLVCount(self):
+        self.CheckLoadData("MGGanwuLV")
+        return self.ipyMGGanwuLVLen
+    def GetMGGanwuLVByIndex(self, index):
+        self.CheckLoadData("MGGanwuLV")
+        return self.ipyMGGanwuLVCache[index]
+
+    def GetMGGuayuQualityCount(self):
+        self.CheckLoadData("MGGuayuQuality")
+        return self.ipyMGGuayuQualityLen
+    def GetMGGuayuQualityByIndex(self, index):
+        self.CheckLoadData("MGGuayuQuality")
+        return self.ipyMGGuayuQualityCache[index]
+
+    def GetMGGuayuTypeCount(self):
+        self.CheckLoadData("MGGuayuType")
+        return self.ipyMGGuayuTypeLen
+    def GetMGGuayuTypeByIndex(self, index):
+        self.CheckLoadData("MGGuayuType")
+        return self.ipyMGGuayuTypeCache[index]
+
+    def GetMGLingyingQualityCount(self):
+        self.CheckLoadData("MGLingyingQuality")
+        return self.ipyMGLingyingQualityLen
+    def GetMGLingyingQualityByIndex(self, index):
+        self.CheckLoadData("MGLingyingQuality")
+        return self.ipyMGLingyingQualityCache[index]
+
     def GetEquipLegendAttrCountCount(self):
         self.CheckLoadData("EquipLegendAttrCount")
         return self.ipyEquipLegendAttrCountLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
index f5d303d..ac125e9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -486,7 +486,7 @@
     
     if itemType in IpyGameDataPY.GetFuncEvalCfg("ItemRecordRule", 4) \
         or itemID in IpyGameDataPY.GetFuncEvalCfg("ItemRecordRule", 5):
-        GameWorld.DebugLog("不需要记录的物品类型或ID! itemType=%s,itemID=%s" % (itemType, itemID))
+        #GameWorld.DebugLog("不需要记录的物品类型或ID! itemType=%s,itemID=%s" % (itemType, itemID))
         return False
     
     itemTypeMinColorDict = IpyGameDataPY.GetFuncEvalCfg("ItemRecordRule", 1)
@@ -978,7 +978,7 @@
         #itemFactory = GameWorld.GetItemFactory()
         #isBind = tagItem.GetIsBind()
         # 目前暂只记录放入背包的
-        if not isNeedRecord and packIndex in [IPY_GameWorld.rptItem, ShareDefine.rptTreasure, IPY_GameWorld.rptIdentify]:
+        if not isNeedRecord and packIndex in [IPY_GameWorld.rptItem, ShareDefine.rptTreasure, IPY_GameWorld.rptIdentify, ShareDefine.rptMGTuiyan]:
             isNeedRecord = ItemNeedRecord(tagItem) or isForceEvent
         putResult = False
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
index b83966e..9823111 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
@@ -321,7 +321,7 @@
     @param isAuctionItem: 是否拍品,默认非拍品
     @param expireTime: 有效时间,时间单位由时效类型决定
     '''
-    if itemCount < 1:
+    if itemCount < 1 or not itemID:
         GameWorld.ErrLog("创建物品个数不能少于1! itemID=%s,itemCount=%s" % (itemID, itemCount))
         return
     curSingleItem = GameWorld.GetItemFactory().CreateItem(itemID)
@@ -376,6 +376,11 @@
         if setAttrDict == None:
             curSingleItem.Clear()
             return
+    elif GetIsMGGuayu(curSingleItem):
+        setAttrDict = GetCreateMGGuayuAttr(curSingleItem, curPlayer, setAttrDict)
+        if setAttrDict == None:
+            curSingleItem.Clear()
+            return
     AddCreateItemAttr(curSingleItem, setAttrDict)
     
     #这里返回的是SingleItem , 如果创建了,未使用,会找出C++内存泄露!!!
@@ -416,7 +421,7 @@
     @param curPlayer: 可能为None
     @param setAttrDict: 直接设置物品的属性 {key:value, ...} key支持  ShareDefine.Def_IudetXXX字符串 或 自定key
     @return: None - 异常情况,物品实例需要clear
-            equipAttrDict - 生成后的最新属性k:v字典,可直接用于 SetCreateEquipAttr
+            equipAttrDict - 生成后的最新属性k:v字典,可直接用于 AddCreateItemAttr
     '''
     if setAttrDict == None:
         setAttrDict = {}
@@ -544,6 +549,109 @@
         GameWorld.DebugLog("    legendAttrIDList=%s,legendAttrValueList=%s" % (legendAttrIDList, legendAttrValueList), playerID)
         
     GameWorld.DebugLog("    装备最终属性: equipAttrDict=%s,setAttrDict=%s" % (equipAttrDict, setAttrDict), playerID)
+    return equipAttrDict
+
+def GetCreateMGGuayuAttr(curItem, curPlayer=None, setAttrDict=None):
+    '''获取生成命格卦玉所有属性
+    @param curPlayer: 可能为None
+    @param setAttrDict: 直接设置物品的属性 {key:value, ...} key支持  ShareDefine.Def_IudetXXX字符串 或 自定key
+    @return: None - 异常情况,物品实例需要clear
+            equipAttrDict - 生成后的最新属性k:v字典,可直接用于 AddCreateItemAttr
+    '''
+    if setAttrDict == None:
+        setAttrDict = {}
+    playerID = 0 if not curPlayer else curPlayer.GetPlayerID()
+    itemID = curItem.GetItemTypeID()
+    itemType = curItem.GetType()
+    itemColor = curItem.GetItemColor()
+    equipAttrDict = {}
+        
+    # 定制属性,如有需要可扩展
+    
+    if not curPlayer:
+        return
+    
+    gwLV = max(1, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGGanwuLV))
+    gwIpyData = IpyGameDataPY.GetIpyGameData("MGGanwuLV", gwLV)
+    colorIpyData = IpyGameDataPY.GetIpyGameData("MGGuayuQuality", itemColor)
+    typeIpyData = IpyGameDataPY.GetIpyGameData("MGGuayuType", itemType)
+    if not gwIpyData or not colorIpyData or not typeIpyData:
+        return
+    
+    # 四维基础值、加成值
+    baseAttrDict = {ChConfig.AttrID_Atk:[gwIpyData.GetAtkBase(), colorIpyData.GetAtkPlus()],
+                    ChConfig.AttrID_Def:[gwIpyData.GetDefBase(), colorIpyData.GetDefPlus()],
+                    ChConfig.AttrID_MaxHP:[gwIpyData.GetHPBase(), colorIpyData.GetHPPlus()],
+                    ChConfig.AttrID_AtkSpeed:[gwIpyData.GetAtkSpeedBase(), colorIpyData.GetAtkSpeedPlus()],
+                    }
+    # 四维占比
+    attrProportion = typeIpyData.GetBaseAttrProportion()
+    
+    randfloat = random.uniform # 随机一个ab区间的数 [a, b],ab支持小数
+    
+    itemLV = setAttrDict.get(str(ShareDefine.Def_IudetItemLV), 0)
+    if not itemLV:
+        # 随机等级
+        lowLV, highLV = IpyGameDataPY.GetFuncEvalCfg("MinggeTY", 2)
+        randLVList = range(max(gwLV + lowLV, 1), gwLV + highLV)
+        itemLV = random.choice(randLVList)
+    equipAttrDict[str(ShareDefine.Def_IudetItemLV)] = itemLV
+    
+    GameWorld.DebugLog("生成命格卦玉: itemID=%s,itemLV=%s,itemColor=%s,itemType=%s" % (itemID, itemLV, itemColor, itemType), playerID)
+    legendAttrIDList = setAttrDict.get(str(ShareDefine.Def_IudetLegendAttrID))
+    legendAttrValueList = setAttrDict.get(str(ShareDefine.Def_IudetLegendAttrValue))
+    if legendAttrIDList != None and legendAttrValueList != None and len(legendAttrIDList) == len(legendAttrValueList):
+        equipAttrDict[str(ShareDefine.Def_IudetLegendAttrID)] = legendAttrIDList
+        equipAttrDict[str(ShareDefine.Def_IudetLegendAttrValue)] = legendAttrValueList
+    else:
+        fixedAttrID = typeIpyData.GetFixedAttrID() # 固定属性
+        attrIDLib = typeIpyData.GetAttrIDLib() # 随机属性库
+        libAttrCnt = colorIpyData.GetAttrLibCnt() # 随机属性个数
+        
+        attrRangeDefault = colorIpyData.GetAttrRange()
+        attrRangeDict = colorIpyData.GetAttrRangeDict()
+        
+        random.shuffle(attrIDLib)
+        randAttrList = attrIDLib[:libAttrCnt]
+        attrIDList = [fixedAttrID] + randAttrList
+        GameWorld.DebugLog("    attrIDList=%s,libAttrCnt=%s,%s" % (attrIDList, libAttrCnt, attrIDLib), playerID)
+        
+        legendAttrIDList = []
+        legendAttrValueList = []
+        for attrID in attrIDList:
+            
+            # 基础四维计算
+            if attrID in baseAttrDict:
+                baseValue, plusValue = baseAttrDict[attrID]
+                attrValue = eval(IpyGameDataPY.GetFuncCompileCfg("MinggeTY", 3))
+                GameWorld.DebugLog("        attrID=%s,attrValue=%s,baseValue=%s,plusValue=%s,attrProportion=%s" 
+                                   % (attrID, attrValue, baseValue, plusValue, attrProportion), playerID)
+                
+            # 其他战斗属性
+            else:
+                attrRange = attrRangeDict.get(attrID, attrRangeDefault)
+                if not attrRange or len(attrRange) != 2:
+                    continue
+                attrMin, attrMax = attrRange
+                attrValue = random.randint(attrMin, attrMax)
+                GameWorld.DebugLog("        attrID=%s,attrValue=%s(%s~%s)" % (attrID, attrValue, attrMin, attrMax), playerID)
+                
+            legendAttrIDList.append(attrID)
+            legendAttrValueList.append(attrValue)
+            
+        if legendAttrIDList:
+            equipAttrDict[str(ShareDefine.Def_IudetLegendAttrID)] = legendAttrIDList
+            equipAttrDict[str(ShareDefine.Def_IudetLegendAttrValue)] = legendAttrValueList
+            
+    # 意象技能
+    if itemType in IpyGameDataPY.GetFuncEvalCfg("MinggeTY", 4):
+        yxSkillTypeIDList = IpyGameDataPY.GetFuncEvalCfg("MinggeTY", 5)
+        randSkillTypeID = random.choice(yxSkillTypeIDList) if yxSkillTypeIDList else 0
+        if randSkillTypeID:
+            equipAttrDict[str(ShareDefine.Def_IudetAddSkillID)] = [randSkillTypeID]
+            GameWorld.DebugLog("        itemType=%s,randSkillTypeID=%s" % (itemType, randSkillTypeID), playerID)
+            
+    GameWorld.DebugLog("    卦玉最终属性: equipAttrDict=%s,setAttrDict=%s" % (equipAttrDict, setAttrDict), playerID)
     return equipAttrDict
 
 def SetItemUserData(curItem, dataInfo):
@@ -1782,6 +1890,10 @@
     ## 返回是否神兽装备
     return curItem.GetType() in ChConfig.Def_DogzEquiipType
 
+def GetIsMGGuayu(curItem):
+    ## 是否命格卦玉
+    return curItem.GetType() in ChConfig.Def_MGGuayuType
+
 #---------------------------------------------------------------------
 ##遍历数据库查找合适的物品, 通过 效果ID + 效果A值确定物品
 # @param itemType 物品类型
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 b1eed6c..c26452a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -131,6 +131,7 @@
 import PlayerOnline
 import PlayerBeauty
 import PlayerTravel
+import PlayerMingge
 import TurnAttack
 import PlayerHJG
 import ChEquip
@@ -730,6 +731,7 @@
         PlayerLLMJ.OnPlayerLogin(curPlayer)
         PlayerBeauty.OnPlayerLogin(curPlayer)
         PlayerTravel.OnPlayerLogin(curPlayer)
+        PlayerMingge.OnPlayerLogin(curPlayer)
         OpenServerActivity.OnPlayerLogin(curPlayer)
         
         __OnFixVersion(curPlayer) # 修正线上玩家数据用,暂时放最后
@@ -1236,6 +1238,10 @@
     #初始化英雄背包
     PlayerControl.Init_PackCount(curPlayer, ShareDefine.rptHero)
     
+    #初始化卦玉背包
+    PlayerControl.Init_PackCount(curPlayer, ShareDefine.rptMGGuayu, defaultMax=True, isSync=False)
+    PlayerControl.Init_PackCount(curPlayer, ShareDefine.rptMGTuiyan, defaultMax=True, isSync=False)
+    
     #初始化临时交换背包,默认最大个数
     PlayerControl.Init_PackCount(curPlayer, ShareDefine.rptTempSwap, defaultMax=True, isSync=False)
     
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 91fe638..bbbc8ca 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
@@ -33,6 +33,7 @@
 import PlayerActLoginNew
 import PlayerActTask
 import ItemControler
+import PlayerMingge
 import PlayerTravel
 import PlayerHorse
 import PlayerArena
@@ -46,6 +47,7 @@
                      ShareDefine.GameFuncID_Shop:lambda curObj:FunctionNPCCommon.DoShopOpen(curObj),
                      ShareDefine.GameFuncID_Horse:lambda curObj:PlayerHorse.DoHorseOpen(curObj),
                      ShareDefine.GameFuncID_Travel:lambda curObj:PlayerTravel.DoTravelOpen(curObj),
+                     ShareDefine.GameFuncID_Mingge:lambda curObj:PlayerMingge.DoMinggeOpen(curObj),
                      ShareDefine.GameFuncID_OSA_MainLevel:lambda curObj:OpenServerActivity.DoOSA_MainLevel(curObj),
                      ShareDefine.GameFuncID_OSA_HeroCall:lambda curObj:OpenServerActivity.DoOSA_HeroCall(curObj),
                      }
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMingge.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMingge.py
new file mode 100644
index 0000000..ffbfad7
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMingge.py
@@ -0,0 +1,358 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerMingge
+#
+# @todo:命格
+# @author hxp
+# @date 2026-01-13
+# @version 1.0
+#
+# 详细描述: 命格
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2026-01-13 11:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PlayerControl
+import ItemControler
+import IpyGameDataPY
+import ChPyNetSendPack
+import NetPackCommon
+import PlayerOnline
+import ShareDefine
+import ItemCommon
+import ChConfig
+
+import random
+
+def OnPlayerLogin(curPlayer):
+    Sync_MinggeInfo(curPlayer)
+    return
+
+def DoMinggeOpen(curPlayer):
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGGanwuLV, 1)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGGanwuExp, 0)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGLingying, 0)
+    Sync_MinggeInfo(curPlayer)
+    return
+
+#// B2 50 命格推演 #tagCSMinggeTuiyan
+#
+#struct    tagCSMinggeTuiyan
+#{
+#    tagHead        Head;
+#    BYTE        Count;    //推演个数
+#};
+def OnMinggeTuiyan(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    tyCount = clientData.Count
+    DoMinggeTuiyan(curPlayer, tyCount)
+    return
+
+def GetMGColorRateList(curPlayer):
+    ## 获取命格推演的品质概率饼图
+    
+    playerID = curPlayer.GetPlayerID()
+    curLingying = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGLingying)
+    
+    curIpyData, nextIpyData = None, None
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for index in range(ipyDataMgr.GetMGLingyingQualityCount()):
+        ipyData = ipyDataMgr.GetMGLingyingQualityByIndex(index)
+        lingying = ipyData.GetLingying()
+        if curLingying >= lingying:
+            curIpyData = ipyData
+        else:
+            nextIpyData = ipyData
+            break
+        
+    if not curIpyData:
+        return []
+    
+    minggeRateList = []
+    if not nextIpyData:
+        rate = 0
+        weightList = curIpyData.GetItemColorWeightList()
+        for quality, weight in enumerate(weightList, 1):
+            if not weight:
+                continue
+            rate += weight
+            minggeRateList.append([rate, quality])
+        GameWorld.DebugLog("灵应满级了: curLingying=%s,%s" % (curLingying, minggeRateList), playerID)
+    else:
+        rate = 0
+        curIpyLingying = curIpyData.GetLingying()
+        nextIpyLingying = nextIpyData.GetLingying()
+        lingyingDiffMax = nextIpyLingying - curIpyLingying # 灵应差值段
+        lingyingDiffNow = curLingying - curIpyLingying # 当前灵应差值
+        diffPer = lingyingDiffNow / float(lingyingDiffMax) # 差值占比
+        curWeightList = curIpyData.GetItemColorWeightList()
+        nextWeightList = nextIpyData.GetItemColorWeightList()
+        #GameWorld.DebugLog("灵应品质饼图计算: curLingying=%s,curIpyLingying=%s,nextIpyLingying=%s" % (curLingying, curIpyLingying, nextIpyLingying), playerID)
+        #GameWorld.DebugLog("    lingyingDiffNow=%s,lingyingDiffMax=%s,diffPer=%s" % (lingyingDiffNow, lingyingDiffMax, diffPer), playerID)
+        #GameWorld.DebugLog("    curWeightList =%s" % (curWeightList), playerID)
+        #GameWorld.DebugLog("    nextWeightList=%s" % (nextWeightList), playerID)
+        for quality, nextWeight in enumerate(nextWeightList, 1):
+            curWeight = curWeightList[quality - 1] if len(curWeightList) >= quality else 0
+            diffWeight = int(round((nextWeight - curWeight) * diffPer))
+            nowWeight = max(0, curWeight + diffWeight)
+            rate += nowWeight
+            #GameWorld.DebugLog("    quality=%s,rate=%s,nowWeight=%s,curWeight=%s,nextWeight=%s,diffPer=%s,diffWeight=%s" 
+            #                   % (quality, rate, nowWeight, curWeight, nextWeight, diffPer, diffWeight), playerID)
+            if nowWeight:
+                minggeRateList.append([rate, quality])
+        GameWorld.DebugLog("最终灵应品质饼图: curLingying=%s,%s" % (curLingying, minggeRateList), playerID)
+        
+    return minggeRateList
+
+def DoMinggeTuiyan(curPlayer, tyCount):
+    ## 命格推演
+    playerID = curPlayer.GetPlayerID()
+    colorRateList = GetMGColorRateList(curPlayer)
+    if not colorRateList:
+        return
+    
+    useCount = tyCount
+    useItemID = IpyGameDataPY.GetFuncCfg("MinggeCfg", 2)
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, useItemID, useCount)
+    lackCnt = useCount - bindCnt - unBindCnt
+    if lackCnt > 0:
+        useCount -= lackCnt # 不足时有多少用多少
+        
+    if useCount <= 0:
+        GameWorld.DebugLog("推演道具不足! useItemID=%s,lackCnt=%s" % (useItemID, lackCnt), playerID)
+        return
+    
+    lastColorCnt = IpyGameDataPY.GetFuncCfg("ItemRecordEquip", 1) # 有产出的最后几个品质需要记录,套用主线装备配置
+    needRecordColorMin = colorRateList[-1][1] - lastColorCnt + 1
+    
+    gameData = GameWorld.GetGameData()
+    succCount = 0
+    useCount = ItemCommon.GetItemPackSpace(curPlayer, ShareDefine.rptMGTuiyan, useCount)
+    for _ in range(useCount):
+        itemColor = GameWorld.GetResultByRandomList(colorRateList)
+        if not itemColor:
+            continue
+        
+        itemType = random.choice(ChConfig.Def_MGGuayuType)
+        randItemID = 0
+        gameData.FilterItemByType(itemType)
+        for i in xrange(gameData.GetFilterItemCount()):
+            itemData = gameData.GetFilterItem(i)
+            if itemData.GetItemColor() == itemColor:
+                randItemID = itemData.GetItemTypeID()
+                break
+            
+        GameWorld.DebugLog("命格推演: itemColor=%s,itemType=%s,randItemID=%s,colorRateList=%s" % (itemColor, itemType, randItemID, colorRateList), playerID)
+        curItem = ItemControler.GetOutPutItemObj(randItemID, 1, False, curPlayer=curPlayer)
+        if curItem == None:
+            continue
+        
+        isForceDR = (needRecordColorMin and curItem.GetItemColor() >= needRecordColorMin) # 记录流向
+        if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, event=["MinggeTuiyan", isForceDR, {}], packIndexList=[ShareDefine.rptMGTuiyan]):
+            continue
+        
+        succCount += 1
+        
+    if succCount <= 0:
+        return
+    
+    ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, succCount, "MinggeTuiyan")
+    addGWExp = succCount
+    
+    ganwuLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGGanwuLV)
+    ganwuExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGGanwuExp)
+    updLV = ganwuLV
+    updExp = ganwuExp + addGWExp
+    GameWorld.DebugLog("更新感悟经验: ganwuLV=%s,addGWExp=%s,updExp=%s" % (ganwuLV, addGWExp, updExp))
+    ipyData = IpyGameDataPY.GetIpyGameData("MGGanwuLV", ganwuLV)
+    nexpIpyData = IpyGameDataPY.GetIpyGameDataNotLog("MGGanwuLV", ganwuLV + 1)
+    while nexpIpyData and ipyData and updExp >= ipyData.GetNextNeedExp():
+        updExp -= ipyData.GetNextNeedExp()
+        updLV += 1
+        GameWorld.DebugLog("    升级: updLV=%s,updExp=%s" % (updLV, updExp))
+        ipyData = nexpIpyData
+        nexpIpyData = IpyGameDataPY.GetIpyGameDataNotLog("MGGanwuLV", updLV + 1)
+        
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGGanwuLV, updLV)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGGanwuExp, updExp)
+    Sync_MinggeInfo(curPlayer)
+    return
+
+#// B2 51 命格分解 #tagCSMinggeDecompose
+#
+#struct    tagCSMinggeDecompose
+#{
+#    tagHead        Head;
+#    BYTE        Count;
+#    BYTE        IndexList[Count];    // 推演背包中的物品格子索引列表
+#};
+def OnMinggeDecompose(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    __doDecomposeMingge(curPlayer, clientData.IndexList)
+    return
+
+def __doDecomposeMingge(curPlayer, itemIndexList):
+    playerID = curPlayer.GetPlayerID()
+    itemID, itemCount = IpyGameDataPY.GetFuncEvalCfg("MinggeTY", 1)
+    GameWorld.DebugLog("分解命格: itemIndexList=%s,itemID=%s,itemCount=%s" % (itemIndexList, itemID, itemCount), playerID)
+    if not itemID or not itemCount:
+        return
+        
+    needRecordColorMin = 0
+    colorRateList = GetMGColorRateList(curPlayer)
+    if colorRateList:
+        lastColorCnt = IpyGameDataPY.GetFuncCfg("ItemRecordEquip", 1) # 有产出的最后几个品质需要记录,套用主线装备配置
+        needRecordColorMin = colorRateList[-1][1] - lastColorCnt + 1
+        
+    GameWorld.DebugLog("needRecordColorMin=%s,colorRateList=%s" % (needRecordColorMin, colorRateList), playerID)
+    decomposeCnt = 0
+    
+    mgTuiyanPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptMGTuiyan)
+    for itemIndex in itemIndexList:
+        if itemIndex < 0 or itemIndex >= mgTuiyanPack.GetCount():
+            continue
+        curEquip = mgTuiyanPack.GetAt(itemIndex)
+        if not ItemCommon.CheckItemCanUse(curEquip):
+            GameWorld.DebugLog("物品为空或不可用: itemIndex=%s" % itemIndex, playerID)
+            continue
+        isForceDR = (needRecordColorMin and curEquip.GetItemColor() >= needRecordColorMin) # 记录分解流向
+        ItemCommon.DelItem(curPlayer, curEquip, curEquip.GetCount(), True, "MinggeDecompose", isForceDR=isForceDR)
+        decomposeCnt += 1
+        
+    if not decomposeCnt:
+        return
+    itemList = [[itemID, itemCount * decomposeCnt]]
+    ItemControler.GivePlayerItemOrMail(curPlayer, itemList, event=["MinggeDecompose", False, {}], isNotifyAward=False)
+    return
+
+#// B2 52 命格装备替换 #tagCSMinggeEquip
+#
+#struct    tagCSMinggeEquip
+#{
+#    tagHead        Head;
+#    BYTE        MGNum;    // 装到哪一套命格,目前支持3套,从1开始
+#    BYTE        Index;    // 推演背包中的物品格子索引
+#    BYTE        AutoDec;    // 是否自动分解
+#};
+def OnMinggeEquip(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    mgNum = clientData.MGNum
+    itemIndex = clientData.Index
+    isAutoDec = clientData.AutoDec
+    GameWorld.DebugLog("命格装备替换: mgNum=%s,itemIndex=%s,isAutoDec=%s" % (mgNum, itemIndex, isAutoDec), playerID)
+    
+    openNum = IpyGameDataPY.GetFuncCfg("MinggeCfg", 1)
+    if mgNum < 1 or mgNum > openNum:
+        GameWorld.DebugLog("命格套编号不支持! mgNum=%s" % mgNum, playerID)
+        return
+    
+    mgTuiyanPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptMGTuiyan)
+    if itemIndex < 0 or itemIndex >= mgTuiyanPack.GetCount():
+        return
+    curEquip = mgTuiyanPack.GetAt(itemIndex)
+    if not ItemCommon.CheckItemCanUse(curEquip):
+        GameWorld.DebugLog("    命格物品为空或不可用: itemIndex=%s" % itemIndex, playerID)
+        return
+    
+    itemID = curEquip.GetItemTypeID()
+    itemType = curEquip.GetType()
+    
+    if itemType not in ChConfig.Def_MGGuayuType:
+        return
+    
+    #支持多套,每套12件,目前支持3套,套编号 1~3
+    #对应卦玉背包索引 = (套编号-1)*12+装备位-1
+    typeIpyData = IpyGameDataPY.GetIpyGameData("MGGuayuType", itemType)
+    if not typeIpyData:
+        return
+    equipPlace = typeIpyData.GetEquipPlace() # 装备位
+    equipPlaceIndex = (mgNum - 1) * len(ChConfig.Def_MGGuayuType) + equipPlace - 1 # 装在命格背包中的索引
+    
+    GameWorld.DebugLog("    itemIndex=%s,itemID=%s,itemType=%s,equipPlace=%s,equipPlaceIndex=%s" 
+                       % (itemIndex, itemID, itemType, equipPlace, equipPlaceIndex), playerID)
+    
+    equipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptMGGuayu)
+    if equipPlaceIndex < 0 or equipPlaceIndex >= equipPack.GetCount():
+        GameWorld.ErrLog("命格卦玉对应装备位置索引异常: itemIndex=%s,mgNum=%s,itemType=%s,equipPlace=%s,equipPlaceIndex=%s" 
+                         % (itemIndex, mgNum, itemType, equipPlace, equipPlaceIndex), playerID)
+        return
+    destEquip = equipPack.GetAt(equipPlaceIndex)
+    canDecomp = ItemCommon.CheckItemCanUse(destEquip)
+    
+    if not ItemCommon.DoLogicSwitchItem(curPlayer, curEquip, destEquip, ShareDefine.rptMGGuayu):
+        return
+    
+    if isAutoDec and canDecomp:
+        __doDecomposeMingge(curPlayer, [itemIndex])
+        
+    # 刷属性
+    RefreshMinggeAttr(curPlayer)
+    return
+
+#// B2 53 命格祈灵#tagCSMinggeQiling
+#
+#struct    tagCSMinggeQiling
+#{
+#    tagHead        Head;
+#    DWORD        UseCount;    //使用个数
+#};
+def OnMinggeQiling(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    #playerID = curPlayer.GetPlayerID()
+    useCount = clientData.UseCount
+    
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    dataCount = ipyDataMgr.GetMGLingyingQualityCount()
+    if not dataCount:
+        return
+    lastIpyData = ipyDataMgr.GetMGLingyingQualityByIndex(dataCount - 1)
+    if not lastIpyData:
+        return
+    maxLingying = lastIpyData.GetLingying()
+    curLingying = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGLingying)
+    if curLingying >= maxLingying:
+        GameWorld.DebugLog("灵应值已达最大值! curLingying=%s >= %s" % (curLingying, maxLingying))
+        return
+    useCount = min(useCount, maxLingying - curLingying)
+    GameWorld.DebugLog("命格祈灵: useCount=%s,curLingying=%s,maxLingying=%s" % (useCount, curLingying, maxLingying))
+    
+    useItemID = IpyGameDataPY.GetFuncCfg("MinggeCfg", 3)
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, useItemID, useCount)
+    lackCnt = useCount - bindCnt - unBindCnt
+    if lackCnt > 0:
+        useCount -= lackCnt # 不足时有多少用多少    
+    if useCount <= 0:
+        GameWorld.DebugLog("祈灵道具不足! useItemID=%s,lackCnt=%s" % (useItemID, lackCnt))
+        return
+    ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, useCount, "MinggeQiling")
+    addLingying = useCount # 每个暂固定增加1点
+    
+    updLingying = curLingying + addLingying
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MGLingying, updLingying)
+    GameWorld.DebugLog("    updLingying=%s,useCount=%s" % (updLingying, useCount))
+    Sync_MinggeInfo(curPlayer)
+    return
+
+def RefreshMinggeAttr(curPlayer):
+    #CalcMinggeAttr(curPlayer)
+    PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr()
+    return
+
+def CalcMinggeAttr(curPlayer):
+    return
+
+def Sync_MinggeInfo(curPlayer):
+    ganwuLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGGanwuLV)
+    if not ganwuLV:
+        return
+    clientPack = ChPyNetSendPack.tagSCMinggeInfo()
+    clientPack.GanwuLV = ganwuLV
+    clientPack.GanwuExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGGanwuExp)
+    clientPack.Lingying = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGLingying)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
index 8c33799..c4f5dfd 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -25,6 +25,7 @@
 import FormulaControl
 import PlayerPrestigeSys
 import GameLogic_Dingjunge
+import PlayerMingge
 import PlayerBeauty
 import PlayerFamily
 import PlayerHorse
@@ -627,6 +628,7 @@
     PlayerHJG.CalcHJGAttr(curPlayer)
     PlayerHorse.CalcHorseAttr(curPlayer)
     PlayerBeauty.CalcBeautyAttr(curPlayer)
+    PlayerMingge.CalcMinggeAttr(curPlayer)
     GameLogic_Dingjunge.CalcDingjungeAttr(curPlayer)
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 9875d4c..f7b94a2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -815,6 +815,7 @@
 GameFuncID_OSA_MainLevel = 45   # 开服关卡榜
 GameFuncID_OSA_HeroCall = 46    # 开服招募榜
 GameFuncID_OSA_Celebration = 47 # 开服庆典
+GameFuncID_Mingge = 54          # 命格
 
 # 以下为暂时无用的
 GameFuncID_Pet = -1             # 宠物,灵宠 6
@@ -829,8 +830,10 @@
 rptDogzEquip,       # 神兽装备背包 33
 rptGarbage,         # 垃圾分类背包 34
 rptHero,            # 武将英雄背包 35
+rptMGGuayu,         # 命格卦玉背包 36
+rptMGTuiyan,        # 命格推演背包 37
 rptMax,             # 最大背包类型数量,放在最后一个
-) = range(28, 28 + 9)  #C++定义的枚举到27
+) = range(28, 28 + 11)  #C++定义的枚举到27
 
 #虚拟背包类型, 从255递减
 Def_VPack_TypeList = (
@@ -1214,12 +1217,6 @@
 Def_IudetItemDecompound = 33  # 拆解返还物品列表 [装备ID,材料1ID,个数,是否绑定,材料2ID,个数,是否绑定,...]
 Def_IudetLiantaiItemID = 35  # 合成该莲台的所有莲台ID [itemID, itemID, ...]
 Def_IudetAddSkillID = 37  # 可添加的技能ID列表  [skillID, skillID, ...]
-Def_IudetLegendAttrIDShen = 51  # 物品传奇属性ID列表 - 神
-Def_IudetLegendAttrValueShen = 61  # 物品传奇属性值列表 - 神
-Def_IudetLegendAttrIDXian = 53  # 物品传奇属性ID列表 - 仙
-Def_IudetLegendAttrValueXian = 63  # 物品传奇属性值列表 - 仙
-Def_IudetLegendAttrIDJi = 55  # 物品传奇属性ID列表 - 极
-Def_IudetLegendAttrValueJi = 65  # 物品传奇属性值列表 - 极
 Def_IudetHeroTalentID = 71  # 英雄天赋ID列表
 Def_IudetHeroTalentIDLV = 73  # 英雄天赋ID等级列表
 Def_IudetHeroTalentWashLock = 75  # 英雄天赋洗炼锁定索引列表

--
Gitblit v1.8.0