From 776cf3759b9801f3795ee975cd77078f505b90d6 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期六, 06 一月 2024 14:49:08 +0800
Subject: [PATCH] 10071 【后端】灵宠改版

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py |  510 +++++++++++++++++---------------------------------------
 1 files changed, 159 insertions(+), 351 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
index 8021f3a..9a5614c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -34,57 +34,36 @@
 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 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 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)
@@ -116,62 +95,28 @@
         return
     
     newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_NPCID, petNPCID)
-    newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_State, ShareDefine.Def_PetState_Null)
+    newPetItem.SetUserAttr(ShareDefine.Def_IudetPet_State, 0)
     
     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)
-    
+    __UpdPetItemSkillByClass(curPlayer, newPetItem, False)    
     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)
+    packItemIndex = GetPetDataItemByNPCID(curPetOwner, rolePet.GetNPCID())
     return GetPetDataItemByIndex(curPetOwner, packItemIndex)
 
 ## 获取宠物数据物品
 def GetPetDataItemByIndex(curPlayer, petItemIndex):
     
     petDataPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)
+    if petItemIndex < 0 or petItemIndex >= petDataPack.GetCount():
+        return
     petDataItem = petDataPack.GetAt(petItemIndex)
     if not ItemCommon.CheckItemCanUse(petDataItem):
         GameWorld.DebugLog("PetDataItem is none! PetItemIndex=%s" % petItemIndex, curPlayer.GetPlayerID())
@@ -190,10 +135,6 @@
             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)
@@ -206,8 +147,33 @@
         
     return -1
 
-#===================================================================================================
-# //////////////////////////////////////////////////////////////
+def GetPetItemCacheDict(petItem):
+    ## 单个灵宠物品缓存信息
+    npcID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
+    state = petItem.GetUserAttr(ShareDefine.Def_IudetPet_State)
+    classLV = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)
+    quality = petItem.GetUserAttr(ShareDefine.Def_IudetPet_QualityLV)
+    star = petItem.GetUserAttr(ShareDefine.Def_IudetPet_Star)
+    skills = [petItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i) for i in xrange(petItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill))]
+    cacheDict = {"npcID":npcID}
+    state and cacheDict.update({"state":state})
+    classLV and cacheDict.update({"classLV":classLV})
+    quality and cacheDict.update({"quality":quality})
+    star and cacheDict.update({"star":star})
+    skills and cacheDict.update({"skills":skills})
+    return cacheDict
+
+def GetPetCacheInfo(curPlayer):
+    ## 获取灵宠功能缓存信息,暂时缓存全部,如果有需要改为仅缓存上阵的
+    itemCacheList = []
+    petDataPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)
+    for petDataIndex in range(petDataPack.GetCount()):
+        petItem = petDataPack.GetAt(petDataIndex)
+        if petItem.IsEmpty():
+            continue
+        itemCacheList.append(GetPetItemCacheDict(petItem))
+    return itemCacheList
+
 # //16 03 宠物出战/召回#tagCPetStateChange
 # tagCPetStateChange       *   GettagCPetStateChange();
 # 
@@ -219,203 +185,77 @@
 #    // 状态.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
+def DoChangePetState(curPlayer, petItemIndex, tagState):
+    # @param tagState: 0-收回;>=1-出战在第几个位置
     
-    if tagState not in ShareDefine.Def_PetStateList:
-        return
-        
     petItem = GetPetDataItemByIndex(curPlayer, petItemIndex)
     if not petItem:
         return
     
+    playerID = curPlayer.GetPlayerID()
+    petNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
+    curState = petItem.GetUserAttr(ShareDefine.Def_IudetPet_State)
+    GameWorld.DebugLog("宠物状态变更! petItemIndex=%s,petNPCID=%s,curState=%s,tagState=%s" 
+                       % (petItemIndex, petNPCID, curState, tagState), playerID)
+    # 收回
+    if tagState <= 0:
+        SetPetState(curPlayer, petItem, tagState)
+        return
+    
+    gooutFightRealmList = IpyGameDataPY.GetFuncEvalCfg("PetGoOutFight", 1)
+    if tagState > len(gooutFightRealmList):
+        GameWorld.DebugLog("    不存在该灵宠上阵位置! tagState=%s" % tagState, playerID)
+        return
+    needRealmLV = gooutFightRealmList[tagState - 1]
+    curRealmLV = curPlayer.GetOfficialRank()
+    if curRealmLV < needRealmLV:
+        GameWorld.DebugLog("    境界不足,无法上阵灵兽! curRealmLV=%s < %s, tagState=%s" % (curRealmLV, curRealmLV, tagState), playerID)
+        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)
+        GameWorld.DebugLog('    灵兽切换外观,阶级不足%s,不可切换!' % needClasslv, playerID)
         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:
-#            #已是出战状态, 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 因为某种未知原因宠物物品的状态是出战(实际场景中未出战),导致该宠物无法出战,故再次发包出战时,此处不拦!
-        PetControl.ReCallFightPet(curPlayer)
-   
+    SetPetState(curPlayer, petItem, tagState)
+    return
+
+def SetPetState(curPlayer, petItem, tagState):
+    ## 设置灵宠出战状态
+    # @param tagState: 0-收回;>=1-出战在第几个位置
+    npcID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
+    if tagState <= 0:
+        GameWorld.DebugLog("    灵宠下阵: npcID=%s" % npcID, curPlayer.GetPlayerID())
     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)
-        
+        petDataPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)
+        for index in range(petDataPack.GetCount()):
+            item = petDataPack.GetAt(index)
+            if item.IsEmpty():
+                continue
+            if item.GetUserAttr(ShareDefine.Def_IudetPet_State) == tagState:
+                SetPetState(curPlayer, item, 0)
+        GameWorld.DebugLog("    灵宠上阵: npcID=%s,tagState=%s" % (npcID, tagState), curPlayer.GetPlayerID())
+    petItem.SetUserAttr(ShareDefine.Def_IudetPet_State, tagState)
     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
-
-    # 先招回出战中的宠物
-    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
 
 ## 获取出战宠物要学的技能
@@ -508,16 +348,7 @@
     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)
     
     # 开服活动数据
@@ -550,6 +381,7 @@
                 packItem.SetUserAttr(ShareDefine.Def_IudetPet_ClassLV, max(0, min(classlv, maxClassLV) - 1))
             packItem.SetUserAttr(ShareDefine.Def_IudetPet_QualityLV, quality) # 宠物品质
             GameWorld.DebugLog("已经拥有该宠物! i=%s,petItemNPCID=%s,petNPCID=%s" % (i, petItemNPCID, petNPCID))
+            __UpdPetItemSkillByClass(curPlayer, packItem, True)
             return True
         
     if classlv == None:
@@ -564,25 +396,8 @@
         return
     if not refresh:
         return True
-    petItemIndex = GetPetDataItemIndexByNPCID(curPlayer, petNPCID)
-    DoChangePetState(curPlayer, petItemIndex, ShareDefine.Def_PetState_Fight)
     RefreshPetItemAddAttr(curPlayer, True)
     return True
-#===============================================================================
-
-
-## 获取已激活的灵兽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
 #
@@ -676,35 +491,22 @@
     
     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)
+    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
+        updClassLV += 1
         
     
     #扣除物品
@@ -713,42 +515,14 @@
         ItemCommon.ReduceItem(curPlayer, curItemPack, itemIndexList, delCnt, True, ChConfig.ItemDel_Pet)
         
     # 更新经验值
-    if updClassLV+1 >=maxClassLV:
-        updExp =0
+    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)
-            
+        learnSkillList = __UpdPetItemSkillByClass(curPlayer, petDataItem, True)
+        
         if not learnSkillList and updClassLV + 1 == maxClassLV:
             PlayerControl.WorldNotify(0, 'PetUpLvMax', [playerName, petNPCID])
         # 如果是当前出战的宠物, 则该宠物学习技能
@@ -769,6 +543,65 @@
     #EventReport.WriteEvent_pet_class(curPlayer, petNpcData.GetName(), classLV, petClassExp, updClassLV, newClassExp)
     
     return
+
+def __UpdPetItemSkillByClass(curPlayer, petDataItem, isNotify=False):
+    # 升阶更新灵宠技能,支持同skillTypeID技能升级
+    playerName = curPlayer.GetName()
+    petNPCID = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
+    classLV = petDataItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV) + 1
+    alreadyLearnSkillInfo = {}
+    for i in xrange(petDataItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)):
+        skillID = petDataItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i)
+        skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
+        if not skillData:
+            continue
+        skillTypeID = skillData.GetSkillTypeID()
+        alreadyLearnSkillInfo[skillTypeID] = [skillID, i]
+    #GameWorld.DebugLog("开始更新灵宠技能: petNPCID=%s,classLV=%s,alreadyLearnSkillInfo=%s" % (petNPCID, classLV, alreadyLearnSkillInfo))
+    
+    petIpyData = GetPetIpydata(petNPCID)
+    petSkillList = petIpyData.GetSkillID()
+    petSkillUnLockList = petIpyData.GetSkillUnLock()
+    sysMarkList = petIpyData.GetSkillUnLockSys()
+    learnSkillList = []
+    for i, skillID in enumerate(petSkillList):
+        limitPetClassLV = petSkillUnLockList[i] # 学习此技能所需宠物阶级
+        if classLV < limitPetClassLV:
+            #GameWorld.DebugLog("    未满足学习阶级: i=%s,skillID=%s,limitPetClassLV=%s" % (i, skillID, limitPetClassLV))
+            break
+        skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
+        if not skillData:
+            continue
+        skillTypeID = skillData.GetSkillTypeID()
+        alreadyLearnSkillID, skillIndex = alreadyLearnSkillInfo.get(skillTypeID, [0, -1])
+        if skillID <= alreadyLearnSkillID:
+            #GameWorld.DebugLog("    技能已经学习过: i=%s,skillID=%s <= alreadyLearnSkillID=%s" % (i, skillID, alreadyLearnSkillID))
+            continue
+        if skillData.GetFuncType() == ChConfig.Def_SkillFuncType_PetOwnerSkill:
+            #GameWorld.DebugLog("    主人学习技能: i=%s,skillID=%s" % (i, skillID))
+            SkillCommon.GivePlayerSkillByJobSkill(curPlayer, [skillID])
+            continue
+        if not alreadyLearnSkillID:
+            #GameWorld.DebugLog("    学习新的技能: i=%s,skillID=%s" % (i, skillID))
+            petDataItem.AddUserAttr(ShareDefine.Def_IudetPet_Skill, skillID)
+        else:
+            #GameWorld.DebugLog("    学习升级技能: i=%s,skillID=%s,skillIndex=%s" % (i, skillID, skillIndex))
+            petDataItem.UpdataUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, skillIndex, skillID)
+        if not SkillCommon.isPassiveAttr(skillData):
+            #被动技能不学
+            learnSkillList.append(skillID)
+        #广播
+        sysMark = sysMarkList[i] if i < len(sysMarkList) else 'PetUpLv'
+        if isNotify and sysMark:
+            PlayerControl.WorldNotify(0, sysMark, [playerName, petNPCID, limitPetClassLV, skillID])
+        #增加升级活跃点效果
+        PlayerActivity.AddActivityByLVOnLearnSkill(curPlayer, skillID)
+        
+    nowSkillIDList = []
+    for i in xrange(petDataItem.GetUserAttrCount(ShareDefine.Def_IudetPet_Skill)):
+        nowSkillIDList.append(petDataItem.GetUserAttrByIndex(ShareDefine.Def_IudetPet_Skill, i))
+    GameWorld.DebugLog("灵宠最新技能: nowSkillIDList=%s" % nowSkillIDList)
+    return learnSkillList
 
 def GetTotalPetLV(curPlayer):
     totalPetLV = 0
@@ -801,18 +634,6 @@
         totalPetCount += 1
     return totalPetCount
 
-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)
@@ -823,9 +644,9 @@
     else:
         PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState(isForce=True)
         
-    fightPet = curPlayer.GetPetMgr().GetFightPet()
-    if fightPet:
-        PetControl.RefurbishPetAttr(fightPet)
+    #fightPet = curPlayer.GetPetMgr().GetFightPet()
+    #if fightPet:
+    #    PetControl.RefurbishPetAttr(fightPet)
     return
 
 def CalcSkill_PetBattleEffect(curPlayer, rolePet, allAttrListPet):
@@ -968,7 +789,7 @@
         fpExTotal += petIpyData.GetInitFightPower() # 初始战力
         #觉醒战力
         skinData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorsePetSkinData % (2, petItemNPCID), 0)
-        skinIpyData = IpyGameDataPY.GetIpyGameDataNotLog('HorsePetSkin', 2, petItemNPCID, skinData/100)
+        skinIpyData = IpyGameDataPY.GetIpyGameDataNotLog('HorsePetSkin', 2, petItemNPCID, skinData / 100)
         if skinIpyData:
             for attrID, attrValue in skinIpyData.GetAttrInfo().items():
                 PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListPetSkin)
@@ -1020,19 +841,6 @@
     totalMinAtk = classAddAtk
     totalMaxAtk = classAddAtk
     return totalMinAtk, totalMaxAtk, qualityAttrInfo
-
-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))

--
Gitblit v1.8.0