| | |
| | | DWORD _DataMapID; //数据地图ID
|
| | | WORD _LineID; //功能线路ID
|
| | | DWORD NPCID; //NPCID
|
| | | DWORD SummerNPCID; //召唤兽ID
|
| | | list PetNPCIDList; //灵宠NPCID列表
|
| | | list AwardItemListFirst; //首次过关奖励列表[[物品ID,个数,是否拍品], ...]
|
| | | list AwardItemList; //再次过关奖励列表[[物品ID,个数,是否拍品], ...]
|
| | | };
|
| | |
| | | fbFightPower = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBFightPower)
|
| | | fbBaseHurt = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.FBPD_HelpBattleFBBaseHurt)
|
| | | helpBattleFormatKey = "HelpRobot_Def"
|
| | | if atkObjType == IPY_GameWorld.gotNPC and PetControl.IsPetNPC(atkObj):
|
| | | mustHit = True
|
| | |
|
| | | #命中公式 攻击方类型不同,公式不同
|
| | | hitFormula = ReadChConfig.GetChConfig('CalcCanHit')
|
| | |
| | | return "HelpRobot"
|
| | | if obj.GetType() in ChConfig.PVPNPCTypeList:
|
| | | return "P"
|
| | | if obj.GetType() == IPY_GameWorld.ntPet:
|
| | | return "Pet"
|
| | |
|
| | | objType = obj.GetGameNPCObjType()
|
| | | if objType == IPY_GameWorld.gnotPet:
|
| | |
| | | # @param None
|
| | | # @return 攻击形式字符串
|
| | | def GetAtkState(atkObj, defObj):
|
| | | isPet = PetControl.IsPet(atkObj)
|
| | | isPet = PetControl.IsPetNPC(atkObj)
|
| | | if IsPVENPCObj(atkObj) or IsPVENPCObj(defObj):
|
| | | return 'PVE_%s' if not isPet else 'PetVE_%s'
|
| | |
|
| | |
| | | import NPCCommon |
| | | import GameWorld |
| | | import GameObj |
| | | import PetControl |
| | | |
| | | ( |
| | | FightState_Start, |
| | |
| | | FightState_Fail, |
| | | FightState_Over, |
| | | ) = range(5) |
| | | |
| | | def GetObjName(gameObj): |
| | | objName = gameObj.GetName() |
| | | faction = GameObj.GetFaction(gameObj) |
| | | fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) |
| | | return "%s%s %s" % ("A" if faction == 1 else "B", fightPlaceNum, objName) |
| | | |
| | | #// B4 10 回合制战斗 #tagCMTurnFight |
| | | # |
| | |
| | | SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Start) |
| | | |
| | | if tagPlayerID: |
| | | PlayerViewCacheTube.GetPlayerPropDataCall(curPlayer, tagPlayerID, DoTrunFightVSPlayer, [mapID, funcLineID]) |
| | | PlayerViewCacheTube.GetPlayerPropDataCall(curPlayer, tagPlayerID, DoTrunFightVSPlayer, [mapID, funcLineID], True) |
| | | return |
| | | |
| | | DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick) |
| | |
| | | def DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick): |
| | | playerID = curPlayer.GetPlayerID() |
| | | posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY() |
| | | |
| | | factionListA, factionListB = [], [] |
| | | factionListA.append(curPlayer) |
| | | curPet = curPlayer.GetPetMgr().GetFightPet() |
| | | curPet and factionListA.append(curPet) |
| | | |
| | | # 玩家阵营的其他战斗实例,可扩展... |
| | | assistNPCID = 0 # 协助召唤兽 |
| | | if assistNPCID: |
| | | assistNPC = NPCCommon.SummonNPC(curPlayer, assistNPCID, posX, posY) |
| | | assistNPC and factionListA.append(assistNPC) |
| | | |
| | | GameWorld.DebugLog("===== 执行回合制战斗: mapID=%s,funcLineID=%s,tagPlayerID=%s" % (mapID, funcLineID, tagPlayerID), playerID) |
| | | tagObj = None |
| | | if tagPlayerID: |
| | | npcID = ChConfig.Def_NPCID_PVP |
| | | tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID, pvpPlayerID=tagPlayerID) |
| | | if not tagObj: |
| | | return |
| | | factionListB.append(tagObj) |
| | | |
| | | # 对手玩家镜像的其他战斗实例... |
| | | |
| | | PlusData = PlayerViewCacheTube.GetPlayerPropPlusDictByID(playerID)[1] # 从缓存中获取 |
| | | petCacheInfo = PlusData.get("Pet") |
| | | fightPetObjListB = PetControl.CalloutFightPet(tagObj, petCacheInfo) |
| | | else: |
| | | ipyData = IpyGameDataPY.GetIpyGameData("FBTurn", mapID, funcLineID) |
| | | if not ipyData: |
| | |
| | | tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID) |
| | | if not tagObj: |
| | | return |
| | | factionListB.append(tagObj) |
| | | summerNPCID = ipyData.GetSummerNPCID() |
| | | if summerNPCID: |
| | | summerNPC = NPCCommon.SummonNPC(tagObj, summerNPCID, posX, posY) |
| | | summerNPC and factionListB.append(summerNPC) |
| | | |
| | | if not factionListB: |
| | | return |
| | | |
| | | for gameObj in factionListA: |
| | | GameObj.SetFaction(gameObj, 1) |
| | | for gameObj in factionListB: |
| | | GameObj.SetFaction(gameObj, 2) |
| | | petNPCIDList = ipyData.GetPetNPCIDList() |
| | | petCacheInfo = [] # 从配表中读取组合,技能默认取NPC表配置的 |
| | | for state, petNPCID in enumerate(petNPCIDList, 1): |
| | | petCacheInfo.append({"npcID":petNPCID, "state":state, "quality":0}) |
| | | fightPetObjListB = PetControl.CalloutFightPet(tagObj, petCacheInfo) |
| | | |
| | | #一个回合攻击顺序,由攻击速度决定,攻速相同下阵营1先攻击,还相同则由ID决定 |
| | | fightObjList = factionListA + factionListB |
| | | fightObjList.sort(key=lambda o: (GameObj.GetAtkSpeed(o), (10 - GameObj.GetFaction(o)), o.GetID()), reverse=True) |
| | | |
| | | turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1) |
| | | GameWorld.DebugLog("===== 执行回合制战斗: mapID=%s,funcLineID=%s,tagPlayerID=%s,tagObjID=%s" |
| | | % (mapID, funcLineID, tagPlayerID, tagObj.GetID()), playerID) |
| | | # 战斗前初始化 |
| | | for gameObj in fightObjList: |
| | | TurnFightObjStartInit(gameObj) |
| | | |
| | | # 宠物先攻击 |
| | | fightPetObjListA = PetControl.CalloutFightPet(curPlayer) |
| | | factionListA = fightPetObjListA + [curPlayer] |
| | | factionListB = fightPetObjListB + [tagObj] |
| | | atkFactionList = [factionListA, factionListB] |
| | | |
| | | # 战斗前初始化,可能会改变攻速,所以先初始化 |
| | | for faction, factionObjList in enumerate(atkFactionList, 1): |
| | | for gameObj in factionObjList: |
| | | TurnFightObjStartInit(gameObj, faction, tick) |
| | | |
| | | #一个回合攻击顺序,为了后续逻辑统一,都是先确定好顺序 |
| | | sortType = 2 # 攻击顺序排序方式 |
| | | fightObjList = [] |
| | | #方式1: 纯由攻击速度决定,攻速相同下阵营1先攻击,还相同则由ID决定 |
| | | if sortType == 1: |
| | | fightObjList = factionListA + factionListB |
| | | fightObjList.sort(key=lambda o: (GameObj.GetAtkSpeed(o), (10 - GameObj.GetFaction(o)), o.GetID()), reverse=True) |
| | | #方式2:根据阵营主角攻速决定先手,然后每个阵营轮流固定位置攻击 |
| | | elif sortType == 2: |
| | | if GameObj.GetAtkSpeed(curPlayer) < GameObj.GetAtkSpeed(tagObj): |
| | | atkFactionList = [factionListB, factionListA] |
| | | for i in range(len(factionListA)): |
| | | for factionObjList in atkFactionList: |
| | | fightObjList.append(factionObjList[i]) |
| | | |
| | | isWin = None |
| | | for turnNum in range(1, turnMax + 1): |
| | | GameWorld.DebugLog("----- 回合制战斗轮次: %s -----" % turnNum, playerID) |
| | | GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】" % turnNum) |
| | | SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Fighting, turnNum, turnMax) |
| | | |
| | | # 回合开始: 做一些每回合重置逻辑或者某些根据回合触发的效果等 |
| | |
| | | TurnFightObjPerTurnStart(gameObj, turnNum, tick) |
| | | |
| | | # 回合战斗: 轮流依次攻击 |
| | | for actNum, gameObj in enumerate(fightObjList, 1): |
| | | if not gameObj: |
| | | for gameObj in fightObjList: |
| | | if not gameObj or GameObj.GetHP(gameObj) <= 0: |
| | | continue |
| | | faction = GameObj.GetFaction(gameObj) |
| | | tagGameObj = tagObj if faction == 1 else curPlayer |
| | | objType = gameObj.GetGameObjType() |
| | | objID = gameObj.GetID() |
| | | objName = GetObjName(gameObj) |
| | | curHP = GameObj.GetHP(gameObj) |
| | | |
| | | tagGameObj = tagObj if faction == 1 else curPlayer |
| | | tagObjType = tagGameObj.GetGameObjType() |
| | | tagObjID = tagGameObj.GetID() |
| | | tagHP = GameObj.GetHP(tagGameObj) |
| | | |
| | | GameWorld.DebugLog(" 行动: turnNum=%s,actNum=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s" |
| | | % (turnNum, actNum, faction, objType, objID, tagObjType, tagObjID)) |
| | | GameWorld.DebugLog(" ★回合%s %s 行动 : objType-ID-HP(%s-%s-%s), tagType-ID-HP(%s-%s-%s)" |
| | | % (turnNum, objName, objType, objID, curHP, tagObjType, tagObjID, tagHP)) |
| | | SyncTurnFightObjAction(curPlayer, turnNum, objType, objID) |
| | | |
| | | DoAttack(gameObj, tagGameObj, tick) |
| | |
| | | % (mapID, funcLineID, tagPlayerID, isWin, overState), playerID) |
| | | return |
| | | |
| | | def TurnFightObjStartInit(gameObj): |
| | | def TurnFightObjStartInit(gameObj, faction, tick): |
| | | ## 回合制战斗实例初始化 |
| | | if not gameObj: |
| | | return |
| | | |
| | | gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 1) |
| | | GameObj.SetFaction(gameObj, faction) |
| | | GameObj.SetHPFull(gameObj) |
| | | gameObj.RefreshView() |
| | | |
| | | objType = gameObj.GetGameObjType() |
| | | npcID = gameObj.GetNPCID() if objType == IPY_GameWorld.gotNPC else 0 |
| | | GameWorld.DebugLog("初始化实例: objID=%s,npcID=%s,faction=%s,atkSpeed=%s,HP=%s,Atk=%s,Def=%s" |
| | | % (gameObj.GetID(), npcID, GameObj.GetFaction(gameObj), GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj), gameObj.GetMaxAtk(), gameObj.GetDef())) |
| | | GameWorld.DebugLog(" 闪命(%s,%s),闪避(%s,%s),暴击(%s,%s),击晕(%s,%s),连击(%s,%s),反击(%s,%s),吸血(%s,%s)" |
| | | % (gameObj.GetMiss(), gameObj.GetHit(), |
| | | GameObj.GetMissRate(gameObj), GameObj.GetMissDefRate(gameObj), |
| | | objName = GetObjName(gameObj) |
| | | fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) |
| | | |
| | | GameWorld.DebugLog("【 %s 初始化 %s 】 objID=%s,npcID=%s,atkSpeed=%s,HP=%s,Atk=%s,Def=%s" |
| | | % (objName, BaseAttack.GetObjAttackName(gameObj), gameObj.GetID(), npcID, |
| | | GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj), gameObj.GetMaxAtk(), gameObj.GetDef())) |
| | | GameWorld.DebugLog(" 闪避(%s,%s),暴击(%s,%s),击晕(%s,%s),连击(%s,%s),反击(%s,%s),吸血(%s,%s)" |
| | | % (GameObj.GetMissRate(gameObj), GameObj.GetMissDefRate(gameObj), |
| | | GameObj.GetSuperHitRate(gameObj), GameObj.GetSuperHitRateReduce(gameObj), |
| | | GameObj.GetFaintRate(gameObj), GameObj.GetFaintDefRate(gameObj), |
| | | GameObj.GetComboRate(gameObj), GameObj.GetComboDefRate(gameObj), |
| | |
| | | if objType == IPY_GameWorld.gotPlayer: |
| | | skillManager = gameObj.GetSkillManager() |
| | | for i in range(skillManager.GetSkillCount()): |
| | | skill = skillManager.GetSkillByIndex(i) |
| | | skill.SetRemainTime(0) |
| | | curSkill = skillManager.GetSkillByIndex(i) |
| | | curSkill.SetRemainTime(0) |
| | | |
| | | elif objType == IPY_GameWorld.gotNPC: |
| | | pass |
| | | skillIDList = [] |
| | | skillManager = gameObj.GetSkillManager() |
| | | for i in range(skillManager.GetSkillCount()): |
| | | curSkill = skillManager.GetSkillByIndex(i) |
| | | if not curSkill: |
| | | continue |
| | | skillIDList.append(curSkill.GetSkillID()) |
| | | if fightPlaceNum: |
| | | # 灵宠技能开始时直接进入CD |
| | | curSkill.SetLastUseTick(tick) |
| | | curSkill.SetRemainTime(curSkill.GetCoolDownTime()) |
| | | GameWorld.DebugLog(" NPC技能: npcID=%s,skillIDList=%s" % (npcID, skillIDList)) |
| | | |
| | | return |
| | | |
| | | def TurnFightObjPerTurnStart(gameObj, turnNum, tick): |
| | |
| | | |
| | | objType = gameObj.GetGameObjType() |
| | | objID = gameObj.GetID() |
| | | GameWorld.DebugLog("ObjPerTurnStart: faction=%s,objType=%s,objID=%s,turnNum=%s,HP=%s" % (GameObj.GetFaction(gameObj), objType, objID, turnNum, GameObj.GetHP(gameObj))) |
| | | objName = GetObjName(gameObj) |
| | | GameWorld.DebugLog("ObjPerTurnStart: 回合%s, %s objType-ID-HP(%s-%s-%s)" % (turnNum, objName, objType, objID, GameObj.GetHP(gameObj))) |
| | | |
| | | # 每回合开始减技能CD |
| | | skillManager = gameObj.GetSkillManager() |
| | |
| | | |
| | | def CanAtkBack(atkObj, defObj): |
| | | ## 可否反击 |
| | | |
| | | if atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) > 0: |
| | | #GameWorld.DebugLog(" 被灵宠攻击时无法触发反击") |
| | | return False |
| | | defAtkBackRate = GameObj.GetAtkBackRate(defObj) # 防方反击率 |
| | | atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # 已反击次数 |
| | | if atkBackNum > 10: |
| | |
| | | ## NPC攻击 |
| | | if not curObj: |
| | | return |
| | | |
| | | objName = "● %s" % GetObjName(curObj) |
| | | #有值代表灵宠上阵位置,判断是否有概率攻击 |
| | | fightPlaceNum = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) |
| | | if fightPlaceNum > 0: |
| | | fightRateList = IpyGameDataPY.GetFuncEvalCfg("PetGoOutFight", 2) |
| | | if fightPlaceNum > len(fightRateList): |
| | | return |
| | | fightRatePer = fightRateList[fightPlaceNum - 1] |
| | | |
| | | qualityAddRateInfo = IpyGameDataPY.GetFuncEvalCfg("PetGoOutFight", 3, {}) |
| | | petQuality = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetQuality) |
| | | qualityAddPer = qualityAddRateInfo.get(str(petQuality), 0) |
| | | fightRatePer += qualityAddPer |
| | | if fightRatePer < 100 and not GameWorld.CanHappen(fightRatePer, 100): |
| | | GameWorld.DebugLog(" 灵宠概率不攻击: curID=%s,fightPlaceNum=%s,petQuality=%s,fightRatePer=%s" |
| | | % (curObj.GetID(), fightPlaceNum, petQuality, fightRatePer)) |
| | | return |
| | | |
| | | tagDist = 0 |
| | | atkOK = AICommon.DoAutoUseSkill(curObj, tagObj, tagDist, tick) |
| | | #---优先释放技能--- |
| | | if not atkOK: |
| | | #普通攻击 |
| | | atkOK = BaseAttack.Attack(curObj, tagObj, None, tick) |
| | | if atkOK: |
| | | GameWorld.DebugLog(" NPC普通攻击: curID=%s,tagID=%s,atkOK=%s" % (curObj.GetID(), tagObj.GetID(), atkOK)) |
| | | if fightPlaceNum: |
| | | GameWorld.DebugLog(" 灵宠不可普通攻击: curID=%s,fightPlaceNum=%s" % (curObj.GetID(), fightPlaceNum)) |
| | | else: |
| | | GameWorld.DebugLog(" NPC攻击失败: curID=%s,tagID=%s,atkOK=%s" % (curObj.GetID(), tagObj.GetID(), atkOK)) |
| | | #普通攻击 |
| | | atkOK = BaseAttack.Attack(curObj, tagObj, None, tick) |
| | | if atkOK: |
| | | GameWorld.DebugLog(" %s 普通攻击: curID=%s,tagID=%s,atkOK=%s" % (objName, curObj.GetID(), tagObj.GetID(), atkOK)) |
| | | else: |
| | | GameWorld.DebugLog(" %s 攻击失败: curID=%s,tagID=%s,atkOK=%s" % (objName, curObj.GetID(), tagObj.GetID(), atkOK)) |
| | | else: |
| | | GameWorld.DebugLog(" NPC技能攻击: curID=%s,tagID=%s,atkOK=%s" % (curObj.GetID(), tagObj.GetID(), atkOK)) |
| | | GameWorld.DebugLog(" %s 技能攻击: curID=%s,tagID=%s,atkOK=%s" % (objName, curObj.GetID(), tagObj.GetID(), atkOK)) |
| | | return atkOK |
| | | |
| | | def PlayerAttack(curPlayer, tagObj, tick): |
| | |
| | | posX, posY = tagPosX, tagPosY = curPlayer.GetPosX(), curPlayer.GetPosY() |
| | | tagObjType, tagObjID = tagObj.GetGameObjType(), tagObj.GetID() |
| | | |
| | | objName = "● %s" % GetObjName(curPlayer) |
| | | curPlayer.ClearUseSkillRec() |
| | | curPlayer.SetAttackTargetPos(posX, posY) |
| | | curPlayer.SetUseSkillPosX(tagPosX) |
| | |
| | | curPlayer.SetUseSkill(curSkill.GetSkillData()) |
| | | useSkillData = curPlayer.GetUseSkill() |
| | | if not PlayerState.__DoClientUseSkillEx(curPlayer, useSkillData, tick): |
| | | GameWorld.DebugLog(" 玩家技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) |
| | | GameWorld.DebugLog(" %s 技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (objName, playerID, tagObjID, skillID)) |
| | | continue |
| | | useSkillResult = True |
| | | GameWorld.DebugLog(" 玩家技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) |
| | | GameWorld.DebugLog(" %s 技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (objName, playerID, tagObjID, skillID)) |
| | | |
| | | break |
| | | |
| | |
| | | atkOK = BaseAttack.Attack(curPlayer, tagObj, None, tick) |
| | | if atkOK: |
| | | useSkillResult = True |
| | | GameWorld.DebugLog(" 玩家普通攻击: curID=%s,tagID=%s,atkOK=%s" % (playerID, tagObjID, atkOK)) |
| | | GameWorld.DebugLog(" %s 普通攻击: curID=%s,tagID=%s,atkOK=%s" % (objName, playerID, tagObjID, atkOK)) |
| | | else: |
| | | GameWorld.DebugLog(" 玩家攻击失败: curID=%s,tagID=%s,atkOK=%s" % (playerID, tagObjID, atkOK)) |
| | | GameWorld.DebugLog(" %s 攻击失败: curID=%s,tagID=%s,atkOK=%s" % (objName, playerID, tagObjID, atkOK)) |
| | | return useSkillResult |
| | | |
| | | def SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, state, turnNum=0, turnMax=0): |
| | |
| | | Def_Obj_Dict_TurnComboNum = 'TurnComboNum' # 本回合已累计连击次数
|
| | | Def_Obj_Dict_TurnAtkBackNum = 'TurnAtkBackNum' # 本回合已累计反击次数
|
| | | Def_Obj_Dict_TurnBattleType = 'TurnBattleType' # 本次攻击战斗类型:TurnBattleType_xxx
|
| | | Def_Obj_Dict_FightPetPlaceNum = 'FightPetPlaceNum' # 出战灵宠上阵位置,1~n
|
| | | Def_Obj_Dict_FightPetQuality = 'FightPetQuality' # 出战灵宠品质
|
| | |
|
| | | #---NPC字典-------
|
| | | #每道龙卷风最终坐标
|
| | |
| | | ("DWORD", "DataMapID", 1),
|
| | | ("WORD", "LineID", 1),
|
| | | ("DWORD", "NPCID", 0),
|
| | | ("DWORD", "SummerNPCID", 0),
|
| | | ("list", "PetNPCIDList", 0),
|
| | | ("list", "AwardItemListFirst", 0),
|
| | | ("list", "AwardItemList", 0),
|
| | | ),
|
| | |
| | | self.DataMapID = 0
|
| | | self.LineID = 0
|
| | | self.NPCID = 0
|
| | | self.SummerNPCID = 0
|
| | | self.PetNPCIDList = []
|
| | | self.AwardItemListFirst = []
|
| | | self.AwardItemList = [] |
| | | return |
| | |
| | | def GetDataMapID(self): return self.DataMapID # 数据地图ID
|
| | | def GetLineID(self): return self.LineID # 功能线路ID
|
| | | def GetNPCID(self): return self.NPCID # NPCID
|
| | | def GetSummerNPCID(self): return self.SummerNPCID # 召唤兽ID
|
| | | def GetPetNPCIDList(self): return self.PetNPCIDList # 灵宠NPCID列表
|
| | | def GetAwardItemListFirst(self): return self.AwardItemListFirst # 首次过关奖励列表[[物品ID,个数,是否拍品], ...]
|
| | | def GetAwardItemList(self): return self.AwardItemList # 再次过关奖励列表[[物品ID,个数,是否拍品], ...] |
| | | |
| | |
| | | return False
|
| | |
|
| | | #CD时间
|
| | | if tick - useSkill.GetLastUseTick() < useSkill.GetCoolDownTime():
|
| | | #GameWorld.Log('检查CD时间触发失败 = %s'%(useSkill.GetSkillName()))
|
| | | return False
|
| | | |
| | | if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum):
|
| | | if useSkill.GetRemainTime():
|
| | | #GameWorld.Log('技能回合CD中 = %s, %s'%(useSkill.GetSkillName(), useSkill.GetRemainTime()))
|
| | | return False
|
| | | else:
|
| | | if tick - useSkill.GetLastUseTick() < useSkill.GetCoolDownTime():
|
| | | #GameWorld.Log('检查CD时间触发失败 = %s'%(useSkill.GetSkillName()))
|
| | | return False
|
| | | |
| | | curSkillUseTag = SkillShell.GetSkillAffectTag(useSkill)
|
| | | if curSkillUseTag == ChConfig.Def_UseSkillTag_CanAttackPlayer:
|
| | | if curTag.GetGameObjType() != IPY_GameWorld.gotPlayer:
|
| | |
| | |
|
| | | #---对宠物主人释放---
|
| | | if skillTag == ChConfig.Def_UseSkillTag_PetMaster:
|
| | | if not PetControl.IsPet(curNPC):
|
| | | if not PetControl.IsPetNPC(curNPC):
|
| | | GameWorld.ErrLog("该NPC非宠物,无法获得主人释放技能")
|
| | | return False
|
| | |
|
| | | petOwner = PetControl.GetPetOwner(curNPC)
|
| | | petOwner = PetControl.GetPetNPCOwner(curNPC)
|
| | |
|
| | | if petOwner == None:
|
| | | GameWorld.ErrLog("宠物(%s)对主人释放技能,找不到主人"%curNPC.GetRolePet().PetID)
|
| | |
| | | #__NotifyMapPlayerSummonMapNPC(npcId, rebornX, rebornY)
|
| | | return curSummon
|
| | |
|
| | | def SummonNPC(gameObj, npcID, rebornX, rebornY):
|
| | | def SummonNPC(gameObj, npcID, rebornX, rebornY, skillIDList=None):
|
| | | ''' 某个实例进行召唤,有从属关系
|
| | | '''
|
| | | npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
|
| | |
| | | curSummon.SetSightLevel(gameObj.GetSightLevel())
|
| | |
|
| | | curSummon.Reborn(rebornX, rebornY, False)
|
| | | #有指定的技能,重新学习
|
| | | if skillIDList:
|
| | | #GameWorld.DebugLog("指定召唤兽技能: npcID=%s,skillIDList=%s" % (npcID, skillIDList))
|
| | | skillManger = curSummon.GetSkillManager()
|
| | | skillManger.ResetSkill()
|
| | | for skillID in skillIDList:
|
| | | skillManger.LVUPSkillByID(skillID)
|
| | | NPCControl(curSummon).DoNPCRebornCommLogic(tick)
|
| | | #curSummon.RefreshView()
|
| | | return curSummon
|
| | |
| | | #范围校验
|
| | | if not posMap:
|
| | | GameWorld.ErrLog("__Func_GetRandPosInRefreshArea GetRefreshPosAt error: return None! npcID=%s" % curNPC.GetNPCID())
|
| | | return
|
| | | return curNPC.GetPosX(), curNPC.GetPosY()
|
| | | posMapX = posMap.GetPosX()
|
| | | posMapY = posMap.GetPosY()
|
| | |
|
| | |
| | | # curNPC.ForbiddenSkillTypeList_Clear()
|
| | |
|
| | | #宠物特殊处理
|
| | | if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotPet:
|
| | | PetControl.RefurbishPetAttr(curNPC, canSyncClient)
|
| | | if PetControl.RefurbishPetAttr(curNPC):
|
| | | return
|
| | |
|
| | | pvpPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PVPPlayerID)
|
| | |
| | | return
|
| | |
|
| | | def SetPVPNPCPlayerAttr(self, pvpPlayerID):
|
| | | PropDict = PlayerViewCacheTube.GetPlayerPropData(pvpPlayerID)
|
| | | PropDict, PlusDict = PlayerViewCacheTube.GetPlayerPropPlusDictByID(pvpPlayerID)
|
| | | if not PropDict:
|
| | | return
|
| | | curNPC = self.__Instance
|
| | |
| | | GameObj.SetAtkBackDefRate(curNPC, PropDict.get("AtkBackDefRate", 0))
|
| | | GameObj.SetSuckHPPer(curNPC, PropDict.get("SuckHPPer", 0))
|
| | | GameObj.SetSuckHPDefPer(curNPC, PropDict.get("SuckHPDefPer", 0))
|
| | | |
| | | GameWorld.DebugLog("SetPVPNPCPlayerAttr: objID=%s,NPCID=%s,pvpPlayerID=%s,maxHP=%s" |
| | | % (curNPC.GetID(), curNPC.GetNPCID(), pvpPlayerID, GameObj.GetMaxHP(curNPC)))
|
| | | |
| | | skillManager = curNPC.GetSkillManager()
|
| | | SkillInfo = PlusDict.get("SkillInfo", {})
|
| | | for _, skillLVDict in SkillInfo.items():
|
| | | for skillID, _ in skillLVDict.items():
|
| | | skillManager.LearnSkillByID(skillID)
|
| | | |
| | | GameWorld.DebugLog("SetPVPNPCPlayerAttr: objID=%s,NPCID=%s,pvpPlayerID=%s,maxHP=%s,SkillInfo=%s" |
| | | % (curNPC.GetID(), curNPC.GetNPCID(), pvpPlayerID, GameObj.GetMaxHP(curNPC), SkillInfo))
|
| | | for index in range(0, skillManager.GetSkillCount()):
|
| | | useSkill = skillManager.GetSkillByIndex(index)
|
| | | GameWorld.DebugLog(" NPC SkillID=%s" % useSkill.GetSkillID())
|
| | | return
|
| | |
|
| | | def SetHelpBattleRobotRebornAttr(self, fightPower):
|
| | |
| | | return
|
| | |
|
| | | #宠物死亡调用独立接口
|
| | | if curNPC_GameNPCObjType == IPY_GameWorld.gnotPet:
|
| | | PetControl.SetPetDead(curNPC)
|
| | | return
|
| | | #if curNPC_GameNPCObjType == IPY_GameWorld.gnotPet:
|
| | | # PetControl.SetPetDead(curNPC)
|
| | | # return
|
| | |
|
| | | #---通用死亡逻辑---
|
| | |
|
| | |
| | | if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):
|
| | | PlayerFB.DoExitCustomScene(curPlayer)
|
| | |
|
| | | PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | | #PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | |
|
| | | # 恢复视野,刷新自己的视野
|
| | | curPlayer.SetVisible(True)
|
| | |
| | | DataRecordPack.DR_PlayerLogin(curPlayer)
|
| | | EventReport.WriteEvent_login(curPlayer)
|
| | | #---玩家上线, 宠物逻辑处理---
|
| | | PetControl.DoLogic_PetInfo_OnLogin(curPlayer, tick)
|
| | | #PetControl.DoLogic_PetInfo_OnLogin(curPlayer, tick)
|
| | |
|
| | | PlayerFamily.FamilyPlayerOnLoginCross(curPlayer)
|
| | |
|
| | |
| | | PlayerRefineStove.DoOnLogin(curPlayer, tick)
|
| | |
|
| | | #---玩家上线, 宠物逻辑处理---
|
| | | PetControl.DoLogic_PetInfo_OnLogin(curPlayer, tick)
|
| | | #PetControl.DoLogic_PetInfo_OnLogin(curPlayer, tick)
|
| | | PlayerPet.OnPlayerPetLogin(curPlayer)
|
| | |
|
| | | #要在SetCanMove之后做这个事情, 否则OnEnter不会卡住玩家
|
| | |
| | | #===========================================================================
|
| | |
|
| | | #初始化宠物 通知客户端
|
| | | PetControl.Sync_PetInfo_ChangeMap(curPlayer, tick)
|
| | | #PetControl.Sync_PetInfo_ChangeMap(curPlayer, tick)
|
| | |
|
| | | #通知GameServer自己现在的地图
|
| | | curPlayer.Sync_GameServer_MapID()
|
| | |
| | | EventShell.EventResponse_OnMapEx(curPlayer)
|
| | |
|
| | | #触发切换地图宠物逻辑
|
| | | PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | | #PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | |
|
| | | #---检查是否卡障碍---
|
| | | curMap = GameWorld.GetMap()
|
| | |
| | | return
|
| | |
|
| | | #出战宠物同时移动
|
| | | PetControl.FightPetFollowMove(curPlayer, sendPack_StartX, sendPack_StartY)
|
| | | #PetControl.FightPetFollowMove(curPlayer, sendPack_StartX, sendPack_StartY)
|
| | |
|
| | |
|
| | | return
|
| | |
| | | #直接取db中配置的复活点
|
| | | PlayerControl.PlayerResetWorldPos(curPlayer, gameMap.GetRebornMapID(), gameMap.GetRebornMapX(), gameMap.GetRebornMapY(), False)
|
| | | #重新召唤宠物
|
| | | PlayerPet.AutoSummonPet(curPlayer)
|
| | | #PlayerPet.AutoSummonPet(curPlayer)
|
| | |
|
| | | #复活成功,重置状态
|
| | | PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)
|
| | |
| | | #出战宠物同时移动
|
| | | if moveType == 0 or tick - fightPet.GetActionTick() > 300:
|
| | |
|
| | | PetControl.FightPetFollowMove(curPlayer,sendPack_SeverPosX, sendPack_SeverPosY)
|
| | | #PetControl.FightPetFollowMove(curPlayer,sendPack_SeverPosX, sendPack_SeverPosY)
|
| | | fightPet.SetCurAction(IPY_GameWorld.laNPCNull)
|
| | |
|
| | | return True
|
| | |
| | | #IPY_RolePetMgr.PetList_Find\GetFightPet\PetList_At -> IPY_RolePet;
|
| | | #IPY_RolePet.GetRolePet -> tagIPY_RolePet(结构体);
|
| | | #IPY_RolePet.GetPetData -> IPY_Pet;
|
| | | #
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | import IPY_GameWorld
|
| | | import ChConfig
|
| | | import GameWorld
|
| | | import BuffSkill
|
| | | import SkillShell
|
| | | import PlayerPet
|
| | | import PlayerControl
|
| | | import NPCCommon
|
| | | import SkillCommon
|
| | | import GameMap
|
| | | import OperControlManager
|
| | | import ShareDefine
|
| | |
|
| | | import random
|
| | | import copy
|
| | | import math
|
| | | import GameObj
|
| | | import AICommon
|
| | | import BaseAttack
|
| | | import PassiveBuffEffMng
|
| | | import ChNetSendPack
|
| | | import IpyGameDataPY
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | DefPetRebornHPRate = 100 # 宠物死亡复活血量百分比
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ## 检查宠物是否出战中
|
| | | # @param curPlayer 玩家对象
|
| | | # @param curPetID 宠物ID
|
| | | # @return True or False 是否出战中
|
| | | # @remarks 检查宠物是否出战中
|
| | | def CheckPetIsFight(curPlayer, curPetID):
|
| | | petMgr = curPlayer.GetPetMgr()
|
| | | #出战的宠物对象
|
| | | fightPetObj = petMgr.GetFightPet() |
| | | |
| | | if fightPetObj == None:
|
| | | return False
|
| | | |
| | | if fightPetObj.GetRolePet().PetID == curPetID:
|
| | | return True
|
| | | |
| | | return False
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | # 宠物跟随人物同时攻击
|
| | | def PetFight(curPlayer, tick):
|
| | | |
| | | rolePet = curPlayer.GetPetMgr().GetFightPet()
|
| | | #无出战宠物
|
| | | if rolePet == None:
|
| | | return
|
| | | rolePetControl = NPCCommon.NPCControl(rolePet)
|
| | | |
| | | useSkillTagID = curPlayer.GetUseSkillTagID()
|
| | | useSkillTagType = curPlayer.GetUseSkillTagType()
|
| | | |
| | | curTag = GameWorld.GetObj(useSkillTagID, useSkillTagType)
|
| | | if not curTag or GameObj.GetHP(curTag) <= 0:
|
| | | # 没有主目标就从仇恨中找
|
| | | for i in range(curPlayer.GetAngryNPCCount()):
|
| | | curTag = curPlayer.GetAngryNPCByIndex(i)
|
| | | if not curTag or GameObj.GetHP(curTag) <= 0:
|
| | | continue
|
| | | |
| | | if not curTag or GameObj.GetHP(curTag) <= 0:
|
| | | return
|
| | | |
| | | #tagDist = GameWorld.GetDist(rolePet.GetPosX(), rolePet.GetPosY(), curTag.GetPosX(), curTag.GetPosY())
|
| | | tagDist = 0
|
| | | #---优先释放技能---
|
| | | if AICommon.DoAutoUseSkill(rolePet, curTag, tagDist, tick):
|
| | | return
|
| | | |
| | | #---释放普通攻击--- 边走边攻击纠正一次位置
|
| | | #if tagDist > rolePet.GetAtkDist():
|
| | | # rolePetControl.MoveToObj_Detel(curTag)
|
| | | |
| | | #普通攻击
|
| | | BaseAttack.Attack(rolePet, curTag, None, tick)
|
| | | return
|
| | |
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##出战宠物跟随移动
|
| | | # @param curPlayer 玩家实例
|
| | | # @param destPosX 移动目标X点
|
| | | # @param destPosY 移动目标Y点
|
| | | # @return 返回值无意义
|
| | | # @remarks 出战宠物跟随移动
|
| | | def FightPetFollowMove(curPlayer, destPosX, destPosY):
|
| | | #主人在战斗中, 宠物不跟随移动
|
| | |
|
| | | fightPet = curPlayer.GetPetMgr().GetFightPet()
|
| | | #无出战宠物
|
| | | if fightPet == None:
|
| | | return
|
| | |
|
| | | petControl = NPCCommon.NPCControl(fightPet)
|
| | | movePosX, movePosY = petControl.GetMoveNearPos(destPosX, destPosY, 2)
|
| | | # 执行一次重置位置,避免快速发包导致无法移动
|
| | | fightPet.ChangePos(movePosX, movePosY)
|
| | | |
| | | #movePosX, movePosY = petControl.GetMoveNearPos(destPosX, destPosY, 1)
|
| | | PetMove(fightPet, movePosX, movePosY)
|
| | | return
|
| | |
|
| | |
|
| | | def PetMove(fightPet, posX, posY):
|
| | | |
| | | sendPack = ChNetSendPack.tagObjMove()
|
| | | |
| | | sendPack.Clear()
|
| | | sendPack.ObjID = fightPet.GetID()
|
| | | sendPack.ObjType = IPY_GameWorld.gotNPC
|
| | | sendPack.MoveType = IPY_GameWorld.mtNormal
|
| | | sendPack.DestPosX = posX
|
| | | sendPack.DestPosY = posY
|
| | | sendPack.Speed = fightPet.GetSpeed()
|
| | | sendPack.StartPosX = fightPet.GetPosX()
|
| | | sendPack.StartPosY = fightPet.GetPosY()
|
| | | |
| | | fightPet.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | ##清除出战宠物仇恨.
|
| | | # @param curPlayer 玩家实例
|
| | | # @return 返回值无意义
|
| | | # @remarks 清除出战宠物仇恨
|
| | | def ClearFightPetAngry(curPlayer):
|
| | | fightPet = curPlayer.GetPetMgr().GetFightPet()
|
| | | #无出战宠物
|
| | | if fightPet == None:
|
| | | return
|
| | |
|
| | | petControl = NPCCommon.NPCControl(fightPet)
|
| | | petControl.ClearNPCAngry()
|
| | | return
|
| | | import ChConfig
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | ##获得宠物的拥有者
|
| | |
| | |
|
| | | return False
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | def IsPetNPC(curObj):
|
| | | ''' 是否灵宠NPC,召唤兽类型,玩家、玩家镜像、NPC通用,均可有灵宠召唤兽
|
| | | 区别于 IsPet 为旧版的 PY_GameWorld.gnotPet 实例对象,仅玩家实例有
|
| | | '''
|
| | | curObjType = curObj.GetGameObjType()
|
| | | if curObjType != IPY_GameWorld.gotNPC:
|
| | | return False
|
| | | npcObjType = curObj.GetGameNPCObjType()
|
| | | if npcObjType != IPY_GameWorld.gnotSummon:
|
| | | return False
|
| | | return curObj.GetType() == IPY_GameWorld.ntPet
|
| | |
|
| | | def GetPetNPCOwner(curPet):
|
| | | ''' 获得宠物的拥有者,可能为玩家、玩家镜像、NPC
|
| | | 区别于 GetPetOwner 为旧版的 PY_GameWorld.gnotPet 归属者仅支持玩家
|
| | | '''
|
| | | if curPet == None:
|
| | | return
|
| | | |
| | | atkObjType = curPet.GetGameObjType()
|
| | | if atkObjType != IPY_GameWorld.gotNPC:
|
| | | return
|
| | | |
| | | summonOwner = None
|
| | | npcObjType = curPet.GetGameNPCObjType()
|
| | | # 判断召唤兽主人
|
| | | if npcObjType == IPY_GameWorld.gnotSummon:
|
| | | curNPCDetail = GameWorld.GetObjDetail(curPet)
|
| | | if curNPCDetail:
|
| | | curNPCOwner = curNPCDetail.GetOwner()
|
| | | if curNPCOwner:
|
| | | summonOwner = GameWorld.GetObjDetail(curNPCOwner)
|
| | | # 召唤兽主人为玩家
|
| | | #if summonOwner and summonOwner.GetGameObjType() == IPY_GameWorld.gotPlayer:
|
| | | # return summonOwner, npcObjType
|
| | | return summonOwner
|
| | |
|
| | | ##清空宠物身上所有buff
|
| | | # @param curPet 宠物对象
|
| | | # @return None
|
| | |
| | | buffState.Clear()
|
| | |
|
| | | return
|
| | | #--------------------------------------------------------------------- |
| | | ##召唤宠物
|
| | | # @param curPet 宠物对象
|
| | | # @param curPosX 宠物出身点位置
|
| | | # @param curPosY 宠物出身点位置
|
| | | # @return None
|
| | | # @remarks 召唤宠物,初始化宠物所有属性(C++处理)
|
| | | def SummonPet(curPet, curPosX, curPosY):
|
| | | #出现(出战逻辑在C++, 将清空宠物的相关信息)
|
| | | curPet.Summon(curPosX, curPosY)
|
| | | #记录该宠物被召回
|
| | | curPet.SetIsBattle(True)
|
| | | #初始化宠物
|
| | | InitRolePet(curPet)
|
| | | PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveEff(curPet)
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##初始化宠物属性
|
| | | # @param rolePet 宠物实例
|
| | | # @param canSyncClient 是否通知客户端
|
| | | # @return 返回值无意义
|
| | | # @remarks 初始化宠物属性
|
| | | def InitRolePet(rolePet, canSyncClient=True):
|
| | | #---初始化时钟---
|
| | | NPCCommon.InitNPC(rolePet)
|
| | | def CalloutFightPet(curObj, petCacheInfo=None):
|
| | | ## 出战上阵的灵宠
|
| | | # @param petCacheInfo: 玩家灵宠功能缓存信息
|
| | | # @return: [第1位置实例, 第2, ...] 按位置顺序,实例可能为None
|
| | |
|
| | | #---初始化仇恨列表---
|
| | | npcAngry = rolePet.GetNPCAngry()
|
| | | if npcAngry.GetAngryCount() == 0:
|
| | | npcAngry.Init(ChConfig.Def_Pet_Angry_Count)
|
| | | else:
|
| | | npcAngry.Clear()
|
| | | fightPlaceCount = len(IpyGameDataPY.GetFuncEvalCfg("PetGoOutFight", 1)) # 战斗位置数
|
| | | fightPetObjList = [None] * fightPlaceCount
|
| | | if petCacheInfo == None and curObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
|
| | | petCacheInfo = PlayerPet.GetPetCacheInfo(curObj)
|
| | | if not petCacheInfo: # 没有灵宠
|
| | | return fightPetObjList
|
| | | |
| | | fightPetDict = {} # 上阵的灵宠
|
| | | for cacheInfo in petCacheInfo:
|
| | | state = cacheInfo.get("state", 0)
|
| | | if not state:
|
| | | continue
|
| | | fightPetDict[state] = cacheInfo
|
| | | |
| | | if not fightPetDict: # 没有上阵的
|
| | | return fightPetObjList
|
| | | |
| | | posX, posY = curObj.GetPosX(), curObj.GetPosY()
|
| | | for index in range(fightPlaceCount):
|
| | | placeNum = index + 1
|
| | | if placeNum not in fightPetDict:
|
| | | continue
|
| | | petInfo = fightPetDict[placeNum]
|
| | | petNPCID = petInfo.get("npcID", 0)
|
| | | if not petNPCID:
|
| | | continue
|
| | | quality = petInfo.get("quality", 0)
|
| | | skillIDList = petInfo.get("skills", [])
|
| | | petObj = NPCCommon.SummonNPC(curObj, petNPCID, posX, posY, skillIDList)
|
| | | if not petObj:
|
| | | continue
|
| | | petObj.SetDict(ChConfig.Def_Obj_Dict_FightPetPlaceNum, placeNum)
|
| | | petObj.SetDict(ChConfig.Def_Obj_Dict_FightPetQuality, quality)
|
| | | fightPetObjList[index] = petObj
|
| | | return fightPetObjList
|
| | |
|
| | | #---初始化宠物属性---
|
| | | petControl = NPCCommon.NPCControl(rolePet)
|
| | | petControl.RefreshNPCState(canSyncClient)
|
| | |
|
| | | #加一个防御措施, 如果宠物血为0, 不可召唤出来, 默认为宠物召回时候的血量
|
| | | if GameObj.GetHP(rolePet) <= 0:
|
| | | PetDead_ReStoreHP(rolePet, GameObj.GetMaxHP(rolePet))
|
| | | GameWorld.ErrLog('宠物重生血量为0, PetID = %s' % (rolePet.GetRolePet().PetID))
|
| | |
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | ##召回出战的宠物
|
| | | # @param curPlayer 玩家实例
|
| | | # @return 布尔值
|
| | | # @remarks 召回出战的宠物
|
| | | def ReCallFightPet(curPlayer):
|
| | | rolePetMgr = curPlayer.GetPetMgr()
|
| | | #获得战斗的宠物
|
| | | fightPet = rolePetMgr.GetFightPet()
|
| | | |
| | | if fightPet == None:
|
| | | return False
|
| | | |
| | | #清空宠物身上附加的buff
|
| | | ClearPetBuff(fightPet)
|
| | | #记录该宠物被召回
|
| | | fightPet.SetIsBattle(False)
|
| | | #此死亡接口(C++将重置所有战斗属性, 要在刷一次)
|
| | | NPCCommon.SetDeadEx(fightPet)
|
| | | #刷新宠物属性
|
| | | petControl = NPCCommon.NPCControl(fightPet)
|
| | | petControl.RefreshNPCState(canSyncClient=True)
|
| | | |
| | | #宠物数据物品状态变更
|
| | | petItemIndex = PlayerPet.GetPetObjItemIndex(fightPet)
|
| | | petItem = PlayerPet.GetPetDataItemByIndex(curPlayer, petItemIndex)
|
| | | if petItem:
|
| | | petItem.SetUserAttr(ShareDefine.Def_IudetPet_State, ShareDefine.Def_PetState_Null)
|
| | | |
| | | petID = fightPet.GetRolePet().PetID
|
| | | npcID = fightPet.GetRolePet().NPCID
|
| | | rolePetMgr.PetList_SetFree(petID) # 永恒召回后默认放生, 最多只存在一个出战宠物实例
|
| | | GameWorld.DebugLog("随从召回后默认放生, petID=%s, npcID=%s" % (petID, npcID))
|
| | | return True
|
| | | #---------------------------------------------------------------------
|
| | | ## 设置宠物死亡
|
| | | # @param curPet 宠物对象
|
| | | # @return None
|
| | | # @remarks 设置宠物死亡
|
| | | def SetPetDead(curPet):
|
| | | #---执行死亡惩罚逻辑---
|
| | | |
| | | #宠物主人
|
| | | curPetOwner = GetPetOwner(curPet)
|
| | | if not curPetOwner:
|
| | | return
|
| | | ReCallFightPet(curPetOwner)
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##宠物死亡恢复血量
|
| | | # @param index 玩家索引
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 宠物死亡恢复血量
|
| | | def PetDead_ReStoreHP(curPet, maxHP):
|
| | | #设置宠物当前血量为其上限的30%
|
| | | SetPetHP(curPet, int(maxHP * DefPetRebornHPRate / 100))
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##设置宠物HP
|
| | | # @param rolePet 玩家宠物
|
| | | # @param ֵ
|
| | | # @param canSyncClient是否通知客户端
|
| | | # @return 返回值无意义
|
| | | # @remarks 设置宠物HP
|
| | | def SetPetHP(rolePet, value, canSyncClient=True):
|
| | | ##设置宠物HP
|
| | | GameObj.SetHP(rolePet, value, canSyncClient)
|
| | | |
| | | if not canSyncClient:
|
| | | return
|
| | | |
| | | #rolePet.Sync_RefreshProp(IPY_GameWorld.PetInfoRefresh_HP, value, True)
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | ##增加宠物HP
|
| | | # @param rolePet 玩家宠物
|
| | | # @param ֵ
|
| | | # @return 返回值无意义
|
| | | # @remarks 加宠物HP
|
| | |
|
| | | def AddPetHP(rolePet, value):
|
| | | remainValue = min(GameObj.GetHP(rolePet) + value, GameObj.GetMaxHP(rolePet))
|
| | | SetPetHP(rolePet, remainValue)
|
| | | ##增加宠物HP
|
| | | #remainValue = min(GameObj.GetHP(rolePet) + value, GameObj.GetMaxHP(rolePet))
|
| | | #SetPetHP(rolePet, remainValue)
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##刷新宠物的属性
|
| | | # @param rolePet 玩家宠物
|
| | | # @param canSyncClient 是否通知客户端(默认为True)
|
| | | # @return 返回值无意义
|
| | | # @remarks 刷新宠物的属性
|
| | | def RefurbishPetAttr(rolePet, canSyncClient=True):
|
| | | curPlayer = GetPetOwner(rolePet)
|
| | | if not curPlayer:
|
| | | def RefurbishPetAttr(curPet):
|
| | | ##刷新宠物的属性,仅支持召唤兽,废弃原 IPY_GameWorld.gnotPet
|
| | | if not IsPetNPC(curPet):
|
| | | return
|
| | | petOwner = GetPetNPCOwner(curPet)
|
| | | if not petOwner:
|
| | | return
|
| | |
|
| | | petDataItem = PlayerPet.GetPetDataItem(curPlayer, rolePet)
|
| | | if not petDataItem:
|
| | | return
|
| | | #宠物不可被攻击, 灵宠继承人物的 百分百攻击和攻速
|
| | | curPet.SetMinAtk(petOwner.GetMinAtk())
|
| | | curPet.SetMaxAtk(petOwner.GetMaxAtk())
|
| | | GameObj.SetAtkSpeed(curPet, GameObj.GetAtkSpeed(petOwner))
|
| | |
|
| | | # 变更需要同步的信息配置, 客户端取宠物信息全部以宠物物品数据为准
|
| | | syncList = [
|
| | | [lambda petObj:petObj.GetMaxAtk(), IPY_GameWorld.PetInfoRefresh_PhysicAtk], #攻击
|
| | | #[lambda petObj:petObj.GetQualityLV(), IPY_GameWorld.PetInfoRefresh_QualityLV], #品质
|
| | | ]
|
| | | beforeValueList = []
|
| | | for syncInfo in syncList:
|
| | | beforeValueList.append(syncInfo[0](rolePet))
|
| | | #allAttrList = [{} for i in range(4)]
|
| | | ##计算技能对战斗属性的影响
|
| | | #PlayerPet.CalcSkill_PetBattleEffect(curPlayer, rolePet, allAttrList)
|
| | | ##计算Buff对战斗属性的影响
|
| | | #PlayerPet.CalcBuffer_PetBattleEffect(rolePet, allAttrList)
|
| | |
|
| | | #添加Buff到宠物身上
|
| | | #AddPlayerPetSkillBuff(rolePet)
|
| | | |
| | | #计算Buff对基础属性的影响
|
| | | #SkillShell.CalcBuffer_NPCBaseEffect(rolePet)
|
| | | |
| | | #宠物不可被攻击, 命中与攻速直接继承主人攻击属性,攻击取等级阶级加成
|
| | | rolePet.SetMinAtk(PlayerControl.GetPetMinAtk(curPlayer))
|
| | | rolePet.SetMaxAtk(PlayerControl.GetPetMaxAtk(curPlayer))
|
| | | rolePet.SetSkillAtkRate(PlayerControl.GetPetSkillAtkRate(curPlayer))
|
| | | GameObj.SetPetDamPer(rolePet, GameObj.GetPetDamPer(curPlayer))
|
| | | #rolePet.SetMAtkMin(curPlayer.GetMAtkMin())
|
| | | #rolePet.SetMAtkMax(curPlayer.GetMAtkMax())
|
| | | rolePet.SetHit(curPlayer.GetHit())
|
| | | rolePet.SetSpeed(curPlayer.GetSpeed())
|
| | | |
| | | allAttrList = [{} for i in range(4)]
|
| | | #计算技能对战斗属性的影响
|
| | | PlayerPet.CalcSkill_PetBattleEffect(curPlayer, rolePet, allAttrList)
|
| | | #计算Buff对战斗属性的影响
|
| | | PlayerPet.CalcBuffer_PetBattleEffect(rolePet, allAttrList)
|
| | | |
| | | GameWorld.DebugLog("RefurbishPetAttr ID=%s,npcID=%s,atk=%s,hit=%s,skillAtkRate=%s" |
| | | % (rolePet.GetID(), rolePet.GetNPCID(), rolePet.GetMaxAtk(), rolePet.GetHit(), rolePet.GetSkillAtkRate()))
|
| | | |
| | | #是否需要通知客户端属性刷新
|
| | | if not canSyncClient:
|
| | | return
|
| | | |
| | | #===========================================================================
|
| | | # for i, syncInfo in enumerate(syncList):
|
| | | # nowValue = syncInfo[0](rolePet)
|
| | | # if beforeValueList[i] != nowValue:
|
| | | # rolePet.Sync_RefreshProp(syncInfo[1], nowValue, True)
|
| | | # #GameWorld.DebugLog("Sync_RefreshProp i=%s,befValue=%s,nowValue=%s,type=%s" % (i, beforeValueList[i], nowValue, syncInfo[1]))
|
| | | #===========================================================================
|
| | | GameWorld.DebugLog("RefurbishPetAttr ID=%s,npcID=%s,maxAtk=%s,atkSpeed=%s" |
| | | % (curPet.GetID(), curPet.GetNPCID(), curPet.GetMaxAtk(), curPet.GetMaxAtk()))
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##添加宠物技能Buff
|
| | | # @param rolePet 宠物实例
|
| | | # @return 返回值无意义
|
| | | # @remarks 添加宠物技能Buff
|
| | | #===============================================================================
|
| | | # def AddPlayerPetSkillBuff(rolePet):
|
| | | # tick = GameWorld.GetGameWorld().GetTick()
|
| | | # |
| | | # #---先清掉---
|
| | | # passiveBuffManager = rolePet.GetPassiveBuf()
|
| | | # passiveBuffManager.Clear()
|
| | | # |
| | | # #---在加上---
|
| | | # rolePetSkillManager = rolePet.GetSkillManager()
|
| | | # |
| | | # for i in range(0, rolePetSkillManager.GetSkillCount()):
|
| | | # learnSkill = rolePetSkillManager.GetSkillByIndex(i)
|
| | | # #只添加被动技能
|
| | | # if not SkillCommon.isPassiveBuffSkill(learnSkill):
|
| | | # continue
|
| | | # |
| | | # #加上buff不刷新状态
|
| | | # BuffSkill.AddBuffNoRefreshState(rolePet, IPY_GameWorld.btPassiveBuf, learnSkill, tick)
|
| | | # |
| | | # return
|
| | | #===============================================================================
|
| | | #---------------------------------------------------------------------
|
| | | def DoLogic_PlayerPetLearnSkillList(rolePet, learnSkillList):
|
| | | #GameWorld.DebugLog("DoLogic_PlayerPetLearnSkillList----%s"%learnSkillList)
|
| | |
| | | #rolePet.Sync_SkillList()
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##检查当前指定宠物是否可出战
|
| | | # @param curPlayer 玩家实例
|
| | | # @param curPetObj 指定宠物实例
|
| | | # @return BOOL 是否可出战
|
| | | # @remarks 检查当前指定宠物是否可出战
|
| | | def CheckPetCanFight(curPlayer, curPetObj):
|
| | | if not GetMapCanOutPet(curPlayer):
|
| | | #Pet_liubo_314885 此地图禁止宠物
|
| | | #PlayerControl.NotifyCode(curPlayer, "Pet_liubo_314885")
|
| | | return False
|
| | | |
| | | petData = curPetObj.GetPetData()
|
| | | |
| | | #防沉迷
|
| | | if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Wallow_LV) > ChConfig.Def_GameWallow_LV_First:
|
| | | PlayerControl.NotifyCode(curPlayer, "AvoidSink09")
|
| | | return False
|
| | | |
| | | if GameObj.GetHP(curPlayer) <= 0:
|
| | | #死亡状态无法出战宠物
|
| | | return False
|
| | | |
| | | # if curPlayer.GetLV() < petData.GetBringLV():
|
| | | # #Pet_hgg_442426 对不起,您尚未到达该宠物的携带等级.
|
| | | # PlayerControl.NotifyCode(curPlayer, "Pet_hgg_442426")
|
| | | # return False
|
| | | # |
| | | # if curPetObj.GetLV() - curPlayer.GetLV() > ChConfig.Def_PetRoleGapLVMax:
|
| | | # #Pet_liubo_570355 对不起,您不能出战超过人物5级的宠物!
|
| | | # PlayerControl.NotifyCode(curPlayer, "Pet_liubo_570355", [ChConfig.Def_PetRoleGapLVMax])
|
| | | # return False
|
| | | |
| | | #---是否已有宠物出战---
|
| | | #fightPetObj = curPlayer.GetPetMgr().GetFightPet() # 出战的宠物对象
|
| | | |
| | | #if fightPetObj != None:
|
| | | # #Pet_hgg_892377 对不起,您只能同时出战一只宠物,请先召回出战的宠物!
|
| | | # PlayerControl.NotifyCode(curPlayer, "Pet_hgg_892377")
|
| | | # return False
|
| | | |
| | | #GameWorld.Log('宠物血量:%s,宠物ID:%s'%(curPetStruct.HP,curPetStruct.PetID))
|
| | | return True
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##玩家离开服务器通知宠物信息
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 玩家离开服务器通知宠物信息
|
| | | def DoLogic_PetInfo_OnLeaveServer(curPlayer, tick):
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##玩家登陆通知宠物信息
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 玩家登陆通知宠物信息
|
| | | def DoLogic_PetInfo_OnLogin(curPlayer, tick):
|
| | | |
| | | petMgr = curPlayer.GetPetMgr()
|
| | | if GameWorld.IsCrossServer():
|
| | | ''' 0435宠物出现包同步的ID是根据宠物的列表位置来的,比如在第2位发的就是2,而地图的可能是1,会导致ID不一致
|
| | | 所以跨服服务器登录时先清除出战宠物列表,确保登录地图成功后都是从1开始的即可
|
| | | '''
|
| | | petList = []
|
| | | for index in range(0, petMgr.PetList_Cnt()):
|
| | | rolePet = petMgr.PetList_At(index)
|
| | | petList.append(rolePet)
|
| | | for rolePet in petList:
|
| | | petMgr.PetList_SetFree(rolePet.GetRolePet().PetID)
|
| | | else:
|
| | | for index in range(0, petMgr.PetList_Cnt()):
|
| | | rolePet = petMgr.PetList_At(index)
|
| | | #刷新宠物信息并通知客户端
|
| | | __RefreshAndSyncPetInfo(rolePet)
|
| | | #自动出战宠物
|
| | | __AutoSummonPet_OnLogin(curPlayer, rolePet)
|
| | |
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | ##玩家上线, 自动出战宠物
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 玩家上线, 自动出战宠物
|
| | | def __AutoSummonPet_OnLogin(curPlayer, rolePet):
|
| | | #是否有出战标志
|
| | | if not rolePet.GetIsBattle():
|
| | | return
|
| | | |
| | | if not GetMapCanOutPet(curPlayer):
|
| | | #此地图禁止宠物
|
| | | return
|
| | | #召唤宠物出战
|
| | | resultPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), ChConfig.Def_SummonAppearDist)
|
| | | |
| | | SummonPet(rolePet, resultPos.GetPosX(), resultPos.GetPosY())
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##玩家切换地图通知宠物信息.
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 玩家切换地图通知宠物信息.
|
| | | def Sync_PetInfo_ChangeMap(curPlayer, tick):
|
| | | petMgr = curPlayer.GetPetMgr()
|
| | | |
| | | for index in range(0, petMgr.PetList_Cnt()):
|
| | | rolePet = petMgr.PetList_At(index)
|
| | | #刷新宠物信息并通知客户端
|
| | | __RefreshAndSyncPetInfo(rolePet)
|
| | |
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##玩家携带宠物登陆地图
|
| | | # @param curPlayer 玩家实例
|
| | | # @return 返回值无意义
|
| | | # @remarks |
| | | def DoLogic_PetLoadMapOK(curPlayer):
|
| | | |
| | | if GetMapCanOutPet(curPlayer):
|
| | | #此地图宠物可以上
|
| | | PlayerPet.AutoSummonPet(curPlayer)
|
| | | return
|
| | | |
| | | #此地图禁止宠物, 召回出战的宠物
|
| | | if not ReCallFightPet(curPlayer):
|
| | | return
|
| | | |
| | | #Pet_liubo_314885 此地图禁止宠物
|
| | | #PlayerControl.NotifyCode(curPlayer, "Pet_liubo_314885")
|
| | | return
|
| | |
|
| | | def GetMapCanOutPet(curPlayer):
|
| | | ## 检查本地图可否出战宠物,支持前端自定义场景
|
| | | customMapID = PlayerControl.GetCustomMapID(curPlayer)
|
| | |
| | | else:
|
| | | canOutPet = GameWorld.GetMap().GetMapCanOutPet()
|
| | | return canOutPet
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ## 刷新宠物信息并通知客户端
|
| | | # @param rolePet 宠物实例
|
| | | # @return 无返回值
|
| | | # @remarks 刷新宠物信息并通知客户端
|
| | | def __RefreshAndSyncPetInfo(rolePet):
|
| | | #---刷新宠物信息(不通知客户端)---
|
| | | InitRolePet(rolePet, False)
|
| | |
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
|
| | |
| | | # @remarks 玩家离开服务器
|
| | | def PlayerLeaveServer(curPlayer, tick):
|
| | | #宠物下线逻辑, 这里要进行排行榜, 优先做, 避免玩家光环等属性影响宠物属性失效
|
| | | PetControl.DoLogic_PetInfo_OnLeaveServer(curPlayer, tick)
|
| | | #PetControl.DoLogic_PetInfo_OnLeaveServer(curPlayer, tick)
|
| | |
|
| | | #清除下线消失的buff, 在更新排行榜之前
|
| | | __DisconnectClearBuff(curPlayer, tick)
|
| | |
| | | NPCCommon.ClearPriWoodPile(curPlayer)
|
| | | GameWorld.Log("玩家开始自定义场景!mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | if mapID:
|
| | | PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | | #PetControl.DoLogic_PetLoadMapOK(curPlayer)
|
| | | FBLogic.OnEnterCustomScene(curPlayer, mapID, lineID)
|
| | |
|
| | | #默认回满血
|
| | |
| | | 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)
|
| | |
| | | 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())
|
| | |
| | | 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)
|
| | |
| | |
|
| | | 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();
|
| | | #
|
| | |
| | | # // 状态.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
|
| | |
|
| | | ## 获取出战宠物要学的技能
|
| | |
| | | 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)
|
| | |
|
| | | # 开服活动数据
|
| | |
| | | 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:
|
| | |
| | | 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
|
| | | #
|
| | |
| | |
|
| | | 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
|
| | |
|
| | |
|
| | | #扣除物品
|
| | |
| | | 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])
|
| | | # 如果是当前出战的宠物, 则该宠物学习技能
|
| | |
| | | #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
|
| | |
| | | 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)
|
| | |
| | | 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):
|
| | |
| | | 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)
|
| | |
| | | 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))
|
| | |
| | |
|
| | | if useSkillData and useSkillData.GetSkillID() != ChConfig.Def_SkillID_Somersault:
|
| | | # 跟随玩家同频率攻击
|
| | | PetControl.PetFight(curPlayer, tick)
|
| | | #PetControl.PetFight(curPlayer, tick)
|
| | | SummonFollowAtk(curPlayer, tick)
|
| | | #===========================================================================
|
| | | # if not result:
|
| | |
| | | import PyGameData
|
| | | import PlayerTJG
|
| | | import SkillShell
|
| | | import PlayerPet
|
| | | import GameObj
|
| | |
|
| | | import time
|
| | |
| | | return json.dumps(classItemDataDict, ensure_ascii=False).replace(" ", "")
|
| | |
|
| | | def UpdPlayerPropPlusCache(curPlayer):
|
| | | if not curPlayer:
|
| | | return
|
| | | curPlayerPropDict = {}
|
| | | curPlayerPropDict["AccID"] = curPlayer.GetAccID()
|
| | | curPlayerPropDict["LV"] = curPlayer.GetLV()
|
| | |
| | | curPlayerPlusDict["TotalStoneLV"] = Operate_EquipStone.GetTotalStoneLV(curPlayer)
|
| | | curPlayerPlusDict["TotalEquipWashLV"] = Operate_EquipWash.GetTotalEquipWashLV(curPlayer)
|
| | | #主动技能总等级
|
| | | curPlayerPlusDict["TotalSkillLV"] = SkillShell.GetAllSkillLV(curPlayer, ChConfig.Def_SkillFuncType_FbSkill)
|
| | | skillInfo = SkillShell.GetAllSkillInfo(curPlayer, [ChConfig.Def_SkillFuncType_FbSkill, ChConfig.Def_SkillFuncType_NormalAttack])
|
| | | curPlayerPlusDict["SkillInfo"] = skillInfo
|
| | | curPlayerPlusDict["TotalSkillLV"] = sum(skillInfo.get(ChConfig.Def_SkillFuncType_FbSkill, {}).values())
|
| | | |
| | | #灵宠数据
|
| | | curPlayerPlusDict["Pet"] = __GetPetInfo(curPlayer)
|
| | | curPlayerPlusDict["Pet"] = PlayerPet.GetPetCacheInfo(curPlayer)
|
| | |
|
| | | #坐骑数据
|
| | | curPlayerPlusDict["Horse"] = __GetHorseInfo(curPlayer)
|
| | |
| | | def GetPlayerPropPlusCache(curPlayer):
|
| | | #玩家属性缓存
|
| | | UpdPlayerPropPlusCache(curPlayer)
|
| | | return GetPlayerPropPlusCacheByID(curPlayer.GetPlayerID())
|
| | | return GetPlayerPropPlusCacheByID(curPlayer.GetPlayerID(), False)
|
| | |
|
| | | def GetPlayerPropPlusCacheByID(playerID):
|
| | | def GetPlayerPropPlusCacheByID(playerID, checkUpd=False):
|
| | | #玩家属性缓存
|
| | | viewCache = PyGameData.g_playerViewCache.get(playerID, {})
|
| | | curPlayerPropDict = viewCache.get("PropData", {})
|
| | | curPlayerPlusDict = viewCache.get("PlusData", {})
|
| | | PropData = json.dumps(curPlayerPropDict, ensure_ascii=False).replace(" ", "")
|
| | | PlusData = json.dumps(curPlayerPlusDict, ensure_ascii=False).replace(" ", "")
|
| | | PropDict, PlusDict = GetPlayerPropPlusDictByID(playerID, checkUpd)
|
| | | PropData = json.dumps(PropDict, ensure_ascii=False).replace(" ", "")
|
| | | PlusData = json.dumps(PlusDict, ensure_ascii=False).replace(" ", "")
|
| | | return PropData, PlusData
|
| | |
|
| | | def GetPlayerPropPlusDictByID(playerID, checkUpd=False):
|
| | | #玩家属性字典
|
| | | if checkUpd:
|
| | | UpdPlayerPropPlusCache(GameWorld.GetPlayerManager().FindPlayerByID(playerID))
|
| | | viewCache = PyGameData.g_playerViewCache.get(playerID, {})
|
| | | PropDict = viewCache.get("PropData", {})
|
| | | PlusDict = viewCache.get("PlusData", {})
|
| | | return PropDict, PlusDict
|
| | |
|
| | | def __GetEquipShowIDList(curPlayer):
|
| | | ## 获取外观装备ID列表
|
| | |
| | | continue
|
| | | equipShowIDList.append(curEquip.GetItemTypeID())
|
| | | return equipShowIDList
|
| | |
|
| | | ## 灵宠信息
|
| | | def __GetPetInfo(curPlayer):
|
| | | petInfo = {}
|
| | | petClassLVList = []
|
| | | equipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)
|
| | | for index in xrange(equipPack.GetCount()):
|
| | | packItem = equipPack.GetAt(index)
|
| | | if not packItem or packItem.IsEmpty():
|
| | | continue
|
| | | petNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
|
| | | classLV = packItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)
|
| | | petClassLVList.append({"id":petNPCID, 'lv':classLV})
|
| | | |
| | | petInfo["PetLV"] = petClassLVList
|
| | | petInfo["AtkSpeed"] = GameObj.GetAtkSpeed(curPlayer)
|
| | | return petInfo
|
| | |
|
| | | ## 坐骑信息
|
| | | def __GetHorseInfo(curPlayer):
|
| | |
| | | NetPackCommon.SendPyPackToGameServer(sendPack)
|
| | | return
|
| | |
|
| | | def GetPlayerPropData(findPlayerID):
|
| | | ## 获取玩家战斗属性数据 UpdPlayerPropPlusCache
|
| | | viewCache = PyGameData.g_playerViewCache.get(findPlayerID, {})
|
| | | return viewCache.get("PropData", {})
|
| | |
|
| | | def GetPlayerPropDataCall(curPlayer, findPlayerID, callFunc, callData=None, syncClient=True):
|
| | | def GetPlayerPropDataCall(curPlayer, findPlayerID, callFunc, callData=None, syncClient=False):
|
| | | ## 获取玩家战斗属性数据 - 支持callback,因为地图可能暂时没有离线玩家缓存数据
|
| | | # @param callFunc: 获取到玩家数据后回调函数,可能地图没有数据,会等向GameServer同步过后再回调
|
| | | # @param callData: 回调函数扩展参数,透传参数
|
| | | # @param syncClient: 是否附带通知前端该玩家数据,一般如果有需要前端配合展示的,需要直接传给前端,如镜像PK类功能
|
| | |
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | dataDict = GetPlayerPropData(findPlayerID)
|
| | | dataDict = GetPlayerPropPlusDictByID(findPlayerID, True)[0]
|
| | | if dataDict:
|
| | | if syncClient:
|
| | | Sync_PlayerCache(curPlayer, findPlayerID)
|
| | |
| | | if skillTag != ChConfig.Def_UseSkillTag_PetMaster:
|
| | | return False
|
| | |
|
| | | if not PetControl.IsPet(curNPC):
|
| | | if not PetControl.IsPetNPC(curNPC):
|
| | | GameWorld.ErrLog("NPCID %s AI %s 非宠物,无法获得主人释放技能"%(curNPC.GetNPCID(), curNPC.GetAIType()))
|
| | | return False
|
| | |
|
| | | petOwner = PetControl.GetPetOwner(curNPC)
|
| | | petOwner = PetControl.GetPetNPCOwner(curNPC)
|
| | |
|
| | | if petOwner == None:
|
| | | GameWorld.ErrLog("宠物(%s)对主人释放技能,找不到主人"%curNPC.GetRolePet().PetID)
|
| | |
| | |
|
| | | # 宠物对主人释放技能
|
| | | elif skillAffectTag == ChConfig.Def_UseSkillTag_PetMaster:
|
| | | if not PetControl.IsPet(attacker):
|
| | | if not PetControl.IsPetNPC(attacker):
|
| | | GameWorld.ErrLog("该NPC非宠物,无法获得主人释放技能")
|
| | | return False
|
| | |
|
| | | petOwner = PetControl.GetPetOwner(attacker)
|
| | | petOwner = PetControl.GetPetNPCOwner(attacker)
|
| | |
|
| | | if petOwner == None:
|
| | | GameWorld.ErrLog("宠物(%s)对主人释放技能,找不到主人"%attacker.GetRolePet().PetID)
|
| | |
| | |
|
| | | else:
|
| | | if affectTag == ChConfig.Def_UseSkillTag_PetMaster:
|
| | | if not PetControl.IsPet(attacker):
|
| | | if not PetControl.IsPetNPC(attacker):
|
| | | return False
|
| | |
|
| | | petOwner = PetControl.GetPetOwner(attacker)
|
| | | petOwner = PetControl.GetPetNPCOwner(attacker)
|
| | | if petOwner == None:
|
| | | return False
|
| | |
|
| | |
| | | ## 获取技能总等级
|
| | | # @param curPlayer
|
| | | # @return allSkillLV:总技能等级
|
| | | def GetAllSkillLV(curPlayer, funcType):
|
| | | allSkillLV = 0
|
| | | def GetAllSkillInfo(curPlayer, funcTypeList):
|
| | | # @return: {funcType:{skillID:skillLV, ...}, ...}
|
| | | skillDict = {}
|
| | | skillManager = curPlayer.GetSkillManager()
|
| | | for i in xrange(skillManager.GetSkillCount()):
|
| | | curPlayerSkill = skillManager.GetSkillByIndex(i)
|
| | | if curPlayerSkill == None:
|
| | | continue
|
| | | if curPlayerSkill.GetFuncType() != funcType:
|
| | | funcType = curPlayerSkill.GetFuncType()
|
| | | if funcType not in funcTypeList:
|
| | | continue
|
| | | skillLV = curPlayerSkill.GetSkillLV()
|
| | | allSkillLV += skillLV
|
| | | return allSkillLV
|
| | | if funcType not in skillDict:
|
| | | skillDict[funcType] = {}
|
| | | skillLVDict = skillDict[funcType]
|
| | | skillLVDict[curPlayerSkill.GetSkillID()] = curPlayerSkill.GetSkillLV()
|
| | | return skillDict
|