hxp
2021-07-02 a9b193b0135c6630edaed8e1bb9770d16bba0e9b
9046 【主干】【BT2】【BT3】【后端】培养功能

# Conflicts:
# PySysDB/PySysDBPY.h
# ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
# ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChEquip.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/EffGetSet.py
9个文件已修改
2个文件已添加
969 ■■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 249 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 249 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Horse.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LingQi.py 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -20104,60 +20104,98 @@
#A3 01 坐骑培养信息 #tagTrainHorseData
class  tagTrainHorseData(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("LV", c_ubyte),    #等阶
                  ("EatItemCount", c_int),    #当前阶已吃丹个数
                  ("SkinPlusState", c_int),    #幻化激活状态,按位存储是否激活,幻化编号ID对应位
                  ]
    Head = tagHead()
    LV = 0    #(BYTE LV)//等阶
    EatItemCount = 0    #(DWORD EatItemCount)//当前阶已吃丹个数
    SkinPlusState = 0    #(DWORD SkinPlusState)//幻化激活状态,按位存储是否激活,幻化编号ID对应位
    TrainTypes = 0    #(BYTE TrainTypes)//培养类型数
    TrainLVList = list()    #(vector<DWORD> TrainLVList)//培养等阶列表,索引为培养类型减1
    TrainItemCountList = list()    #(vector<DWORD> TrainItemCountList)//培养当前阶已吃培养丹个数列表,索引为培养类型减1
    data = None
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA3
        self.SubCmd = 0x01
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x01
        return
    def ReadData(self, stringData, _pos=0, _len=0):
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.EatItemCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.SkinPlusState,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.TrainTypes,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainLVList.append(value)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainItemCountList.append(value)
        return _pos
    def Clear(self):
        self.Cmd = 0xA3
        self.SubCmd = 0x01
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x01
        self.LV = 0
        self.EatItemCount = 0
        self.SkinPlusState = 0
        self.TrainTypes = 0
        self.TrainLVList = list()
        self.TrainItemCountList = list()
        return
    def GetLength(self):
        return sizeof(tagTrainHorseData)
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 4
        length += 4
        length += 1
        length += 4 * self.TrainTypes
        length += 4 * self.TrainTypes
        return length
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.LV)
        data = CommFunc.WriteDWORD(data, self.EatItemCount)
        data = CommFunc.WriteDWORD(data, self.SkinPlusState)
        data = CommFunc.WriteBYTE(data, self.TrainTypes)
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainLVList[i])
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainItemCountList[i])
        return data
    def OutputString(self):
        DumpString = '''//A3 01 坐骑培养信息 //tagTrainHorseData:
                                Cmd:%s,
                                SubCmd:%s,
        DumpString = '''
                                Head:%s,
                                LV:%d,
                                EatItemCount:%d,
                                SkinPlusState:%d
                                SkinPlusState:%d,
                                TrainTypes:%d,
                                TrainLVList:%s,
                                TrainItemCountList:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Head.OutputString(),
                                self.LV,
                                self.EatItemCount,
                                self.SkinPlusState
                                self.SkinPlusState,
                                self.TrainTypes,
                                "...",
                                "..."
                                )
        return DumpString
m_NAtagTrainHorseData=tagTrainHorseData()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagTrainHorseData.Cmd,m_NAtagTrainHorseData.SubCmd))] = m_NAtagTrainHorseData
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagTrainHorseData.Head.Cmd,m_NAtagTrainHorseData.Head.SubCmd))] = m_NAtagTrainHorseData
#------------------------------------------------------
@@ -23748,6 +23786,90 @@
#------------------------------------------------------
# A8 18 灵器培养信息 #tagMCLingQiTrainInfo
class  tagMCLingQiTrainInfo(Structure):
    Head = tagHead()
    EquipPlace = 0    #(BYTE EquipPlace)//灵器装备位
    TrainTypes = 0    #(BYTE TrainTypes)//培养类型数
    TrainLVList = list()    #(vector<DWORD> TrainLVList)//培养等阶列表,索引为培养类型减1
    TrainItemCountList = list()    #(vector<DWORD> TrainItemCountList)//培养当前阶已吃培养丹个数列表,索引为培养类型减1
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x18
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.EquipPlace,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TrainTypes,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainLVList.append(value)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainItemCountList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x18
        self.EquipPlace = 0
        self.TrainTypes = 0
        self.TrainLVList = list()
        self.TrainItemCountList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += 4 * self.TrainTypes
        length += 4 * self.TrainTypes
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.EquipPlace)
        data = CommFunc.WriteBYTE(data, self.TrainTypes)
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainLVList[i])
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainItemCountList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                EquipPlace:%d,
                                TrainTypes:%d,
                                TrainLVList:%s,
                                TrainItemCountList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.EquipPlace,
                                self.TrainTypes,
                                "...",
                                "..."
                                )
        return DumpString
m_NAtagMCLingQiTrainInfo=tagMCLingQiTrainInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCLingQiTrainInfo.Head.Cmd,m_NAtagMCLingQiTrainInfo.Head.SubCmd))] = m_NAtagMCLingQiTrainInfo
#------------------------------------------------------
# A8 14 合成结果通知 #tagMCMakeItemAnswer
class  tagMCMakeItemAnswer(Structure):
@@ -24175,6 +24297,83 @@
#------------------------------------------------------
# A8 17 宠物培养信息 #tagMCPetTrainInfo
class  tagMCPetTrainInfo(Structure):
    Head = tagHead()
    TrainTypes = 0    #(BYTE TrainTypes)//培养类型数
    TrainLVList = list()    #(vector<DWORD> TrainLVList)//培养等阶列表,索引为培养类型减1
    TrainItemCountList = list()    #(vector<DWORD> TrainItemCountList)//培养当前阶已吃培养丹个数列表,索引为培养类型减1
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x17
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.TrainTypes,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainLVList.append(value)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainItemCountList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x17
        self.TrainTypes = 0
        self.TrainLVList = list()
        self.TrainItemCountList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 4 * self.TrainTypes
        length += 4 * self.TrainTypes
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.TrainTypes)
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainLVList[i])
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainItemCountList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                TrainTypes:%d,
                                TrainLVList:%s,
                                TrainItemCountList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.TrainTypes,
                                "...",
                                "..."
                                )
        return DumpString
m_NAtagMCPetTrainInfo=tagMCPetTrainInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCPetTrainInfo.Head.Cmd,m_NAtagMCPetTrainInfo.Head.SubCmd))] = m_NAtagMCPetTrainInfo
#------------------------------------------------------
# A8 02 通知NPC商店物品今日已购买次数 #tagMCShopItemDayBuyCntInfo
class  tagMCShopItemDayBuyCnt(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -40,7 +40,7 @@
Writer = wdb
Releaser = wdb
RegType = 0
RegisterPackCount = 5
RegisterPackCount = 6
PacketCMD_1=0xA5
PacketSubCMD_1=0x01
@@ -61,6 +61,10 @@
PacketCMD_5=0xA5
PacketSubCMD_5=0x30
PacketCallFunc_5=OnHorsePetSkinSelect
PacketCMD_6=0xA5
PacketSubCMD_6=0x31
PacketCallFunc_6=OnHorseTrain
;玛雅加强
[EquipPlus]
@@ -225,7 +229,7 @@
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 2
RegisterPackCount = 3
PacketCMD_1=0xA7
PacketSubCMD_1=0x02
@@ -235,6 +239,9 @@
PacketSubCMD_2=0x04
PacketCallFunc_2=PetClassUp
PacketCMD_3=0xA7
PacketSubCMD_3=0x05
PacketCallFunc_3=OnPetTrain
;事件
[EventShell]
@@ -1256,7 +1263,7 @@
Writer = xdh
Releaser = xdh
RegType = 0
RegisterPackCount = 3
RegisterPackCount = 4
PacketCMD_1=
PacketSubCMD_1=
@@ -1270,6 +1277,10 @@
PacketSubCMD_3=0xC6
PacketCallFunc_3=OnEquipPartSuiteActivate
PacketCMD_4=A3
PacketSubCMD_4=27
PacketCallFunc_4=OnLingQiTrain
;仙盟抢boss
[FamilyRobBoss]
ScriptName = GameWorldLogic\FamilyRobBoss.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -20104,60 +20104,98 @@
#A3 01 坐骑培养信息 #tagTrainHorseData
class  tagTrainHorseData(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("LV", c_ubyte),    #等阶
                  ("EatItemCount", c_int),    #当前阶已吃丹个数
                  ("SkinPlusState", c_int),    #幻化激活状态,按位存储是否激活,幻化编号ID对应位
                  ]
    Head = tagHead()
    LV = 0    #(BYTE LV)//等阶
    EatItemCount = 0    #(DWORD EatItemCount)//当前阶已吃丹个数
    SkinPlusState = 0    #(DWORD SkinPlusState)//幻化激活状态,按位存储是否激活,幻化编号ID对应位
    TrainTypes = 0    #(BYTE TrainTypes)//培养类型数
    TrainLVList = list()    #(vector<DWORD> TrainLVList)//培养等阶列表,索引为培养类型减1
    TrainItemCountList = list()    #(vector<DWORD> TrainItemCountList)//培养当前阶已吃培养丹个数列表,索引为培养类型减1
    data = None
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA3
        self.SubCmd = 0x01
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x01
        return
    def ReadData(self, stringData, _pos=0, _len=0):
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.EatItemCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.SkinPlusState,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.TrainTypes,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainLVList.append(value)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainItemCountList.append(value)
        return _pos
    def Clear(self):
        self.Cmd = 0xA3
        self.SubCmd = 0x01
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x01
        self.LV = 0
        self.EatItemCount = 0
        self.SkinPlusState = 0
        self.TrainTypes = 0
        self.TrainLVList = list()
        self.TrainItemCountList = list()
        return
    def GetLength(self):
        return sizeof(tagTrainHorseData)
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 4
        length += 4
        length += 1
        length += 4 * self.TrainTypes
        length += 4 * self.TrainTypes
        return length
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.LV)
        data = CommFunc.WriteDWORD(data, self.EatItemCount)
        data = CommFunc.WriteDWORD(data, self.SkinPlusState)
        data = CommFunc.WriteBYTE(data, self.TrainTypes)
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainLVList[i])
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainItemCountList[i])
        return data
    def OutputString(self):
        DumpString = '''//A3 01 坐骑培养信息 //tagTrainHorseData:
                                Cmd:%s,
                                SubCmd:%s,
        DumpString = '''
                                Head:%s,
                                LV:%d,
                                EatItemCount:%d,
                                SkinPlusState:%d
                                SkinPlusState:%d,
                                TrainTypes:%d,
                                TrainLVList:%s,
                                TrainItemCountList:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Head.OutputString(),
                                self.LV,
                                self.EatItemCount,
                                self.SkinPlusState
                                self.SkinPlusState,
                                self.TrainTypes,
                                "...",
                                "..."
                                )
        return DumpString
m_NAtagTrainHorseData=tagTrainHorseData()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagTrainHorseData.Cmd,m_NAtagTrainHorseData.SubCmd))] = m_NAtagTrainHorseData
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagTrainHorseData.Head.Cmd,m_NAtagTrainHorseData.Head.SubCmd))] = m_NAtagTrainHorseData
#------------------------------------------------------
@@ -23748,6 +23786,90 @@
#------------------------------------------------------
# A8 18 灵器培养信息 #tagMCLingQiTrainInfo
class  tagMCLingQiTrainInfo(Structure):
    Head = tagHead()
    EquipPlace = 0    #(BYTE EquipPlace)//灵器装备位
    TrainTypes = 0    #(BYTE TrainTypes)//培养类型数
    TrainLVList = list()    #(vector<DWORD> TrainLVList)//培养等阶列表,索引为培养类型减1
    TrainItemCountList = list()    #(vector<DWORD> TrainItemCountList)//培养当前阶已吃培养丹个数列表,索引为培养类型减1
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x18
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.EquipPlace,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TrainTypes,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainLVList.append(value)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainItemCountList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x18
        self.EquipPlace = 0
        self.TrainTypes = 0
        self.TrainLVList = list()
        self.TrainItemCountList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += 4 * self.TrainTypes
        length += 4 * self.TrainTypes
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.EquipPlace)
        data = CommFunc.WriteBYTE(data, self.TrainTypes)
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainLVList[i])
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainItemCountList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                EquipPlace:%d,
                                TrainTypes:%d,
                                TrainLVList:%s,
                                TrainItemCountList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.EquipPlace,
                                self.TrainTypes,
                                "...",
                                "..."
                                )
        return DumpString
m_NAtagMCLingQiTrainInfo=tagMCLingQiTrainInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCLingQiTrainInfo.Head.Cmd,m_NAtagMCLingQiTrainInfo.Head.SubCmd))] = m_NAtagMCLingQiTrainInfo
#------------------------------------------------------
# A8 14 合成结果通知 #tagMCMakeItemAnswer
class  tagMCMakeItemAnswer(Structure):
@@ -24175,6 +24297,83 @@
#------------------------------------------------------
# A8 17 宠物培养信息 #tagMCPetTrainInfo
class  tagMCPetTrainInfo(Structure):
    Head = tagHead()
    TrainTypes = 0    #(BYTE TrainTypes)//培养类型数
    TrainLVList = list()    #(vector<DWORD> TrainLVList)//培养等阶列表,索引为培养类型减1
    TrainItemCountList = list()    #(vector<DWORD> TrainItemCountList)//培养当前阶已吃培养丹个数列表,索引为培养类型减1
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x17
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.TrainTypes,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainLVList.append(value)
        for i in range(self.TrainTypes):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.TrainItemCountList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA8
        self.Head.SubCmd = 0x17
        self.TrainTypes = 0
        self.TrainLVList = list()
        self.TrainItemCountList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 4 * self.TrainTypes
        length += 4 * self.TrainTypes
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.TrainTypes)
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainLVList[i])
        for i in range(self.TrainTypes):
            data = CommFunc.WriteDWORD(data, self.TrainItemCountList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                TrainTypes:%d,
                                TrainLVList:%s,
                                TrainItemCountList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.TrainTypes,
                                "...",
                                "..."
                                )
        return DumpString
m_NAtagMCPetTrainInfo=tagMCPetTrainInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCPetTrainInfo.Head.Cmd,m_NAtagMCPetTrainInfo.Head.SubCmd))] = m_NAtagMCPetTrainInfo
#------------------------------------------------------
# A8 02 通知NPC商店物品今日已购买次数 #tagMCShopItemDayBuyCntInfo
class  tagMCShopItemDayBuyCnt(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Horse.py
@@ -20,7 +20,6 @@
import PlayerControl
import PlayerHorse
#---------------------------------------------------------------------
#逻辑实现
@@ -33,7 +32,8 @@
    
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "重置所有: Horse 0")
        GameWorld.DebugAnswer(curPlayer, "设置培养: Horse 等阶 丹数")
        GameWorld.DebugAnswer(curPlayer, "设置进阶: Horse 等阶 丹数")
        GameWorld.DebugAnswer(curPlayer, "设置培养: Horse 培养类型 等阶 丹数")
        return
    
    if len(msgList) == 1:
@@ -41,7 +41,10 @@
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserLV, 1)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserEatItemCount, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, 0)
            for trainType in xrange(1, PlayerHorse.GetHorseTrainTypes() + 1):
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainLV % trainType, 1)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainItemCount % trainType, 0)
    elif len(msgList) == 2:
        lv, eatItemCount = msgList
        if lv < 1:
@@ -49,6 +52,12 @@
            return
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserLV, lv)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserEatItemCount, eatItemCount)
    elif len(msgList) == 3:
        trainType, trainLV, eatItemCount = msgList
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainLV % trainType, trainLV)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainItemCount % trainType, eatItemCount)
    else:
        return
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LingQi.py
New file
@@ -0,0 +1,58 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.LingQi
#
# @todo:灵器
# @author hxp
# @date 2021-07-02
# @version 1.0
#
# 详细描述: 灵器
#
#-------------------------------------------------------------------------------
#"""Version = 2021-07-02 19:00"""
#-------------------------------------------------------------------------------
import ChConfig
import GameWorld
import PlayerControl
import ChEquip
#---------------------------------------------------------------------
#逻辑实现
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param msgList 参数列表
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "重置所有灵器: LingQi 0")
        GameWorld.DebugAnswer(curPlayer, "设置培养灵器: LingQi 装备位 培养类型 等阶 丹数")
        return
    if msgList[0] == 0:
        for equipPlace in ChConfig.EquipPlace_LingQi:
            for trainType in xrange(1, ChEquip.GetLingQiTrainTypes() + 1):
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LingQiTrainLV % (equipPlace, trainType), 1)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LingQiTrainItemCount % (equipPlace, trainType), 0)
            ChEquip.Sync_LingQiTrainData(curPlayer, equipPlace)
    elif len(msgList) == 4:
        equipPlace, trainType, trainLV, eatItemCount = msgList
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LingQiTrainLV % (equipPlace, trainType), trainLV)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LingQiTrainItemCount % (equipPlace, trainType), eatItemCount)
        ChEquip.Sync_LingQiTrainData(curPlayer, equipPlace)
    else:
        return
    # 刷属性
    ChEquip.RefreshPlayerLingQiEquipAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py
New file
@@ -0,0 +1,59 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.Pet
#
# @todo:宠物
# @author hxp
# @date 2021-07-02
# @version 1.0
#
# 详细描述: 宠物
#
#-------------------------------------------------------------------------------
#"""Version = 2021-07-02 19:30"""
#-------------------------------------------------------------------------------
import ChConfig
import GameWorld
import PlayerControl
import PlayerPet
import PetClear
#---------------------------------------------------------------------
#逻辑实现
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param msgList 参数列表
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "重置所有灵宠: Pet 0")
        GameWorld.DebugAnswer(curPlayer, "设置培养灵宠: Pet 培养类型 等阶 丹数")
        return
    if msgList[0] == 0:
        if len(msgList) > 1 and msgList[1] == 1:
            PetClear.OnExec(curPlayer, [])
        for trainType in xrange(1, PlayerPet.GetPetTrainTypes() + 1):
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, 1)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainItemCount % trainType, 0)
    elif len(msgList) == 3:
        trainType, trainLV, eatItemCount = msgList
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, trainLV)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainItemCount % trainType, eatItemCount)
    else:
        return
    PlayerPet.RefreshPetItemAddAttr(curPlayer, True)
    PlayerPet.OnPlayerPetLogin(curPlayer)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintFightPower.py
@@ -92,6 +92,12 @@
                     ChConfig.Def_CalcAttrFunc_MagicWeapon4:"王者法宝属性", 
                     ChConfig.Def_CalcAttrFunc_HorseSkin:"坐骑觉醒", 
                     ChConfig.Def_CalcAttrFunc_PetSkin:"灵宠觉醒", 
                     ChConfig.Def_CalcAttrFunc_HorseTarin:"坐骑培养",
                     ChConfig.Def_CalcAttrFunc_PetTarin:"灵宠培养",
                     ChConfig.Def_CalcAttrFunc_GuardTarin:"守护培养",
                     ChConfig.Def_CalcAttrFunc_WingTarin:"翅膀培养",
                     ChConfig.Def_CalcAttrFunc_PeerlessWeaponTrain:"灭世培养",
                     ChConfig.Def_CalcAttrFunc_PeerlessWeapon2Train:"噬魂培养",
                     }
    
    GameWorld.DebugAnswer(curPlayer, "PrintFightPower 模块类型(可选)")
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -530,6 +530,7 @@
    
    #---玩家上线, 宠物逻辑处理---
    PetControl.DoLogic_PetInfo_OnLogin(curPlayer, tick)
    PlayerPet.OnPlayerPetLogin(curPlayer)
    
    #要在SetCanMove之后做这个事情, 否则OnEnter不会卡住玩家
    EventShell.EventResponse_OnEnter(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4712,6 +4712,13 @@
                           ChConfig.TYPE_Calc_StoneBasePer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Stone],
                           ChConfig.TYPE_Calc_RealmBasePer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Prestige],
                           ChConfig.TYPE_Calc_HorseAtkPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Horse],
                           ChConfig.TYPE_Calc_HorseMaxHPPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_Horse],
                           ChConfig.TYPE_Calc_HorseTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_HorseTarin],
                           ChConfig.TYPE_Calc_PetTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_PetTarin],
                           ChConfig.TYPE_Calc_GuardTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_GuardTarin],
                           ChConfig.TYPE_Calc_WingTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_WingTarin],
                           ChConfig.TYPE_Calc_PeerlessWeaponTrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_PeerlessWeaponTrain],
                           ChConfig.TYPE_Calc_PeerlessWeapon2TrainAttrPer:funcAttrInfoList[ChConfig.Def_CalcAttrFunc_PeerlessWeapon2Train],
                           }
        #    3.2 统计各功能之间非线性属性交叉影响累加
        funcCrossAttrPerInfoDict = {} # 百分比交叉影响所提升的属性值 {功能属性编号:{提升的属性类型:数值, ...}, ...}
@@ -6863,6 +6870,38 @@
def GetHorseAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HorseAtkPer)
def SetHorseAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HorseAtkPer, value)
# 坐骑生命加成
def GetHorseMaxHPPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HorseMaxHPPer)
def SetHorseMaxHPPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HorseMaxHPPer, value)
# 灵宠攻击加成
def GetPetAtkPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PetAtkPer)
def SetPetAtkPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PetAtkPer, value)
# 坐骑培养属性加成
def GetHorseTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_HorseTrainAttrPer)
def SetHorseTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_HorseTrainAttrPer, value)
# 灵宠培养属性加成
def GetPetTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PetTrainAttrPer)
def SetPetTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PetTrainAttrPer, value)
# 守护培养属性加成
def GetGuardTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GuardTrainAttrPer)
def SetGuardTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GuardTrainAttrPer, value)
# 翅膀培养属性加成
def GetWingTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_WingTrainAttrPer)
def SetWingTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_WingTrainAttrPer, value)
# 灭世培养属性加成
def GetPeerlessWeaponTrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PeerlessWeaponTrainAttrPer)
def SetPeerlessWeaponTrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PeerlessWeaponTrainAttrPer, value)
# 弑神培养属性加成
def GetPeerlessWeapon2TrainAttrPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_PeerlessWeapon2TrainAttrPer)
def SetPeerlessWeapon2TrainAttrPer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_PeerlessWeapon2TrainAttrPer, value)
# 宝石基础属性百分比
def GetStoneBasePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_StoneBasePer)
def SetStoneBasePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_StoneBasePer, value)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
@@ -316,7 +316,9 @@
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserLV, horseLV)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserEatItemCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, 0)
    for trainType in xrange(1, GetHorseTrainTypes() + 1):
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainLV % trainType, 1)
    horseID = ipyData.GetHorseSkinID()
    if not ItemCommon.FindItemInPackByItemID(curPlayer, horseID, IPY_GameWorld.rptEquip):
        isOK = ItemControler.PutItemInTempSwap(curPlayer, horseID)
@@ -350,6 +352,7 @@
    allAttrList = [{} for _ in range(4)]
    allAttrListHorseSoul = [{} for _ in range(4)]
    allAttrListSkin = [{} for _ in range(4)]
    allAttrListTrain = [{} for _ in range(4)]
    
    horseSpeed = 0 # 坐骑功能增加的速度值,骑乘时才有效果
    horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)
@@ -399,6 +402,40 @@
                continue
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListSkin)
            
    # 新培养属性
    for index in xrange(ipyDataMgr.GetHorseTrainCount()):
        trainIpyData = ipyDataMgr.GetHorseTrainByIndex(index)
        trainType = trainIpyData.GetTrainType()
        dataTrainLV = trainIpyData.GetTrainLV()
        trainLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainLV % trainType)
        if dataTrainLV > trainLV:
            continue
        elif dataTrainLV == trainLV:
            trainItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainItemCount % trainType)
        else:
            trainItemCount = trainIpyData.GetEatCntTotal()
        # 等阶额外属性
        lvAttrTypeList = trainIpyData.GetLVAttrTypeList()
        lvAttrValueList = trainIpyData.GetLVAttrValueList()
        for i, attrID in enumerate(lvAttrTypeList):
            attrValue = lvAttrValueList[i]
            if attrID == ShareDefine.Def_Effect_Speed:
                horseSpeed += attrValue
                continue
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListTrain)
        # 培养丹增加属性
        eatCntEverytime = trainIpyData.GetEatCntEverytime()
        if trainItemCount and eatCntEverytime:
            eatItemAttrTypeList = trainIpyData.GetEatItemAttrTypeList()
            eatItemAttrValueList = trainIpyData.GetEatItemAttrValueList()
            attrMultiple = trainItemCount / eatCntEverytime
            for i, attrID in enumerate(eatItemAttrTypeList):
                attrValue = eatItemAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue * attrMultiple, allAttrListTrain)
    curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_Horse, initFPAdd)
    
    #GameWorld.DebugLog("坐骑功能属性: horseLV=%s,horseSpeed=%s,totalItemCount=%s,initFPAdd=%s" % (horseLV, horseSpeed, totalItemCount, initFPAdd))
@@ -414,6 +451,7 @@
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Horse, allAttrList)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSoul, allAttrListHorseSoul)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin, allAttrListSkin)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseTarin, allAttrListTrain)
    return
#// A5 27 坐骑提升 #tagCMHorseUp
@@ -502,11 +540,98 @@
    RefreshHorseAttr(curPlayer)
    return
#// A5 31 坐骑培养 #tagCMHorseTrain
#
#struct    tagCMHorseTrain
#{
#    tagHead        Head;
#    BYTE        TrainType;        //培养类型: 1-基础培养,2-特殊培养,3-百分比培养
#    WORD        UseItemCnt;        //消耗材料个数
#};
def OnHorseTrain(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    trainType = curPackData.TrainType # 培养类型
    costItemCount = curPackData.UseItemCnt # 消耗材料个数
    trainLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainLV % trainType)
    curEatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainItemCount % trainType)
    GameWorld.DebugLog("坐骑培养: trainType=%s,trainLV=%s,costItemCount=%s,curEatItemCount=%s"
                       % (trainType, trainLV, costItemCount, curEatItemCount))
    if trainType <= 0 or trainType > GetHorseTrainTypes():
        return
    if trainLV <= 0:
        GameWorld.DebugLog("    坐骑培养未激活  trainType=%s" % trainType)
        return
    trainIpyData = IpyGameDataPY.GetIpyGameData("HorseTrain", trainType, trainLV)
    if not trainIpyData:
        return
    needRealmLV = trainIpyData.GetNeedRealmLV()
    curRealmLV = curPlayer.GetOfficialRank()
    if curRealmLV < needRealmLV:
        GameWorld.DebugLog("    境界不足,无法培养!  curRealmLV(%s) < needRealmLV(%s)" % (curRealmLV, needRealmLV))
        return
    needEatCountTotal = trainIpyData.GetEatCntTotal()
    if not needEatCountTotal:
        GameWorld.DebugLog("    该培养已满级!")
        return
    costItemIDList = IpyGameDataPY.GetFuncEvalCfg("HorseTrain", 1)
    costItemID = costItemIDList[trainType - 1]
    if not costItemID or not costItemCount:
        return
    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)
    lackCnt = costItemCount - bindCnt - unBindCnt
    if lackCnt > 0:
        GameWorld.DebugLog("    消耗道具不足,无法培养!costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s"
                           % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))
        return
    delCnt = costItemCount
    # 扣除消耗
    if delCnt:
        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, ChConfig.ItemDel_Horse)
    updClassLV = trainLV
    updEatItemCount = curEatItemCount + costItemCount
    GameWorld.DebugLog("    updEatItemCount=%s,needEatCountTotal=%s" % (updEatItemCount, needEatCountTotal))
    if updEatItemCount >= needEatCountTotal:
        updClassLV += 1
        updEatItemCount -= needEatCountTotal
        GameWorld.DebugLog("    进阶: updClassLV=%s,updEatItemCount=%s" % (updClassLV, updEatItemCount))
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainLV % trainType, updClassLV)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainItemCount % trainType, updEatItemCount)
    # 升阶
    if updClassLV > trainLV:
        pass
    Sync_HorseClassData(curPlayer)
    # 刷属性,更新排行榜
    RefreshHorseAttr(curPlayer)
    return
def GetHorseTrainTypes():
    return len(IpyGameDataPY.GetFuncEvalCfg("HorseTrain", 1))
def PlayerHorseLogin(curPlayer):
    ##坐骑登录处理
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):
        return
    
    # 培养是后面加的功能,每次登录补检查一下功能开始时设置为培养1级
    for trainType in xrange(1, GetHorseTrainTypes() + 1):
        if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainLV % trainType) == 0:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainLV % trainType, 1)
    Sync_HorseClassData(curPlayer)
    SyncHorsePetSkinData(curPlayer)
    return
@@ -517,6 +642,12 @@
    horseData.LV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)
    horseData.EatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserEatItemCount)
    horseData.SkinPlusState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinPlusState)
    horseData.TrainLVList = []
    horseData.TrainItemCountList = []
    for trainType in xrange(1, GetHorseTrainTypes() + 1):
        horseData.TrainLVList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainLV % trainType))
        horseData.TrainItemCountList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserTrainItemCount % trainType))
    horseData.TrainTypes = len(horseData.TrainLVList)
    NetPackCommon.SendFakePack(curPlayer, horseData)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -43,6 +43,8 @@
import CrossPlayerData
import CalcLineEffect
import PlayerActivity
import ChPyNetSendPack
import NetPackCommon
import PlayerHorse
import GameObj
@@ -84,6 +86,9 @@
#        GameWorld.DebugLog("自动出战新手宠!petNPCID=%s,petItemIndex=%s" % (petNPCID, petItemIndex))
#        DoChangePetState(curPlayer, petItemIndex, ShareDefine.Def_PetState_Fight)
    
    for trainType in xrange(1, GetPetTrainTypes() + 1):
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, 1)
    Sync_PetTrainData(curPlayer)
    return True
## 功能开启后, 角色升级需要的处理
@@ -835,6 +840,7 @@
    allAttrListPetSoul = [{} for _ in range(4)]
    skillAttrList = [{} for _ in range(4)]
    allAttrListPetSkin = [{} for _ in range(4)]
    allAttrListTrain = [{} for _ in range(4)]
    totalMinAtk, totalMaxAtk = GetPetAtkValue(curPlayer)
    PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_PetMinAtk, totalMinAtk, allAttrListPet)
    PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_PetMaxAtk, totalMaxAtk, allAttrListPet)
@@ -866,6 +872,39 @@
                continue
            SkillShell.CalcBuffEffAttr(curPlayer, curEffect, skillAttrList)
    
    # 新培养属性
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetPetTrainCount()):
        trainIpyData = ipyDataMgr.GetPetTrainByIndex(index)
        trainType = trainIpyData.GetTrainType()
        dataTrainLV = trainIpyData.GetTrainLV()
        trainLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType)
        if dataTrainLV > trainLV:
            continue
        elif dataTrainLV == trainLV:
            trainItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainItemCount % trainType)
        else:
            trainItemCount = trainIpyData.GetEatCntTotal()
        # 等阶额外属性
        lvAttrTypeList = trainIpyData.GetLVAttrTypeList()
        lvAttrValueList = trainIpyData.GetLVAttrValueList()
        for i, attrID in enumerate(lvAttrTypeList):
            attrValue = lvAttrValueList[i]
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListTrain)
        # 培养丹增加属性
        eatCntEverytime = trainIpyData.GetEatCntEverytime()
        if trainItemCount and eatCntEverytime:
            eatItemAttrTypeList = trainIpyData.GetEatItemAttrTypeList()
            eatItemAttrValueList = trainIpyData.GetEatItemAttrValueList()
            attrMultiple = trainItemCount / eatCntEverytime
            for i, attrID in enumerate(eatItemAttrTypeList):
                attrValue = eatItemAttrValueList[i]
                PlayerControl.CalcAttrDict_Type(attrID, attrValue * attrMultiple, allAttrListTrain)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetTarin, allAttrListTrain)
    
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Pet, allAttrListPet)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSoul, allAttrListPetSoul)
@@ -925,5 +964,109 @@
    totalMaxAtk = classAddAtk
    return totalMinAtk, totalMaxAtk
def OnPlayerPetLogin(curPlayer):
    ## 登录处理
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Pet):
        return
    # 培养是后面加的功能,每次登录补检查一下功能开始时设置为培养1级
    for trainType in xrange(1, GetPetTrainTypes() + 1):
        if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType) == 0:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, 1)
    Sync_PetTrainData(curPlayer)
    return
def GetPetTrainTypes():
    return len(IpyGameDataPY.GetFuncEvalCfg("PetUpItem", 3))
#// A7 05 宠物培养 #tagCMPetTrain
#
#struct    tagCMPetTrain
#{
#    tagHead        Head;
#    BYTE        TrainType;        //培养类型: 1-基础培养,2-特殊培养,3-百分比培养
#    WORD        UseItemCnt;        //消耗材料个数
#};
def OnPetTrain(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    trainType = clientData.TrainType # 培养类型
    costItemCount = clientData.UseItemCnt # 消耗材料个数
    trainLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType)
    curEatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainItemCount % trainType)
    GameWorld.DebugLog("灵宠培养: trainType=%s,trainLV=%s,costItemCount=%s,curEatItemCount=%s"
                       % (trainType, trainLV, costItemCount, curEatItemCount))
    if trainType <= 0 or trainType > GetPetTrainTypes():
        return
    if trainLV <= 0:
        GameWorld.DebugLog("    培养未激活  trainType=%s" % trainType)
        return
    trainIpyData = IpyGameDataPY.GetIpyGameData("PetTrain", trainType, trainLV)
    if not trainIpyData:
        return
    needRealmLV = trainIpyData.GetNeedRealmLV()
    curRealmLV = curPlayer.GetOfficialRank()
    if curRealmLV < needRealmLV:
        GameWorld.DebugLog("    境界不足,无法培养!  curRealmLV(%s) < needRealmLV(%s)" % (curRealmLV, needRealmLV))
        return
    needEatCountTotal = trainIpyData.GetEatCntTotal()
    if not needEatCountTotal:
        GameWorld.DebugLog("    该培养已满级!")
        return
    costItemIDList = IpyGameDataPY.GetFuncEvalCfg("PetUpItem", 3)
    costItemID = costItemIDList[trainType - 1]
    if not costItemID or not costItemCount:
        return
    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)
    lackCnt = costItemCount - bindCnt - unBindCnt
    if lackCnt > 0:
        GameWorld.DebugLog("    消耗道具不足,无法培养!costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s"
                           % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))
        return
    delCnt = costItemCount
    # 扣除消耗
    if delCnt:
        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, ChConfig.ItemDel_Pet)
    updClassLV = trainLV
    updEatItemCount = curEatItemCount + costItemCount
    GameWorld.DebugLog("    updEatItemCount=%s,needEatCountTotal=%s" % (updEatItemCount, needEatCountTotal))
    if updEatItemCount >= needEatCountTotal:
        updClassLV += 1
        updEatItemCount -= needEatCountTotal
        GameWorld.DebugLog("    进阶: updClassLV=%s,updEatItemCount=%s" % (updClassLV, updEatItemCount))
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, updClassLV)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainItemCount % trainType, updEatItemCount)
    # 升阶
    if updClassLV > trainLV:
        pass
    Sync_PetTrainData(curPlayer)
    # 刷属性,更新排行榜
    RefreshPetItemAddAttr(curPlayer, True)
    return
def Sync_PetTrainData(curPlayer):
    clientPack = ChPyNetSendPack.tagMCPetTrainInfo()
    clientPack.TrainLVList = []
    clientPack.TrainItemCountList = []
    for trainType in xrange(1, GetPetTrainTypes() + 1):
        clientPack.TrainLVList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType))
        clientPack.TrainItemCountList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainItemCount % trainType))
    clientPack.TrainTypes = len(clientPack.TrainLVList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return