| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package Player.PlayerPet  | 
| #  | 
| # @todo:³èÎï/ÁéÊÞ  | 
| # @author xdh  | 
| # @date 2018-7-20  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ³èÎï  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2018-7-20 15:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| #µ¼Èë  | 
| import ChConfig  | 
| import NPCCommon  | 
| import ItemCommon  | 
| import IPY_GameWorld  | 
| import DataRecordPack  | 
| import PlayerBillboard  | 
| import SkillShell  | 
| import ItemControler  | 
| import PlayerControl  | 
| import PlayerSuccess  | 
| import GameFuncComm  | 
| import ShareDefine  | 
| import SkillCommon  | 
| import PetControl  | 
| import EventShell  | 
| import GameWorld  | 
| import IpyGameDataPY  | 
| import PlayerAttrFruit  | 
| import GameMap  | 
| import OpenServerCampaign  | 
| import PlayerMagicWeapon  | 
| import PlayerWeekParty  | 
| import CalcNoLineEffect  | 
| import PassiveBuffEffMng  | 
| import CrossPlayerData  | 
| import CalcLineEffect  | 
| import PlayerActivity  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import PlayerHorse  | 
| import GameObj  | 
|   | 
| import random  | 
| import math  | 
| #---------------------------------------------------------------------  | 
|   | 
|   | 
| def DoLogic_PetInfo_OnDay(curPlayer):  | 
|               | 
|     return  | 
| #---------------------------------------------------------------------  | 
|   | 
| ## ³èÎ﹦ÄÜ¿ªÆô  | 
| #  @return: ÊÇ·ñ¼¤»î³É¹¦  | 
| def DoPetOpen(curPlayer):  | 
|     GameWorld.DebugLog("DoPetOpen...", curPlayer.GetPlayerID())  | 
|           | 
| #    firstPetData = ReadChConfig.GetEvalChConfig("FirstPet")  | 
| #    petNPCID = firstPetData[0]  | 
| #    isAutoFight = firstPetData[1]  | 
| #    if petNPCID <= 0:  | 
| #        return  | 
| #      | 
| #    # Èç¹ûÒѾÓиóèÎï, ²»ÔÙ¸ø  | 
| #    if GetPetDataItemIndexByNPCID(curPlayer, petNPCID) < 0:  | 
| #        newPetItem = GetNewPetDataItem(curPlayer, petNPCID)  | 
| #        if not newPetItem:  | 
| #            return  | 
| #          | 
| #        if not ItemControler.PlayerItemControler(curPlayer).PutInItem(ShareDefine.rptPet, newPetItem):  | 
| #            return  | 
| #          | 
| #        petData = newPetItem.GetUserData()  | 
| #        DataRecordPack.DR_UsePetEgg(curPlayer, 0, petNPCID, petData)  | 
| #          | 
| #    if isAutoFight and not curPlayer.GetPetMgr().GetFightPet():  | 
| #        petItemIndex = GetPetDataItemIndexByNPCID(curPlayer, petNPCID)  | 
| #        GameWorld.DebugLog("×Ô¶¯³öÕ½ÐÂÊÖ³è!petNPCID=%s,petItemIndex=%s" % (petNPCID, petItemIndex))  | 
| #        DoChangePetState(curPlayer, petItemIndex, ShareDefine.Def_PetState_Fight)  | 
|       | 
|     for trainType in xrange(1, GetPetTrainTypes() + 1):  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, 1)  | 
|     Sync_PetTrainData(curPlayer)  | 
|     return True  | 
|   | 
| ## ¹¦ÄÜ¿ªÆôºó, ½ÇÉ«Éý¼¶ÐèÒªµÄ´¦Àí  | 
| def DoLVUPLogic_Pet(curPlayer):  | 
|     #GameWorld.DebugLog("DoLVUPLogic_Pet")  | 
|     return  | 
|   | 
| def GetPetIpydata(petNPCID):return IpyGameDataPY.GetIpyGameData("PetInfo", petNPCID)  | 
|   | 
| ## »ñȡгèÎïÊý¾ÝÎïÆ·  | 
| def GetNewPetDataItem(curPlayer, petNPCID, classlv= -1):  | 
|   | 
|     gameData = GameWorld.GetGameData()  | 
|     petNpcData = gameData.FindNPCDataByID(petNPCID)  | 
|     if not petNpcData:  | 
|         GameWorld.ErrLog("FindNPCDataByID can not find npcData petNPCID=%s" % (petNPCID))  | 
|         return  | 
|     petIpyData = GetPetIpydata(petNPCID)  | 
|     if not petIpyData:  | 
|         GameWorld.ErrLog("tagPetInfo.txt can not find petData petNPCID=%s" % (petNPCID))  | 
|         return  | 
|       | 
|     newPetItem = ItemCommon.CreateSingleItem(ChConfig.Def_ItemID_PetData)  | 
|     if not newPetItem:  | 
|         return  | 
|       | 
|     newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_NPCID, petNPCID)  | 
|     newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_State, ShareDefine.Def_PetState_Null)  | 
|       | 
|     initClass = petIpyData.GetInitRank() if classlv == -1 else classlv#³õʼ½×¼¶  | 
|     newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_ClassLV, max(0, initClass - 1)) #´úÂëÀï´Ó0¿ªÊ¼  | 
|     newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_QualityLV, petIpyData.GetQuality()) # ³èÎïÆ·ÖÊ  | 
|       | 
|       | 
|     petSkillList = petIpyData.GetSkillID()  | 
|     petSkillUnLockList = petIpyData.GetSkillUnLock()  | 
|   | 
|     for i, skillid in enumerate(petSkillList):  | 
|         limitPetClassLV = petSkillUnLockList[i] # Ñ§Ï°´Ë¼¼ÄÜËùÐè³èÎï½×¼¶  | 
|         if initClass < limitPetClassLV:  | 
|             continue  | 
|         curSkilData = GameWorld.GetGameData().GetSkillBySkillID(skillid)  | 
|         if not curSkilData:  | 
|             continue  | 
|         if curSkilData.GetFuncType() == ChConfig.Def_SkillFuncType_PetOwnerSkill:  | 
|             __GiveOwnerSkill(curPlayer, skillid)  | 
|             continue  | 
|         newPetItem.AddUserAttr(ShareDefine.Def_IudetPet_Skill, skillid)  | 
|       | 
|     return newPetItem  | 
|   | 
| # ´Ó³ÆºÅ»ñµÃ¼¼ÄÜ  | 
| def __GiveOwnerSkill(curPlayer, skillResID):  | 
|     GameWorld.DebugLog("¸øÁé³èÖ÷È˼¼ÄÜ: skillResID=%s" % skillResID)  | 
|     skillData = GameWorld.GetGameData().FindSkillByType(skillResID, 1)  | 
|     if skillData == None:  | 
|         GameWorld.DebugLog("    not find skill(%s)" % skillResID)  | 
|         return  | 
|     if not SkillCommon.CheckSkillJob(curPlayer, skillData):  | 
|         return  | 
|     if not SkillShell.CheckLearnSkillCondition(curPlayer, skillData):  | 
|         GameWorld.DebugLog("    learn skill condition isn't enough! skillResID=%s" % skillResID)  | 
|         return  | 
|     skillManager = curPlayer.GetSkillManager()  | 
|     if skillManager.FindSkillBySkillTypeID(skillResID):  | 
|         GameWorld.DebugLog("    have learned skill(%s)" % skillResID)  | 
|         return  | 
|       | 
|     skillManager.LVUpSkillBySkillTypeID(skillResID)  | 
|     PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveEff(curPlayer, skillResID)      | 
|     PlayerControl.PlayerControl(curPlayer).RefreshSkillFightPowerEx(skillResID, 0)  | 
|     return  | 
|   | 
| ## »ñÈ¡³èÎïʵÀý¶ÔÓ¦µÄ³èÎïÊý¾ÝÎïÆ·  | 
| def GetPetDataItem(curPetOwner, rolePet):  | 
|     if not curPetOwner:  | 
|         return  | 
|     packItemIndex = GetPetObjItemIndex(rolePet)  | 
|     return GetPetDataItemByIndex(curPetOwner, packItemIndex)  | 
|   | 
| ## »ñÈ¡³èÎïÊý¾ÝÎïÆ·  | 
| def GetPetDataItemByIndex(curPlayer, petItemIndex):  | 
|       | 
|     petDataPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)  | 
|     petDataItem = petDataPack.GetAt(petItemIndex)  | 
|     if not ItemCommon.CheckItemCanUse(petDataItem):  | 
|         GameWorld.DebugLog("PetDataItem is none! PetItemIndex=%s" % petItemIndex, curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     return petDataItem  | 
|   | 
| ## »ñÈ¡³èÎïÊý¾ÝÎïÆ·  | 
| def GetPetDataItemByNPCID(curPlayer, petNPCID):  | 
|     petDataPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)  | 
|     for petDataIndex in range(petDataPack.GetCount()):  | 
|         petItem = petDataPack.GetAt(petDataIndex)  | 
|         if petItem.IsEmpty():  | 
|             continue  | 
|         if petNPCID == petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID):  | 
|             return petItem  | 
|     return  | 
|   | 
| ## ÓÀºãÔÝÓÃÓѺöÈÀ´´æ´¢¸Ã³èÎïËùÊôµÄ³èÎï±³°üÎïÆ·Ë÷Òý  | 
| def GetPetObjItemIndex(rolePet): return rolePet.GetRolePet().Friendliness  | 
| def SetPetObjItemIndex(petStruct, petItemIndex): petStruct.Friendliness = petItemIndex  | 
|   | 
| ## ¸ù¾Ý³èÎïNPCID»ñÈ¡³èÎïÊý¾ÝÎïÆ·ÔÚ±³°üÖеÄË÷Òý  | 
| def GetPetDataItemIndexByNPCID(curPlayer, petNPCID):  | 
|     petDataPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)  | 
|     for petDataIndex in range(petDataPack.GetCount()):  | 
|         petItem = petDataPack.GetAt(petDataIndex)  | 
|         if petItem.IsEmpty():  | 
|             continue  | 
|         if petNPCID == petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID):  | 
|             return petDataIndex  | 
|           | 
|     return -1  | 
|   | 
| #===================================================================================================  | 
| # //////////////////////////////////////////////////////////////  | 
| # //16 03 ³èÎï³öÕ½/ÕÙ»Ø#tagCPetStateChange  | 
| # tagCPetStateChange       *   GettagCPetStateChange();  | 
| #   | 
| # class   IPY_CPetStateChange  | 
| # {  | 
| # public:  | 
| #   | 
| #    int      GetPetID();  | 
| #    // ×´Ì¬.0-ÕÙ»Ø;1-³öÕ½;2xx-ÊØ»¤(ÊØ»¤+Ä¿±êÊØ»¤Î»)  | 
| #    int      GetState(); 0~255  | 
| # };  | 
| #===================================================================================================  | 
| ##¿Í»§¶Ë·â°üÏìÓ¦  | 
| #@param index Íæ¼ÒË÷Òý  | 
| #@param tick Ê±¼ä´Á  | 
| #@return ·µ»ØÖµÎÞÒâÒå  | 
| #@remarks ¿Í»§¶Ë·â°üÏìÓ¦ //16 03 ³èÎï³öÕ½/ÕÙ»Ø#tagCPetStateChange  | 
| def PetStateChange(index, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     pack = IPY_GameWorld.IPY_CPetStateChange()  | 
|     petItemIndex = pack.GetPetID()  | 
|     state = pack.GetState()  | 
|       | 
|     #ʱ¼ä¼ä¸ôδµ½£¬²»´¦Àí£¨2010-06-23 16:20 ²ß»®ÁõºèÉú˵ÎÞÐëϵͳÌáʾ£©  | 
|     if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_ChangePetState) \  | 
|        < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_ChangePetState]:  | 
|         #ûÓе½Ë¢Ð¼ä¸ô  | 
|         return  | 
|       | 
|     curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_ChangePetState, tick)  | 
|       | 
|     DoChangePetState(curPlayer, petItemIndex, state)  | 
|     return  | 
|   | 
| ## ³èÎïÕ½¶·×´Ì¬±ä¸ü; 0-Êջأ»1-³öÕ½  (ÊÖÓΰ汾ֻÄܳöÕ½)  | 
| def DoChangePetState(curPlayer, petItemIndex, tagState, isRefresh=True):  | 
|     if petItemIndex < 0:  | 
|         return  | 
|       | 
|     if tagState not in ShareDefine.Def_PetStateList:  | 
|         return  | 
|           | 
|     petItem = GetPetDataItemByIndex(curPlayer, petItemIndex)  | 
|     if not petItem:  | 
|         return  | 
|       | 
|     #ÅжÏÊÇ·ñ´ïµ½¿ÉÇл»µÄ½×Êý  | 
|     curClasslv = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  | 
|     petNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|     ipyData = GetPetIpydata(petNPCID)  | 
|     if not ipyData:  | 
|         return  | 
|     needClasslv = ipyData.GetUseNeedRank()  | 
|     if curClasslv < needClasslv - 1: #ÅäÖõĽ׼¶´Ó1¿ªÊ¼  | 
|         GameWorld.DebugLog('    ÁéÊÞÇл»Íâ¹Û,½×¼¶²»×ã%s,²»¿ÉÇл»£¡' % needClasslv)  | 
|         return  | 
|       | 
|     curState = petItem.GetUserAttr(ShareDefine.Def_IudetPet_State) # µ±Ç°×´Ì¬  | 
|    | 
|     GameWorld.DebugLog("³èÎï״̬±ä¸ü!petItemIndex=%s,curState=%s,tagState=%s"   | 
|                        % (petItemIndex, curState, tagState))  | 
|       | 
|     # µ±Ç°×´Ì¬´¦Àí  | 
|     if curState == ShareDefine.Def_PetState_Fight:  | 
| #        curPet = curPlayer.GetPetMgr().GetFightPet()  | 
| #        if curPet:  | 
| #            #ÒÑÊdzöս״̬, C++ÕÙ»½×ø±êºÍÈËÖØµþ  | 
| #            resultPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), ChConfig.Def_SummonAppearDist)  | 
| #            curPet.ResetPos(resultPos.GetPosX(), resultPos.GetPosY())  | 
| #            PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveEff(curPet)  | 
| #            PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveBuff(curPet)  | 
| #        return  | 
|         #18/10/15 ÒòΪijÖÖδ֪ÔÒò³èÎïÎïÆ·µÄ״̬ÊdzöÕ½£¨Êµ¼Ê³¡¾°ÖÐδ³öÕ½£©£¬µ¼Ö¸óèÎïÎÞ·¨³öÕ½£¬¹ÊÔٴη¢°ü³öսʱ£¬´Ë´¦²»À¹£¡  | 
|         PetControl.ReCallFightPet(curPlayer)  | 
|      | 
|     else:  | 
|         pass  | 
|       | 
|     # Ä¿±ê״̬´¦Àí  | 
|     if tagState == ShareDefine.Def_PetState_Null:  | 
|         #ÕâÀï¿É²»ÔÙ³èÎïÉèÖÃNull״̬  | 
|         #petItem.SetUserAttr(ShareDefine.Def_IudetPet_State, ShareDefine.Def_PetState_Null)  | 
|         pass  | 
|     elif tagState == ShareDefine.Def_PetState_Fight:  | 
|         __DoPetGoOutToFight(curPlayer, petItem)  | 
|      | 
|           | 
|     if isRefresh:  | 
|         RefreshPetItemAddAttr(curPlayer, True) # ²»Ë¢ÅÅÐаñ  | 
|           | 
| #    if petItem.GetUserAttr(ShareDefine.Def_IudetPet_State) != tagState:  | 
| #        petItem.SetUserAttr(ShareDefine.Def_IudetPet_State, tagState)  | 
| #        GameWorld.DebugLog("Çл»³èÎï״̬Òì³£·À·¶! curState=%s,tagState=%s" % (curState, tagState))  | 
|           | 
|     if not GameWorld.IsCrossServer():  | 
|         dataList = [petNPCID, curClasslv, tagState]  | 
|         CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_PetState, dataList)  | 
|           | 
|     return  | 
|   | 
| def CrossServer_DoChangePetState(curPlayer, dataList):  | 
|     ## ¿ç·þ´¦Àí ³èÎïÕ½¶·×´Ì¬±ä¸ü  | 
|     petNPCID, curClasslv, tagState = dataList  | 
|     petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)  | 
|     if not petItem:  | 
|         newPetItem = GetNewPetDataItem(curPlayer, petNPCID)  | 
|         if not newPetItem:  | 
|             return  | 
|         if not ItemControler.PlayerItemControler(curPlayer).PutInItem(ShareDefine.rptPet, newPetItem):  | 
|             return  | 
|         petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)  | 
|     if not petItem:  | 
|         return  | 
|       | 
|     curItemClasslv = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  | 
|     # ´¦Àí¼¼ÄÜÎÊÌ⣬Ôݲ»´¦Àí  | 
|     if curClasslv > curItemClasslv:  | 
|         pass  | 
|       | 
|     curState = petItem.GetUserAttr(ShareDefine.Def_IudetPet_State) # µ±Ç°×´Ì¬  | 
|     if curState == ShareDefine.Def_PetState_Fight:  | 
|         PetControl.ReCallFightPet(curPlayer)  | 
|           | 
|     if tagState == ShareDefine.Def_PetState_Fight:  | 
|         __DoPetGoOutToFight(curPlayer, petItem)  | 
|           | 
|     return  | 
|   | 
|   | 
| ## Ö´ÐгèÎï³öÕ½Âß¼  | 
| def __DoPetGoOutToFight(curPlayer, petItem):  | 
|     npcID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|   | 
|     petNpcData = GameWorld.GetGameData().FindNPCDataByID(npcID)  | 
|     if not petNpcData:  | 
|         GameWorld.Log("PetStateChange FindNPCDataByID, pet npcID = %s" % (npcID))  | 
|         return  | 
|       | 
|     petMgr = curPlayer.GetPetMgr()  | 
|     rolePet = petMgr.PetList_Add(npcID)  | 
|     if rolePet == None:  | 
|         GameWorld.ErrLog("PetStateChange PetList_Add, Ìí¼Ó³èÎï = %sʧ°Ü" % (npcID))  | 
|         return  | 
|       | 
|     #---³õʼ»¯³èÎïÊôÐÔ---  | 
|     petStruct = rolePet.GetRolePet()  | 
|     petID = petStruct.PetID  | 
|     petStruct.BindType = petItem.GetIsBind()  | 
|     petStruct.Name = str(petStruct.PetID)#petNpcData.GetName() Åä±í²»ÊÇUTF8»áµ¼Ö±¨´í£¬Ä¬ÈÏÓÃIDµ±Ãû×Ö  | 
|     petStruct.DailyTrainCnt = PlayerHorse.GetHorsePetSkinIndex(curPlayer, 2, npcID)  | 
|     # ³èÎïlv ¸ÄΪ ½×¼¶ ÓÃÓÚ¿Í»§¶ËÏÔʾÃû×ÖÑÕÉ«Óà  | 
| #    classLV = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  | 
| #    rolePet.SetLV(classLV)  | 
|   | 
|     #λÖÃ.1, ÔÚ³èÎïÁбí; 2, ÔÚÎïÆ·±³°ü       | 
|     petStruct.Pos = 1  | 
|       | 
|     petItemIndex = petItem.GetItemPlaceIndex()  | 
|     SetPetObjItemIndex(petStruct, petItemIndex)  | 
|     rolePet.SetRolePet(petStruct)  | 
|       | 
|     learnSkillList, passiveSkillList = GetPetLearnSkill(curPlayer)  | 
|     PetControl.DoLogic_PlayerPetLearnSkillList(rolePet, learnSkillList)  | 
|       | 
|     #---Ë¢ÐÂÊôÐÔ(²»Í¨Öª)---  | 
|     #GameWorld.DebugLog("ˢǰ: petID=%s,playerID=%s,npcID=%s,BindType=%s,AIMode=%s,PetIndex=%s,grade=%s,qualLV=%s,"   | 
|     #                   % (petStruct.PetID, petStruct.PlayerID, petStruct.NPCID, petStruct.BindType, petStruct.AIMode, petStruct.PetIndex,  | 
|     #                      rolePet.GetGrade(), rolePet.GetQualityLV()))  | 
|     petControl = NPCCommon.NPCControl(rolePet)  | 
|     petControl.RefreshNPCState(canSyncClient=False)  | 
|     #GameWorld.DebugLog("Ë¢ºó: petID=%s,playerID=%s,npcID=%s,BindType=%s,AIMode=%s,PetIndex=%s,grade=%s,qualLV=%s,"   | 
|     #                   % (petStruct.PetID, petStruct.PlayerID, petStruct.NPCID, petStruct.BindType, petStruct.AIMode, petStruct.PetIndex,  | 
|     #                      rolePet.GetGrade(), rolePet.GetQualityLV()))  | 
|       | 
|     #µ±Ç°ÑªÁ¿(²»Í¨Öª)  | 
|     PetControl.SetPetHP(rolePet, GameObj.GetMaxHP(rolePet), False)  | 
|       | 
|     #---֪ͨ¿Í»§¶Ë---  | 
|     #rolePet.Sync_PetInfo()  | 
|     #ˢм¼ÄÜÀ¸  | 
|     #rolePet.Sync_SkillList()  | 
|       | 
|     #---ÊÕµ½"³èÎï³öÕ½"ÇëÇó---  | 
|     #¼ì²éÊÇ·ñ¿É³öÕ½  | 
|     if not PetControl.CheckPetCanFight(curPlayer, rolePet):  | 
|         GameWorld.DebugLog("²»¿É³öÕ½£¡PetList_SetFree petID=%s" % petID)  | 
|         petMgr.PetList_SetFree(petID)  | 
|         return  | 
|   | 
|     # ÏÈÕлسöÕ½ÖеijèÎï  | 
|     PetControl.ReCallFightPet(curPlayer)  | 
|       | 
|     #ÕÙ»½³èÎï³öÕ½  | 
|     resultPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), ChConfig.Def_SummonAppearDist)  | 
|     PetControl.SummonPet(rolePet, resultPos.GetPosX(), resultPos.GetPosY())  | 
|     petItem.SetUserAttr(ShareDefine.Def_IudetPet_State, ShareDefine.Def_PetState_Fight)  | 
|       | 
|     #¼Ç¼³öÕ½µÄ³èÎïË÷Òý Ä¬ÈÏ+1 0Ôò´ú±íûÓÐ  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FightPetIndex, petItemIndex + 1)  | 
|     rolePet.SetSightLevel(curPlayer.GetSightLevel())  | 
|     return True  | 
|   | 
| def AutoSummonPet(curPlayer):  | 
|     #ÖØÐÂÕÙ»½Ö®Ç°µÄ³èÎ¸´»î¡¢Çл»µØÍ¼Ê±µ÷Óà  | 
|     fightPetIndex = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FightPetIndex)  | 
|     if not fightPetIndex:  | 
|         return  | 
|     DoChangePetState(curPlayer, fightPetIndex - 1, ShareDefine.Def_PetState_Fight)  | 
|     return  | 
|   | 
| ## »ñÈ¡³öÕ½³èÎïҪѧµÄ¼¼ÄÜ  | 
| def GetPetLearnSkill(curPlayer):  | 
|     learnSkillDict = {}  | 
|     passiveSkillList = []  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         petItem = petPack.GetAt(i)  | 
|         if petItem.IsEmpty():  | 
|             continue  | 
|         for i in range(petItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)):  | 
|             skillID = petItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i)  | 
|             curSkilData = GameWorld.GetGameData().GetSkillBySkillID(skillID)  | 
|             if not curSkilData:  | 
|                 continue  | 
|             if SkillCommon.isPassiveAttr(curSkilData):  | 
|                 #±»¶¯¼¼ÄÜÊôÐÔ²»Ñ§  | 
|                 passiveSkillList.append(skillID)  | 
|                 continue  | 
|             skillTypeID = curSkilData.GetSkillTypeID()  | 
|             if skillTypeID in learnSkillDict:  | 
|                 learnSkillDict[skillTypeID].append(skillID)  | 
|             else:  | 
|                 learnSkillDict[skillTypeID] = [skillID]  | 
|               | 
|     learnSkillIDList = [max(a) for a in learnSkillDict.values()]  | 
|     return learnSkillIDList, passiveSkillList  | 
|       | 
| #===============================================================================  | 
| #// A7 02 ³èÎD»î #tagCMActivatePet  | 
| #  | 
| #struct    tagCMActivatePet  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        PetNPCID; // ³èÎïNPCID  | 
| #    BYTE        IsUseGold; // ÊÇ·ñʹÓÃ×êʯֱ½Ó¹ºÂò¼¤»î  | 
| #};  | 
| def OnActivatePet(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     petNPCID = clientData.PetNPCID  | 
|     isUseGold = clientData.IsUseGold  | 
|     DoActivatePet(curPlayer, petNPCID, isUseGold, True)  | 
|     return  | 
|   | 
| def DoActivatePet(curPlayer, petNPCID, isUseGold=False, isUseItem=False):  | 
|     if not isUseItem:  | 
|         #ĿǰֻÄÜÎïÆ·¼¤»î  | 
|         return  | 
|       | 
|     hasSpace = False  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         packItem = petPack.GetAt(i)  | 
|         if packItem.IsEmpty():  | 
|             hasSpace = True  | 
|             continue  | 
|           | 
|         petItemNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|         if petItemNPCID == petNPCID:  | 
|             GameWorld.DebugLog("ÒѾӵÓиóèÎ i=%s,petItemNPCID=%s,petNPCID=%s" % (i, petItemNPCID, petNPCID))  | 
|             return  | 
|       | 
|     if not hasSpace:  | 
|         PlayerControl.NotifyCode(curPlayer, "Pet_liubo_76326") # ³èÎïÊýÁ¿´ïµ½ÉÏÏÞ  | 
|         return  | 
|     ipyData = GetPetIpydata(petNPCID)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     needItemID = ipyData.GetUnLockNeedItemID()  | 
|     needItemCnt = ipyData.GetUnLockNeedItemCnt()  | 
|     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|     hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(needItemID, itemPack, needItemCnt)  | 
|     if not hasEnough:  | 
|         GameWorld.DebugLog("DoActivatePet() item(%s[%s]) isn't enough" % (needItemID, needItemCnt))  | 
|         return  | 
|       | 
|     newPetItem = GetNewPetDataItem(curPlayer, petNPCID)  | 
|     if not newPetItem:  | 
|         return  | 
|       | 
|     if not ItemControler.PlayerItemControler(curPlayer).PutInItem(petPackIndex, newPetItem):  | 
|         return  | 
|       | 
|     ItemCommon.ReduceItem(curPlayer, itemPack, itemList, needItemCnt, False, ChConfig.ItemDel_Pet)  | 
|           | 
|     EventShell.EventRespons_OnActivatePet(curPlayer, petNPCID)  | 
|     sysMark = ipyData.GetUnlockSys() or 'GetPet'  | 
|     PlayerControl.WorldNotify(0, sysMark, [curPlayer.GetName(), petNPCID])  | 
|     rolePet = curPlayer.GetPetMgr().GetFightPet()  | 
|     if not rolePet:  | 
|         petItemIndex = GetPetDataItemIndexByNPCID(curPlayer, petNPCID)  | 
|         GameWorld.DebugLog("ûÓгèÎï³öÕ½£¬»ñµÃгèÎĬÈϳöÕ½¸Ã³èÎpetNPCID=%s,petItemIndex=%s" % (petNPCID, petItemIndex))  | 
|         DoChangePetState(curPlayer, petItemIndex, ShareDefine.Def_PetState_Fight)  | 
|     else:  | 
|           | 
|         if rolePet:  | 
|             learnSkillList, passiveSkillList = GetPetLearnSkill(curPlayer)  | 
|             PetControl.DoLogic_PlayerPetLearnSkillList(rolePet, learnSkillList)  | 
|     RefreshPetItemAddAttr(curPlayer, True)  | 
|       | 
|     # ¿ª·þ»î¶¯Êý¾Ý  | 
|     OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_PetLV, GetTotalPetLV(curPlayer))  | 
|     PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_Pet, petNPCID, False)  | 
|     return True  | 
|   | 
|   | 
| def DoPetActivate(curPlayer, index, classlv):  | 
|     ##Ö±½Ó¼¤»î Íⲿµ÷ÓÃGM²âÊÔÓà  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     petInfoCount = ipyDataMgr.GetPetInfoCount()  | 
|     if petInfoCount <= 0 or index > petInfoCount:  | 
|         GameWorld.ErrLog("¼¤»î³èÎﳬ¹ý³èÎï±íÊý¾ÝÊý: index=%s,petInfoCount=%s" % (index, petInfoCount))  | 
|         return  | 
|     petNPCID = ipyDataMgr.GetPetInfoByIndex(index - 1).GetID()  | 
|     quality = ipyDataMgr.GetPetInfoByIndex(index - 1).GetQuality()  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         packItem = petPack.GetAt(i)  | 
|         if packItem.IsEmpty():  | 
|             continue  | 
|         petItemNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|         if petItemNPCID == petNPCID:  | 
|             packItem.SetUserAttr(ShareDefine.Def_IudetPet_ClassLV, max(0, classlv - 1))  | 
|             packItem.SetUserAttr(ShareDefine.Def_IudetPet_QualityLV, quality) # ³èÎïÆ·ÖÊ  | 
|             GameWorld.DebugLog("ÒѾӵÓиóèÎ i=%s,petItemNPCID=%s,petNPCID=%s" % (i, petItemNPCID, petNPCID))  | 
|             return  | 
|       | 
|       | 
|     newPetItem = GetNewPetDataItem(curPlayer, petNPCID, classlv)  | 
|     if not newPetItem:  | 
|         return  | 
|     petPackIndex = ShareDefine.rptPet  | 
|       | 
|     if not ItemControler.PlayerItemControler(curPlayer).PutInItem(petPackIndex, newPetItem):  | 
|         return  | 
|     petItemIndex = GetPetDataItemIndexByNPCID(curPlayer, petNPCID)  | 
|     DoChangePetState(curPlayer, petItemIndex, ShareDefine.Def_PetState_Fight)  | 
|     RefreshPetItemAddAttr(curPlayer, True)  | 
|     return  | 
| #===============================================================================  | 
|   | 
|   | 
| ## »ñÈ¡ÒѼ¤»îµÄÁéÊÞID  | 
| def GetActivePetID(curPlayer):  | 
|     petIDList = []  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         packItem = petPack.GetAt(i)  | 
|         if packItem.IsEmpty():  | 
|             continue  | 
|         petItemNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|         petIDList.append(petItemNPCID)  | 
|     return petIDList  | 
|   | 
| #// A7 04 ³èÎïÉý½× #tagCMPetClassUP  | 
| #  | 
| #struct    tagCMPetClassUP  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        PetItemIndex;    //³èÎïÊý¾Ý±³°üË÷Òý  | 
| #};  | 
| def PetClassUp(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Pet):  | 
|         GameWorld.DebugLog(' ³èÎ﹦ÄÜ먦Æô')  | 
|         return  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     PetItemIndex = clientData.PetItemIndex  | 
|     costItemCount = clientData.UseItemCnt # ÏûºÄ²ÄÁϸöÊý  | 
|     isAutoBuy = 0 #clientData.IsAutoBuy # ÊÇ·ñ×Ô¶¯¹ºÂò  | 
|     petDataItem = GetPetDataItemByIndex(curPlayer, PetItemIndex)  | 
|     if not petDataItem:  | 
|         return  | 
|       | 
|     petNPCID = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|   | 
|     petNpcData = GameWorld.GetGameData().FindNPCDataByID(petNPCID)  | 
|     if not petNpcData:  | 
|         GameWorld.ErrLog("can not found pet npcID = %s" % (petNPCID))  | 
|         return  | 
|       | 
|     classLV = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  | 
|     petIpyData = GetPetIpydata(petNPCID)  | 
|     if not petIpyData:  | 
|         return  | 
|     maxClassLV = petIpyData.GetMaxRank()  | 
|     if classLV + 2 > maxClassLV:  | 
|         GameWorld.DebugLog("³èÎïÉý½× ÒÑÂú¼¶¡£¡£¡£classLV=%s" % classLV, playerID)  | 
|         return  | 
|       | 
|     ipyData = IpyGameDataPY.GetIpyGameData("PetClassCost", petNPCID, classLV + 1)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     needExp = ipyData.GetUpNeedExp()  | 
|     if not needExp:  | 
|         return  | 
|       | 
|     curPetClassExp = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_Exp)  | 
|       | 
|       | 
|     curItemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|       | 
|     itemIndexList = []  | 
|     costItemIDList = IpyGameDataPY.GetFuncEvalCfg('PetUpItem')  | 
|       | 
|     #¿Û²ÄÁÏ  | 
|     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("PetClassUp Éý½×µÀ¾ß²»×ã¡£¡£¡£")  | 
|         return  | 
|       | 
|     autoBuyItemID = costItemIDList[0]  | 
|     if itemIndexList:  | 
|         curItem = curItemPack.GetAt(itemIndexList[0])  | 
|     else:  | 
|         curItem = GameWorld.GetGameData().GetItemByTypeID(autoBuyItemID)  | 
|     if not curItem:  | 
|         return  | 
|       | 
|     if lackCnt > 0:  | 
|         return  | 
|         #===========================================================================================  | 
|         # if not isAutoBuy:  | 
|         #    return  | 
|         # lackCost = ItemCommon.GetAutoBuyItemNeedGold({autoBuyItemID:lackCnt})  | 
|         # if lackCost <= 0:  | 
|         #    return  | 
|         # itemData = GameWorld.GetGameData().GetItemByTypeID(autoBuyItemID)  | 
|         # itemName = autoBuyItemID if not itemData else itemData.GetName()  | 
|         # infoDict = {ChConfig.Def_Cost_Reason_SonKey:itemName}  | 
|         # if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, lackCost,  | 
|         #                              ChConfig.Def_Cost_PetClassUP, infoDict, lackCnt):  | 
|         #    return  | 
|         #===========================================================================================  | 
|          | 
|     playerName = curPlayer.GetName()  | 
|      | 
|     curEff = curItem.GetEffectByIndex(0)  | 
|     addExp = curEff.GetEffectValue(0) * costItemCount  | 
|     updExp = curPetClassExp + addExp  | 
|     updClassLV = classLV  | 
|     for lv in xrange(classLV, maxClassLV-1):  | 
|         ipyData = IpyGameDataPY.GetIpyGameData("PetClassCost", petNPCID, lv+1)  | 
|         if not ipyData:  | 
|             break  | 
|         upNeedExp = ipyData.GetUpNeedExp()  | 
|         if updExp < upNeedExp:  | 
|             break  | 
|         updExp -= upNeedExp  | 
|         updClassLV +=1  | 
|           | 
|       | 
|     #¿Û³ýÎïÆ·  | 
|     delCnt = max(0, costItemCount - lackCnt) # Êµ¼Ê¿Û³ýµÄ¸öÊý  | 
|     if itemIndexList:  | 
|         ItemCommon.ReduceItem(curPlayer, curItemPack, itemIndexList, delCnt, True, ChConfig.ItemDel_Pet)  | 
|           | 
|     # ¸üоÑéÖµ  | 
|     if updClassLV+1 >=maxClassLV:  | 
|         updExp =0  | 
|     petDataItem.SetUserAttr(ShareDefine.Def_IudetPet_Exp, updExp)  | 
|     if updClassLV > classLV:  | 
|         petDataItem.SetUserAttr(ShareDefine.Def_IudetPet_ClassLV, updClassLV)  | 
|           | 
|         # Éý½×¿ªÆô¼¼ÄÜ  | 
|         petIpyData = GetPetIpydata(petNPCID)  | 
|         petSkillList = petIpyData.GetSkillID()  | 
|         petSkillUnLockList = petIpyData.GetSkillUnLock()  | 
|         sysMarkList = petIpyData.GetSkillUnLockSys()  | 
|         learnSkillList = []  | 
|         for i, skillid in enumerate(petSkillList):  | 
|             limitPetClassLV = petSkillUnLockList[i] # Ñ§Ï°´Ë¼¼ÄÜËùÐè³èÎï½×¼¶  | 
|             #ÉÏÒ»½×ÒѾ´¦Àí¹ýµÄ¼¼Äܲ»ÔÙ´¦Àí  | 
|             if updClassLV >= limitPetClassLV:  | 
|                 continue  | 
|             # Î´´ïµ½ËùÐè½×¼¶  | 
|             if updClassLV + 1 < limitPetClassLV:  | 
|                 continue  | 
|             curSkilData = GameWorld.GetGameData().GetSkillBySkillID(skillid)  | 
|             if not curSkilData:  | 
|                 continue  | 
|             if curSkilData.GetFuncType() == ChConfig.Def_SkillFuncType_PetOwnerSkill:  | 
|                 __GiveOwnerSkill(curPlayer, skillid)  | 
|                 continue  | 
|             petDataItem.AddUserAttr(ShareDefine.Def_IudetPet_Skill, skillid)  | 
|             if not SkillCommon.isPassiveAttr(curSkilData):  | 
|                 #±»¶¯¼¼Äܲ»Ñ§  | 
|                 learnSkillList.append(skillid)  | 
|             #¹ã²¥  | 
|             sysMark = sysMarkList[i] if i < len(sysMarkList) else 'PetUpLv'  | 
|             PlayerControl.WorldNotify(0, sysMark, [playerName, petNPCID, limitPetClassLV, skillid])  | 
|             #Ôö¼ÓÉý¼¶»îÔ¾µãЧ¹û  | 
|             PlayerActivity.AddActivityByLVOnLearnSkill(curPlayer, skillid)  | 
|               | 
|         if not learnSkillList and updClassLV + 1 == maxClassLV:  | 
|             PlayerControl.WorldNotify(0, 'PetUpLvMax', [playerName, petNPCID])  | 
|         # Èç¹ûÊǵ±Ç°³öÕ½µÄ³èÎï, Ôò¸Ã³èÎïѧϰ¼¼ÄÜ  | 
|         fightPet = curPlayer.GetPetMgr().GetFightPet()  | 
|         if learnSkillList and fightPet:  | 
|             PetControl.DoLogic_PlayerPetLearnSkillList(fightPet, learnSkillList)  | 
|               | 
|         RefreshPetItemAddAttr(curPlayer, True)  | 
|           | 
|         # ¿ª·þ»î¶¯Êý¾Ý  | 
|         OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_PetLV, GetTotalPetLV(curPlayer))  | 
|           | 
|     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_PetClassLV, 1, [petNPCID, updClassLV + 1])  | 
|     extraInfoDict = {"petItemIndex":PetItemIndex, "petNPCID":petNPCID}  | 
|     extraInfoDict.update(eval(petDataItem.GetUserData()))  | 
|     DataRecordPack.DR_ClassUpSystem(curPlayer, "PetClassUp", updClassLV, extraInfoDict)  | 
|           | 
|     #EventReport.WriteEvent_pet_class(curPlayer, petNpcData.GetName(), classLV, petClassExp, updClassLV, newClassExp)  | 
|       | 
|     return  | 
|   | 
| def GetTotalPetLV(curPlayer):  | 
|     totalPetLV = 0  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         petItem = petPack.GetAt(i)  | 
|         if petItem.IsEmpty():  | 
|             continue   | 
|         petItemNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|         classLV = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV) + 1  | 
|         petIpyData = GetPetIpydata(petItemNPCID)  | 
|         if not petIpyData:  | 
|             continue  | 
|         totalPetLV += classLV  | 
|     return totalPetLV  | 
|   | 
| def IsPetMaxLV(curPlayer, petNPCID):  | 
|     petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)  | 
|     if not petItem:  | 
|         return  | 
|     petNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|     classLV = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  | 
|     petIpyData = GetPetIpydata(petNPCID)  | 
|     if not petIpyData:  | 
|         return  | 
|     maxClassLV = petIpyData.GetMaxRank()  | 
|     return classLV + 2 > maxClassLV  | 
|   | 
| ## Ë¢Ð³èÎïÊý¾ÝÎïÆ·Ôö¼ÓµÄÊôÐÔ  | 
| def RefreshPetItemAddAttr(curPlayer, isUpdBillboard):  | 
|     CalcPetItemAddPlayerAttr(curPlayer)  | 
|       | 
|     if isUpdBillboard:  | 
|         PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState(billboardFunc=PlayerBillboard.UpdatePyPetBillboard, isForce=True)  | 
|         #PlayerBillboard.UpdatePyPetBillboard(curPlayer, True)  | 
|     else:  | 
|         PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState(isForce=True)  | 
|           | 
|     fightPet = curPlayer.GetPetMgr().GetFightPet()  | 
|     if fightPet:  | 
|         PetControl.RefurbishPetAttr(fightPet)  | 
|     return  | 
|   | 
| def CalcSkill_PetBattleEffect(curPlayer, rolePet, allAttrListPet):  | 
|     #ÁéÊÞ¼¼ÄܸøÁéÊÞ¼ÓµÄÊôÐÔ£¬²»¸øÈËÎï¼ÓµÄÊôÐÔ  | 
|     learnSkillList, passiveSkillList = GetPetLearnSkill(curPlayer)  | 
|     #GameWorld.DebugLog("1Ë¢¼¼ÄÜÊôÐÔ: %s" % allAttrList)  | 
|     for skillID in passiveSkillList:  | 
|         curSkill = GameWorld.GetGameData().GetSkillBySkillID(skillID)  | 
|         if not curSkill:  | 
|             continue  | 
|         for effectIndex in xrange(curSkill.GetEffectCount()):  | 
|             curEffect = curSkill.GetEffect(effectIndex)  | 
|             if curEffect.GetEffectID() not in ChConfig.Def_SkillEffs_Pet:  | 
|                 # ²»¸ø³èÎï¼ÓµÄ²»´¦Àí  | 
|                 continue  | 
|             SkillShell.CalcBuffEffAttr(rolePet, curEffect, allAttrListPet)  | 
|   | 
|   | 
| ##¼ÆËãNPCÕ½¶·ÊôÐÔ  | 
| # @param curNPC NPCʵÀý  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks ¼ÆËãNPCÕ½¶·ÊôÐÔ  | 
| def CalcBuffer_PetBattleEffect(rolePet, allAttrListPet):  | 
|     #@warning:Õ½¶·ÊôÐÔÏÈËã·ÇÏßÐÔÔÚËãÏßÐÔ  | 
|     buffRefreshList = NPCCommon.GetNPCBuffRefreshList(rolePet)  | 
|       | 
|     for buffState, canPileup in buffRefreshList:  | 
|         SkillShell.CalcCurBuffer_Effect(buffState, rolePet, allAttrListPet)  | 
|       | 
|     #·ÇÏßÐÔ  | 
|     CalcNoLineEffect.ChangeNPCAttrInNoLineEffectList(rolePet, allAttrListPet[ChConfig.CalcAttr_BattleNoline])  | 
|     #ÏßÐÔ  | 
|     CalcLineEffect.ChangeNPCAttrInLineEffectList(rolePet, allAttrListPet[ChConfig.CalcAttr_Battle])  | 
|     return  | 
|   | 
|   | 
| ## ¼ÆËã³èÎïÔö¼ÓµÄÍæ¼ÒÊôÐÔ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @return None  | 
| def CalcPetItemAddPlayerAttr(curPlayer):  | 
|     allAttrListPet = [{} for _ in range(4)]  | 
|     allAttrListPetSign = [{} for _ in range(4)] # ÊôÐÔº¬ ÌØÊâµÄ¼¼ÄÜÊôÐÔ(ÒòΪǩµ½¼¼ÄÜÊôÐԳɳ¤£¬Õ½Á¦Ò²Êdzɳ¤µÄ£¬ËùÒÔ²»Äܷż¼ÄÜÖÐËãÕ½Á¦£¬ÔÝʱ·Å»êʯÖÐ)  | 
|     allAttrListPetSoul = [{} for _ in range(4)]  | 
|     skillAttrList = [{} for _ in range(4)]  | 
|     allAttrListPetSkin = [{} for _ in range(4)]  | 
|     allAttrListTrain = [{} for _ in range(4)]  | 
|     totalMinAtk, totalMaxAtk = GetPetAtkValue(curPlayer)  | 
|     PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_PetMinAtk, totalMinAtk, allAttrListPet)  | 
|     PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_PetMaxAtk, totalMaxAtk, allAttrListPet)  | 
|     totalSignNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TotalSignNum) # ×ÜÇ©µ½ÌìÊý  | 
|     # ¹ûʵ¸øÈËÎï¼ÓÊôÐÔ, »êʯ¹ûʵË㸽¼ÓÊôÐԲ㣬µ¥¶À¼ÆËã  | 
|     fightPowerEx = PlayerAttrFruit.CalcAttrFruitAddAtrr(curPlayer, allAttrListPetSoul, ShareDefine.Def_AttrFruitFunc_Pet)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_PetSoul, fightPowerEx)  | 
|       | 
|     #ÁéÊÞ¼¼ÄܸøÈËÎï¼ÓµÄÊôÐÔ  | 
|     learnSkillList, passiveSkillList = GetPetLearnSkill(curPlayer)  | 
|     #GameWorld.DebugLog("1Ë¢¼¼ÄÜÊôÐÔ: %s" % allAttrList)  | 
|     for skillID in passiveSkillList:  | 
|         curSkill = GameWorld.GetGameData().GetSkillBySkillID(skillID)  | 
|         if not curSkill:  | 
|             continue  | 
|         # Áé³èÇ©µ½¼¼ÄÜÌØÊâ´¦Àí  | 
|         if curSkill.GetSkillTypeID() == ChConfig.Def_SkillID_PetSignDay:  | 
|             for effectIndex in xrange(curSkill.GetEffectCount()):  | 
|                 curEffect = curSkill.GetEffect(effectIndex)  | 
|                 effID = curEffect.GetEffectID()  | 
|                 effValue = curEffect.GetEffectValue(0)  | 
|                 PlayerControl.CalcAttrDict_Type(effID, effValue * totalSignNum, allAttrListPetSign)  | 
|               | 
|             continue  | 
|         for effectIndex in xrange(curSkill.GetEffectCount()):  | 
|             curEffect = curSkill.GetEffect(effectIndex)  | 
|             if curEffect.GetEffectID() in ChConfig.Def_SkillEffs_Pet:  | 
|                 # ¸ø³èÎï¼ÓµÄ²»´¦Àí  | 
|                 continue  | 
|             SkillShell.CalcBuffEffAttr(curPlayer, curEffect, skillAttrList)  | 
|       | 
|     # ÐÂÅàÑøÊôÐÔ  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in xrange(ipyDataMgr.GetPetTrainCount()):  | 
|         trainIpyData = ipyDataMgr.GetPetTrainByIndex(index)  | 
|         trainType = trainIpyData.GetTrainType()  | 
|         dataTrainLV = trainIpyData.GetTrainLV()  | 
|         trainLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType)  | 
|           | 
|         if dataTrainLV > trainLV:  | 
|             continue  | 
|         elif dataTrainLV == trainLV:  | 
|             trainItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainItemCount % trainType)  | 
|         else:  | 
|             trainItemCount = trainIpyData.GetEatCntTotal()  | 
|               | 
|         # µÈ½×¶îÍâÊôÐÔ  | 
|         lvAttrTypeList = trainIpyData.GetLVAttrTypeList()  | 
|         lvAttrValueList = trainIpyData.GetLVAttrValueList()  | 
|         for i, attrID in enumerate(lvAttrTypeList):  | 
|             attrValue = lvAttrValueList[i]  | 
|             PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListTrain)  | 
|               | 
|         # ÅàÑøµ¤Ôö¼ÓÊôÐÔ  | 
|         eatCntEverytime = trainIpyData.GetEatCntEverytime()  | 
|         if trainItemCount and eatCntEverytime:  | 
|             eatItemAttrTypeList = trainIpyData.GetEatItemAttrTypeList()  | 
|             eatItemAttrValueList = trainIpyData.GetEatItemAttrValueList()  | 
|             attrMultiple = trainItemCount / eatCntEverytime  | 
|             for i, attrID in enumerate(eatItemAttrTypeList):  | 
|                 attrValue = eatItemAttrValueList[i]  | 
|                 PlayerControl.CalcAttrDict_Type(attrID, attrValue * attrMultiple, allAttrListTrain)  | 
|                   | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetTarin, allAttrListTrain)  | 
|       | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Pet, allAttrListPet)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSoul, allAttrListPetSoul)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSign, allAttrListPetSign)  | 
|       | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSkill, skillAttrList)  | 
|       | 
|     #³õʼսÁ¦  | 
|     fpExTotal = 0  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         petItem = petPack.GetAt(i)  | 
|         if petItem.IsEmpty():  | 
|             continue  | 
|         # ÎïÆ·Éϵļ¼ÄÜÕ½Á¦£¬Ö÷ÈËÉϵÄÁíËã  | 
|         for i in range(petItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)):  | 
|             skillID = petItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i)  | 
|             curSkilData = GameWorld.GetGameData().GetSkillBySkillID(skillID)  | 
|             if not curSkilData:  | 
|                 continue  | 
|             fpExTotal += curSkilData.GetFightPower()  | 
|         petItemNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|         petIpyData = GetPetIpydata(petItemNPCID)  | 
|         if not petIpyData:  | 
|             continue  | 
|         fpExTotal += petIpyData.GetInitFightPower() # ³õʼսÁ¦  | 
|         #¾õÐÑÕ½Á¦  | 
|         skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (2, petItemNPCID), 0)  | 
|         skinIpyData = IpyGameDataPY.GetIpyGameDataNotLog('HorsePetSkin', 2, petItemNPCID, skinData/100)  | 
|         if skinIpyData:  | 
|             for attrID, attrValue in skinIpyData.GetAttrInfo().items():  | 
|                 PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListPetSkin)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_PetSkin, allAttrListPetSkin)  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_Pet, fpExTotal)  | 
| #    GameWorld.DebugLog("³èÎï°ñNPCID: %s, petDict=%s" % (billPetNPCID, str(billPetDict)))  | 
|     return  | 
|   | 
| ## »ñÈ¡ÁéÊÞ³öսʱµÄ¹¥»÷Á¦  | 
| def GetPetAtkValue(curPlayer):  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Pet):  | 
|         #GameWorld.DebugLog(' ³èÎ﹦ÄÜ먦Æô')  | 
|         return 0, 0  | 
|       | 
|     classAddAtk = 0  | 
|     petPackIndex = ShareDefine.rptPet  | 
|     petPack = curPlayer.GetItemManager().GetPack(petPackIndex)  | 
|     for i in range(petPack.GetCount()):  | 
|         packItem = petPack.GetAt(i)  | 
|         if packItem.IsEmpty():  | 
|             continue  | 
|         petItemNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)  | 
|         classlv = packItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)  | 
|         classIpyData = IpyGameDataPY.GetIpyGameData("PetClassCost", petItemNPCID, classlv + 1)  | 
|         classAddAtk += (classIpyData.GetAtkAdd() if classIpyData else 0)  | 
|     totalMinAtk = classAddAtk  | 
|     totalMaxAtk = classAddAtk  | 
|     return totalMinAtk, totalMaxAtk  | 
|   | 
| def OnPlayerPetLogin(curPlayer):  | 
|     ## µÇ¼´¦Àí  | 
|     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Pet):  | 
|         return  | 
|       | 
|     # ÅàÑøÊǺóÃæ¼ÓµÄ¹¦ÄÜ£¬Ã¿´ÎµÇ¼²¹¼ì²éһϹ¦ÄÜ¿ªÊ¼Ê±ÉèÖÃΪÅàÑø1¼¶  | 
|     for trainType in xrange(1, GetPetTrainTypes() + 1):  | 
|         if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType) == 0:  | 
|             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, 1)  | 
|               | 
|     Sync_PetTrainData(curPlayer)  | 
|     return  | 
|   | 
| def GetPetTrainTypes():  | 
|     return len(IpyGameDataPY.GetFuncEvalCfg("PetUpItem", 3))  | 
|   | 
| #// A7 05 ³èÎïÅàÑø #tagCMPetTrain  | 
| #  | 
| #struct    tagCMPetTrain  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        TrainType;        //ÅàÑøÀàÐÍ£º 1-»ù´¡ÅàÑø£¬2-ÌØÊâÅàÑø£¬3-°Ù·Ö±ÈÅàÑø  | 
| #    WORD        UseItemCnt;        //ÏûºÄ²ÄÁϸöÊý  | 
| #};  | 
| def OnPetTrain(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     trainType = clientData.TrainType # ÅàÑøÀàÐÍ  | 
|     costItemCount = clientData.UseItemCnt # ÏûºÄ²ÄÁϸöÊý  | 
|       | 
|     trainLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType)  | 
|     curEatItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainItemCount % trainType)  | 
|     GameWorld.DebugLog("Áé³èÅàÑø: trainType=%s,trainLV=%s,costItemCount=%s,curEatItemCount=%s"   | 
|                        % (trainType, trainLV, costItemCount, curEatItemCount))  | 
|       | 
|     if trainType <= 0 or trainType > GetPetTrainTypes():  | 
|         return  | 
|       | 
|     if trainLV <= 0:  | 
|         GameWorld.DebugLog("    ÅàÑøÎ´¼¤»î  trainType=%s" % trainType)  | 
|         return  | 
|       | 
|     trainIpyData = IpyGameDataPY.GetIpyGameData("PetTrain", trainType, trainLV)  | 
|     if not trainIpyData:  | 
|         return  | 
|       | 
|     needRealmLV = trainIpyData.GetNeedRealmLV()  | 
|     curRealmLV = curPlayer.GetOfficialRank()  | 
|     if curRealmLV < needRealmLV:  | 
|         GameWorld.DebugLog("    ¾³½ç²»×㣬ÎÞ·¨ÅàÑø£¡  curRealmLV(%s) < needRealmLV(%s)" % (curRealmLV, needRealmLV))  | 
|         return  | 
|       | 
|     needEatCountTotal = trainIpyData.GetEatCntTotal()  | 
|     if not needEatCountTotal:  | 
|         GameWorld.DebugLog("    ¸ÃÅàÑøÒÑÂú¼¶£¡")  | 
|         return  | 
|       | 
|     costItemIDList = IpyGameDataPY.GetFuncEvalCfg("PetUpItem", 3)  | 
|     costItemID = costItemIDList[trainType - 1]  | 
|     if not costItemID or not costItemCount:  | 
|         return  | 
|       | 
|     costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)  | 
|     lackCnt = costItemCount - bindCnt - unBindCnt  | 
|     if lackCnt > 0:  | 
|         GameWorld.DebugLog("    ÏûºÄµÀ¾ß²»×㣬ÎÞ·¨ÅàÑø!costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s"   | 
|                            % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt))  | 
|         return  | 
|       | 
|     delCnt = costItemCount  | 
|       | 
|     # ¿Û³ýÏûºÄ  | 
|     if delCnt:  | 
|         ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delCnt, ChConfig.ItemDel_Pet)  | 
|           | 
|     updClassLV = trainLV  | 
|     updEatItemCount = curEatItemCount + costItemCount  | 
|     GameWorld.DebugLog("    updEatItemCount=%s,needEatCountTotal=%s" % (updEatItemCount, needEatCountTotal))  | 
|       | 
|     if updEatItemCount >= needEatCountTotal:  | 
|         updClassLV += 1  | 
|         updEatItemCount -= needEatCountTotal  | 
|         GameWorld.DebugLog("    ½ø½×: updClassLV=%s,updEatItemCount=%s" % (updClassLV, updEatItemCount))  | 
|           | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, updClassLV)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainItemCount % trainType, updEatItemCount)  | 
|       | 
|     # Éý½×  | 
|     if updClassLV > trainLV:  | 
|         pass  | 
|       | 
|     Sync_PetTrainData(curPlayer)  | 
|     # Ë¢ÊôÐÔ£¬¸üÐÂÅÅÐаñ  | 
|     RefreshPetItemAddAttr(curPlayer, True)  | 
|     return  | 
|   | 
| def Sync_PetTrainData(curPlayer):  | 
|     clientPack = ChPyNetSendPack.tagMCPetTrainInfo()  | 
|     clientPack.TrainLVList = []  | 
|     clientPack.TrainItemCountList = []  | 
|     for trainType in xrange(1, GetPetTrainTypes() + 1):  | 
|         clientPack.TrainLVList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainLV % trainType))  | 
|         clientPack.TrainItemCountList.append(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_PetTrainItemCount % trainType))  | 
|     clientPack.TrainTypes = len(clientPack.TrainLVList)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   |