xdh
2019-07-10 8305a5153495bed079462c629f9902174a0e5b6e
7940 【后端】【主干】骑宠觉醒功能
11个文件已修改
520 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChEquip.py 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -1906,4 +1906,16 @@
    DWORD        ID;    //ΨһID
    DWORD        _PointID;    //灵根ID
    BYTE        _QualityLV;    //品级
};
//骑宠幻化表
struct tagHorsePetSkin
{
    BYTE        _Type;    //1坐骑2灵宠
    DWORD        _ID;    //关联ID(坐骑表和灵宠表ID)
    BYTE        _SkinLV;    //幻化等级
    DWORD        NeedExp;    //升级需要经验
    dict        AttrInfo;    //属性
    BYTE        SkinIndex;    //外观
};
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -9814,6 +9814,126 @@
#------------------------------------------------------
# A5 29 骑宠觉醒 #tagCMHorsePetAwake
class  tagCMHorsePetAwake(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Type", c_ushort),    # 1-坐骑 2-灵宠
                  ("ID", c_int),    # 对应坐骑表灵宠表ID
                  ("EatItemID", c_int),    # 吞噬的物品ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA5
        self.SubCmd = 0x29
        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 = 0x29
        self.Type = 0
        self.ID = 0
        self.EatItemID = 0
        return
    def GetLength(self):
        return sizeof(tagCMHorsePetAwake)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A5 29 骑宠觉醒 //tagCMHorsePetAwake:
                                Cmd:%s,
                                SubCmd:%s,
                                Type:%d,
                                ID:%d,
                                EatItemID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Type,
                                self.ID,
                                self.EatItemID
                                )
        return DumpString
m_NAtagCMHorsePetAwake=tagCMHorsePetAwake()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMHorsePetAwake.Cmd,m_NAtagCMHorsePetAwake.SubCmd))] = m_NAtagCMHorsePetAwake
#------------------------------------------------------
# A5 30 骑宠外观选择 #tagCMHorsePetSkinSelect
class  tagCMHorsePetSkinSelect(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Type", c_ushort),    # 1-坐骑 2-灵宠
                  ("ID", c_int),    # 对应坐骑表灵宠表ID
                  ("SkinIndex", c_ubyte),    # 外观索引
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA5
        self.SubCmd = 0x30
        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 = 0x30
        self.Type = 0
        self.ID = 0
        self.SkinIndex = 0
        return
    def GetLength(self):
        return sizeof(tagCMHorsePetSkinSelect)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A5 30 骑宠外观选择 //tagCMHorsePetSkinSelect:
                                Cmd:%s,
                                SubCmd:%s,
                                Type:%d,
                                ID:%d,
                                SkinIndex:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Type,
                                self.ID,
                                self.SkinIndex
                                )
        return DumpString
m_NAtagCMHorsePetSkinSelect=tagCMHorsePetSkinSelect()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMHorsePetSkinSelect.Cmd,m_NAtagCMHorsePetSkinSelect.SubCmd))] = m_NAtagCMHorsePetSkinSelect
#------------------------------------------------------
# A5 27 坐骑提升 #tagCMHorseUp
class  tagCMHorseUp(Structure):
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1278,6 +1278,8 @@
Def_IudetPet_QualityLV = 206  # 品质
Def_IudetPet_Exp = 208  # 经验
Def_IudetPet_Skill = 201  # 技能列表
Def_IudetHorsePetSkinIndex = 210  # 骑宠觉醒外观索引
# ----------------------------------------------------
# 宠物物品数据状态
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -40,7 +40,7 @@
Writer = wdb
Releaser = wdb
RegType = 0
RegisterPackCount = 3
RegisterPackCount = 5
PacketCMD_1=0xA5
PacketSubCMD_1=0x01
@@ -54,6 +54,14 @@
PacketSubCMD_3=0x27
PacketCallFunc_3=OnHorseClassLVUP
PacketCMD_4=0xA5
PacketSubCMD_4=0x29
PacketCallFunc_4=OnHorsePetAwake
PacketCMD_5=0xA5
PacketSubCMD_5=0x30
PacketCallFunc_5=OnHorsePetSkinSelect
;玛雅加强
[EquipPlus]
ScriptName = Event\EventSrc\Operate_EquipPlus.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -441,6 +441,7 @@
Def_Effect_ItemGiveWeekPartyPoint1 = 246      #使用道具给予节日巡礼积分
Def_Effect_AddRealmExpRate = 251 #增加聚灵效率
Def_Effect_TouchMission = 252 #触发任务
Def_Effect_HorsePetSkinExp = 253 #骑宠觉醒值
#----以下未使用或代码依然存在的---
Def_Effect_ItemGiveGongXun = 1920        #使用道具给予功勋
Def_Effect_ItemGiveRuneJH = 1925       #使用道具给予符印精华
@@ -3747,7 +3748,9 @@
Def_PDict_Horser_LV = "Horser_LV_%d"  # 坐骑等级 0代表未激活 1代表1级
Def_PDict_Horser_Exp = "Horser_Exp_%d"  # 坐骑经验
Def_PDict_Horser_Multiple = "Horser_Multiple"  # 坐骑下次升阶暴击倍数
#骑宠觉醒
Def_PDict_HorsePetSkinData = "HorsePetSkinData%d_%s"  #觉醒等级*100+外观索引  参数(类型,关联ID)
Def_PDict_HorsePetSkinExp = "HorsePetSkinExp%d_%s"  #经验  参数(类型,关联ID)
# 符印
Def_PDict_Rune_HoleOpenState = "Rune_HoleOpenState"  # 符印解锁状态
Def_PDict_Rune_Data = "Rune_Data_%s"  # 符印镶嵌数据, 参数(第几孔)
@@ -4858,7 +4861,8 @@
ItemDel_EquipStarUp, # 装备升星
ItemDel_EquipPlusEvolve, # 装备强化进化
ItemDel_LingQiEquipBreak, # 灵器突破
) = range(2000, 2000 + 41)
ItemDel_HorsePetAwake, # 骑宠觉醒
) = range(2000, 2000 + 42)
# 物品扣除类型对应信息 {类型:eventName, ...}
ItemDelTypeDict = {
@@ -4902,6 +4906,7 @@
                   ItemDel_EquipStarUp:"EquipStarUp",
                   ItemDel_EquipPlusEvolve:"EquipPlusEvolve",
                   ItemDel_LingQiEquipBreak:"LingQiEquipBreak",
                   ItemDel_HorsePetAwake:"HorsePetAwake",
                   }
##==================================================================================================
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -9814,6 +9814,126 @@
#------------------------------------------------------
# A5 29 骑宠觉醒 #tagCMHorsePetAwake
class  tagCMHorsePetAwake(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Type", c_ushort),    # 1-坐骑 2-灵宠
                  ("ID", c_int),    # 对应坐骑表灵宠表ID
                  ("EatItemID", c_int),    # 吞噬的物品ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA5
        self.SubCmd = 0x29
        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 = 0x29
        self.Type = 0
        self.ID = 0
        self.EatItemID = 0
        return
    def GetLength(self):
        return sizeof(tagCMHorsePetAwake)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A5 29 骑宠觉醒 //tagCMHorsePetAwake:
                                Cmd:%s,
                                SubCmd:%s,
                                Type:%d,
                                ID:%d,
                                EatItemID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Type,
                                self.ID,
                                self.EatItemID
                                )
        return DumpString
m_NAtagCMHorsePetAwake=tagCMHorsePetAwake()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMHorsePetAwake.Cmd,m_NAtagCMHorsePetAwake.SubCmd))] = m_NAtagCMHorsePetAwake
#------------------------------------------------------
# A5 30 骑宠外观选择 #tagCMHorsePetSkinSelect
class  tagCMHorsePetSkinSelect(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Type", c_ushort),    # 1-坐骑 2-灵宠
                  ("ID", c_int),    # 对应坐骑表灵宠表ID
                  ("SkinIndex", c_ubyte),    # 外观索引
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA5
        self.SubCmd = 0x30
        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 = 0x30
        self.Type = 0
        self.ID = 0
        self.SkinIndex = 0
        return
    def GetLength(self):
        return sizeof(tagCMHorsePetSkinSelect)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A5 30 骑宠外观选择 //tagCMHorsePetSkinSelect:
                                Cmd:%s,
                                SubCmd:%s,
                                Type:%d,
                                ID:%d,
                                SkinIndex:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Type,
                                self.ID,
                                self.SkinIndex
                                )
        return DumpString
m_NAtagCMHorsePetSkinSelect=tagCMHorsePetSkinSelect()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMHorsePetSkinSelect.Cmd,m_NAtagCMHorsePetSkinSelect.SubCmd))] = m_NAtagCMHorsePetSkinSelect
#------------------------------------------------------
# A5 27 坐骑提升 #tagCMHorseUp
class  tagCMHorseUp(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1476,6 +1476,15 @@
                        ("DWORD", "PointID", 1),
                        ("BYTE", "QualityLV", 1),
                        ),
                "HorsePetSkin":(
                        ("BYTE", "Type", 1),
                        ("DWORD", "ID", 1),
                        ("BYTE", "SkinLV", 1),
                        ("DWORD", "NeedExp", 0),
                        ("dict", "AttrInfo", 0),
                        ("BYTE", "SkinIndex", 0),
                        ),
                }
@@ -4516,6 +4525,25 @@
    def GetID(self): return self.ID # ΨһID
    def GetPointID(self): return self.PointID # 灵根ID
    def GetQualityLV(self): return self.QualityLV # 品级
# 骑宠幻化表
class IPY_HorsePetSkin():
    def __init__(self):
        self.Type = 0
        self.ID = 0
        self.SkinLV = 0
        self.NeedExp = 0
        self.AttrInfo = {}
        self.SkinIndex = 0
        return
    def GetType(self): return self.Type # 1坐骑2灵宠
    def GetID(self): return self.ID # 关联ID(坐骑表和灵宠表ID)
    def GetSkinLV(self): return self.SkinLV # 幻化等级
    def GetNeedExp(self): return self.NeedExp # 升级需要经验
    def GetAttrInfo(self): return self.AttrInfo # 属性
    def GetSkinIndex(self): return self.SkinIndex # 外观
def Log(msg, playerID=0, par=0):
@@ -4837,6 +4865,8 @@
        self.ipySkyTowerLen = len(self.ipySkyTowerCache)
        self.ipyLingGenEffectCache = self.__LoadFileData("LingGenEffect", IPY_LingGenEffect)
        self.ipyLingGenEffectLen = len(self.ipyLingGenEffectCache)
        self.ipyHorsePetSkinCache = self.__LoadFileData("HorsePetSkin", IPY_HorsePetSkin)
        self.ipyHorsePetSkinLen = len(self.ipyHorsePetSkinCache)
        Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict))
        Log("IPY_DataMgr InitOK!")
        return
@@ -5299,6 +5329,8 @@
    def GetSkyTowerByIndex(self, index): return self.ipySkyTowerCache[index]
    def GetLingGenEffectCount(self): return self.ipyLingGenEffectLen
    def GetLingGenEffectByIndex(self, index): return self.ipyLingGenEffectCache[index]
    def GetHorsePetSkinCount(self): return self.ipyHorsePetSkinLen
    def GetHorsePetSkinByIndex(self, index): return self.ipyHorsePetSkinCache[index]
IPYData = IPY_DataMgr()
def IPY_Data(): return IPYData
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChEquip.py
@@ -1195,7 +1195,7 @@
#===============================================================================
# #//03 2F 请求装备显隐#tagRequestEquipShowHide
# //装备显示开关
# int GetEquipShowSwitch(); 灵根特效表key * 1000+第几套*10+是否有套装
# int GetEquipShowSwitch(); 灵宠外观索引*10000000+坐骑外观索引*1000000+灵根特效表key * 1000+第几套*10+是否有套装
#===============================================================================
##请求装备显隐. (设置显示哪套装备外观)
# @param index 玩家索引
@@ -1312,16 +1312,27 @@
            return
        effectID = ipyData.GetID()
    oldEquipShowSwitch = curPlayer.GetEquipShowSwitch()
    updEquipShowSwitch = oldEquipShowSwitch % 1000 + 1000 * effectID
    updEquipShowSwitch = oldEquipShowSwitch % 1000 + oldEquipShowSwitch / 1000000 * 1000000+ 1000 * effectID
    GameWorld.DebugLog('灵根品级变化影响角色外观显示g_skillElementCntDict=%s,oldEquipShowSwitch=%s,updEquipShowSwitch=%s'%
                       (g_skillElementCntDict, oldEquipShowSwitch, updEquipShowSwitch))
    if oldEquipShowSwitch != updEquipShowSwitch:
        curPlayer.SetEquipShowSwitch(updEquipShowSwitch)
    return
def ChangeEquipfacadeByHorsePetSkin(curPlayer, skinType, skinIndex):
    ##骑宠觉醒外观变更  灵宠外观索引*10000000+坐骑外观索引*1000000+灵根特效表key * 1000+第几套*10+是否有套装
    oldEquipShowSwitch = curPlayer.GetEquipShowSwitch()
    if skinType == 1:
        updEquipShowSwitch = GameWorld.ChangeDataByDigitPlace(oldEquipShowSwitch, 7, skinIndex)
    else:
        updEquipShowSwitch = GameWorld.ChangeDataByDigitPlace(oldEquipShowSwitch, 8, skinIndex)
    if oldEquipShowSwitch == updEquipShowSwitch:
        return
    curPlayer.SetEquipShowSwitch(updEquipShowSwitch)
    return
#获取当前是第几套装备外观
def GetEquipFacadeClassLV(curPlayer):return curPlayer.GetEquipShowSwitch()/10
def GetEquipFacadeClassLV(curPlayer):return curPlayer.GetEquipShowSwitch()%1000/10
## 获取公共部位强化熟练度
def GetEquipPartProficiency(curPlayer, packType, index):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
@@ -41,6 +41,7 @@
import PassiveBuffEffMng
import CrossPlayerData
import PlayerWeekParty
import PlayerPet
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -373,7 +374,7 @@
        GameWorld.DebugLog("OnPlayerChangeHorse() pack(%s) no horse(%s) item" \
                           % (ShareDefine.rptTempSwap, horseItemID))
        return
    curHorse.SetUserAttr(ShareDefine.Def_IudetHorsePetSkinIndex, GetHorsePetSkinIndex(curPlayer, 1, horseIndex))
    #检查玩家状态是否可以换装
    if not ChEquip.CheckPlayerCanEquipItem(curPlayer):
        return
@@ -733,7 +734,6 @@
    #EventReport.WriteEvent_horse_class(curPlayer, horseLV, curExp, delCnt, updClassLV, updExp)
    return
## 坐骑阶级提升
#  @param curPlayer
#  @param horseID: 坐骑id
@@ -797,6 +797,7 @@
# @return None
def PlayerHorseLogin(curPlayer):
    Sync_HorseClassData(curPlayer)
    SyncHorsePetSkinData(curPlayer)
    return
@@ -1002,4 +1003,179 @@
        if horseLV > maxLV:
            maxLV = horseLV
    return maxLV
def IsHorseMaxLV(curPlayer, horseID):
    horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)
    if horseLV <= 0:
        return
    horseIpyData = IpyGameDataPY.GetIpyGameData("Horse", horseID)
    if not horseIpyData:
        return
    maxLV = horseIpyData.GetMaxLV()
    return horseLV >= maxLV
#============================骑宠觉醒=============================
#// A5 29 骑宠觉醒 #tagCMHorsePetAwake
#
#struct    tagCMHorsePetAwake
#{
#    tagHead        Head;
#    WORD    Type;    // 1-坐骑 2-灵宠
#    DWORD    ID;    // 对应坐骑表灵宠表ID
#    DWORD    EatItemID;    // 吞噬的物品ID
#};
def OnHorsePetAwake(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    skintype = curPackData.Type
    horsePetID = curPackData.ID
    eatItemID = curPackData.EatItemID
    if not IpyGameDataPY.GetIpyGameDataByCondition('HorsePetSkin', {'Type':skintype, 'ID':horsePetID}):
        return
    if skintype == 1:
        if not IsHorseMaxLV(curPlayer, horsePetID):
            GameWorld.DebugLog('骑宠觉醒 对应骑宠未满级 horsePetID=%s'%horsePetID)
            return
    else:
        if not PlayerPet.IsPetMaxLV(curPlayer, horsePetID):
            GameWorld.DebugLog('骑宠觉醒 对应骑宠未满级 horsePetID=%s'%horsePetID)
            return
    skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (skintype, horsePetID), 0)
    curSkinLV, curSkinIndex = skinData/100, skinData%100
    ipyData = IpyGameDataPY.GetIpyGameData('HorsePetSkin', skintype, horsePetID, curSkinLV)
    if not ipyData:
        return
    upNeedExp = ipyData.GetNeedExp()
    if not upNeedExp:
        GameWorld.DebugLog('骑宠觉醒 已满级')
        return
    curExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinExp % (skintype, horsePetID), 0)
    curItem = GameWorld.GetGameData().GetItemByTypeID(eatItemID)
    if not curItem:
        return
    curEff = curItem.GetEffectByIndex(1)
    curEffID = curEff.GetEffectID()
    if curEffID != ChConfig.Def_Effect_HorsePetSkinExp:
        return
    addExp = curEff.GetEffectValue(0)
    if not addExp:
        return
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
    hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(eatItemID, itemPack, 1)
    if not hasEnough:
        GameWorld.DebugLog("OnHorsePetAwake() item(%s[%s]) isn't enough" % (eatItemID, 1))
        return
    ItemCommon.ReduceItem(curPlayer, itemPack, itemList, 1, False, ChConfig.ItemDel_HorsePetAwake)
    updExp = curExp + addExp
    updSkinLV = curSkinLV
    updSkinIndex = curSkinIndex
    if updExp >= upNeedExp:
        for _ in xrange(10):
            ipyData = IpyGameDataPY.GetIpyGameDataNotLog('HorsePetSkin', skintype, horsePetID, updSkinLV+1)
            if not ipyData:
                break
            if updExp < upNeedExp:
                break
            updExp -= upNeedExp
            updSkinLV += 1
            updSkinIndex = ipyData.GetSkinIndex()
            upNeedExp = ipyData.GetNeedExp()
    updSkinData = updSkinLV*100+updSkinIndex
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorsePetSkinData % (skintype, horsePetID), updSkinData)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorsePetSkinExp % (skintype, horsePetID), updExp)
    if curSkinIndex != updSkinIndex:
        __DoHorsePetSkinChange(curPlayer, skintype, horsePetID, updSkinIndex)
    SyncHorsePetSkinData(curPlayer, [[skintype, horsePetID]])
    return
#// A5 30 骑宠外观选择 #tagCMHorsePetSkinSelect
#struct    tagCMHorsePetSkinSelect
#{
#    tagHead        Head;
#    WORD    Type;    // 1-坐骑 2-灵宠
#    DWORD    ID;    // 对应坐骑表灵宠表ID
#    BYTE    SkinIndex;    // 外观索引
#};
def OnHorsePetSkinSelect(index, curPackData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    skintype = curPackData.Type
    horsePetID = curPackData.ID
    skinIndex = curPackData.SkinIndex
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition('HorsePetSkin', {'Type':skintype, 'ID':horsePetID, 'SkinIndex':skinIndex})
    if not ipyData:
        return
    skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (skintype, horsePetID), 0)
    curSkinLV, curSkinIndex = skinData/100, skinData%100
    if skinIndex == curSkinIndex:
        return
    if curSkinLV < ipyData.GetSkinLV():
        return
    updSkinData = curSkinLV*100+skinIndex
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorsePetSkinData % (skintype, horsePetID), updSkinData)
    __DoHorsePetSkinChange(curPlayer, skintype, horsePetID, skinIndex)
    SyncHorsePetSkinData(curPlayer, [[skintype, horsePetID]])
    return
def __DoHorsePetSkinChange(curPlayer, skinType, horsePetID, skinIndex):
    ##骑宠觉醒外观更换
    ChEquip.ChangeEquipfacadeByHorsePetSkin(curPlayer, skinType, skinIndex)
    if skinType == 1:#坐骑
        playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
        itemRideHorse = playerEquip.GetAt(Def_HorseEquipIndex)
        #无指定道具
        if itemRideHorse.IsEmpty():
            return
        ipyData = IpyGameDataPY.GetIpyGameData("Horse", horsePetID)
        if not ipyData:
            return
        horseItemID = ipyData.GetItemID()
        if itemRideHorse.GetItemTypeID() != horseItemID:
            return
        itemRideHorse.SetUserAttr(ShareDefine.Def_IudetHorsePetSkinIndex, skinIndex)
    elif skinType == 2:#灵宠
        pass
    return
def GetHorsePetSkinIndex(curPlayer, skintype, horsePetID):
    # 获取骑宠觉醒外观索引
    skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (skintype, horsePetID), 0)
    return skinData%100
def SyncHorsePetSkinData(curPlayer, skinList=None):
    if not skinList:
        skinList = []
        ipyMgr = IpyGameDataPY.IPY_Data()
        for i in xrange(ipyMgr.GetHorsePetSkinCount()):
            ipyData = ipyMgr.GetHorsePetSkinByIndex(i)
            if [ipyData.GetType(), ipyData.GetID()] not in skinList:
                skinList.append([ipyData.GetType(), ipyData.GetID()])
    packData = ChPyNetSendPack.tagMCHorsePetSkinData()
    packData.Clear()
    packData.InfoList = []
    for skintype, horsePetID in skinList:
        skinInfo = ChPyNetSendPack.tagMCHorsePetSkinInfo()
        skinInfo.Type = skintype
        skinInfo.ID = horsePetID
        curExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinExp % (skintype, horsePetID), 0)
        skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (skintype, horsePetID), 0)
        if not curExp and not skinData:
            continue
        curSkinLV, curSkinIndex = skinData/100, skinData%100
        skinInfo.Exp = curExp
        skinInfo.SkinLV = curSkinLV
        skinInfo.SkinIndex = curSkinIndex
        packData.InfoList.append(skinInfo)
    packData.Num = len(packData.InfoList)
    NetPackCommon.SendFakePack(curPlayer, packData)
    return
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -42,6 +42,7 @@
import CrossPlayerData
import CalcLineEffect
import PlayerActivity
import PlayerHorse
import random
import math
@@ -322,6 +323,7 @@
    petID = petStruct.PetID
    petStruct.BindType = petItem.GetIsBind()
    petStruct.Name = str(petStruct.PetID)#petNpcData.GetName() 配表不是UTF8会导致报错,默认用ID当名字
    petStruct.DailyTrainCnt = PlayerHorse.GetHorsePetSkinIndex(curPlayer, 2, npcID)
    # 宠物lv 改为 阶级 用于客户端显示名字颜色用
#    classLV = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)
#    rolePet.SetLV(classLV)
@@ -750,6 +752,18 @@
        totalPetLV += classLV
    return totalPetLV
def IsPetMaxLV(curPlayer, petNPCID):
    petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)
    if not petItem:
        return
    petNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
    classLV = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)
    petIpyData = GetPetIpydata(petNPCID)
    if not petIpyData:
        return
    maxClassLV = petIpyData.GetMaxRank()
    return classLV + 2 > maxClassLV
## 刷新宠物数据物品增加的属性
def RefreshPetItemAddAttr(curPlayer, isUpdBillboard):
    CalcPetItemAddPlayerAttr(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1278,6 +1278,8 @@
Def_IudetPet_QualityLV = 206  # 品质
Def_IudetPet_Exp = 208  # 经验
Def_IudetPet_Skill = 201  # 技能列表
Def_IudetHorsePetSkinIndex = 210  # 骑宠觉醒外观索引
# ----------------------------------------------------
# 宠物物品数据状态