| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
|   | 
| ##@package PlayerHorse  | 
| # ÆïÂíʼþÂß¼´¦Àí  | 
| #  | 
| # @author eggxp  | 
| # @date 2010-4-28  | 
| # @version 6.4  | 
| #  | 
| # Ä£¿éÏêϸ˵Ã÷  | 
| # ÐÞ¸Äʱ¼ä ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ  | 
| # @change: "2016-11-29 15:30" hxp ¼¼ÄÜÕ½Á¦ËãÔÚ¹¦ÄÜÉÏ  | 
| # @change: "2017-08-11 21:30" xdh ÊÖÓΰæ×øÆï  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2017-08-11 21: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 PlayerSuccess  | 
| import SkillShell  | 
| import SkillCommon  | 
| import PlayerMagicWeapon  | 
| import PassiveBuffEffMng  | 
| #---------------------------------------------------------------------  | 
|   | 
| #---------------------------------------------------------------------  | 
| #===============================================================================  | 
| # #Íæ¼ÒÆïÂí, Òª:  | 
| # #1.ÉèÖÃÍæ¼ÒΪÆï³Ë״̬,   | 
| #   | 
| # #Íæ¼ÒÏÂÂí, Òª:  | 
| # #1.ÉèÖÃΪ¿ÕÏÐ״̬    | 
| #===============================================================================  | 
|   | 
| ############################################  | 
|     #Èç¹ûÍæ¼ÒÒªÉÏÂí:  | 
|     #1. Èç¹ûÍæ¼Ò²»ÔÚ¿ÕÏÐ״̬, ·µ»Ø  | 
|     #2. Èç¹ûÍæ¼ÒûÓÐ×°±¸ÂíÆ¥, ·µ»Ø  | 
|     #3. Éè¶¨Íæ¼Ò½øÈë×¼±¸×´Ì¬(ÀàËÆÓÚÍÚ±¦×¼±¸)  | 
|     #4. ×¼±¸×´Ì¬½áÊøºó, µ÷ÓÃÕâ¸öÄ£¿éµÄDoPlayerRideHorseº¯Êý, Ë¢ÐÂËùÓÐ״̬  | 
| ############################################  | 
|   | 
| ################################################  | 
| #×¢Òâ1:  | 
| #Íæ¼ÒÔÚË¢ÐÂËùÓÐ״̬µÄʱºò:  | 
| #Èç¹ûÍæ¼ÒÓÐ×°±¸ÂíÆ¥, µ«ÊÇûÓÐÆïÂí, ²»Ë¢ÐÂÂíÆ¥×°±¸²úÉúµÄbuff  | 
| #×¢Òâ2:  | 
| #Íæ¼ÒÒÆ¶¯µÄʱºò, Èç¹ûÍæ¼ÒÓÐÂíÆ¥ , ÔòÔÊÐíÍæ¼ÒÒÆ¶¯  | 
| ################################################  | 
|   | 
| ## Íæ¼ÒÆïÂí½Å±¾(·â°ü²ÎÊý)  | 
| #  @param index Íæ¼ÒË÷Òý  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def OnRideHorse(index, tick):  | 
|     GameWorld.GetPsycoFunc(__Func_OnRideHorse)(index, tick)  | 
|     return  | 
|   | 
| ## Íæ¼ÒÆïÂí½Å±¾(·â°ü²ÎÊý)  | 
| #  @param index Íæ¼ÒË÷Òý  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def __Func_OnRideHorse(index, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|       | 
|     # ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÒÔÉý¼¶ÂíÆ¥  | 
|     if not CheckCanTrainHorse(curPlayer):  | 
|         return  | 
|       | 
|     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 not OperControlManager.IsObjCanDoAction(curPlayer,  | 
|                                                ChConfig.Def_Obj_ActState_ClientAct,  | 
|                                                IPY_GameWorld.oalRide):  | 
|         return    | 
|       | 
|     #ÏÂÂí  | 
|     if curPlayerRideType == 0 :  | 
|         #ÊÇ·ñ¿ÉÒÔÏÂÂí  | 
|         if CheckPlayerRideHorseDown(curPlayer) != True :  | 
|             return  | 
|         PlayerRideHorseDown(curPlayer, True)  | 
|           | 
|     #ÆïÂí     | 
|     elif curPlayerRideType == 1:  | 
|         #ÊÇ·ñ¿ÉÒÔÆïÂí  | 
|         #if curPlayer.GetPlayerAction() not in [IPY_GameWorld.paNull, IPY_GameWorld.paAttack]:  | 
|             #CanNotRideHoreWrongState ¶Ô²»Æð,ÄúµÄµ±Ç°×´Ì¬,ÎÞ·¨ÉÏÂí  | 
|         #    PlayerControl.NotifyCode(curPlayer, "CanNotRideHoreWrongState")  | 
|         #    return  | 
|           | 
|         #ÒÆ¶¯Öв»Ö´Ðд˲Ù×÷  | 
|           | 
|         if not CheckPlayerRideHorseUp(curPlayer):  | 
|             return  | 
|           | 
|         PlayerRideHorseUp(curPlayer, True)  | 
|         #´Ë´¦²»¼ÓPlayerRideHorseUp, µÈ´ýPlayerStateµ÷ÓàPlayerRideHorseUp  | 
|         #PlayerControl.Sync_PrepareBegin(curPlayer, ChConfig.Def_RidehorseTime, IPY_GameWorld.pstHorse)  | 
|       | 
|     #if curPlayer.IsMoving():  | 
|     #    curPlayer.Move(curPlayer.GetDestPosX(), curPlayer.GetDestPosY())      | 
|     return  | 
|   | 
| #---------------------ÏÂÂíÂß¼  | 
|   | 
| ## ÊÇ·ñ¿ÉÒÔÏÂÂí   | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None or True  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayerRideHorseDown(curPlayer) :  | 
|     if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvHorse :  | 
|         #GameWorld.Log("²»ÔÚÆïÂí״̬,ÎÞ·¨ÏÂÂí")  | 
|         return  | 
|       | 
|     #GameWorld.Log("Íæ¼ÒÏÂÂí" , curPlayer.GetPlayerID())  | 
|     return True  | 
|   | 
| ## Íæ¼ÒÏÂÂí  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param refreshState: ÊÇ·ñÐèҪˢÐÂ״̬   | 
| #  @return None   | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def PlayerRideHorseDown(curPlayer, refreshState=True) :  | 
|     #ÉèÖÃÍæ¼ÒÎÞ½»Í¨¹¤¾ß  | 
|     curPlayer.SetPlayerVehicle(IPY_GameWorld.pvNull)  | 
|     curPlayer.Sync_GetoffHorse()  | 
|       | 
|     playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|     playerControl.RefreshPlayerAttrByBuff()  | 
|     return  | 
|   | 
| #----------------------ÉÏÂíÂß¼  | 
|   | 
| ## ÊÇ·ñ¿ÉÒÔÉÏÂí   | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None or True   | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayerRideHorseUp(curPlayer):  | 
|     # Î´¼ÓÔØ³É¹¦Æï³Ë»áµ¼ÖÂÄ£ÐͼÓÔØÊ§°Ü±¨´í  | 
|     if not curPlayer.GetInitOK():  | 
|         return False  | 
|                       | 
|     #µØÍ¼²»ÔÊÐíÆïÂí RideLimit_lhs_0  | 
|     if not GameWorld.GetMap().GetMapCanRide():  | 
|         PlayerControl.NotifyCode(curPlayer, "RideLimit_lhs_0")  | 
|         return False  | 
|       | 
|     #¼ì²éÍæ¼Ò״̬,Ö»ÓÐÔÚ¿ÕÏÐ״̬²ÅÄÜÉÏÂí  | 
|     if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvNull :  | 
|         #GameWorld.Log("ÒѾÓн»Í¨¹¤¾ß,ÎÞ·¨ÉÏÂí")  | 
|         return False  | 
|       | 
|     #¼ì²éÊÇ·ñ×°±¸Ö¸¶¨IDÎïÆ·  | 
|     playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  | 
|     itemRideHorse = playerEquip.GetAt(ShareDefine.retHorse)  | 
|     #ÎÞÖ¸¶¨µÀ¾ß  | 
|     if itemRideHorse.IsEmpty():  | 
|         #PlayerControl.NotifyCode(curPlayer, "NotPrepareSteed")  | 
|         return False  | 
|   | 
|       | 
|     #ÎÞÄ;ÃÒ²ÄÜÉÏÂí  | 
| #===============================================================================  | 
| #    #ÎÞÄ;Ã,ÎÞ·¨¼¤»î  | 
| #    if itemRideHorse.GetCurDurg() <= 0 :  | 
| #        GameWorld.Log("×°±¸µÄÂíÆ¥Ä;ÃΪ0,ÎÞ·¨ÉÏÂí")  | 
| #        return  | 
| #===============================================================================  | 
|       | 
|     #GameWorld.Log("Íæ¼ÒÉÏÂí" , curPlayer.GetPlayerID())  | 
|     return True   | 
|   | 
| ## Íæ¼ÒÉÏÂí   | 
| #  @param curPlayer: µ±Ç°Íæ¼Ò  | 
| #  @param refreshState: ÊÇ·ñÐèҪˢÐÂ״̬   | 
| #  @return ÉÏÂíÊÇ·ñ³É¹¦  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def PlayerRideHorseUp(curPlayer, refreshState=True, isNotify=True) :  | 
|   | 
|     if not CheckPlayerRideHorseUp(curPlayer):  | 
|         GameWorld.Log("Can not Ride Horse")  | 
|         return False  | 
|   | 
|     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  | 
|       | 
| ## ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÒÔÉý¼¶ÂíÆ¥  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @return ÎÞÒâÒå  | 
| def CheckCanTrainHorse(curPlayer):  | 
|       | 
|     if curPlayer.GetHP() <= 0 or curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  | 
|         return False  | 
|       | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         #¶ÔÓ¦µÄÈÎÎñÏÞÖÆÎ´Íê³É  | 
|         return False  | 
|       | 
|     return True  | 
|           | 
|   | 
| ## Í¨Öª¿Í»§¶Ë£¬ÅàÑøÇé¿ö  | 
| #  @param curPlayer  | 
| #  @return ÎÞÒâÒå  | 
| def Sync_HorseTrainData(curPlayer):  | 
|     Sync_HorseClassData(curPlayer)  | 
|     return  | 
|   | 
| #=====================================================================  | 
| #//A5 02 ×øÆïÑ¡Ôñ #tagPlayerChooseHorse  | 
| #  | 
| #struct    tagPlayerChooseHorse  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        Index;        //Ñ¡ÔñË÷Òý  | 
| #};  | 
| #=====================================================================  | 
| ## Íæ¼Ò¸ü»»ÂíÆ¥  | 
| #  @param index Íæ¼ÒË÷Òý  | 
| #  @param packData ·â°üÊý¾Ý  | 
| #  @param tick Ê±¼ä´Á  | 
| #  @return ÎÞÒâÒå  | 
| def OnPlayerChangeHorse(index, packData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|   | 
|     #¼ì²é»»×°¼ä¸ô  | 
|     if tick - curPlayer.GetLastChangeEquipTick() <= ChConfig.Def_MinChangeEquipTime:  | 
|         return  | 
|       | 
|     curPlayer.SetLastChangeEquipTick(tick)  | 
|       | 
|     # ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÒÔÉý¼¶ÂíÆ¥  | 
|     if not CheckCanTrainHorse(curPlayer):  | 
|         return  | 
|   | 
|     horseIndex = packData.Index  | 
|       | 
|     DoChangeHorse(curPlayer, horseIndex, tick)  | 
|     return  | 
|   | 
|   | 
| def DoChangeHorse(curPlayer, horseIndex, tick):  | 
|     ipyData = IpyGameDataPY.GetIpyGameData("Horse", horseIndex)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     horseItemID = ipyData.GetItemID()  | 
|       | 
|     if not horseItemID:  | 
|         GameWorld.DebugLog("ÕÒ²»µ½Ñ¡ÔñµÄ×øÆïID horseIndex=%s" % (horseIndex))  | 
|         return  | 
|     horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseIndex, 0, ChConfig.Def_PDictType_Horse)  | 
|     if horseLV < ipyData.GetUseNeedRank():  | 
|         GameWorld.DebugLog("%s½××øÆï²ÅÄÜÇл»Íâ¹Û  curLv=%s, horseIndex=%s" % (ipyData.GetUseNeedRank(), horseLV, horseIndex))  | 
|         return  | 
|       | 
|     if ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, IPY_GameWorld.rptEquip):  | 
|         GameWorld.DebugLog("OnPlayerChangeHorse() had equipped horse(%s)" % horseItemID)  | 
|         return  | 
|       | 
|     isOK = ItemControler.PutItemInTempSwap(curPlayer, horseItemID)  | 
|     if not isOK:  | 
|         GameWorld.DebugLog("OnPlayerChangeHorse() horse(%s) put in pack(%s) fail" \  | 
|                            % (horseItemID, ShareDefine.rptTempSwap))  | 
|         return  | 
|       | 
|     curHorse = ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, ShareDefine.rptTempSwap)  | 
|     if not curHorse:  | 
|         GameWorld.DebugLog("OnPlayerChangeHorse() pack(%s) no horse(%s) item" \  | 
|                            % (ShareDefine.rptTempSwap, horseItemID))  | 
|         return  | 
|       | 
|     #¼ì²éÍæ¼Ò״̬ÊÇ·ñ¿ÉÒÔ»»×°  | 
|     if not ChEquip.CheckPlayerCanEquipItem(curPlayer):  | 
|         return  | 
|       | 
|     isRideHorse = curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse  | 
|       | 
|     # Èç¹ûÆï³Ë״̬£¬ÏÈÏÂÂí£¬»»×°£¬ÔÙÉÏÂí  | 
|     if isRideHorse:  | 
|         PlayerRideHorseDown(curPlayer, False)  | 
|       | 
|     #---Ö´ÐÐÍæ¼Ò»»×°Âß¼---  | 
|     if ChEquip.DoPlayerEquipItem(curPlayer, curHorse, ShareDefine.retHorse, tick):  | 
|         if isRideHorse:  | 
|             PlayerRideHorseUp(curPlayer, False)  | 
|         return  | 
|       | 
|     return  | 
|   | 
| ## ÂíÆ¥¹¦ÄÜ¿ªÆô  | 
| def DoHorseOpen(curPlayer):      | 
| #    maxStarLV, maxClassLV, horsesList, npcList = ReadChConfig.GetEvalChConfig("HorseTrainUpgrade")  | 
| #    horseID = horsesList[0]  | 
| #      | 
| #    if ItemCommon.FindItemInPackByItemID(curPlayer, horseID, IPY_GameWorld.rptEquip):  | 
| #        return  | 
| #      | 
| #    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, ShareDefine.retHorse, tick)  | 
| #      | 
| #    __HorseLearnSkill(curPlayer, 0)  | 
| #    # ¼ÆËãÊôÐÔ ·ÀÖ¹¸øµÚÒ»Ö»×øÆïºó,¿Í»§¶Ë×øÆïÕ½¶·Á¦Îª0  | 
| #    RefreshHorseAttr(curPlayer, False)  | 
| #      | 
| #    EventReport.WriteEvent_custom_mission_log(curPlayer, ChConfig.CME_Class_Horse, ChConfig.CME_Log_End, 1, cmeInfoEx="0")  | 
|     return True  | 
|   | 
| def RefreshHorseAttr(curPlayer, isCheckOpen=True, isUpdateBill=True):  | 
|     # ×øÆï¹¦ÄÜÊôÐÔ±ä¸üˢР | 
|     CalcHorseAttrEx(curPlayer, isCheckOpen)  | 
|     # ÐèÒª¸üÐÂ×øÆï°ñ¡¢Ç¿ÖÆË¢ÐÂÊôÐÔ  | 
|     PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState(billboardFunc=PlayerBillboard.UpdateHorseBillboard if isUpdateBill else None)  | 
|     return  | 
|   | 
| ################################################################################  | 
|   | 
|   | 
| ## ³É¾Í  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param srcBackpack ±³°üÀàÐÍ  | 
| #  @param packIndex ±³°üË÷Òý  | 
| #  @param skillPackIndex ¼¼ÄÜÊé±³°üË÷Òý  | 
| #  @return ÎïÆ·ÊµÀý  | 
| def __SetSuccess(curPlayer):  | 
|     #allLV = GetHorseSkillAllLV(curPlayer)  | 
|       | 
|     # ³É¾Í  | 
|     #PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_HorseSkillBookLV, allLV)  | 
|     return  | 
|   | 
| ## »ñÈ¡×øÆï¼¼Äܵȼ¶ÁÐ±í  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @return  | 
| def GetHorseSkillInfo(curPlayer):  | 
|     horseSkillIDList = GetHorseSkillList()  | 
|    | 
|     skillManager = curPlayer.GetSkillManager()  | 
|     skilllvList = []  | 
|     for skillresid in horseSkillIDList:  | 
|         Skill = skillManager.FindSkillBySkillTypeID(skillresid)  | 
|         #δѧϰ  | 
|         if Skill == None :  | 
|             skilllv = 0  | 
|         else:  | 
|             skilllv = Skill.GetSkillLV()  | 
|         skilllvList.append(skilllv)  | 
|           | 
|     return skilllvList  | 
|   | 
| ## »ñÈ¡×øÆï¼¼ÄÜID  | 
| def GetHorseSkillList():  | 
|     horseSkillIDList = []  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetHorseUpCount()):  | 
|         ipyData = ipyDataMgr.GetHorseUpByIndex(i)  | 
|         skillIDList = ipyData.GetSkillID()  | 
|         if not skillIDList:  | 
|             continue  | 
|         for skillID in skillIDList:  | 
|             horseSkillIDList.append(skillID)  | 
|     return horseSkillIDList  | 
|   | 
| ## ¼ì²éÊÇ·ñ¿ÉÒÔÑ§Ï°×øÆï¼¼ÄÜ  | 
| def CheckLearnHorseSkill(curPlayer, curSkillTypeID):  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetHorseUpCount()):  | 
|         ipyData = ipyDataMgr.GetHorseUpByIndex(i)  | 
|         skillIDList = ipyData.GetSkillID()  | 
|         if curSkillTypeID not in skillIDList:  | 
|             continue  | 
|         horseID = ipyData.GetHorseID()  | 
|         horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  | 
|         if horseLV < ipyData.GetLV():  | 
|             GameWorld.DebugLog('    ¸Ã×øÆï%s¼¶²Å½âËø´Ë¼¼ÄÜ curSkillTypeID=%s'%(ipyData.GetLV(), curSkillTypeID))  | 
|             return False  | 
|         return True  | 
|     #²»ÊÇ×øÆï¼¼ÄÜ  | 
|     return True  | 
|           | 
|   | 
| ## ¼ÆËãÂíÆ¥ÊôÐÔ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param allAttrList ÊôÐÔÁÐ±í  | 
| #  @return None  | 
| def CalcHorseAttrEx(curPlayer, isCheckOpen=True):  | 
|     allAttrList = [{} for _ in range(4)]  | 
|     allAttrListHorseSoul = [{} for _ in range(4)]  | 
|     skillAttrList = [{} for _ in range(4)]  | 
|     # ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÒÔÉý¼¶ÂíÆ¥  | 
|     if isCheckOpen and not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         #¶ÔÓ¦µÄÈÎÎñÏÞÖÆÎ´Íê³É  | 
|         return  | 
|     maxSpeed = 0 #×øÆï×î´óÒÆ¶¯ËÙ¶È  | 
|       | 
|     # ×øÆï¼¼ÄÜÌí¼ÓÊôÐÔ°Ù·Ö±ÈÔö¼ÓÔÚbuffÖÐÒÑתΪ¹Ì¶¨ÊôÐÔ£¬Ö»¶Ô½ø½×ÊôÐÔÓÐЧ²»º¬ Òƶ¯ËÙ¶È  | 
|     skillFPEx = __CalcHorseSkillAttr(curPlayer, skillAttrList)  | 
|     initFPAdd = 0 #³õʼսÁ¦  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetHorseCount()):  | 
|         ipyData = ipyDataMgr.GetHorseByIndex(i)  | 
|         horseID = ipyData.GetHorseID()  | 
|         horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  | 
|         if not horseLV:  | 
|             continue  | 
|         initFPAdd += ipyData.GetInitFightPower()  | 
|         horseUpData = IpyGameDataPY.GetIpyGameData("HorseUp", horseID, horseLV)  | 
|         if not horseUpData:  | 
|             continue  | 
|         attrTypeList = horseUpData.GetAttrType()  | 
|         attrValueList = horseUpData.GetAttrValue()  | 
|         for i, attrID in enumerate(attrTypeList):  | 
|             if attrID == ShareDefine.Def_Effect_Speed:  | 
|                 maxSpeed = max(maxSpeed, attrValueList[i])  | 
|                 continue  | 
|             PlayerControl.CalcAttrDict_Type(attrID, attrValueList[i], allAttrList)  | 
|       | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_Horse, skillFPEx+initFPAdd)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSkill, skillAttrList)  | 
|       | 
|     # ÏÈ»º´æÖµ£¬Æï³Ë״̬ʱ½øÐи½¼Ó  | 
|     GameWorld.DebugLog('×øÆïÈ¡×î´óÒÆ¶¯ËÙ¶È£¬maxSpeed=%s' % maxSpeed)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_SpeedHorse, maxSpeed)  | 
|       | 
|     # ¹ûʵ¶Ô×øÆïµÄ¼Ó³É, »êʯ¹ûʵË㸽¼ÓÊôÐԲ㣬µ¥¶À¼ÆËã  | 
|     PlayerAttrFruit.CalcAttrFruitAddAtrr(curPlayer, allAttrListHorseSoul, ShareDefine.Def_AttrFruitFunc_Horse)  | 
|   | 
|     #PlayerControl.CalcFuncPackItem(curPlayer, ShareDefine.Def_Pack_Type_HorseSkill, allAttrList)  | 
|       | 
|     # ±£´æ¼ÆËãÖµ  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Horse, allAttrList)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_HorseSoul, allAttrListHorseSoul)  | 
|     return  | 
|   | 
| def __CalcHorseSkillAttr(curPlayer, allAttrList):  | 
|     # ¼ÆËã¼¼ÄÜÊôÐÔ  | 
|     skillFPEx = 0  | 
|     skillManager = curPlayer.GetSkillManager()  | 
|     #GameWorld.DebugLog("1Ë¢×øÆï¼¼ÄÜÊôÐÔ: %s" % allAttrList)  | 
|     for i in range(0 , skillManager.GetSkillCount()):  | 
|         curSkill = skillManager.GetSkillByIndex(i)  | 
|         if not curSkill:  | 
|             continue  | 
|           | 
|         if curSkill.GetFuncType() != ChConfig.Def_SkillFuncType_HorseSkill:  | 
|             continue  | 
|           | 
|         if not SkillCommon.isPassiveAttr(curSkill):  | 
|             continue  | 
|           | 
|           | 
|         for effectIndex in xrange(curSkill.GetEffectCount()):  | 
|             curEffect = curSkill.GetEffect(effectIndex)  | 
|             SkillShell.CalcBuffEffAttr(curPlayer, curEffect, allAttrList)  | 
|               | 
|       | 
|     #GameWorld.DebugLog("2Ë¢×øÆï¼¼ÄÜÊôÐÔ: skillFPEx=%s, %s" % ( skillFPEx, allAttrList))  | 
|     return skillFPEx  | 
|   | 
| ## // A5 27 ×øÆïÌáÉý #tagCMHorseUp  | 
| ## ×øÆïÉý½×  | 
| #  @param curPlayer  | 
| #  @return None  | 
| def OnHorseClassLVUP(index, curPackData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     costItemCount = curPackData.UseItemCnt # ÏûºÄ²ÄÁϸöÊý  | 
|     isAutoBuy = curPackData.IsAutoBuy # ÊÇ·ñ×Ô¶¯¹ºÂò  | 
|     horseID = curPackData.HorseID  | 
|     # ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÒÔÉý¼¶ÂíÆ¥  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         #¶ÔÓ¦µÄÈÎÎñÏÞÖÆÎ´Íê³É  | 
|         GameWorld.DebugLog("HorseClassLVUP ×øÆï먦Æô¡£¡£¡£")  | 
|         return  | 
|     horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  | 
|     if horseLV <= 0:  | 
|         GameWorld.DebugLog("×øÆïÌáÉý ¸Ã×øÆïδ¼¤»î horseID=%s" % horseID)  | 
|         return  | 
|       | 
|     horseIpyData = IpyGameDataPY.GetIpyGameData("Horse", horseID)  | 
|     if not horseIpyData:  | 
|         return  | 
|       | 
|     maxLV = horseIpyData.GetMaxLV()  | 
|     if horseLV >= maxLV:  | 
|         GameWorld.DebugLog("HorseClassLVUP ¸Ã×øÆïÒÑÂú¼¶ horseID=%s" % horseID)  | 
|         return  | 
|       | 
|     horseUpIpyData = IpyGameDataPY.GetIpyGameData("HorseUp", horseID, horseLV)  | 
|     if not horseUpIpyData:  | 
|         return  | 
|     needExp = horseUpIpyData.GetNeedExp()  | 
|     if not needExp:  | 
|         return  | 
|     curExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_Exp % horseID,  | 
|                                                 0,  | 
|                                                 ChConfig.Def_PDictType_Horse)  | 
|       | 
|     curItemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|       | 
|     itemIndexList = []  | 
|     costItemIDList = IpyGameDataPY.GetFuncEvalCfg('HorseUpItem')  | 
|       | 
|     #¿Û²ÄÁÏ  | 
|     nowCnt = 0  | 
|     for itemID in costItemIDList:  | 
|         hasEnough, indexList, findItemIsBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(itemID, curItemPack, costItemCount - nowCnt)  | 
|           | 
|         itemIndexList.extend(indexList)  | 
|         if hasEnough:  | 
|             #×ã¹»Í˳ö  | 
|             break  | 
|           | 
|         if itemIndexList:  | 
|             nowCnt = 0  | 
|             for itemIndex in itemIndexList:  | 
|                 curItem = curItemPack.GetAt(itemIndex)  | 
|                   | 
|                 #¼ì²éÎïÆ·  | 
|                 if not ItemCommon.CheckItemCanUse(curItem):  | 
|                     continue  | 
|                   | 
|                 itemCnt = curItem.GetCount()  | 
|                 nowCnt += itemCnt  | 
|           | 
|     if not hasEnough and not isAutoBuy:  | 
|         GameWorld.DebugLog("HorseClassLVUP Éý½×µÀ¾ß²»×ã¡£¡£¡£")  | 
|         return  | 
|       | 
|     autoBuyItemID = costItemIDList[0]  | 
|     if itemIndexList:  | 
|         curItem = curItemPack.GetAt(itemIndexList[0])  | 
|     else:  | 
|         curItem = GameWorld.GetGameData().GetItemByTypeID(autoBuyItemID)  | 
|     if not curItem:  | 
|         return  | 
|       | 
|     if lackCnt > 0:  | 
|         if not isAutoBuy:  | 
|             return  | 
|         itemGold = ItemCommon.GetShopItemPrice(curItem.GetItemTypeID(), IPY_GameWorld.TYPE_Price_Gold_Money)  | 
|         #lackCost = ItemCommon.GetAutoBuyItemNeedGold({autoBuyItemID:lackCnt})  | 
|         if itemGold <= 0:  | 
|             return  | 
|         costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, itemGold*lackCnt)  | 
|         if not costMoneyList:  | 
|             return  | 
|         infoDict = {ChConfig.Def_Cost_Reason_SonKey:autoBuyItemID}  | 
|         for moneyType, moneyCnt in costMoneyList:  | 
|             if not PlayerControl.PayMoney(curPlayer, moneyType, moneyCnt,  | 
|                                           ChConfig.Def_Cost_BuyStoreItem, infoDict, lackCnt):  | 
|                 return  | 
|     lastMultiple = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_Multiple, 1, ChConfig.Def_PDictType_Horse)  | 
|     multiple = 1 if costItemCount == 1 else lastMultiple #±¾´Î±¶Êý (Ö»ÓÃ1¸ö²ÄÁϲ»Äܶ౶)  | 
|           | 
|     if multiple > 1:  | 
|         EventShell.EventRespons_HorseMultiple(curPlayer, multiple)  | 
|     playerName = curPlayer.GetName()  | 
| #    needSysHorseLVDict = IpyGameDataPY.GetFuncEvalCfg('NeedSysHorseLV')  | 
| #    needSysHorseLVList = needSysHorseLVDict.get(horseID, [])  | 
|     curEff = curItem.GetEffectByIndex(0)  | 
|     addExp = curEff.GetEffectValue(0) * costItemCount * multiple  | 
|     updExp = curExp + addExp  | 
|     updClassLV = horseLV  | 
|     for lv in range(horseLV, maxLV):  | 
|         ipyData = IpyGameDataPY.GetIpyGameData("HorseUp", horseID, lv)  | 
|         if not ipyData:  | 
|             break  | 
|         upNeedExp = ipyData.GetNeedExp()  | 
|         if updExp < upNeedExp:  | 
|             break  | 
|         updClassLV +=1  | 
|         upIpyData = IpyGameDataPY.GetIpyGameData("HorseUp", horseID, updClassLV)  | 
|         if not upIpyData:  | 
|             break  | 
|         updExp -= upNeedExp  | 
|           | 
|         #½âËø¼¼ÄÜ  | 
|           | 
|         skillIDList = upIpyData.GetSkillID()  | 
|         if skillIDList:  | 
|             sysMark = upIpyData.GetSysMark() or 'MountUpLv'  | 
|             for skillID in skillIDList:  | 
|                 __GiveSkill(curPlayer, skillID, tick)  | 
|                 PlayerControl.WorldNotify(0, sysMark, [playerName, horseID, updClassLV, skillID])  | 
|         if not skillIDList and updClassLV == maxLV:  | 
|             PlayerControl.WorldNotify(0, 'MountUpLvMax', [playerName, horseID])  | 
|           | 
|         #X×øÆïXµÈ¼¶³É¾Í  | 
|         PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_HorseAllLV, 1, [horseID, updClassLV])  | 
|           | 
|         EventShell.EventRespons_HorseLV(curPlayer, updClassLV)  | 
|         EventShell.EventRespons_HorseUp(curPlayer)  | 
|           | 
|     addLV = updClassLV - horseLV  | 
|     if addLV:  | 
|         __HorseClassLVUP(curPlayer, horseID, updClassLV)  | 
|     if updClassLV >= maxLV:  | 
|         updExp = 0  | 
|       | 
|   | 
|     #¿Û³ýÎïÆ·  | 
|     delCnt = max(0, costItemCount - lackCnt) # Êµ¼Ê¿Û³ýµÄ¸öÊý  | 
|     if itemIndexList:  | 
|         ItemCommon.ReduceItem(curPlayer, curItemPack, itemIndexList, delCnt, True, ChConfig.ItemDel_Horse)  | 
|     # ¸üоÑéÖµ  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_Exp % horseID, updExp, ChConfig.Def_PDictType_Horse)  | 
|     # Ï´α©»÷±¶Êý  | 
|     horseSuperRateDict = IpyGameDataPY.GetFuncEvalCfg('HorseSuperRate')  | 
|     keyNO = 0 #ĬÈÏ0  | 
|     rateDict = horseSuperRateDict.get(keyNO, {})  | 
|     rateList = rateDict.get(multiple, [])  | 
|     nextMultiple = GameWorld.GetResultByRandomList(rateList, 1)  | 
|     if costItemCount != 1 or nextMultiple > lastMultiple:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_Multiple, nextMultiple, ChConfig.Def_PDictType_Horse)  | 
|       | 
|     Sync_HorseClassData(curPlayer, horseID)  | 
|     # »îÔ¾¶È  | 
|     #PlayerActivity.AddActivityFinishCnt(curPlayer, ShareDefine.ActivityNum_HorseUP)  | 
|     #EventReport.WriteEvent_horse_class(curPlayer, horseLV, curExp, delCnt, updClassLV, updExp)  | 
|     return  | 
|   | 
|   | 
| ## ×øÆï½×¼¶ÌáÉý  | 
| #  @param curPlayer  | 
| #  @param horseID: ×øÆïid  | 
| #  @param updateClassLV: ¸üеĽ׼¶  | 
| #  @return None  | 
| def __HorseClassLVUP(curPlayer, horseID, updateClassLV):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_LV%horseID, updateClassLV, ChConfig.Def_PDictType_Horse)  | 
|     #EventReport.WriteEvent_custom_mission_log(curPlayer, ChConfig.CME_Class_Horse, ChConfig.CME_Log_End, 1, cmeInfoEx=str(updateClassLV))  | 
|     sumLV = GetHorseSumLV(curPlayer)  | 
|     PlayerMagicWeapon.SetMWPrivilegeData(curPlayer, ChConfig.MWPrivilege_Horse, sumLV)  | 
|   | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshHorseAttr(curPlayer)  | 
|     # Íæ¼ÒÂíÆ¥½ø½×  | 
|     DataRecordPack.DR_NewHorseByClassUp(curPlayer, updateClassLV, horseID)     | 
|       | 
|     # ¼Ç¼¿ª·þ»î¶¯ÂíÆ¥½×¼¶  | 
|     OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_HorseLV, sumLV)  | 
|     return  | 
|   | 
|   | 
| ## ¸ø¼¼ÄÜ  | 
| #  @param curPlayer  | 
| #  @param skillResID ¼¼ÄÜÔ´ID  | 
| #  @param tick Ê±¼ä´Á  | 
| #  @return None  | 
| def __GiveSkill(curPlayer, skillResID, tick):  | 
|       | 
|     skillData = GameWorld.GetGameData().FindSkillByType(skillResID, 1)  | 
|     if skillData == None:  | 
|         GameWorld.DebugLog("__GiveSkill() hasn't find skill(%s)" % skillResID)  | 
|         return  | 
|     if not SkillCommon.CheckSkillJob(curPlayer, skillData):  | 
|         return  | 
|     if not SkillShell.CheckLearnSkillCondition(curPlayer, skillData):  | 
|         GameWorld.DebugLog("__GiveSkill() learn skill(%s) condition isn't enough" % skillResID)  | 
|         return  | 
|     skillManager = curPlayer.GetSkillManager()  | 
|     if skillManager.FindSkillBySkillTypeID(skillResID):  | 
|         GameWorld.DebugLog("__GiveSkill() have learned skill(%s)" % skillResID)  | 
|         return  | 
|     GameWorld.DebugLog('     ¼¤»î×øÆï¼¼ÄÜ skillResID=%s' % (skillResID))  | 
|     skillManager.LVUpSkillBySkillTypeID(skillResID)  | 
|     #PlayerControl.NotifyCode(curPlayer, "GetSkillInfo", [skillResID])  | 
|     if not SkillCommon.isPassiveAttr(skillData):  | 
|         PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveEff(curPlayer, skillData.GetSkillID())  | 
|       | 
|     DataRecordPack.DR_LearnORUPSkill(curPlayer, skillResID, 0)  | 
|     PlayerControl.PlayerControl(curPlayer).RefreshSkillFightPowerEx(skillResID, 0)  | 
|     return  | 
|   | 
|   | 
| ##OnDayʱ´¦Àí  | 
| # @param curPlayer Íæ¼Ò  | 
| # @return None  | 
| def HorseOnDay(curPlayer):  | 
|     return  | 
|   | 
|   | 
| ##×øÆïµÇ¼´¦Àí  | 
| # @param curPlayer Íæ¼Ò  | 
| # @return None  | 
| def PlayerHorseLogin(curPlayer):  | 
|     Sync_HorseClassData(curPlayer)  | 
|     return  | 
|   | 
|   | 
| ## Í¨Öª¿Í»§¶Ë£¬ÅàÑøÇé¿ö  | 
| #  @param curPlayer  | 
| #  @return ÎÞÒâÒå  | 
| def Sync_HorseClassData(curPlayer, horseID= -1):  | 
|     horseData = ChPyNetSendPack.tagTrainHorseData()  | 
|     horseData.Clear()  | 
|       | 
|     horseData.InfoList = []  | 
|   | 
|     if horseID == -1:  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetHorseCount()):  | 
|             ipyData = ipyDataMgr.GetHorseByIndex(i)  | 
|             index = ipyData.GetHorseID()  | 
|             lv = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % index,  | 
|                                                        0, ChConfig.Def_PDictType_Horse)  | 
|             if not lv:  | 
|                 continue  | 
|             skinInfo = ChPyNetSendPack.tagMCHorseInfo()  | 
|             skinInfo.Clear()  | 
|             skinInfo.HorseID = index  | 
|             skinInfo.LV = lv  | 
|             skinInfo.Exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_Exp % index,  | 
|                                                        0, ChConfig.Def_PDictType_Horse)  | 
|             horseData.InfoList.append(skinInfo)  | 
|     else:  | 
|         skinInfo = ChPyNetSendPack.tagMCHorseInfo()  | 
|         skinInfo.Clear()  | 
|         skinInfo.HorseID = horseID  | 
|         skinInfo.LV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID,  | 
|                                                        0, ChConfig.Def_PDictType_Horse)  | 
|         skinInfo.Exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_Exp % horseID,  | 
|                                                        0, ChConfig.Def_PDictType_Horse)  | 
|         horseData.InfoList.append(skinInfo)  | 
|       | 
|     horseData.Num = len(horseData.InfoList)  | 
|     horseData.Multiple = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_Multiple, 1, ChConfig.Def_PDictType_Horse)  | 
|     NetPackCommon.SendFakePack(curPlayer, horseData)  | 
|     return  | 
|   | 
| #------------------------------------------------------------------------  | 
|   | 
| #//A5 01 ×øÆï¼¤»î #tagPlayerActivateHorse  | 
| #  | 
| #struct    tagPlayerActivateHorse  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        HorseID;        //×øÆïID  | 
| #};  | 
|   | 
| ## ¼¤»î×øÆï  | 
| #  @param curPlayer  | 
| #  @return None  | 
| def ActivateHorseSkinItem(index, curPackData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse):  | 
|         GameWorld.Log("×øÆï¹¦ÄÜ먦Æô£¬ÎÞ·¨¼¤»î×øÆï£¡", playerID)  | 
|         return False  | 
|     horseID = curPackData.HorseID  | 
|     ipyData = IpyGameDataPY.GetIpyGameData('Horse', horseID)  | 
|       | 
|     if not ipyData:  | 
|         GameWorld.ErrLog("×øÆï»Ã»¯ÎïÆ·Òì³££¬Î޸ûû¯ÎïÆ·ÐÅÏ¢£¡¼ì²étagHorse.txt! horseID=%s" % horseID, playerID)  | 
|         return False  | 
|       | 
|     horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID,  | 
|                                                        0, ChConfig.Def_PDictType_Horse)  | 
|     if horseLV > 0:  | 
|         GameWorld.DebugLog('¸Ã×øÆïÒѼ¤»î horseID=%s' % horseID)  | 
|         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("ActivateHorseSkinItem() item(%s[%s]) isn't enough" % (needItemID, needItemCnt))  | 
|         return  | 
|     ItemCommon.ReduceItem(curPlayer, itemPack, itemList, needItemCnt, False, ChConfig.ItemDel_Horse)  | 
|     #ÉèÖóõʼµÈ¼¶  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_LV % horseID, ipyData.GetInitLV(), ChConfig.Def_PDictType_Horse)  | 
|     for _ in xrange(ipyData.GetInitLV()):  | 
|         EventShell.EventRespons_HorseUp(curPlayer)  | 
|     # ¼Ç¼¿ª·þ»î¶¯ÂíÆ¥½×¼¶  | 
|     sumLV = GetHorseSumLV(curPlayer)  | 
|     OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_HorseLV, sumLV)  | 
|     PlayerMagicWeapon.SetMWPrivilegeData(curPlayer, ChConfig.MWPrivilege_Horse, sumLV)  | 
|     playerEquip = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)  | 
|     itemRideHorse = playerEquip.GetAt(ShareDefine.retHorse)  | 
|     #ÎÞÖ¸¶¨µÀ¾ß  | 
|     if itemRideHorse.IsEmpty():  | 
|         DoChangeHorse(curPlayer, horseID, tick)  | 
| #    curHorseSkin = None  | 
| #    horseItemID = ipyData.GetItemID()  | 
| #    isOK = ItemControler.PutItemInTempSwap(curPlayer, horseItemID)  | 
| #    if isOK:  | 
| #        curHorseSkin = ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, ShareDefine.rptTempSwap)  | 
| #    if curHorseSkin and not curHorseSkin.IsEmpty():  | 
| #        tick = GameWorld.GetGameWorld().GetTick()  | 
| #        PlayerRideHorseDown(curPlayer, False)  | 
| #        # Ö´ÐÐÍæ¼Ò»»×°Âß¼  | 
| #        if ChEquip.DoPlayerEquipItem(curPlayer, curHorseSkin, ShareDefine.retHorse, tick):  | 
| #            PlayerRideHorseUp(curPlayer, False)  | 
|            | 
|           | 
|     #GameWorld.DebugLog("¸ø»Ã»¯×øÆïÎïÆ·giveOK=%s" % giveOK)  | 
|    | 
|     Sync_HorseClassData(curPlayer, horseID)  | 
|     GameWorld.Log("×øÆï¼¤»î³É¹¦£¡horseID=%s" % (horseID), playerID)  | 
|   | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshHorseAttr(curPlayer)  | 
|     sysMark = ipyData.GetUnlockSys() or 'GetMount'  | 
|     PlayerControl.WorldNotify(0, sysMark, [curPlayer.GetName(), ipyData.GetItemID()])  | 
| #      | 
| #    HorseSkinNotifyDict = ReadChConfig.GetEvalChConfig("HorseSkinNotify")  | 
| #    if horseSkinID in HorseSkinNotifyDict:  | 
| #        notifyMark = HorseSkinNotifyDict[horseSkinID]  | 
| #        PlayerControl.WorldNotify(0, notifyMark, [curPlayer.GetPlayerName(), horseSkinID])  | 
|       | 
|     return True  | 
|   | 
| def DoHorseActivate(curPlayer, index, classLV, classExp=None):  | 
|     '''GMÃüÁî²âÊÔÓà  | 
|     @param index: µÚ¼¸Ö»×øÆï»ò×øÆïID  | 
|     '''  | 
|     ipyData = IpyGameDataPY.GetIpyGameDataNotLog('Horse', index)  | 
|     if not ipyData:  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         if index > ipyDataMgr.GetHorseCount() or index < 1:  | 
|             GameWorld.DebugAnswer(curPlayer, '²»´æÔÚ±¾Ö»×øÆï')  | 
|             return  | 
|         horseID = ipyDataMgr.GetHorseByIndex(index-1).GetHorseID()  | 
|         ipyData = IpyGameDataPY.GetIpyGameData('Horse', horseID)  | 
|         if not ipyData:  | 
|             return  | 
|     else:  | 
|         horseID = index  | 
|     maxLV = ipyData.GetMaxLV()  | 
|     classLV = min(classLV, maxLV)  | 
|     befClassLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  | 
|       | 
|     #ÉèÖóõʼµÈ¼¶  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_LV % horseID, classLV, ChConfig.Def_PDictType_Horse)  | 
|     if classExp != None and type(classExp) == int:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_Exp % horseID, classExp, ChConfig.Def_PDictType_Horse)  | 
|       | 
|     #´¦Àí¼¼ÄÜ  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     playerSkillManager = curPlayer.GetSkillManager()  | 
|     for lv in xrange(1, maxLV + 1):  | 
|         upIpyData = IpyGameDataPY.GetIpyGameData("HorseUp", horseID, lv)  | 
|         if not upIpyData:  | 
|             break  | 
|         skillIDList = upIpyData.GetSkillID()  | 
|         if not skillIDList:  | 
|             continue  | 
|           | 
|         if befClassLV >= lv and classLV < lv:  | 
|             for skillID in skillIDList:  | 
|                 playerSkillManager.DeleteSkillBySkillTypeID(skillID)  | 
|         elif befClassLV < lv and classLV >= lv:  | 
|             for skillID in skillIDList:  | 
|                 __GiveSkill(curPlayer, skillID, tick)  | 
|                   | 
|     pControl = PlayerControl.PlayerControl(curPlayer)  | 
|     pControl.RefreshAllSkill()  | 
|       | 
|     Sync_HorseClassData(curPlayer, horseID)  | 
|     GameWorld.Log("×øÆï¼¤»î³É¹¦£¡horseID=%s,befClassLV=%s,classLV=%s,classExp=%s"   | 
|                   % (horseID, befClassLV, classLV, classExp), curPlayer.GetPlayerID())  | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshHorseAttr(curPlayer)  | 
|     return  | 
|   | 
| # ×øÆï×ܵȼ¶  | 
| def GetHorseSumLV(curPlayer):  | 
|     sumLV = 0  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetHorseCount()):  | 
|         ipyData = ipyDataMgr.GetHorseByIndex(i)  | 
|         horseID = ipyData.GetHorseID()  | 
|         horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  | 
|         if not horseLV:  | 
|             continue  | 
|         sumLV += horseLV  | 
|           | 
|     return sumLV  | 
|   | 
| def GetHorseCurMaxLV(curPlayer):  | 
|     ##»ñÈ¡×øÆïµ±Ç°×î´óµÈ¼¶  | 
|     maxLV = 0  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetHorseCount()):  | 
|         ipyData = ipyDataMgr.GetHorseByIndex(i)  | 
|         horseID = ipyData.GetHorseID()  | 
|         horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse)  | 
|         if horseLV > maxLV:  | 
|             maxLV = horseLV  | 
|     return maxLV  | 
|          |