| #!/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 PlayerPet  | 
|   | 
|   | 
| 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()  | 
|           | 
|     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  | 
|       | 
|     activateState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinPlusState)  | 
|     if activateState & pow(2, activateID):  | 
|         GameWorld.DebugLog("¸Ã×øÆïÒѻû¯!activateState=%s,activateID=%s" % (activateState, activateID))  | 
|         return  | 
|       | 
|     ipyData = IpyGameDataPY.GetIpyGameData("HorseSkinPlus", activateID)  | 
|     if not ipyData:  | 
|         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)  | 
|       | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, activateState|pow(2, activateID))  | 
|       | 
|     playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  | 
|     itemRideHorse = playerEquip.GetAt(Def_HorseEquipIndex)  | 
|     #ÎÞÖ¸¶¨µÀ¾ß  | 
|     if itemRideHorse.IsEmpty():  | 
|         DoChangeHorse(curPlayer, 2, activateID, tick)  | 
|           | 
|     Sync_HorseClassData(curPlayer)  | 
|     GameWorld.Log("×øÆï¼¤»î³É¹¦£¡activateID=%s" % (activateID), 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:  | 
|         activateState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinPlusState)  | 
|         if not activateState & pow(2, lvID):  | 
|             GameWorld.DebugLog("×øÆï»Ã»¯Î´¼¤»î£¬ÎÞ·¨Ê¹ÓøÃ×øÆïƤ·ô!  activateState=%s,lvID=%s" % (activateState, lvID))  | 
|             return  | 
|           | 
|         skinPlusIpyData = IpyGameDataPY.GetIpyGameData("HorseSkinPlus", lvID)  | 
|         if not 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 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)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorserSkinPlusState, 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)]  | 
|       | 
|     horseSpeed = 0 # ×øÆï¹¦ÄÜÔö¼ÓµÄËÙ¶ÈÖµ£¬Æï³Ëʱ²ÅÓÐЧ¹û  | 
|     horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserLV)  | 
|     # µÈ½×ÅàÑøÊôÐÔ  | 
|     totalItemCount = 0  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in xrange(ipyDataMgr.GetHorseLVUpCount()):  | 
|         horseIpyData = ipyDataMgr.GetHorseLVUpByIndex(index)  | 
|         dataHorseLV = horseIpyData.GetHorseLV()  | 
|         if dataHorseLV > horseLV:  | 
|             break  | 
|         elif dataHorseLV == horseLV:  | 
|             totalItemCount += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserEatItemCount)  | 
|         else:  | 
|             totalItemCount += 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)  | 
|               | 
|     # µÈ½×ÅàÑøµ¤ÀÛ¼Ó¸öÊýÊôÐÔ  | 
|     eatItemAttrInfo = IpyGameDataPY.GetFuncCfg("HorseUpItem", 3)  | 
|     for attrID, attrValue in eatItemAttrInfo:  | 
|         PlayerControl.CalcAttrDict_Type(attrID, attrValue * totalItemCount, allAttrList)  | 
|           | 
|     # »Ã»¯ÊôÐÔ  | 
|     initFPAdd = 0 #³õʼսÁ¦  | 
|     activateState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorserSkinPlusState)  | 
|     for index in xrange(ipyDataMgr.GetHorseSkinPlusCount()):  | 
|         skinPlusIpyData = ipyDataMgr.GetHorseSkinPlusByIndex(index)  | 
|         skinPlusID = skinPlusIpyData.GetID()  | 
|         if not activateState & pow(2, skinPlusID):  | 
|             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)  | 
|               | 
|     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)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSoul, allAttrListHorseSoul)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkin, allAttrListSkin)  | 
|     return  | 
|   | 
| #// 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)  | 
|       | 
|     # Éý½×  | 
|     if updClassLV > horseLV:  | 
|         EventShell.EventRespons_HorseLV(curPlayer, updClassLV)  | 
|         EventShell.EventRespons_HorseUp(curPlayer)  | 
|         # Íæ¼ÒÂíÆ¥½ø½×  | 
|         DataRecordPack.DR_NewHorseByClassUp(curPlayer, updClassLV, 0)  | 
|         # ¼Ç¼¿ª·þ»î¶¯ÂíÆ¥½×¼¶  | 
|         #OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_Horse, updClassLV)  | 
|           | 
|     Sync_HorseClassData(curPlayer)  | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshHorseAttr(curPlayer)  | 
|     return  | 
|   | 
| def PlayerHorseLogin(curPlayer):  | 
|     ##×øÆïµÇ¼´¦Àí  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         return  | 
|       | 
|     Sync_HorseClassData(curPlayer)  | 
|     SyncHorsePetSkinData(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)  | 
|     NetPackCommon.SendFakePack(curPlayer, horseData)  | 
|     return  | 
|   | 
| 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  | 
|     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()  | 
|     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)  | 
|     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  | 
|   | 
|           |