| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package Player.PlayerHorse  | 
| #  | 
| # @todo:×øÆï  | 
| # @author hxp  | 
| # @date 2019-12-17  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ×øÆï  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2019-12-17 18:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import ChPyNetSendPack  | 
| import IPY_GameWorld  | 
| import GameWorld  | 
| import PlayerControl  | 
| import ChConfig  | 
| import OperControlManager  | 
| import OpenServerCampaign  | 
| import ItemCommon  | 
| import ChEquip  | 
| import ShareDefine  | 
| import DataRecordPack  | 
| import ItemControler  | 
| import NetPackCommon  | 
| import PlayerBillboard  | 
| import PlayerAttrFruit  | 
| import PlayerGameEvent  | 
| import GameFuncComm  | 
| import EventShell  | 
| import IpyGameDataPY  | 
| import CrossPlayerData  | 
| import PlayerSuccess  | 
| import PlayerActHorsePetTrain  | 
| import PlayerActTask  | 
| import PlayerPet  | 
|   | 
| import time  | 
|   | 
|   | 
| Def_HorseEquipIndex = 5  | 
|   | 
|   | 
| #//03 09 Íæ¼ÒÆïÂí#tagCRideHorse  | 
| #  | 
| #struct    tagCRideHorse  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        Ride;        //1: ÆïÂí 0: ÏÂÂí  | 
| #};  | 
| def OnRideHorse(index, tick):  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         return False  | 
|       | 
|     cdTime = ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_HorseChangState]  | 
|     # ÅжÏʱ¼äÊÇ·ñ³¬¹ý¼ä¸ô  | 
|     if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_HorseChangState) <= cdTime:  | 
|         #ûÓе½Ë¢Ð¼ä¸ô  | 
|         return  | 
|     curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_HorseChangState, tick)  | 
|       | 
|     pack = IPY_GameWorld.IPY_CRideHorse()  | 
|     #//1: ÆïÂí 0: ÏÂÂí  | 
|     curPlayerRideType = pack.GetRide()  | 
|     if PlayerControl.GetCrossMapID(curPlayer):  | 
|         # ÔÝÖ»´¦ÀíÉÏÂí  | 
|         if curPlayerRideType:  | 
|             dataList = [curPlayerRideType]  | 
|             CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_RideHorse, dataList)  | 
|         return  | 
|     #ÆïÂíÐÐΪ״̬, ¿Í»§¶ËÏÞÖÆ  | 
|     if not OperControlManager.IsObjCanDoAction(curPlayer,  | 
|                                                ChConfig.Def_Obj_ActState_ClientAct,  | 
|                                                IPY_GameWorld.oalRide):  | 
|         return  | 
|       | 
|     #ÏÂÂí  | 
|     if curPlayerRideType == 0 :  | 
|         PlayerRideHorseDown(curPlayer, True)  | 
|           | 
|     #ÆïÂí     | 
|     elif curPlayerRideType == 1:  | 
|         PlayerRideHorseUp(curPlayer, True)  | 
|           | 
|     return  | 
|   | 
| def CrossServer_RideHorse(curPlayer, dataList):  | 
|     curPlayerRideType = dataList[0]  | 
|       | 
|     #ÆïÂí  | 
|     if curPlayerRideType == 1:  | 
|         PlayerRideHorseUp(curPlayer, True)  | 
|               | 
|     return  | 
|   | 
| def PlayerRideHorseDown(curPlayer, refreshState=True) :  | 
|     ## Íæ¼ÒÏÂÂí  | 
|     if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvHorse:  | 
|         return  | 
|       | 
|     curPlayer.SetPlayerVehicle(IPY_GameWorld.pvNull)  | 
|     curPlayer.Sync_GetoffHorse()  | 
|       | 
|     playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|     playerControl.RefreshPlayerAttrByBuff()  | 
|     return  | 
|   | 
| def PlayerRideHorseUp(curPlayer, refreshState=True, isNotify=True) :  | 
|     ## Íæ¼ÒÉÏÂí   | 
|       | 
|     # Î´¼ÓÔØ³É¹¦Æï³Ë»áµ¼ÖÂÄ£ÐͼÓÔØÊ§°Ü±¨´í  | 
|     if not curPlayer.GetInitOK():  | 
|         return  | 
|       | 
|     customMapID = PlayerControl.GetCustomMapID(curPlayer)  | 
|     if customMapID:  | 
|         ipyMapData = IpyGameDataPY.GetIpyGameData("ChinMap", customMapID)  | 
|         if not ipyMapData or not ipyMapData.GetCanRide():  | 
|             PlayerControl.NotifyCode(curPlayer, "RideLimit_lhs_0")  | 
|             return  | 
|     else:  | 
|         #µØÍ¼²»ÔÊÐíÆïÂí RideLimit_lhs_0  | 
|         if not GameWorld.GetMap().GetMapCanRide():  | 
|             PlayerControl.NotifyCode(curPlayer, "RideLimit_lhs_0")  | 
|             return  | 
|           | 
|     #¼ì²éÍæ¼Ò״̬,Ö»ÓÐÔÚ¿ÕÏÐ״̬²ÅÄÜÉÏÂí  | 
|     if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvNull :  | 
|         #GameWorld.Log("ÒѾÓн»Í¨¹¤¾ß,ÎÞ·¨ÉÏÂí")  | 
|         return  | 
|       | 
|     #¼ì²éÊÇ·ñ×°±¸Ö¸¶¨IDÎïÆ·  | 
|     playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  | 
|     itemRideHorse = playerEquip.GetAt(Def_HorseEquipIndex)  | 
|     #ÎÞÖ¸¶¨µÀ¾ß  | 
|     if itemRideHorse.IsEmpty():  | 
|         return  | 
|       | 
|     if curPlayer.GetPlayerAction() == IPY_GameWorld.paGameEvent:  | 
|         tick = GameWorld.GetGameWorld().GetTick()  | 
|         PlayerGameEvent.StopGameEvent(curPlayer, tick)  | 
|           | 
|     #ÉèÖÃÍæ¼ÒΪÆïÂí״̬  | 
|     curPlayer.SetPlayerVehicle(IPY_GameWorld.pvHorse)  | 
|     #ÉèÖÃÂíÆ¥ÎªÆÕÍ¨ÒÆ¶¯×´Ì¬  | 
|     curPlayer.SetPlayerRidehorseState(IPY_GameWorld.prsNormal)  | 
|       | 
|     if isNotify:  | 
|         curPlayer.Sync_RideHorse()  | 
|           | 
|     if refreshState:  | 
|         playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|         playerControl.RefreshPlayerAttrByBuff()  | 
|     return True  | 
|   | 
| #=====================================================================  | 
|   | 
| #//A5 01 ×øÆï¼¤»î #tagPlayerActivateHorse  | 
| #  | 
| #struct    tagPlayerActivateHorse  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        HorseID;        //×øÆï»Ã»¯ID  | 
| #};  | 
| def ActivateHorseSkinItem(index, curPackData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     activateID = curPackData.HorseID  | 
|       | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         return  | 
|       | 
|     ipyData = IpyGameDataPY.GetIpyGameData("HorseSkinPlus", activateID)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     updSkinEndTime = 0  | 
|     validTime = ipyData.GetSkinValidTime()  | 
|     if validTime:  | 
|         curTime = int(time.time())  | 
|         skinEndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinEndTime % activateID)  | 
|         if curTime >= skinEndTime:  | 
|             updSkinEndTime = curTime + validTime  | 
|         else:  | 
|             updSkinEndTime = skinEndTime + validTime  | 
|     else:  | 
|         if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, activateID):  | 
|             GameWorld.DebugLog("¸Ã×øÆïÒѻû¯! activateID=%s" % activateID)  | 
|             return  | 
|           | 
|     needItemID = ipyData.GetUnlockItemID()  | 
|     needItemCnt = ipyData.GetUnlockItemCnt()  | 
|     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|     hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(needItemID, itemPack, needItemCnt)  | 
|     if not hasEnough:  | 
|         GameWorld.DebugLog("×øÆï»Ã»¯µÀ¾ß²»×ã! needItemID=%s,needItemCnt=%s" % (needItemID, needItemCnt))  | 
|         return  | 
|     ItemCommon.ReduceItem(curPlayer, itemPack, itemList, needItemCnt, False, ChConfig.ItemDel_Horse)  | 
|       | 
|     if validTime:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinEndTime % activateID, updSkinEndTime)  | 
|         GameWorld.DebugLog("×øÆï»Ã»¯Ê±Ð§ activateID=%s,updSkinEndTime=%s(%s)" % (activateID, updSkinEndTime, GameWorld.ChangeTimeNumToStr(updSkinEndTime)), playerID)  | 
|           | 
|     #ʱЧ¼°·ÇʱЧ¸Ã״̬¾ùÉèÖü¤»î  | 
|     activateState, updActivateState = GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, activateID, 1)  | 
|       | 
|     playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  | 
|     itemRideHorse = playerEquip.GetAt(Def_HorseEquipIndex)  | 
|     #ÎÞÖ¸¶¨µÀ¾ß  | 
|     if itemRideHorse.IsEmpty():  | 
|         DoChangeHorse(curPlayer, 2, activateID, tick)  | 
|           | 
|     Sync_HorseClassData(curPlayer)  | 
|     if validTime:  | 
|         SyncHorseSkinTimeInfo(curPlayer, activateID)  | 
|     GameWorld.Log("×øÆï¼¤»î³É¹¦£¡activateID=%s,activateState=%s,updActivateState=%s,updSkinEndTime=%s"   | 
|                   % (activateID, activateState, updActivateState, updSkinEndTime), playerID)  | 
|       | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshHorseAttr(curPlayer)  | 
|     PlayerControl.WorldNotify(0, "GetMount", [curPlayer.GetName(), ipyData.GetHorseSkinPlusID()])  | 
|     return  | 
|   | 
|   | 
| #//A5 02 ×øÆïÑ¡Ôñ #tagPlayerChooseHorse  | 
| #  | 
| #struct    tagPlayerChooseHorse  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        ChooseType;    // 1-°´µÈ½×£¬2-°´»Ã»¯  | 
| #    BYTE        LVID;        // ½×µÈ¼¶»ò»Ã»¯ID  | 
| #};  | 
| def OnPlayerChangeHorse(index, packData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|       | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         return  | 
|       | 
|     #¼ì²é»»×°¼ä¸ô  | 
|     if tick - curPlayer.GetLastChangeEquipTick() <= ChConfig.Def_MinChangeEquipTime:  | 
|         return  | 
|     curPlayer.SetLastChangeEquipTick(tick)  | 
|       | 
|     chooseType = packData.ChooseType  | 
|     lvID = packData.LVID  | 
|       | 
|     if not DoChangeHorse(curPlayer, chooseType, lvID, tick):  | 
|         return  | 
|       | 
|     if not GameWorld.IsCrossServer():  | 
|         dataList = [chooseType, lvID]  | 
|         CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_HorseChange, dataList)  | 
|           | 
|     return  | 
|   | 
| def CrossServer_ChangeHorse(curPlayer, dataList):  | 
|     ## ¿ç·þ´¦Àí ×øÆï±ä¸ü  | 
|     chooseType, lvID = dataList  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     DoChangeHorse(curPlayer, chooseType, lvID, tick)  | 
|     return  | 
|   | 
| def DoChangeHorse(curPlayer, chooseType, lvID, tick):  | 
|     ''' ×øÆïÑ¡Ôñ  | 
|     @param chooseType: 1-°´½×£¬2-°´»Ã»¯  | 
|     @param lvID:  ½×µÈ¼¶»ò»Ã»¯ID  | 
|     '''  | 
|       | 
|     # °´½×  | 
|     if chooseType == 1:  | 
|         horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)  | 
|         if horseLV < lvID:  | 
|             GameWorld.DebugLog("×øÆïµÈ¼¶²»×㣬ÎÞ·¨Ê¹ÓøÃ×øÆïƤ·ô!  horseLV=%s,lvID=%s" % (horseLV, lvID))  | 
|             return  | 
|           | 
|         horseIpyData = IpyGameDataPY.GetIpyGameData("HorseLVUp", lvID)  | 
|         if not horseIpyData:  | 
|             return  | 
|         horseItemID = horseIpyData.GetHorseSkinID()  | 
|           | 
|     # °´»Ã»¯  | 
|     elif chooseType == 2:  | 
|         skinPlusIpyData = IpyGameDataPY.GetIpyGameData("HorseSkinPlus", lvID)  | 
|         if not skinPlusIpyData:  | 
|             return  | 
|         if not CheckHorseSkinState(curPlayer, skinPlusIpyData):  | 
|             return  | 
|         horseItemID = skinPlusIpyData.GetHorseSkinPlusID()  | 
|           | 
|     else:  | 
|         return  | 
|       | 
|     if not horseItemID:  | 
|         GameWorld.DebugLog("ÕÒ²»µ½Ñ¡ÔñµÄ×øÆïID! chooseType=%s,lvID=%s" % (chooseType, lvID))  | 
|         return  | 
|       | 
|     if ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, IPY_GameWorld.rptEquip):  | 
|         GameWorld.DebugLog("ÒѾѡÔñÁ˸Ã×øÆï£¬ÎÞÐèÖØÐÂÑ¡Ôñ! horseItemID=%s" % horseItemID)  | 
|         return  | 
|       | 
|     isOK = ItemControler.PutItemInTempSwap(curPlayer, horseItemID)  | 
|     if not isOK:  | 
|         return  | 
|       | 
|     curHorse = ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, ShareDefine.rptTempSwap)  | 
|     if not curHorse:  | 
|         return  | 
|     isRideHorse = curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse  | 
|       | 
|     # Èç¹ûÆï³Ë״̬£¬ÏÈÏÂÂí£¬»»×°£¬ÔÙÉÏÂí  | 
|     if isRideHorse:  | 
|         PlayerRideHorseDown(curPlayer, False)  | 
|       | 
|     #---Ö´ÐÐÍæ¼Ò»»×°Âß¼---  | 
|     if ChEquip.DoPlayerEquipItem(curPlayer, curHorse, ItemCommon.GetEquipPackIndex(curHorse), tick):  | 
|         if isRideHorse:  | 
|             PlayerRideHorseUp(curPlayer, False)  | 
|               | 
|     return True  | 
|   | 
| def CheckHorseSkinState(curPlayer, skinPlusIpyData):  | 
|     skinID = skinPlusIpyData.GetID()  | 
|     if skinPlusIpyData.GetSkinValidTime():  | 
|         skinEndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinEndTime % skinID)  | 
|         if not skinEndTime:  | 
|             return False  | 
|         curTime = int(time.time())  | 
|         if curTime >= skinEndTime:  | 
|             playerID = curPlayer.GetPlayerID()  | 
|             GameWorld.Log("×øÆï»Ã»¯ÒѹýÆÚ! skinID=%s,skinEndTime=%s(%s)" % (skinID, skinEndTime, GameWorld.ChangeTimeNumToStr(skinEndTime)), playerID)  | 
|             # ·¢Ë͹ýÆÚ֪ͨÓʼþ£¬ÖØÖÃΪ0  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinEndTime % skinID, 0)  | 
|               | 
|             skinItemID = skinPlusIpyData.GetUnlockItemID()  | 
|             addItemList = []  | 
|             paramList = [skinItemID]  | 
|             PlayerControl.SendMailByKey("HorseSkinInvalidNotify", [playerID], addItemList, paramList)  | 
|               | 
|             activateState, updActivateState = GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, skinID, 0)  | 
|             GameWorld.Log("×øÆï»Ã»¯¹ýÆÚ¸üÐÂ״̬! skinID=%s,activateState=%s,updActivateState=%s" % (skinID, activateState, updActivateState), playerID)  | 
|             Sync_HorseClassData(curPlayer)  | 
|             return False  | 
|     else:  | 
|         if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, skinID):  | 
|             #GameWorld.DebugLog("×øÆï»Ã»¯Î´¼¤»î! skinID=%s,activateState=%s" % (skinID, activateState), curPlayer.GetPlayerID())  | 
|             return False  | 
|     return True  | 
|   | 
| def DoHorseOpen(curPlayer):  | 
|     ## ÂíÆ¥¹¦ÄÜ¿ªÆô  | 
|     horseLV = 1  | 
|     ipyData = IpyGameDataPY.GetIpyGameData("HorseLVUp", horseLV)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserLV, horseLV)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserEatItemCount, 0)  | 
|     for trainType in xrange(1, GetHorseTrainTypes() + 1):  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserTrainLV % trainType, 1)  | 
|           | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):  | 
|         skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)  | 
|         skinID = skinPlusIpyData.GetID()  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinEndTime % skinID, 0)  | 
|         GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, skinID, 0)  | 
|           | 
|     horseID = ipyData.GetHorseSkinID()  | 
|     if not ItemCommon.FindItemInPackByItemID(curPlayer, horseID, IPY_GameWorld.rptEquip):  | 
|         isOK = ItemControler.PutItemInTempSwap(curPlayer, horseID)  | 
|         if not isOK:  | 
|             return  | 
|           | 
|         curHorse = ItemCommon.FindItemInPackByItemID(curPlayer, horseID, ShareDefine.rptTempSwap)  | 
|         if not curHorse:  | 
|             return  | 
|         #---Ö´ÐÐÍæ¼Ò»»×°Âß¼---  | 
|         tick = GameWorld.GetGameWorld().GetTick()  | 
|         ChEquip.DoPlayerEquipItem(curPlayer, curHorse, Def_HorseEquipIndex, tick)  | 
|           | 
|     GameWorld.DebugLog("×øÆï¹¦ÄÜ¿ªÆô! horseLV=%s,horseID=%s" % (horseLV, horseID))  | 
|     Sync_HorseClassData(curPlayer)  | 
|     RefreshHorseAttr(curPlayer)  | 
|     return True  | 
|   | 
| def RefreshHorseAttr(curPlayer, isUpdateBill=True):  | 
|     # ×øÆï¹¦ÄÜÊôÐÔ±ä¸üˢР | 
|     CalcHorseAttrEx(curPlayer)  | 
|     # ÐèÒª¸üÐÂ×øÆï°ñ¡¢Ç¿ÖÆË¢ÐÂÊôÐÔ  | 
|     PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState(billboardFunc=PlayerBillboard.UpdateHorseBillboard if isUpdateBill else None)  | 
|     return  | 
|   | 
| def CalcHorseAttrEx(curPlayer):  | 
|     ## ¼ÆËãÂíÆ¥ÊôÐÔ  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         return  | 
|           | 
|     allAttrList = [{} for _ in range(4)]  | 
|     allAttrListHorseSoul = [{} for _ in range(4)]  | 
|     allAttrListSkin = [{} for _ in range(4)]  | 
|     allAttrListTrain = [{} for _ in range(4)]  | 
|     allAttrListStar = [{} for _ in range(4)]  | 
|       | 
|     customAttrDictHorse = {}  | 
|     customAttrDictSkin = {}  | 
|       | 
|     horseSpeed = 0 # ×øÆï¹¦ÄÜÔö¼ÓµÄËÙ¶ÈÖµ£¬Æï³Ëʱ²ÅÓÐЧ¹û  | 
|     horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)  | 
|     # µÈ½×ÅàÑøÊôÐÔ  | 
|     #totalItemCount = 0  | 
|     horseBaseAttrInfo = {}  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in xrange(ipyDataMgr.GetHorseLVUpCount()):  | 
|         horseIpyData = ipyDataMgr.GetHorseLVUpByIndex(index)  | 
|         dataHorseLV = horseIpyData.GetHorseLV()  | 
|         if dataHorseLV > horseLV:  | 
|             break  | 
|         elif dataHorseLV == horseLV:  | 
|             upItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserEatItemCount)  | 
|         else:  | 
|             upItemCount = horseIpyData.GetNeedEatCount()  | 
|                   | 
|         # µÈ½×¶îÍâÊôÐÔ  | 
|         lvAttrTypeList = horseIpyData.GetLVAttrType()  | 
|         lvAttrValueList = horseIpyData.GetLVAttrValue()  | 
|         for i, attrID in enumerate(lvAttrTypeList):  | 
|             attrValue = lvAttrValueList[i]  | 
|             if attrID == ShareDefine.Def_Effect_Speed:  | 
|                 horseSpeed += attrValue  | 
|                 continue  | 
|             PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)  | 
|             horseBaseAttrInfo[attrID] = horseBaseAttrInfo.get(attrID, 0) + attrValue  | 
|               | 
|         # ÅàÑøµ¤Ôö¼ÓÊôÐÔ  | 
|         upItemPerCount = horseIpyData.GetUpEatItemPerCount()  | 
|         if upItemCount and upItemPerCount:  | 
|             upItemAttrTypeList = horseIpyData.GetUpItemAttrType()  | 
|             upItemAttrValueList = horseIpyData.GetUpItemAttrValue()  | 
|             attrMultiple = upItemCount / upItemPerCount  | 
|             for i, attrID in enumerate(upItemAttrTypeList):  | 
|                 attrValue = upItemAttrValueList[i]  | 
|                 PlayerControl.CalcAttrDict_Type(attrID, attrValue * attrMultiple, allAttrList)  | 
|                 horseBaseAttrInfo[attrID] = horseBaseAttrInfo.get(attrID, 0) + attrValue * attrMultiple  | 
|                   | 
|     customAttrDictHorse["horseBaseAttrInfo"] = horseBaseAttrInfo  | 
|       | 
| #    # µÈ½×ÅàÑøµ¤ÀÛ¼Ó¸öÊýÊôÐÔ  | 
| #    eatItemAttrInfo = IpyGameDataPY.GetFuncCfg("HorseUpItem", 3)  | 
| #    for attrID, attrValue in eatItemAttrInfo:  | 
| #        PlayerControl.CalcAttrDict_Type(attrID, attrValue * totalItemCount, allAttrList)  | 
|           | 
|     # »Ã»¯ÊôÐÔ  | 
|     initFPAdd = 0 #³õʼսÁ¦  | 
|     horseSkinQualityAttrInfo = {}  | 
|     for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):  | 
|         skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)  | 
|         if not CheckHorseSkinState(curPlayer, skinPlusIpyData):  | 
|             continue  | 
|         initFPAdd += skinPlusIpyData.GetInitFightPower()  | 
|         attrTypeList = skinPlusIpyData.GetAttrType()  | 
|         attrValueList = skinPlusIpyData.GetAttrValue()  | 
|         for i, attrID in enumerate(attrTypeList):  | 
|             attrValue = attrValueList[i]  | 
|             if attrID == ShareDefine.Def_Effect_Speed:  | 
|                 horseSpeed += attrValue  | 
|                 continue  | 
|             PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListSkin)  | 
|               | 
|         #¾õÐÑÕ½Á¦  | 
|         skintype = 1  | 
|         horseID = skinPlusIpyData.GetHorseID()  | 
|         skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (skintype, horseID))  | 
|         skinIpyData = IpyGameDataPY.GetIpyGameDataNotLog('HorsePetSkin', skintype, horseID, skinData / 100)  | 
|         if skinIpyData:  | 
|             for attrID, attrValue in skinIpyData.GetAttrInfo().items():  | 
|                 PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListSkin)  | 
|                   | 
|         hIpyData = IpyGameDataPY.GetIpyGameData("Horse", horseID)  | 
|         if hIpyData:  | 
|             quality = hIpyData.GetQuality()  | 
|             if quality not in horseSkinQualityAttrInfo:  | 
|                 horseSkinQualityAttrInfo[quality] = {}  | 
|             qualityAttrDict = horseSkinQualityAttrInfo[quality]  | 
|             for i, attrID in enumerate(attrTypeList):  | 
|                 attrValue = attrValueList[i]  | 
|                 qualityAttrDict[attrID] = qualityAttrDict.get(attrID, 0) + attrValue  | 
|                   | 
|         #ÐǼ¶  | 
|         horseStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserStar % horseID)  | 
|         starIpyData = IpyGameDataPY.GetIpyGameDataNotLog("HorseStarUp", horseID, horseStar)  | 
|         if starIpyData:  | 
|             starAttrType = starIpyData.GetStarAttrType()  | 
|             starAttrValue = starIpyData.GetStarAttrValue()  | 
|             for i, attrID in enumerate(starAttrType):  | 
|                 attrValue = starAttrValue[i]  | 
|                 if attrID == ShareDefine.Def_Effect_Speed:  | 
|                     horseSpeed += attrValue  | 
|                     continue  | 
|                 PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListStar)  | 
|           | 
|     customAttrDictSkin["horseSkinQualityAttrInfo"] = horseSkinQualityAttrInfo  | 
|       | 
|     # ÐÂÅàÑøÊôÐÔ  | 
|     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))  | 
|       | 
|     # ÏÈ»º´æÖµ£¬Æï³Ë״̬ʱ½øÐи½¼Ó  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_SpeedHorse, horseSpeed)  | 
|       | 
|     # ¹ûʵ¶Ô×øÆïµÄ¼Ó³É, »êʯ¹ûʵË㸽¼ÓÊôÐԲ㣬µ¥¶À¼ÆËã  | 
|     fightPowerEx = PlayerAttrFruit.CalcAttrFruitAddAtrr(curPlayer, allAttrListHorseSoul, ShareDefine.Def_AttrFruitFunc_Horse)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_HorseSoul, fightPowerEx)  | 
|       | 
|     # ±£´æ¼ÆËãÖµ  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Horse, allAttrList, customAttrDict=customAttrDictHorse)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSoul, allAttrListHorseSoul)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin, allAttrListSkin, customAttrDict=customAttrDictSkin)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseTarin, allAttrListTrain)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseStar, allAttrListStar)  | 
|     return  | 
|   | 
| def GetHorseSkinActCount(curPlayer):  | 
|     horseSkinActCount = 0  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):  | 
|         skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)  | 
|         if not CheckHorseSkinState(curPlayer, skinPlusIpyData):  | 
|             continue  | 
|         horseSkinActCount += 1  | 
|     return horseSkinActCount  | 
|   | 
| #// A5 27 ×øÆïÌáÉý #tagCMHorseUp  | 
| #  | 
| #struct    tagCMHorseUp  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        UseItemCnt;        //ÏûºÄ²ÄÁϸöÊý  | 
| #    BYTE        IsAutoBuy;        //ÊÇ·ñ×Ô¶¯¹ºÂò  | 
| #};  | 
| def OnHorseClassLVUP(index, curPackData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     costItemCount = curPackData.UseItemCnt # ÏûºÄ²ÄÁϸöÊý  | 
|     isAutoBuy = curPackData.IsAutoBuy # ÊÇ·ñ×Ô¶¯¹ºÂò  | 
|       | 
|     # ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÒÔÉý¼¶ÂíÆ¥  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         GameWorld.DebugLog("×øÆï먦Æô!")  | 
|         return  | 
|       | 
|     horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)  | 
|     curEatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserEatItemCount)  | 
|     if horseLV <= 0:  | 
|         GameWorld.DebugLog("×øÆïÌáÉý ¸Ã×øÆïδ¼¤»î horseLV=%s" % horseLV)  | 
|         return  | 
|       | 
|     horseIpyData = IpyGameDataPY.GetIpyGameData("HorseLVUp", horseLV)  | 
|     if not horseIpyData:  | 
|         return  | 
|       | 
|     needEatCount = horseIpyData.GetNeedEatCount()  | 
|     if not needEatCount:  | 
|         GameWorld.DebugLog("×øÆïÒÑÂú¼¶£¡horseLV=%s" % horseLV)  | 
|         return  | 
|       | 
|     costItemID = IpyGameDataPY.GetFuncCfg("HorseUpItem", 1)  | 
|     if not costItemID or not costItemCount:  | 
|         return  | 
|       | 
|     costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)  | 
|     lackCnt = costItemCount - bindCnt - unBindCnt  | 
|     if lackCnt > 0 and not isAutoBuy:  | 
|         GameWorld.DebugLog("ÏûºÄµÀ¾ß²»×㣬ÎÞ·¨Éý¼¶×øÆï!costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s"   | 
|                            % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))  | 
|         return  | 
|       | 
|     delCnt = costItemCount  | 
|     if lackCnt > 0:  | 
|         lackCost = ItemCommon.GetAutoBuyItemNeedGold({costItemID:lackCnt})  | 
|         if lackCost <= 0:  | 
|             return  | 
|         infoDict = {ChConfig.Def_Cost_Reason_SonKey:costItemID}  | 
|         if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, lackCost, ChConfig.Def_Cost_BuyStoreItem, infoDict):  | 
|             return  | 
|         delCnt -= lackCnt  | 
|           | 
|     # ¿Û³ýÏûºÄ  | 
|     if delCnt:  | 
|         ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, ChConfig.ItemDel_Horse)  | 
|           | 
|     updClassLV = horseLV  | 
|     updEatItemCount = curEatItemCount + costItemCount  | 
|     GameWorld.DebugLog("×øÆïÅàÑø: horseLV=%s,curEatItemCount=%s,costItemCount=%s,updEatItemCount=%s,needEatCount=%s"   | 
|                        % (horseLV, curEatItemCount, costItemCount, updEatItemCount, needEatCount))  | 
|       | 
|     if updEatItemCount >= needEatCount:  | 
|         updClassLV += 1  | 
|         updEatItemCount -= needEatCount  | 
|         GameWorld.DebugLog("    Éý½×: updClassLV=%s,updEatItemCount=%s" % (updClassLV, updEatItemCount))  | 
|           | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserLV, updClassLV)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserEatItemCount, updEatItemCount)  | 
|       | 
|     # Éý½×  | 
|     EventShell.EventRespons_HorseUp(curPlayer) # ¸ÄΪʹÓþÍËã  | 
|     if updClassLV > horseLV:  | 
|         EventShell.EventRespons_HorseLV(curPlayer, updClassLV)  | 
|         # Íæ¼ÒÂíÆ¥½ø½×  | 
|         DataRecordPack.DR_NewHorseByClassUp(curPlayer, updClassLV, 0)  | 
|         # ¼Ç¼¿ª·þ»î¶¯ÂíÆ¥½×¼¶  | 
|         #OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_Horse, updClassLV)  | 
|         PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_HorseAllLV, updClassLV)  | 
|           | 
|     Sync_HorseClassData(curPlayer)  | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshHorseAttr(curPlayer)  | 
|       | 
|     PlayerActHorsePetTrain.OnHorsePetTrainCost(curPlayer, {costItemID:costItemCount})  | 
|     PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_HorseUpItem, costItemCount)  | 
|     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 = PlayerControl.GetTrainRealmLVReal(curPlayer, 1)  | 
|     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)  | 
|       | 
|     PlayerActHorsePetTrain.OnHorsePetTrainCost(curPlayer, {costItemID:costItemCount})  | 
|     if trainType == 2:  | 
|         PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_HorseTrainItem2, costItemCount)  | 
|     elif trainType == 3:  | 
|         PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_HorseTrainItem3, costItemCount)  | 
|     return  | 
|   | 
| #// A5 35 ×øÆïÉýÐÇ #tagCMHorseStarUp  | 
| #  | 
| #struct    tagCMHorseStarUp  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        HorseID;        //×øÆïID£¬¶ÔӦ׸Æï±íID  | 
| #};  | 
| def OnHorseStarUp(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     horseID = clientData.HorseID  | 
|       | 
|     horseStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserStar % horseID)          | 
|     nextStar = horseStar + 1  | 
|     nextIpyData = IpyGameDataPY.GetIpyGameData("HorseStarUp", horseID, nextStar)  | 
|     if not nextIpyData:  | 
|         GameWorld.DebugLog("×øÆï²»´æÔÚ¸ÃÐǼ¶£¬ÎÞ·¨ÉýÐÇ. horseID=%s,curStar=%s" % (horseID, horseStar), playerID)  | 
|         return  | 
|     needItemList = nextIpyData.GetStarUpNeedItemList()  | 
|     if not needItemList:  | 
|         return  | 
|     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|     lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack)  | 
|     if lackItemDict:  | 
|         GameWorld.DebugLog("×øÆïÉýÐÇËùÐèÎïÆ·²»×㣡 horseID=%s,nextStar=%s,needItemList=%s,lackItemDict=%s"   | 
|                            % (horseID, nextStar, needItemList, lackItemDict), playerID)  | 
|         return  | 
|       | 
|     ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "HorseStarUp")  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserStar % horseID, nextStar)  | 
|       | 
|     GameWorld.DebugLog("×øÆïÉýÐÇ. horseID=%s,curStar=%s,nextStar=%s" % (horseID, horseStar, nextStar), playerID)  | 
|       | 
|     RefreshHorseAttr(curPlayer)  | 
|     SyncHorseStarInfo(curPlayer, horseID)  | 
|     return  | 
|   | 
| def GetHorseTrainTypes():  | 
|     return len(IpyGameDataPY.GetFuncEvalCfg("HorseTrain", 1))  | 
|   | 
| def PlayerHorseLogin(curPlayer):  | 
|     ##×øÆïµÇ¼´¦Àí  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         return  | 
|       | 
|     # ×øÆï»Ã»¯×´Ì¬¶àÖµÖ§³ÖÐ޸ģ¬ÏßÉϰ汾×ö¾ÉÖµ×ªÒÆ  | 
|     oldVerSkinStateKey = "HorserSkinPlusState"  | 
|     oldVerSkinStateValue = curPlayer.NomalDictGetProperty(oldVerSkinStateKey)  | 
|     if oldVerSkinStateValue:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState % 0, oldVerSkinStateValue)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, oldVerSkinStateKey, 0)  | 
|         GameWorld.Log("ÏßÉÏ°æ±¾×ªÒÆ×øÆï»Ã»¯×´Ì¬¼Ç¼×ÖµäÖµ! oldVerSkinStateValue=%s" % (oldVerSkinStateValue), curPlayer.GetPlayerID())  | 
|           | 
|     # ÅàÑøÊǺóÃæ¼ÓµÄ¹¦ÄÜ£¬Ã¿´ÎµÇ¼²¹¼ì²éһϹ¦ÄÜ¿ªÊ¼Ê±ÉèÖÃΪÅàÑø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)  | 
|     SyncHorseSkinTimeInfo(curPlayer)  | 
|     SyncHorseStarInfo(curPlayer)  | 
|     return  | 
|   | 
| def Sync_HorseClassData(curPlayer):  | 
|     horseData = ChPyNetSendPack.tagTrainHorseData()  | 
|     horseData.Clear()  | 
|     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)  | 
|     horseData.SkinPlusStateList = GetHorseSkinPlusStateList(curPlayer)  | 
|     horseData.SkinPlusStateCount = len(horseData.SkinPlusStateList)  | 
|     NetPackCommon.SendFakePack(curPlayer, horseData)  | 
|     return  | 
|   | 
| def GetHorseSkinPlusStateList(curPlayer):  | 
|     maxSkinID = 0  | 
|     skinPlusStateList = []  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     skinCnt = ipyDataMgr.GetHorseSkinPlusCount()  | 
|     for index in xrange(skinCnt):  | 
|         maxSkinID = max(maxSkinID, ipyDataMgr.GetHorseSkinPlusByIndex(index).GetID())  | 
|     for index in xrange(maxSkinID / 31+1):  | 
|         skinPlusStateList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinPlusState % index))  | 
|     return skinPlusStateList  | 
|   | 
| def GetHorseSumLV(curPlayer):  | 
|     ## ×øÆï×ܵȼ¶  | 
|     return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)  | 
|   | 
| #============================Æï³è¾õÐÑ=============================  | 
| #// 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  | 
|     GameWorld.DebugLog("Æï³è¾õÐÑ: skintype=%s,horsePetID=%s,eatItemID=%s" % (skintype, horsePetID, eatItemID))  | 
|     if not IpyGameDataPY.GetIpyGameDataByCondition('HorsePetSkin', {'Type':skintype, 'ID':horsePetID}):  | 
|         return  | 
| #    if skintype == 1:  | 
| #        #×øÆïÍæ·¨Ð޸ģ¬ÔݹرÕ×øÆï¾õÐÑ  | 
| #        return  | 
| #        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(4)  | 
|     curEffID = curEff.GetEffectID()  | 
|     addExp = curEff.GetEffectValue(0)  | 
|     if curEffID != ChConfig.Def_Effect_HorsePetSkinExp or not addExp:  | 
|         GameWorld.ErrLog('ÎïÆ·Ð§¹û5ûÓÐÅäÖÃÆï³è¾õÐѾÑéЧ¹û! eatItemID=%s,curEffID=%s,addExp=%s,needEffID=%s'   | 
|                          % (eatItemID, curEffID, addExp, ChConfig.Def_Effect_HorsePetSkinExp))  | 
|         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)  | 
|     GameWorld.DebugLog("skinData=%s,curExp=%s,updSkinData=%s,updExp=%s" % (skinData, curExp, updSkinData, updExp))  | 
|     if curSkinIndex != updSkinIndex:  | 
|         __DoHorsePetSkinChange(curPlayer, skintype, horsePetID, updSkinIndex)  | 
|     if updSkinLV != curSkinLV:  | 
|         if skintype == 1:  | 
|             RefreshHorseAttr(curPlayer)  | 
|         else:  | 
|             PlayerPet.RefreshPetItemAddAttr(curPlayer, True)  | 
|           | 
|     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:#×øÆï  | 
|         # ×øÆï¹¦ÄÜÐ޸ģ¬ÔݹرվõÐÑ  | 
|         return  | 
|         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  | 
|   | 
| def SyncHorseSkinTimeInfo(curPlayer, skinID=None):  | 
|     skinList = []  | 
|     if skinID > 0:  | 
|         timeInfo = ChPyNetSendPack.tagMCHorseSkinTimeInfo()  | 
|         timeInfo.ID = skinID  | 
|         timeInfo.InvalidTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinEndTime % skinID)  | 
|         skinList.append(timeInfo)  | 
|     else:  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):  | 
|             skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)  | 
|             skinID = skinPlusIpyData.GetID()  | 
|             if not skinPlusIpyData.GetSkinValidTime():  | 
|                 continue  | 
|             timeInfo = ChPyNetSendPack.tagMCHorseSkinTimeInfo()  | 
|             timeInfo.ID = skinID  | 
|             timeInfo.InvalidTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinEndTime % skinID)  | 
|             skinList.append(timeInfo)  | 
|               | 
|     packData = ChPyNetSendPack.tagMCHorseSkinTimeInfoList()  | 
|     packData.Clear()  | 
|     packData.TimeInfoList = skinList  | 
|     packData.TimeCnt = len(packData.TimeInfoList)  | 
|     NetPackCommon.SendFakePack(curPlayer, packData)  | 
|     return  | 
|   | 
| def SyncHorseStarInfo(curPlayer, horseID=None):  | 
|     if horseID > 0:  | 
|         syncIDList = [horseID]  | 
|     else:  | 
|         syncIDList = []  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for index in range(ipyDataMgr.GetHorseCount()):  | 
|             ipyData = ipyDataMgr.GetHorseByIndex(index)  | 
|             syncIDList.append(ipyData.GetHorseID())  | 
|               | 
|     if not syncIDList:  | 
|         return  | 
|       | 
|     horseStarList = []  | 
|     for horseID in syncIDList:  | 
|         horseStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserStar % horseID)  | 
|         if not horseStar:  | 
|             continue  | 
|         starInfo = ChPyNetSendPack.tagMCHorseStar()  | 
|         starInfo.Clear()  | 
|         starInfo.HorseID = horseID  | 
|         starInfo.Star = horseStar  | 
|         horseStarList.append(starInfo)  | 
|           | 
|     if not horseStarList:  | 
|         return  | 
|       | 
|     clientPack = ChPyNetSendPack.tagMCHorseStarInfo()  | 
|     clientPack.Clear()  | 
|     clientPack.HorseStarList = horseStarList  | 
|     clientPack.Count = len(clientPack.HorseStarList)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  |