From 7fc3d3d85a5ae32e7ffa00fb1f0893e50f39922e Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 20 八月 2018 16:40:04 +0800
Subject: [PATCH] Add: 1886 【后端】神兽功能及神兽装备相关;2615 【后端】神兽——强化功能;

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py          |   16 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                 |   21 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                 |  297 +++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py             |  108 ++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                      |  297 +++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                  |  108 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                         |   28 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py     |   14 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerDogz.py           |  514 +++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py               |   58 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py             |   12 
 PySysDB/PySysDBPY.h                                                                                |   21 
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                      |   21 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py        |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                    |   50 +
 16 files changed, 1,533 insertions(+), 36 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index cfc54e1..397e977 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -126,6 +126,27 @@
 	list		AttrValue;	//属性值
 };
 
+//神兽表
+
+struct tagDogz
+{
+	BYTE		_DogzID;	//神兽ID
+	list		BaseAttrTypes;	//基础属性类型列表
+	list		BaseAttrValues;	//基础属性值列表
+	list		HelpBattleSkills;	//助战技能ID列表
+	list		EquipPlaceColorList;	//穿戴装备颜色限制
+};
+
+//神兽强化表
+
+struct tagDogzEquipPlus
+{
+	BYTE		_EquipPlace;	//装备位
+	BYTE		_PlusLV;	//强化等级
+	list		PlusAttrTypes;	//强化属性类型列表
+	list		PlusAttrValues;	//强化属性值列表
+	DWORD		PlusLVUPTotalExp;	//升级所需累计熟练度总值
+};
 
 //符印表
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 6862883..c69e43d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -7717,6 +7717,303 @@
 
 
 #------------------------------------------------------
+# A5 C2 神兽变更助战状态 #tagCMDogzBattleStateChange
+
+class  tagCMDogzBattleStateChange(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("BatteState", c_ubyte),    #助战状态,0-召回,1-助战
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC2
+        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 = 0xC2
+        self.DogzID = 0
+        self.BatteState = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzBattleStateChange)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C2 神兽变更助战状态 //tagCMDogzBattleStateChange:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                BatteState:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.BatteState
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzBattleStateChange=tagCMDogzBattleStateChange()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzBattleStateChange.Cmd,m_NAtagCMDogzBattleStateChange.SubCmd))] = m_NAtagCMDogzBattleStateChange
+
+
+#------------------------------------------------------
+# A5 C3 神兽购买助战位 #tagCMDogzBuyBatteCount
+
+class  tagCMDogzBuyBatteCount(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC3
+        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 = 0xC3
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzBuyBatteCount)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C3 神兽购买助战位 //tagCMDogzBuyBatteCount:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzBuyBatteCount=tagCMDogzBuyBatteCount()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzBuyBatteCount.Cmd,m_NAtagCMDogzBuyBatteCount.SubCmd))] = m_NAtagCMDogzBuyBatteCount
+
+
+#------------------------------------------------------
+# A5 C0 神兽穿戴装备 #tagCMDogzEquipItem
+
+class  tagCMDogzEquipItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("EquipIndex", c_ubyte),    #神兽装备所在神兽背包索引
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC0
+        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 = 0xC0
+        self.DogzID = 0
+        self.EquipIndex = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzEquipItem)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C0 神兽穿戴装备 //tagCMDogzEquipItem:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                EquipIndex:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.EquipIndex
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzEquipItem=tagCMDogzEquipItem()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzEquipItem.Cmd,m_NAtagCMDogzEquipItem.SubCmd))] = m_NAtagCMDogzEquipItem
+
+
+#------------------------------------------------------
+# A5 C4 神兽装备强化 #tagCMDogzEquipPlus
+
+class  tagCMDogzEquipPlus(Structure):
+    Head = tagHead()
+    EquipIndex = 0    #(BYTE EquipIndex)//神兽装备背包中索引
+    IndexCount = 0    #(BYTE IndexCount)//材料所在神兽物品背包索引的数量
+    IndexList = list()    #(vector<BYTE> IndexList)//材料所在神兽物品背包索引列表
+    IsDouble = 0    #(BYTE IsDouble)//是否双倍强化
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xA5
+        self.Head.SubCmd = 0xC4
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.EquipIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.IndexCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.IndexCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.IndexList.append(value)
+        self.IsDouble,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xA5
+        self.Head.SubCmd = 0xC4
+        self.EquipIndex = 0
+        self.IndexCount = 0
+        self.IndexList = list()
+        self.IsDouble = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 1
+        length += 1 * self.IndexCount
+        length += 1
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.EquipIndex)
+        data = CommFunc.WriteBYTE(data, self.IndexCount)
+        for i in range(self.IndexCount):
+            data = CommFunc.WriteBYTE(data, self.IndexList[i])
+        data = CommFunc.WriteBYTE(data, self.IsDouble)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                EquipIndex:%d,
+                                IndexCount:%d,
+                                IndexList:%s,
+                                IsDouble:%d
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.EquipIndex,
+                                self.IndexCount,
+                                "...",
+                                self.IsDouble
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzEquipPlus=tagCMDogzEquipPlus()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzEquipPlus.Head.Cmd,m_NAtagCMDogzEquipPlus.Head.SubCmd))] = m_NAtagCMDogzEquipPlus
+
+
+#------------------------------------------------------
+# A5 C1 神兽卸下装备 #tagCMDogzUnEquipItem
+
+class  tagCMDogzUnEquipItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("EquipPlace", c_ubyte),    #卸下的装备位, 0代表卸下全部
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC1
+        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 = 0xC1
+        self.DogzID = 0
+        self.EquipPlace = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzUnEquipItem)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C1 神兽卸下装备 //tagCMDogzUnEquipItem:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                EquipPlace:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.EquipPlace
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzUnEquipItem=tagCMDogzUnEquipItem()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzUnEquipItem.Cmd,m_NAtagCMDogzUnEquipItem.SubCmd))] = m_NAtagCMDogzUnEquipItem
+
+
+#------------------------------------------------------
 # A5 48 兑换大师等级经验 #tagCMExchangeMasterEXP
 
 class  tagCMExchangeMasterEXP(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index b526613..a49e731 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -10662,6 +10662,114 @@
 
 
 #------------------------------------------------------
+# A3 C1 神兽助战状态刷新 #tagMCDogzHelpbattleState
+
+class  tagMCDogzHelpbattleState(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("BatteState", c_ubyte),    #是否已助战, 0否1是
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA3
+        self.SubCmd = 0xC1
+        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 = 0xC1
+        self.DogzID = 0
+        self.BatteState = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCDogzHelpbattleState)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A3 C1 神兽助战状态刷新 //tagMCDogzHelpbattleState:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                BatteState:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.BatteState
+                                )
+        return DumpString
+
+
+m_NAtagMCDogzHelpbattleState=tagMCDogzHelpbattleState()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCDogzHelpbattleState.Cmd,m_NAtagMCDogzHelpbattleState.SubCmd))] = m_NAtagMCDogzHelpbattleState
+
+
+#------------------------------------------------------
+# A3 C0 神兽信息 #tagMCDogzInfo
+
+class  tagMCDogzInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("BuyHelpbattleCount", c_ubyte),    #额外购买的助战数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA3
+        self.SubCmd = 0xC0
+        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 = 0xC0
+        self.BuyHelpbattleCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCDogzInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A3 C0 神兽信息 //tagMCDogzInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                BuyHelpbattleCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.BuyHelpbattleCount
+                                )
+        return DumpString
+
+
+m_NAtagMCDogzInfo=tagMCDogzInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCDogzInfo.Cmd,m_NAtagMCDogzInfo.SubCmd))] = m_NAtagMCDogzInfo
+
+
+#------------------------------------------------------
 # A3 1C 通知装备分解信息 #tagMCEquipDecomposeInfo
 
 class  tagMCEquipDecomposeInfo(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 0f70343..007b2e3 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -894,16 +894,15 @@
 rptTempItem,        # 临时存放背包 29
 rptTreasure,        # 寻宝物品背包 30
 rptPet,             # 宠物背包(用物品存储宠物的数据) 31
+rptDogzItem,        # 神兽物品背包 32
+rptDogzEquip,       # 神兽装备背包 33
 rptMax,             # 最大背包类型数量,放在最后一个
-) = range(28, 28 + 5)  #C++定义的枚举到27
+) = range(28, 28 + 7)  #C++定义的枚举到27
 
 #虚拟背包类型, 从255递减
 Def_VPack_TypeList = (
 rptRune,            # 符印背包 255
 ) = range(256 - 1, 256)
-
-
-#虚拟背包物品信息 ChConfig.Def_VPackItem_Dict
 
 
 #武器的手持形式
@@ -1220,6 +1219,7 @@
 Def_IudetPartSuiteLV = 25  # 部位套装等级 [套装类型1等级, 套装类型2等级, ...]
 Def_IudetWingMaterialItemID = 27  # 翅膀精炼材料ID列表
 Def_IudetWingMaterialItemCount = 29  # 翅膀精炼材料个数列表
+Def_IudetDogzEquipPlus = 31  # 神兽装备强化信息列表 [强化等级, 累计总熟练度]
 
 Def_IudetItemColor = 16  # 物品颜色,如果该值没有就取物品
 Def_IudetItemCount = 18  # 物品个数,支持20亿,目前仅特殊转化物品会用到
@@ -1296,7 +1296,7 @@
 )=range(5)
 
 # 战斗力模块类型
-Def_MFPType_Max = 24
+Def_MFPType_Max = 25
 ModuleFightPowerTypeList = (
 Def_MFPType_Role, # 角色 0
 Def_MFPType_Equip, # 装备(基本装备位) 1
@@ -1319,6 +1319,7 @@
 Def_MFPType_PetSoul, # 灵宠魂石 18
 Def_MFPType_HorseSoul, # 坐骑魂石 19
 Def_MFPType_MagicWeaponSoul, # 法宝之魂 20
+Def_MFPType_Dogz, # 神兽 21
 Def_MFPType_Other, # 其他
 
 #以下暂时没用到,改时再处理
@@ -1666,6 +1667,16 @@
 ) = range(1, 21)
 
 
+# 神兽装备位定义
+DogzEquipPlace = (
+    dogzetHorn,     # 神兽兽角
+    dogzetEye,      # 神兽魔眼
+    dogzetTooth,    # 神兽獠牙
+    dogzetClaw,     # 神兽兽爪
+    dogzetScute,    # 神兽鳞甲
+) = range(101, 101 + 5)
+
+
 # 请求进入副本通用检查结果,优先提示的放前面(即索引越大,提示优先级越低)
 EnterFBAskResult = (
     EntFBAskRet_OK,             # 0 可以进入 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 23580fe..e1f34d8 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1242,6 +1242,34 @@
 PacketSubCMD_1=0x03
 PacketCallFunc_1=OnActiveAllEquipAttr
 
+;神兽
+[PlayerDogz]
+ScriptName = Player\PlayerDogz.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 5
+
+PacketCMD_1=0xA5
+PacketSubCMD_1=0xC0
+PacketCallFunc_1=OnDogzEquipItem
+
+PacketCMD_2=0xA5
+PacketSubCMD_2=0xC1
+PacketCallFunc_2=OnDogzUnEquipItem
+
+PacketCMD_3=0xA5
+PacketSubCMD_3=0xC2
+PacketCallFunc_3=OnDogzBattleStateChange
+
+PacketCMD_4=0xA5
+PacketSubCMD_4=0xC3
+PacketCallFunc_4=OnDogzBuyBatteCount
+
+PacketCMD_5=0xA5
+PacketSubCMD_5=0xC4
+PacketCallFunc_5=OnDogzEquipPlus
+
 ;个推
 [PlayerGeTui]
 ScriptName = Player\PlayerGeTui.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index b2eeee1..719c2e0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -313,11 +313,6 @@
 Def_ItemType_ResetAttrPoint = 59       #洗点卷轴 使用后将某个属性一定值变为未分配属性
 
 Def_ItemType_DogzEquipExp = 70  # 神兽装备经验
-Def_ItemType_DogzEquipHorn = 71      # 神兽装备兽角
-Def_ItemType_DogzEquipEye = 72      # 神兽装备魔眼
-Def_ItemType_DogzEquipTooth = 73      # 神兽装备獠牙
-Def_ItemType_DogzEquipClaw = 74     # 神兽装备兽爪
-Def_ItemType_DogzEquipSquama = 75       # 神兽装备鳞甲
 
 Def_ItemType_TreasureBox = 81       #不限制开启条件宝箱
 Def_ItemType_TreasureBox2 = 82       #限制开启条件宝箱
@@ -345,6 +340,12 @@
 Def_ItemType_retBaldric5 = 117     #17 佩饰
 Def_ItemType_retBaldric6 = 118     #18 佩饰
 
+Def_ItemType_DogzEquipHorn = 119    # 神兽兽角
+Def_ItemType_DogzEquipEye = 120     # 神兽魔眼
+Def_ItemType_DogzEquipTooth = 121   # 神兽獠牙
+Def_ItemType_DogzEquipClaw = 122    # 神兽兽爪
+Def_ItemType_DogzEquipScute = 123   # 神兽鳞甲
+
 #以下定义物品类型下次删除
 Def_Item_Type_Horse = 1000036          #坐骑
 
@@ -354,16 +355,18 @@
                      }
 
 #虚拟背包可以放入的物品字典
-Def_VPackItem_Dict = {
+Def_PackItemTypeList_Dict = {
 ShareDefine.rptRune:[Def_ItemType_Rune, Def_ItemType_RuneExp],
+ShareDefine.rptDogzItem:[Def_ItemType_DogzEquipExp, Def_ItemType_DogzEquipHorn, Def_ItemType_DogzEquipEye, 
+                         Def_ItemType_DogzEquipTooth, Def_ItemType_DogzEquipClaw, Def_ItemType_DogzEquipScute],
                       }
 
-def GetItemPackType(itemType):
+def GetItemPackType(itemType, defaultPack=IPY_GameWorld.rptItem):
     ## 获取物品类型对应存放的默认背包类型
-    for pack, itemTypeList in Def_VPackItem_Dict.items():
+    for pack, itemTypeList in Def_PackItemTypeList_Dict.items():
         if itemType in itemTypeList:
             return pack
-    return IPY_GameWorld.rptItem
+    return defaultPack
 
 # 部位对应装备类型列表
 Def_PlaceEquipType = {
@@ -410,6 +413,7 @@
 Def_Effect_ResetAttrPoint = 231   # 洗点
 Def_Effect_AddFBCnt = 233   # 增加副本可进入次数
 Def_Effect_AddKillBossCnt = 234   # 增加BOSS可击杀次数
+Def_Effect_DogzEquipPlusExp = 235   # 神兽强化材料经验效果,A值基础经验,B值双倍强化消耗仙玉
 
 #----以下未使用或代码依然存在的---
 Def_Effect_ItemGiveGongXun = 1920        #使用道具给予功勋
@@ -752,10 +756,13 @@
 
 Def_EquipItemType_TJGAutoEat = xrange(Def_ItemType_retWeapon, Def_ItemType_retShoes + 1)
 #装备类型
-Def_EquipItemType = xrange(Def_ItemType_retWeapon, Def_ItemType_retBaldric6 + 1)
+Def_EquipItemType = xrange(Def_ItemType_retWeapon, Def_ItemType_DogzEquipScute + 1)
 
 #武器类型
 Def_WeaponItemType = [Def_ItemType_retWeapon, Def_ItemType_retWeapon2]
+
+#神兽装备类型
+Def_DogzEquiipType = xrange(Def_ItemType_DogzEquipHorn, Def_ItemType_DogzEquipScute + 1)
 
 # 技能造成实质性伤害的类型
 Def_RealAttack_Type = [Def_HurtType_Normal,         # 普通伤害 1
@@ -810,6 +817,10 @@
 Def_PackCnt_OfficerSkill = 0
 #寻宝背包格子数
 Def_PackCnt_Treasure = 100
+#初始化神兽背包格子数
+Def_PackCnt_DogzItem = 100
+#初始化神兽装备格子数
+Def_PackCnt_DogzEquip = 100
 #初始化装备栏2
 Def_PackCnt_Equip2 = 0
 #初始化回收站
@@ -1051,6 +1062,8 @@
                                     ShareDefine.rptTempItem,
                                     ShareDefine.rptTreasure,
                                     ShareDefine.rptPet,
+                                    ShareDefine.rptDogzItem,
+                                    ShareDefine.rptDogzEquip,
                                     ]
 
 #装备可强化背包列表
@@ -3766,6 +3779,11 @@
 #套装
 Def_PDict_EquipPartSuiteLV = "EQPartSuiteLV_%s_%s" #部位套装等级 参数 部位、套装类型
 Def_PDict_EquipPartSuiteNotify = "EQPartSuiteNotify_%s_%s_%s" #部位套装提示记录 参数 组合类型、套装类型、X件
+
+#神兽
+Def_PDict_DogzFightState = "DogzFightState_%s" # 神兽助战状态,参数为key编号,按神兽ID二进制位存储
+Def_PDict_DogzBuyHelpbattleCount = "DogzBuyHelpbattleCount" # 额外购买的神兽助战位
+
 #-------------------------------------------------------------------------------
 #可以从07 41封包购买的背包类型,和对应字典{背包类型:[字典key, 默认格子数]}
 
@@ -4165,7 +4183,8 @@
 Def_CalcAttrFunc_StoveYao, # 炼丹炉丹药 32
 Def_CalcAttrFunc_PetSign, # 宠物签到 33
 Def_CalcAttrFunc_MagicWeaponSoul, # 法宝之魂属性34
-) = range(35)
+Def_CalcAttrFunc_Dogz, # 神兽35
+) = range(36)
 
 
 # 在此列表中的功能属性,不享受百分比加成,--属性参与战力计算
@@ -4202,6 +4221,7 @@
                             ShareDefine.Def_MFPType_MagicWeapon3:[Def_CalcAttrFunc_MagicWeapon3, Def_CalcAttrFunc_Stove, Def_CalcAttrFunc_VIP],
                             ShareDefine.Def_MFPType_StoveYao:[Def_CalcAttrFunc_StoveYao],
                             ShareDefine.Def_MFPType_MagicWeaponSoul:[Def_CalcAttrFunc_MagicWeaponSoul],
+                            ShareDefine.Def_MFPType_Dogz:[Def_CalcAttrFunc_Dogz],
                             ShareDefine.Def_MFPType_Other:[Def_CalcAttrFunc_Success, Def_CalcAttrFunc_FamilyTech, Def_CalcAttrFunc_EquipDecompose],
                             }
 
@@ -4406,6 +4426,7 @@
 Def_Cost_EnterFB, # 进入副本
 Def_Cost_GameServer, # GameServer 30
 Def_Cost_FreeGoods, # 极品白拿
+Def_Cost_DogzEquipPlus, # 神兽装备强化
 #-----------以下为暂时没用的,先不删除,如有新增消费点则放在这些之前------------
 Def_Cost_RefreshArrestTask, # 刷新悬赏任务
 Def_Cost_OffLineExp, # 兑换离线经验
@@ -4427,7 +4448,7 @@
 Def_Cost_Trade, # 交易
 Def_Cost_Rename, # 改名
 Def_Cost_SkillLvUp, # 技能升级
-) = range(2000, 2000 + 52)
+) = range(2000, 2000 + 53)
 
 Def_Cost_Reason_SonKey = "reason_name_son" # 消费点原因子类说明key
 
@@ -4506,6 +4527,7 @@
 Def_Cost_FamilyBroadcast:"FamilyBroadcast",
 Def_Cost_FamilyRedPacket:"FamilyRedPacket",
 Def_Cost_FreeGoods:"FreeGoods",
+Def_Cost_DogzEquipPlus:"DogzEquipPlus",
 }
 ## -----------------------------------------------------
 
@@ -4654,7 +4676,8 @@
 ItemDel_EquipSuit, # 套装 30
 ItemDel_AddFBCnt, # 增加副本可进入次数 31
 ItemDel_AddKillBossCnt, # 增加BOSS可击杀次数 32
-) = range(2000, 2000 + 33)
+ItemDel_DogzEquipPlus, # 神兽装备强化
+) = range(2000, 2000 + 34)
 
 # 物品扣除类型对应信息 {类型:eventName, ...}
 ItemDelTypeDict = {
@@ -4691,6 +4714,7 @@
                    ItemDel_EquipSuit:"EquipSuit",
                    ItemDel_AddFBCnt:"AddFBCnt",
                    ItemDel_AddKillBossCnt:"AddKillBossCnt",
+                   ItemDel_DogzEquipPlus:"DogzEquipPlus",
                    }
 
 ##==================================================================================================
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 6862883..c69e43d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -7717,6 +7717,303 @@
 
 
 #------------------------------------------------------
+# A5 C2 神兽变更助战状态 #tagCMDogzBattleStateChange
+
+class  tagCMDogzBattleStateChange(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("BatteState", c_ubyte),    #助战状态,0-召回,1-助战
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC2
+        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 = 0xC2
+        self.DogzID = 0
+        self.BatteState = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzBattleStateChange)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C2 神兽变更助战状态 //tagCMDogzBattleStateChange:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                BatteState:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.BatteState
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzBattleStateChange=tagCMDogzBattleStateChange()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzBattleStateChange.Cmd,m_NAtagCMDogzBattleStateChange.SubCmd))] = m_NAtagCMDogzBattleStateChange
+
+
+#------------------------------------------------------
+# A5 C3 神兽购买助战位 #tagCMDogzBuyBatteCount
+
+class  tagCMDogzBuyBatteCount(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC3
+        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 = 0xC3
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzBuyBatteCount)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C3 神兽购买助战位 //tagCMDogzBuyBatteCount:
+                                Cmd:%s,
+                                SubCmd:%s
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzBuyBatteCount=tagCMDogzBuyBatteCount()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzBuyBatteCount.Cmd,m_NAtagCMDogzBuyBatteCount.SubCmd))] = m_NAtagCMDogzBuyBatteCount
+
+
+#------------------------------------------------------
+# A5 C0 神兽穿戴装备 #tagCMDogzEquipItem
+
+class  tagCMDogzEquipItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("EquipIndex", c_ubyte),    #神兽装备所在神兽背包索引
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC0
+        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 = 0xC0
+        self.DogzID = 0
+        self.EquipIndex = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzEquipItem)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C0 神兽穿戴装备 //tagCMDogzEquipItem:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                EquipIndex:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.EquipIndex
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzEquipItem=tagCMDogzEquipItem()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzEquipItem.Cmd,m_NAtagCMDogzEquipItem.SubCmd))] = m_NAtagCMDogzEquipItem
+
+
+#------------------------------------------------------
+# A5 C4 神兽装备强化 #tagCMDogzEquipPlus
+
+class  tagCMDogzEquipPlus(Structure):
+    Head = tagHead()
+    EquipIndex = 0    #(BYTE EquipIndex)//神兽装备背包中索引
+    IndexCount = 0    #(BYTE IndexCount)//材料所在神兽物品背包索引的数量
+    IndexList = list()    #(vector<BYTE> IndexList)//材料所在神兽物品背包索引列表
+    IsDouble = 0    #(BYTE IsDouble)//是否双倍强化
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xA5
+        self.Head.SubCmd = 0xC4
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.EquipIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.IndexCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.IndexCount):
+            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
+            self.IndexList.append(value)
+        self.IsDouble,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xA5
+        self.Head.SubCmd = 0xC4
+        self.EquipIndex = 0
+        self.IndexCount = 0
+        self.IndexList = list()
+        self.IsDouble = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += 1
+        length += 1 * self.IndexCount
+        length += 1
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.EquipIndex)
+        data = CommFunc.WriteBYTE(data, self.IndexCount)
+        for i in range(self.IndexCount):
+            data = CommFunc.WriteBYTE(data, self.IndexList[i])
+        data = CommFunc.WriteBYTE(data, self.IsDouble)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                EquipIndex:%d,
+                                IndexCount:%d,
+                                IndexList:%s,
+                                IsDouble:%d
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.EquipIndex,
+                                self.IndexCount,
+                                "...",
+                                self.IsDouble
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzEquipPlus=tagCMDogzEquipPlus()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzEquipPlus.Head.Cmd,m_NAtagCMDogzEquipPlus.Head.SubCmd))] = m_NAtagCMDogzEquipPlus
+
+
+#------------------------------------------------------
+# A5 C1 神兽卸下装备 #tagCMDogzUnEquipItem
+
+class  tagCMDogzUnEquipItem(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("EquipPlace", c_ubyte),    #卸下的装备位, 0代表卸下全部
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA5
+        self.SubCmd = 0xC1
+        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 = 0xC1
+        self.DogzID = 0
+        self.EquipPlace = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMDogzUnEquipItem)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A5 C1 神兽卸下装备 //tagCMDogzUnEquipItem:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                EquipPlace:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.EquipPlace
+                                )
+        return DumpString
+
+
+m_NAtagCMDogzUnEquipItem=tagCMDogzUnEquipItem()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDogzUnEquipItem.Cmd,m_NAtagCMDogzUnEquipItem.SubCmd))] = m_NAtagCMDogzUnEquipItem
+
+
+#------------------------------------------------------
 # A5 48 兑换大师等级经验 #tagCMExchangeMasterEXP
 
 class  tagCMExchangeMasterEXP(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index b526613..a49e731 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -10662,6 +10662,114 @@
 
 
 #------------------------------------------------------
+# A3 C1 神兽助战状态刷新 #tagMCDogzHelpbattleState
+
+class  tagMCDogzHelpbattleState(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("DogzID", c_ubyte),    # 神兽ID
+                  ("BatteState", c_ubyte),    #是否已助战, 0否1是
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA3
+        self.SubCmd = 0xC1
+        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 = 0xC1
+        self.DogzID = 0
+        self.BatteState = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCDogzHelpbattleState)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A3 C1 神兽助战状态刷新 //tagMCDogzHelpbattleState:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                DogzID:%d,
+                                BatteState:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.DogzID,
+                                self.BatteState
+                                )
+        return DumpString
+
+
+m_NAtagMCDogzHelpbattleState=tagMCDogzHelpbattleState()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCDogzHelpbattleState.Cmd,m_NAtagMCDogzHelpbattleState.SubCmd))] = m_NAtagMCDogzHelpbattleState
+
+
+#------------------------------------------------------
+# A3 C0 神兽信息 #tagMCDogzInfo
+
+class  tagMCDogzInfo(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("BuyHelpbattleCount", c_ubyte),    #额外购买的助战数
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA3
+        self.SubCmd = 0xC0
+        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 = 0xC0
+        self.BuyHelpbattleCount = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCDogzInfo)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A3 C0 神兽信息 //tagMCDogzInfo:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                BuyHelpbattleCount:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.BuyHelpbattleCount
+                                )
+        return DumpString
+
+
+m_NAtagMCDogzInfo=tagMCDogzInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCDogzInfo.Cmd,m_NAtagMCDogzInfo.SubCmd))] = m_NAtagMCDogzInfo
+
+
+#------------------------------------------------------
 # A3 1C 通知装备分解信息 #tagMCEquipDecomposeInfo
 
 class  tagMCEquipDecomposeInfo(Structure):
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 a311054..c5b0f45 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
@@ -50,6 +50,7 @@
                    ShareDefine.Def_MFPType_PetSoul:"宠魂",
                    ShareDefine.Def_MFPType_HorseSoul:"骑魂",
                    ShareDefine.Def_MFPType_MagicWeaponSoul:"法宝之魂",
+                   ShareDefine.Def_MFPType_Dogz:"神兽",
                    ShareDefine.Def_MFPType_Other:"其他",
                    }
     
@@ -89,6 +90,7 @@
                      ChConfig.Def_CalcAttrFunc_StoveYao:"炼丹炉丹药",
                      ChConfig.Def_CalcAttrFunc_PetSign:"宠物签到",
                      ChConfig.Def_CalcAttrFunc_MagicWeaponSoul:"法宝之魂",
+                     ChConfig.Def_CalcAttrFunc_Dogz:"神兽",
                      }
     
     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 853ff88..9d231c9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -125,6 +125,22 @@
                         ("list", "AttrValue", 0),
                         ),
 
+                "Dogz":(
+                        ("BYTE", "DogzID", 1),
+                        ("list", "BaseAttrTypes", 0),
+                        ("list", "BaseAttrValues", 0),
+                        ("list", "HelpBattleSkills", 0),
+                        ("list", "EquipPlaceColorList", 0),
+                        ),
+
+                "DogzEquipPlus":(
+                        ("BYTE", "EquipPlace", 1),
+                        ("BYTE", "PlusLV", 1),
+                        ("list", "PlusAttrTypes", 0),
+                        ("list", "PlusAttrValues", 0),
+                        ("DWORD", "PlusLVUPTotalExp", 0),
+                        ),
+
                 "Rune":(
                         ("DWORD", "ID", 1),
                         ("list", "AttrType", 0),
@@ -1132,6 +1148,40 @@
     def GetStarsNeed(self): return self.StarsNeed # 全身星数
     def GetAttrType(self): return self.AttrType # 属性类型
     def GetAttrValue(self): return self.AttrValue # 属性值
+
+# 神兽表
+class IPY_Dogz():
+    
+    def __init__(self):
+        self.DogzID = 0
+        self.BaseAttrTypes = []
+        self.BaseAttrValues = []
+        self.HelpBattleSkills = []
+        self.EquipPlaceColorList = []
+        return
+        
+    def GetDogzID(self): return self.DogzID # 神兽ID
+    def GetBaseAttrTypes(self): return self.BaseAttrTypes # 基础属性类型列表
+    def GetBaseAttrValues(self): return self.BaseAttrValues # 基础属性值列表
+    def GetHelpBattleSkills(self): return self.HelpBattleSkills # 助战技能ID列表
+    def GetEquipPlaceColorList(self): return self.EquipPlaceColorList # 穿戴装备颜色限制
+
+# 神兽强化表
+class IPY_DogzEquipPlus():
+    
+    def __init__(self):
+        self.EquipPlace = 0
+        self.PlusLV = 0
+        self.PlusAttrTypes = []
+        self.PlusAttrValues = []
+        self.PlusLVUPTotalExp = 0
+        return
+        
+    def GetEquipPlace(self): return self.EquipPlace # 装备位
+    def GetPlusLV(self): return self.PlusLV # 强化等级
+    def GetPlusAttrTypes(self): return self.PlusAttrTypes # 强化属性类型列表
+    def GetPlusAttrValues(self): return self.PlusAttrValues # 强化属性值列表
+    def GetPlusLVUPTotalExp(self): return self.PlusLVUPTotalExp # 升级所需累计熟练度总值
 
 # 符印表
 class IPY_Rune():
@@ -2873,6 +2923,10 @@
         self.ipyItemPlusSumAttrLen = len(self.ipyItemPlusSumAttrCache)
         self.ipyRoleEquipStarsCache = self.__LoadFileData("RoleEquipStars", IPY_RoleEquipStars)
         self.ipyRoleEquipStarsLen = len(self.ipyRoleEquipStarsCache)
+        self.ipyDogzCache = self.__LoadFileData("Dogz", IPY_Dogz)
+        self.ipyDogzLen = len(self.ipyDogzCache)
+        self.ipyDogzEquipPlusCache = self.__LoadFileData("DogzEquipPlus", IPY_DogzEquipPlus)
+        self.ipyDogzEquipPlusLen = len(self.ipyDogzEquipPlusCache)
         self.ipyRuneCache = self.__LoadFileData("Rune", IPY_Rune)
         self.ipyRuneLen = len(self.ipyRuneCache)
         self.ipyEquipWashCache = self.__LoadFileData("EquipWash", IPY_EquipWash)
@@ -3207,6 +3261,10 @@
     def GetItemPlusSumAttrByIndex(self, index): return self.ipyItemPlusSumAttrCache[index]
     def GetRoleEquipStarsCount(self): return self.ipyRoleEquipStarsLen
     def GetRoleEquipStarsByIndex(self, index): return self.ipyRoleEquipStarsCache[index]
+    def GetDogzCount(self): return self.ipyDogzLen
+    def GetDogzByIndex(self, index): return self.ipyDogzCache[index]
+    def GetDogzEquipPlusCount(self): return self.ipyDogzEquipPlusLen
+    def GetDogzEquipPlusByIndex(self, index): return self.ipyDogzEquipPlusCache[index]
     def GetRuneCount(self): return self.ipyRuneLen
     def GetRuneByIndex(self, index): return self.ipyRuneCache[index]
     def GetEquipWashCount(self): return self.ipyEquipWashLen
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 9544906..18205d2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -1094,13 +1094,8 @@
         if not curItemData:
             return False
         
-        vPackItemDict = ChConfig.Def_VPackItem_Dict
+        packIndex = ChConfig.GetItemPackType(curItemData.GetType(), packIndex)
         
-        for pack, itemTypeList in vPackItemDict.items():
-            if curItemData.GetType() in itemTypeList:
-                packIndex = pack
-                break
-  
         if not self.CanPutInItem(packIndex, tagItem.GetItemTypeID(), tagItem.GetCount(), tagItem.GetIsBind(), defaultPile):
             GameWorld.DebugLog("背包满,不能放入物品 count = %d"%tagItem.GetCount())
             tagItem.Clear()
@@ -1882,11 +1877,10 @@
         PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_GetSpecialItem, 1, [itemID])
         return True
     
-    vPackItemDict = ChConfig.Def_VPackItem_Dict
-    for pack, itemTypeList in vPackItemDict.items():
-        if curItemData.GetType() in itemTypeList:
-            packIndexList = [pack]
-            break
+    defaultPack = IPY_GameWorld.rptItem if not packIndexList else packIndexList[0]
+    packIndex = ChConfig.GetItemPackType(curItemData.GetType(), defaultPack)
+    if packIndex != defaultPack or not packIndexList:
+        packIndexList = [packIndex]
     
     if not __Check_CanPutItemInPack(curPlayer, itemID, itemCount, itemIsBind, packIndexList, defaultPile):
         #不可放入
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 d922bbe..a6b1bad 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
@@ -1592,11 +1592,17 @@
 def DoLogicSwitchItemEx(curPlayer, srcBackpack, desBackPack, srcIndex, destIndex):
     
     #---物品检查---
-    srcItem = curPlayer.GetItemManager().GetPack(srcBackpack).GetAt(srcIndex)
+    srcPack = curPlayer.GetItemManager().GetPack(srcBackpack)
+    if srcIndex < 0 or srcIndex >= srcPack.GetCount():
+        return
+    srcItem = srcPack.GetAt(srcIndex)
     if not CheckItemCanUse(srcItem):
         return
     
-    destItem = curPlayer.GetItemManager().GetPack(desBackPack).GetAt(destIndex)
+    destPack = curPlayer.GetItemManager().GetPack(desBackPack)
+    if destIndex < 0 or destIndex >= destPack.GetCount():
+        return
+    destItem = destPack.GetAt(destIndex)
     #目标格子只验证锁定, 可以允许空位
     if destItem == None or destItem.GetIsLocked():
         return
@@ -1675,6 +1681,10 @@
 def GetIsEquip(curItem):
     return curItem.GetType() in ChConfig.Def_EquipItemType
 
+def GetIsDogzEquip(curItem):
+    ## 返回是否神兽装备
+    return curItem.GetType() in ChConfig.Def_DogzEquiipType
+
 ## 返回是否武器
 #  @param curItem 当前物品
 #  @return None
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 3420321..6ed28d3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -110,6 +110,7 @@
 import PyGameData
 import PlayerCoin
 import PlayerGeTui
+import PlayerDogz
 
 import datetime
 import time
@@ -535,6 +536,8 @@
     SyncPackDownloadAward(curPlayer)
     # 登录触发功能开启(老号处理)
     GameFuncComm.DoFuncOpenLogic(curPlayer)
+    # 神兽
+    PlayerDogz.OnPlayerLogin(curPlayer)
     # 上线查询一次充值订单
     curPlayer.SendDBQueryRecharge()
     
@@ -1028,6 +1031,15 @@
     #初始化寻宝背包
     PlayerControl.Init_TreasurePack(curPlayer)
     
+    #初始化神兽物品背包
+    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzItem)
+    curPack.SetCount(ChConfig.Def_PackCnt_DogzItem)
+    curPack.Sync_PackCanUseCount()
+    #初始化神兽装备背包
+    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzEquip)
+    curPack.SetCount(ChConfig.Def_PackCnt_DogzEquip)
+    curPack.Sync_PackCanUseCount()
+    
     #初始化临时交换背包
     curPack = itemManager.GetPack(ShareDefine.rptTempSwap)
     curPack.SetCount(ChConfig.Def_PackCnt_TempSwap)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index bf03785..a9219ee 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -86,6 +86,7 @@
 import ChNetSendPack
 import PlayerState
 import QuestCommon
+import PlayerDogz
 import GMShell
 
 import random
@@ -3960,6 +3961,7 @@
         PlayerRefineStove.CalcStoveAttr(curPlayer)
         PlayerFamilyTech.CalcFamilyTechAttr(curPlayer)
         PlayerEquipDecompose.RefreshEDAttr(curPlayer)
+        PlayerDogz.RefreshDogzAttr(curPlayer)
         self.RefreshAllState(isForce=True)
         GameWorld.DebugLog("End ReCalcAllState!!!")
         return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerDogz.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerDogz.py
new file mode 100644
index 0000000..8e6639b
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerDogz.py
@@ -0,0 +1,514 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerDogz
+#
+# @todo:神兽系统
+# @author hxp
+# @date 2018-08-20
+# @version 1.0
+#
+# 详细描述: 神兽系统
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2018-08-20 17:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import ItemCommon
+import ShareDefine
+import PlayerControl
+import ChPyNetSendPack
+import NetPackCommon
+import IPY_GameWorld
+import IpyGameDataPY
+import ChConfig
+import ChEquip
+
+'''
+神兽编号: 1~20,上线后不可修改
+神兽装备位: 101~105 物品表中的装备位配置
+神兽装备类型:119~123,策划说打死不会再加类型了,固定5个神兽装备类型
+
+神兽物品背包(类型32,暂开放100格),存放神兽装备(类型119~123),及强化材料(类型70),
+神兽装备背包(类型33,暂开放100格),所有神兽共用,每只神兽5格,(格子索引/5)+1=对应神兽编号,(格子索引%5)+100+1=对应神兽装备位
+'''
+
+DogzEquipCount = 5 # 神兽装备位数量,固定5个,策划说打死也不改
+
+def GetDogzEquipPlaceIndex(equipPlace):
+    ## 获取神兽装备位对应的索引
+    return equipPlace - 1 - 100
+
+def GetDogzEquipPackIndex(dogzID, equipPlaceIndex):
+    ## 获取神兽装备在神兽装备背包中的固定位置索引
+    return (dogzID - 1) * DogzEquipCount + equipPlaceIndex
+
+def GetDogzIsHelpFight(curPlayer, dogzID):
+    ## 神兽是否助战状态
+    return GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_DogzFightState, dogzID - 1)
+
+def SetDogzIsHelpFight(curPlayer, dogzID, isFight):
+    ## 设置神兽是否助战状态
+    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_DogzFightState, dogzID - 1, 1 if isFight else 0)
+    Sync_DogzHelpbattleState(curPlayer, dogzID, isFight)
+    return
+
+
+def OnPlayerLogin(curPlayer):
+    
+    if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DogzBuyHelpbattleCount):
+        Sync_DogzInfo(curPlayer)
+        
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for i in xrange(ipyDataMgr.GetDogzCount()):
+        ipyData = ipyDataMgr.GetDogzByIndex(i)
+        if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_DogzFightState, i):
+            Sync_DogzHelpbattleState(curPlayer, ipyData.GetDogzID(), 1)
+            
+    return
+
+#// A5 C0 神兽穿戴装备 #tagCMDogzEquipItem
+#
+#struct    tagCMDogzEquipItem
+#
+#{
+#    tagHead        Head;
+#    BYTE        DogzID;    // 神兽ID
+#    BYTE        EquipIndex;    //神兽装备所在神兽背包索引
+#};
+def OnDogzEquipItem(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    dogzID = clientData.DogzID
+    equipIndex = clientData.EquipIndex
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("Dogz", dogzID)
+    if not ipyData:
+        return
+    
+    dogzItemPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzItem)
+    curEquip = dogzItemPack.GetAt(equipIndex)
+    if not ItemCommon.CheckItemCanUse(curEquip):
+        GameWorld.DebugLog("物品不可用: equipIndex=%s" % equipIndex)
+        return
+    if not ItemCommon.GetIsDogzEquip(curEquip):
+        GameWorld.DebugLog("非神兽装备: equipIndex=%s" % equipIndex)
+        return
+    
+    equipPlace = curEquip.GetEquipPlace()
+    equipPlaceIndex = GetDogzEquipPlaceIndex(equipPlace)
+    equipPlaceColorList = ipyData.GetEquipPlaceColorList()
+    if equipPlaceIndex < 0 or equipPlaceIndex >= len(equipPlaceColorList):
+        GameWorld.ErrLog("神兽装备位异常: equipPlace=%s,equipPlaceIndex=%s" % (equipPlace, equipPlaceIndex))
+        return
+    
+    dogzEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzEquip)
+    equipPackIndex = GetDogzEquipPackIndex(dogzID, equipPlaceIndex)
+    if equipPackIndex < 0 or equipPackIndex >= dogzEquipPack.GetCount():
+        GameWorld.ErrLog("神兽装备背包索引异常: dogzID=%s,equipPlace=%s,equipPackIndex=%s" % (dogzID, equipPlace, equipPackIndex))
+        return
+    
+    equipColor = curEquip.GetItemColor()
+    limitColor = equipPlaceColorList[equipPlaceIndex]
+    if equipColor < limitColor:
+        GameWorld.Log("神兽装备位穿戴颜色限制:dogzID=%s,equipPlaceIndex=%s,limitColor=%s > equipColor=%s" 
+                      % (dogzID, equipPlaceIndex, limitColor, equipColor), playerID)
+        return
+    
+    destEquip = dogzEquipPack.GetAt(equipPackIndex)
+    isOK = ItemCommon.DoLogicSwitchItem(curPlayer, curEquip, destEquip, ShareDefine.rptDogzEquip)
+    if not isOK:
+        return
+    
+    # 助战状态换装需要刷属性
+    if GetDogzIsHelpFight(curPlayer, dogzID):
+        RefreshDogzAttr(curPlayer)
+        
+    return
+
+
+#// A5 C1 神兽卸下装备 #tagCMDogzUnEquipItem
+#
+#struct    tagCMDogzUnEquipItem
+#
+#{
+#    tagHead        Head;
+#    BYTE        DogzID;    // 神兽ID
+#    BYTE        EquipPlace;    //卸下的装备位, 0代表卸下全部
+#};
+def OnDogzUnEquipItem(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    dogzID = clientData.DogzID
+    equipPlace = clientData.EquipPlace
+    
+    if equipPlace and equipPlace not in ShareDefine.DogzEquipPlace:
+        GameWorld.DebugLog("非神兽装备位,无法卸下!equipPlace=%s" % equipPlace, playerID)
+        return
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("Dogz", dogzID)
+    if not ipyData:
+        return
+    
+    # 卸下全部
+    if equipPlace == 0:
+        unEquipIndexList = [] # 需要脱下的神兽装备索引
+        dogzEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzEquip)
+        equipPackCount = dogzEquipPack.GetCount()
+        startIndex = (dogzID - 1) * DogzEquipCount
+        for i in range(startIndex, startIndex + DogzEquipCount):
+            if i < 0 or i >= equipPackCount:
+                return
+            curItem = dogzEquipPack.GetAt(i)            
+            if not curItem.IsEmpty():
+                unEquipIndexList.append(i)
+                
+        if not unEquipIndexList:
+            GameWorld.DebugLog("没有穿戴神兽装备!dogzID=%s" % dogzID, playerID)
+            return
+        
+        unEquipCount = len(unEquipIndexList)
+        emptyIndexList = []
+        
+        dogzItemPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzItem)
+        for i in xrange(dogzItemPack.GetCount()):
+            curItem = dogzItemPack.GetAt(i)
+            if curItem.IsEmpty():
+                emptyIndexList.append(i)
+                if len(emptyIndexList) >= unEquipCount:
+                    break
+                
+        if len(emptyIndexList) < unEquipCount:
+            PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [ShareDefine.rptDogzItem])
+            #GameWorld.DebugLog("神兽背包空格不足,无法脱下所有装备")
+            return
+        
+        for i in xrange(unEquipCount):
+            ItemCommon.DoLogicSwitchItemEx(curPlayer, ShareDefine.rptDogzEquip, ShareDefine.rptDogzItem,
+                                           unEquipIndexList[i], emptyIndexList[i])
+            
+    else:
+        equipPackIndex = GetDogzEquipPackIndex(dogzID, GetDogzEquipPlaceIndex(equipPlace))
+        emptyIndex = ItemCommon.GetEmptyIndexInPack(curPlayer, ShareDefine.rptDogzItem)
+        
+        if not ItemCommon.DoLogicSwitchItemEx(curPlayer, ShareDefine.rptDogzEquip, ShareDefine.rptDogzItem, equipPackIndex, emptyIndex):
+            GameWorld.DebugLog("神兽卸下装备失败: dogzID=%s,equipPlace=%s" % (dogzID, equipPlace), playerID)
+            return
+    
+    # 助战状态换装需要刷属性
+    if GetDogzIsHelpFight(curPlayer, dogzID):
+        SetDogzIsHelpFight(curPlayer, dogzID, False) # 因为脱下了状态,所以必须设置为非助战状态
+        RefreshDogzAttr(curPlayer)
+        
+    return
+
+
+#// A5 C2 神兽变更助战状态 #tagCMDogzBattleStateChange
+#
+#struct    tagCMDogzBattleStateChange
+#
+#{
+#    tagHead        Head;
+#    BYTE        DogzID;    // 神兽ID
+#    BYTE        BatteState;    //助战状态,0-召回,1-助战
+#};
+def OnDogzBattleStateChange(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    dogzID = clientData.DogzID
+    batteState = clientData.BatteState
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("Dogz", dogzID)
+    if not ipyData:
+        return
+    
+    curState = GetDogzIsHelpFight(curPlayer, dogzID)
+    if curState == batteState:
+        GameWorld.DebugLog("神兽已经是该状态,无需变更助战状态! dogzID=%s,batteState=%s,curState=%s" 
+                           % (dogzID, batteState, curState), playerID)
+        return
+    
+    # 变为助战状态需检查神兽装备是否穿满
+    if batteState:
+        helpbattleInitCount = IpyGameDataPY.GetFuncEvalCfg("DogzAssist", 1)[0]
+        helpbattleBuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DogzBuyHelpbattleCount)
+        canHelpFightCount = helpbattleInitCount + helpbattleBuyCount
+        
+        curHelpFightCount = 0
+        dogzCount = IpyGameDataPY.IPY_Data().GetDogzCount()
+        for i in xrange(dogzCount):
+            if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_DogzFightState, i):
+                curHelpFightCount += 1
+                
+        if curHelpFightCount >= canHelpFightCount:
+            GameWorld.DebugLog("当前神兽助战数已满,无法助战!canHelpFightCount=%s <= curHelpFightCount=%s" 
+                               % (canHelpFightCount, curHelpFightCount), playerID)
+            return
+        
+        dogzEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzEquip)
+        equipPackCount = dogzEquipPack.GetCount()
+        startIndex = (dogzID - 1) * DogzEquipCount
+        for i in range(startIndex, startIndex + DogzEquipCount):
+            if i < 0 or i >= equipPackCount:
+                return
+            curItem = dogzEquipPack.GetAt(i)            
+            if curItem.IsEmpty():
+                GameWorld.DebugLog("神兽有装备未穿戴,无法助战!dogzID=%s,packIndex=%s" % (dogzID, i), playerID)
+                return
+            
+    isFight = True if batteState else False
+    GameWorld.DebugLog("神兽助战状态变更!dogzID=%s,isFight=%s" % (dogzID, isFight), playerID)
+    SetDogzIsHelpFight(curPlayer, dogzID, isFight)
+    RefreshDogzAttr(curPlayer)
+    return
+
+
+#// A5 C3 神兽购买助战位 #tagCMDogzBuyBatteCount
+#
+#struct    tagCMDogzBuyBatteCount
+#
+#{
+#    tagHead        Head;
+#};
+def OnDogzBuyBatteCount(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    
+    helpbattleInitCount, helpbattleMaxCount = IpyGameDataPY.GetFuncEvalCfg("DogzAssist", 1)
+    helpbattleBuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DogzBuyHelpbattleCount)
+    curHelpFightCount = helpbattleInitCount + helpbattleBuyCount
+    if curHelpFightCount >= helpbattleMaxCount:
+        GameWorld.DebugLog("已超过最大神兽助战数,无法购买!curHelpFightCount=%s,helpbattleMaxCount=%s" 
+                           % (curHelpFightCount, helpbattleMaxCount), playerID)
+        return
+    
+    needItemID = IpyGameDataPY.GetFuncCfg("DogzAssist", 2)
+    needCountList = IpyGameDataPY.GetFuncEvalCfg("DogzAssist", 3)
+    needCount = needCountList[-1] if helpbattleBuyCount >= len(needCountList) else needCountList[helpbattleBuyCount]
+    
+    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, needItemID)
+    if bindCnt + unBindCnt < needCount:
+        GameWorld.DebugLog("购买神兽助战位所需道具不足 !needItemID=%s,needCount=%s" % (needItemID, needCount), playerID)
+        return
+    ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, needCount, "DogzBuyHelpFight")
+    
+    updBuyCount = helpbattleBuyCount + 1
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DogzBuyHelpbattleCount, updBuyCount)
+    GameWorld.DebugLog("购买神兽助战位! updBuyCount=%s" % updBuyCount, playerID)
+    
+    Sync_DogzInfo(curPlayer)
+    return
+
+
+#// A5 C4 神兽装备强化 #tagCMDogzEquipPlus
+#
+#struct    tagCMDogzEquipPlus
+#
+#{
+#    tagHead        Head;
+#    BYTE        EquipIndex;    //神兽装备背包中索引
+#    BYTE        IndexCount;        //材料所在神兽物品背包索引的数量
+#    BYTE        IndexList[IndexCount];    //材料所在神兽物品背包索引列表
+#    BYTE        IsDouble;        //是否双倍强化
+#};
+def OnDogzEquipPlus(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    playerID = curPlayer.GetPlayerID()
+    equipIndex = clientData.EquipIndex
+    indexList = clientData.IndexList
+    isDouble = clientData.IsDouble
+    GameWorld.DebugLog("神兽装备强化: equipIndex=%s,indexList=%s,isDouble=%s" % (equipIndex, indexList, isDouble), playerID)
+    
+    dogzEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzEquip)
+    curEquip = dogzEquipPack.GetAt(equipIndex)
+    if not ItemCommon.CheckItemCanUse(curEquip) or not ItemCommon.GetIsDogzEquip(curEquip):
+        GameWorld.DebugLog("    非神兽装备,无法强化!equipIndex=%s,itemID=%s" 
+                           % (equipIndex, curEquip.GetItemTypeID()), playerID)
+        return
+    
+    equipPlace = curEquip.GetEquipPlace()
+    curPlusLV = curEquip.GetUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 0)
+    curPlusExpTotal = curEquip.GetUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 1)
+    
+    ipyData = IpyGameDataPY.GetIpyGameData("DogzEquipPlus", equipPlace, curPlusLV)
+    if not ipyData:
+        return
+    curLVUPTotalExp = ipyData.GetPlusLVUPTotalExp()
+    if not curLVUPTotalExp:
+        GameWorld.Log("神兽装备升级所需总经验为0, 无法强化!equipPlace=%s,curPlusLV=%s" % (equipPlace, curPlusLV), playerID)
+        return
+    
+    nextLVIpyData = None
+    if curPlusExpTotal >= curLVUPTotalExp:
+        nextLVIpyData = IpyGameDataPY.GetIpyGameDataNotLog("DogzEquipPlus", equipPlace, curPlusLV + 1)
+        if not nextLVIpyData:
+            GameWorld.Log("神兽装备已满级, 无法强化!equipPlace=%s,curPlusLV=%s" % (equipPlace, curPlusLV), playerID)
+            return
+        
+    costGoldTotal = 0
+    addExpTotal = 0
+    delItemList = []
+    dogzItemPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzItem)
+    dogzItemPackCount = dogzItemPack.GetCount()
+    for i in indexList:
+        if i < 0 or i >= dogzItemPackCount:
+            GameWorld.ErrLog("神兽背包索引不存在,无法强化!i=%s" % (i), playerID)
+            return
+        curItem = dogzItemPack.GetAt(i)
+        if curItem.IsEmpty():
+            GameWorld.ErrLog("神兽背包物品为空,无法强化!i=%s" % (i), playerID)
+            return
+        effect = ItemCommon.GetItemEffectByEffectID(curItem, ChConfig.Def_Effect_DogzEquipPlusExp)
+        if not effect:
+            GameWorld.ErrLog("神兽背包物品无经验效果,无法强化!i=%s,itemID=%s" % (i, curItem.GetItemTypeID()), playerID)
+            return
+        
+        baseExp = effect.GetEffectValue(0)
+        doubleCostGold = effect.GetEffectValue(1)
+        
+        addExp = baseExp
+        plusInfoCount = curItem.GetUserAttrCount(ShareDefine.Def_IudetDogzEquipPlus)
+        if not plusInfoCount:
+            if isDouble and doubleCostGold:
+                addExp = (baseExp * 2)
+                costGoldTotal += doubleCostGold
+            GameWorld.DebugLog("    强化: addExp=%s,baseExp=%s,isDouble=%s,doubleCostGold=%s,costGoldTotal=%s" 
+                               % (addExp, baseExp, isDouble, doubleCostGold, costGoldTotal), playerID)
+        else:
+            #plusLV = curItem.GetUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 0)
+            plusExpTotal = curItem.GetUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 1)
+            addExp += plusExpTotal
+            GameWorld.DebugLog("    强化: addExp=%s,baseExp=%s,plusExpTotal=%s" % (addExp, baseExp, plusExpTotal), playerID)
+        addExpTotal += addExp
+        delItemList.append(curItem)
+        
+    if not delItemList:
+        GameWorld.DebugLog("    没有材料可强化!", playerID)
+        return
+    
+    updPlusExpTotal = curPlusExpTotal + addExpTotal
+    infoDict = {"updPlusExpTotal":updPlusExpTotal}
+    
+    if costGoldTotal:
+        if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal, 
+                                      ChConfig.Def_Cost_DogzEquipPlus, infoDict):
+            return
+        
+    for delItem in delItemList:
+        ItemCommon.DelItem(curPlayer, delItem, curItem.GetCount(), False, ChConfig.ItemDel_DogzEquipPlus, infoDict)
+        
+    updPlusLV = curPlusLV
+    if updPlusExpTotal >= curLVUPTotalExp:
+        doCount = 0
+        while nextLVIpyData and updPlusExpTotal >= nextLVIpyData.GetPlusLVUPTotalExp() and doCount < 100:
+            doCount += 1
+            nextLV = updPlusLV + 1
+            nextLVIpyData = IpyGameDataPY.GetIpyGameDataNotLog("DogzEquipPlus", equipPlace, nextLV)
+            if not nextLVIpyData:
+                break
+            updPlusLV = nextLV
+            
+    isRefreshAtrr = False
+    # 未强化过
+    if not curPlusExpTotal:
+        curEquip.AddUserAttr(ShareDefine.Def_IudetDogzEquipPlus, updPlusLV)
+        curEquip.AddUserAttr(ShareDefine.Def_IudetDogzEquipPlus, updPlusExpTotal)
+        isRefreshAtrr = (updPlusLV > 0)
+    else:
+        if curPlusLV != updPlusLV:
+            isRefreshAtrr = True
+            curEquip.UpdataUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 0, updPlusLV)
+        curEquip.UpdataUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 1, updPlusExpTotal)
+        
+    GameWorld.DebugLog("    curPlus(LV=%s,EXP=%s),addExpTotal=%s,updPlus(LV=%s,EXP=%s)" 
+                       % (curPlusLV, curPlusExpTotal, addExpTotal, updPlusLV, updPlusExpTotal), playerID)
+    
+    if isRefreshAtrr:
+        RefreshDogzAttr(curPlayer)
+        
+    return
+
+def RefreshDogzAttr(curPlayer):
+    ## 刷新神兽属性
+    
+    allAttrList = [{} for _ in range(4)]
+    
+    dogzEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzEquip)
+    equipPackCount = dogzEquipPack.GetCount()
+    ipyDataMgr = IpyGameDataPY.IPY_Data()
+    for dogzIndex in xrange(ipyDataMgr.GetDogzCount()):
+        if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_DogzFightState, dogzIndex):
+            continue
+        
+        ipyData = ipyDataMgr.GetDogzByIndex(dogzIndex)
+        dogzID = ipyData.GetDogzID()
+        #GameWorld.DebugLog("神兽属性: dogzID=%s" % dogzID)
+        
+        # 1. 基础属性
+        attrTypeList = ipyData.GetBaseAttrTypes()
+        attrValueList = ipyData.GetBaseAttrValues()
+        if attrTypeList and len(attrTypeList) == len(attrValueList):
+            for attrIndex, baseAttrID in enumerate(attrTypeList):
+                baseAttrValue = attrValueList[attrIndex]
+                PlayerControl.CalcAttrDict_Type(baseAttrID, baseAttrValue, allAttrList)
+                #GameWorld.DebugLog("    基础属性: baseAttrID=%s,baseAttrValue=%s, %s" % (baseAttrID, baseAttrValue, allAttrList))
+                
+        # 2. 装备属性
+        startIndex = (dogzID - 1) * DogzEquipCount
+        for equipIndex in range(startIndex, startIndex + DogzEquipCount):
+            if equipIndex < 0 or equipIndex >= equipPackCount:
+                break
+            curEquip = dogzEquipPack.GetAt(equipIndex)            
+            if curEquip.IsEmpty():
+                continue
+            
+            #itemID = curEquip.GetItemTypeID()
+            # 装备基础属性
+            for effIndex in xrange(curEquip.GetEffectCount()):
+                curEffect = curEquip.GetEffectByIndex(effIndex)
+                if not curEffect or not curEffect.GetEffectID():
+                    break
+                effID = curEffect.GetEffectID()
+                if not effID or effID == ChConfig.Def_Effect_DogzEquipPlusExp:
+                    continue
+                effValue = curEffect.GetEffectValue(0)
+                PlayerControl.CalcAttrDict_Type(effID, effValue, allAttrList)
+                #GameWorld.DebugLog("    装备基础: itemID=%s,effID=%s,effValue=%s, %s" % (itemID, effID, effValue, allAttrList))
+                
+            # 强化属性
+            curPlusLV = curEquip.GetUserAttrByIndex(ShareDefine.Def_IudetDogzEquipPlus, 0)
+            plusIpyData = IpyGameDataPY.GetIpyGameData("DogzEquipPlus", curEquip.GetEquipPlace(), curPlusLV)
+            if plusIpyData:
+                plusAttrTypeList = plusIpyData.GetPlusAttrTypes()
+                plusAttrValueList = plusIpyData.GetPlusAttrValues()
+                if plusAttrTypeList and len(plusAttrTypeList) == len(plusAttrValueList):
+                    for plusIndex, plusAttrID in enumerate(plusAttrTypeList):
+                        plusAttrValue = plusAttrValueList[plusIndex]
+                        PlayerControl.CalcAttrDict_Type(plusAttrID, plusAttrValue, allAttrList)
+                        #GameWorld.DebugLog("    装备强化: itemID=%s,plusAttrID=%s, plusAttrValue=%s, %s" % (itemID, plusAttrID, plusAttrValue, allAttrList))
+                        
+            # 传奇属性
+            ChEquip.CalcAttr_LegendAttr(curPlayer, curEquip, allAttrList)
+            #GameWorld.DebugLog("    装备传奇: itemID=%s,%s" % (itemID, allAttrList))
+            
+    # 保存计算值
+    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Dogz, allAttrList)
+    return
+
+def Sync_DogzInfo(curPlayer):
+    ## 同步神兽信息
+    dogzInfoPack = ChPyNetSendPack.tagMCDogzInfo()
+    dogzInfoPack.BuyHelpbattleCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DogzBuyHelpbattleCount)
+    NetPackCommon.SendFakePack(curPlayer, dogzInfoPack)
+    return
+
+def Sync_DogzHelpbattleState(curPlayer, dogzID, batteState):
+    ## 同步神兽助战状态
+    helpbattleState = ChPyNetSendPack.tagMCDogzHelpbattleState()
+    helpbattleState.DogzID = dogzID
+    helpbattleState.BatteState = 1 if batteState else 0
+    NetPackCommon.SendFakePack(curPlayer, helpbattleState)
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 0f70343..007b2e3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -894,16 +894,15 @@
 rptTempItem,        # 临时存放背包 29
 rptTreasure,        # 寻宝物品背包 30
 rptPet,             # 宠物背包(用物品存储宠物的数据) 31
+rptDogzItem,        # 神兽物品背包 32
+rptDogzEquip,       # 神兽装备背包 33
 rptMax,             # 最大背包类型数量,放在最后一个
-) = range(28, 28 + 5)  #C++定义的枚举到27
+) = range(28, 28 + 7)  #C++定义的枚举到27
 
 #虚拟背包类型, 从255递减
 Def_VPack_TypeList = (
 rptRune,            # 符印背包 255
 ) = range(256 - 1, 256)
-
-
-#虚拟背包物品信息 ChConfig.Def_VPackItem_Dict
 
 
 #武器的手持形式
@@ -1220,6 +1219,7 @@
 Def_IudetPartSuiteLV = 25  # 部位套装等级 [套装类型1等级, 套装类型2等级, ...]
 Def_IudetWingMaterialItemID = 27  # 翅膀精炼材料ID列表
 Def_IudetWingMaterialItemCount = 29  # 翅膀精炼材料个数列表
+Def_IudetDogzEquipPlus = 31  # 神兽装备强化信息列表 [强化等级, 累计总熟练度]
 
 Def_IudetItemColor = 16  # 物品颜色,如果该值没有就取物品
 Def_IudetItemCount = 18  # 物品个数,支持20亿,目前仅特殊转化物品会用到
@@ -1296,7 +1296,7 @@
 )=range(5)
 
 # 战斗力模块类型
-Def_MFPType_Max = 24
+Def_MFPType_Max = 25
 ModuleFightPowerTypeList = (
 Def_MFPType_Role, # 角色 0
 Def_MFPType_Equip, # 装备(基本装备位) 1
@@ -1319,6 +1319,7 @@
 Def_MFPType_PetSoul, # 灵宠魂石 18
 Def_MFPType_HorseSoul, # 坐骑魂石 19
 Def_MFPType_MagicWeaponSoul, # 法宝之魂 20
+Def_MFPType_Dogz, # 神兽 21
 Def_MFPType_Other, # 其他
 
 #以下暂时没用到,改时再处理
@@ -1666,6 +1667,16 @@
 ) = range(1, 21)
 
 
+# 神兽装备位定义
+DogzEquipPlace = (
+    dogzetHorn,     # 神兽兽角
+    dogzetEye,      # 神兽魔眼
+    dogzetTooth,    # 神兽獠牙
+    dogzetClaw,     # 神兽兽爪
+    dogzetScute,    # 神兽鳞甲
+) = range(101, 101 + 5)
+
+
 # 请求进入副本通用检查结果,优先提示的放前面(即索引越大,提示优先级越低)
 EnterFBAskResult = (
     EntFBAskRet_OK,             # 0 可以进入 

--
Gitblit v1.8.0