#!/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 import CrossPlayerData import PlayerWeekParty #--------------------------------------------------------------------- #--------------------------------------------------------------------- #=============================================================================== # #Íæ¼ÒÆïÂí, Òª: # #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 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 : #ÊÇ·ñ¿ÉÒÔÏÂÂí 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 def CrossServer_RideHorse(curPlayer, dataList): curPlayerRideType = dataList[0] #ÆïÂí if curPlayerRideType == 1: PlayerRideHorseUp(curPlayer, True) 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) if not GameWorld.IsCrossServer(): dataList = [horseIndex] CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_HorseChange, dataList) return def CrossServer_ChangeHorse(curPlayer, dataList): ## ¿ç·þ´¦Àí ×øÆï±ä¸ü horseIndex = dataList[0] ipyData = IpyGameDataPY.GetIpyGameData("Horse", horseIndex) if not ipyData: return horseItemID = ipyData.GetItemID() if ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, IPY_GameWorld.rptEquip): 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) #---Ö´ÐÐÍæ¼Ò»»×°Âß¼­--- tick = GameWorld.GetGameWorld().GetTick() if ChEquip.DoPlayerEquipItem(curPlayer, curHorse, ItemCommon.GetEquipPackIndex(curHorse), tick): if isRideHorse: PlayerRideHorseUp(curPlayer, False) 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, ItemCommon.GetEquipPackIndex(curHorse), 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) # ¹ûʵ¶Ô×øÆïµÄ¼Ó³É, »êʯ¹ûʵË㸽¼ÓÊôÐԲ㣬µ¥¶À¼ÆËã fightPowerEx = PlayerAttrFruit.CalcAttrFruitAddAtrr(curPlayer, allAttrListHorseSoul, ShareDefine.Def_AttrFruitFunc_Horse) curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_HorseSoul, fightPowerEx) #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): if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_Horse): GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_VersionFix, ChConfig.Def_VerFix_Horse, 1) #µÈ¼¶²»Äܳ¬ÉÏÏÞ£¬¼¼ÄÜɾÁËÖØÐÂѧ skillManager = curPlayer.GetSkillManager() delCnt = 0 for i in xrange(skillManager.GetSkillCount()): dataIndex = i-delCnt skill = skillManager.GetSkillByIndex(dataIndex) if skill == None: continue if skill.GetFuncType() != ChConfig.Def_SkillFuncType_HorseSkill: continue skillTypeID = skill.GetSkillTypeID() skillManager.DeleteSkillBySkillTypeID(skillTypeID) delCnt += 1 tick = GameWorld.GetGameWorld().GetTick() ipyDataMgr = IpyGameDataPY.IPY_Data() for i in xrange(ipyDataMgr.GetHorseCount()): ipyData = ipyDataMgr.GetHorseByIndex(i) horseID = ipyData.GetHorseID() curlv = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Horser_LV % horseID, 0, ChConfig.Def_PDictType_Horse) if not curlv: continue maxLV = ipyData.GetMaxLV() if curlv > maxLV: PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_LV % horseID, maxLV, ChConfig.Def_PDictType_Horse) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Horser_Exp % horseID, 0, ChConfig.Def_PDictType_Horse) GameWorld.Log(' ÀϺÅ×øÆïµÈ¼¶³¬¹ýÉÏÏÞ£¬×øÆïID=%s,Ô­LV=%s£¬ÖØÖÃΪ=%s'%(horseID, curlv, maxLV)) curlv = maxLV for lv in xrange(1, curlv + 1): upIpyData = IpyGameDataPY.GetIpyGameData("HorseUp", horseID, lv) if not upIpyData: break skillIDList = upIpyData.GetSkillID() if not skillIDList: continue for skillID in skillIDList: __GiveSkill(curPlayer, skillID, tick) # ÖØË¢Õ½Á¦ curControl = PlayerControl.PlayerControl(curPlayer) curControl.RefreshAllSkill() RefreshHorseAttr(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) PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_Horse, horseID, False) 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