From 81d4c82d07f4d5aff78c40579049ae70a94163d5 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期二, 06 二月 2024 18:08:13 +0800 Subject: [PATCH] 10019 【砍树】回合战斗(增加道法技能支持;) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 164 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 135 insertions(+), 29 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py index dd30895..833acea 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py @@ -9,7 +9,7 @@ # @date 2023-11-30 # @version 1.0 # -# 详细描述: 回合制攻击逻辑 +# 详细描述: 回合制攻击逻辑,均使用NPC实例作为战斗主体 # #------------------------------------------------------------------------------- #"""Version = 2023-11-30 15:30""" @@ -174,8 +174,9 @@ playerID = 0 sightLevel, posX, posY = 99, 192, 109 # 系统默认处理的层级及坐标 - objRetA = __SummonFactionObjs(factionInfoA, sightLevel, posX, posY) - objRetB = __SummonFactionObjs(factionInfoB, sightLevel, posX, posY) + factionA, factionB, mainRolePlace = 1, 2, 1 + objRetA = __SummonFactionObjs(factionA, mainRolePlace, factionInfoA, sightLevel, posX, posY) + objRetB = __SummonFactionObjs(factionB, mainRolePlace, factionInfoB, sightLevel, posX, posY) objA, petObjListA, factionSyncInfoA = objRetA if objRetA else (None, []) objB, petObjListB, factionSyncInfoB = objRetB if objRetB else (None, []) if not objA or not objB: @@ -194,15 +195,13 @@ atkFactionList = [factionListA, factionListB] # 设置战斗主体 - objA.SetDict(ChConfig.Def_Obj_Dict_TurnFightMainRole, 1) - objB.SetDict(ChConfig.Def_Obj_Dict_TurnFightMainRole, 1) objA.SetDict(ChConfig.Def_Obj_Dict_TurnEnemyID, objB.GetID()) objB.SetDict(ChConfig.Def_Obj_Dict_TurnEnemyID, objA.GetID()) # 战斗前初始化,可能会改变攻速,所以先初始化 - for faction, factionObjList in enumerate(atkFactionList, 1): + for factionObjList in atkFactionList: for gameObj in factionObjList: - TurnFightObjStartInit(playerID, gameObj, faction, tick) + TurnFightObjStartInit(playerID, gameObj, tick) #一个回合攻击顺序,为了后续逻辑统一,都是先确定好顺序 sortType = 2 # 攻击顺序排序方式 @@ -268,7 +267,7 @@ GameWorld.DebugLog("★回合%s.%s %s 行动 : objType-ID-HP(%s-%s-%s),curAtk=%s, tagType-ID-HP(%s-%s-%s)" % (turnNum, actionNum, objName, objType, objID, curHP, gameObj.GetMaxAtk(), tagObjType, tagObjID, tagHP)) - if not DoAttack(gameObj, tagGameObj, tick): + if not DoAttack(gameObj, tagGameObj, tick, checkUseXP=True): continue isWin = CheckIswin(objA, objB) @@ -313,13 +312,17 @@ % (mapID, funcLineID, playerIDA, playerIDB, isWin)) return isWin, turnNum, turnMax, factionTotalHurtDict, playbackID -def __SummonFactionObjs(factionInfo, sightLevel, posX, posY): - ## 召唤阵营战斗实例 +def __SummonFactionObjs(faction, mainRolePlace, objInfo, sightLevel, posX, posY): + '''召唤阵营战斗实例 + @param faction: 所属阵营,目前支持两个阵营,1或2 + @param mainRolePlace: 战斗主体在该阵营上阵位置,1V1时默认1,多对多时,代表所在阵营位置 + @param objInfo: 该战斗主体出战信息 + ''' factionSyncInfo = {} # 同步前端的阵营信息,包含主ID、灵宠、其他灵通等 - playerID = factionInfo.get("playerID") - npcID = factionInfo.get("npcID") - skillIDList = factionInfo.get("skillIDList") # 技能ID列表 - skillIDExList = factionInfo.get("skillIDExList") # 附加技能ID列表 + playerID = objInfo.get("playerID") + npcID = objInfo.get("npcID") + skillIDList = objInfo.get("skillIDList") # 技能ID列表 + skillIDExList = objInfo.get("skillIDExList") # 附加技能ID列表 if playerID: npcID = ChConfig.Def_NPCID_PVP mainObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=sightLevel, mirrorPlayerID=playerID, skillIDList=skillIDList, skillIDExList=skillIDExList) @@ -331,7 +334,9 @@ return if not mainObj: return - petObjList = PetControl.CalloutFightPet(mainObj, factionInfo.get("pet")) + GameObj.SetFaction(mainObj, faction) + mainObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace, mainRolePlace) + petObjList = PetControl.CalloutFightPet(mainObj, objInfo.get("pet")) petObjIDList = [] for petObj in petObjList: if petObj: @@ -362,7 +367,7 @@ return isWin def SetKilled(gameObj, killer=None): - if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRole): + if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace): #GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID()) return @@ -406,7 +411,7 @@ if not gameObj: return - if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRole): + if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace): # 仅主体可复活 return @@ -504,6 +509,7 @@ NetPackCommon.SendFakePack(curPlayer, clientPack) return True +def GetTurnNum(timeline): return timeline / 100 def SetTimeline(gameObj, turnNum, actionNum): '''设置回合制战斗所在时间节点 @param turnNum: 第几回合,如果在回合制战斗中,则回合数一定大于0, @@ -512,17 +518,17 @@ gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightTimeline, turnNum * 100 + actionNum) return -def TurnFightObjStartInit(playerID, gameObj, faction, tick): +def TurnFightObjStartInit(playerID, gameObj, tick): ## 回合制战斗实例初始化 if not gameObj: return - isMainRole = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRole) + mainRolePlace = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace) gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightID, playerID) gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnRebornCount, 0) gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnTotalHurt, 0) gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnTotalHurtEx, 0) SetTimeline(gameObj, 1, 0) - GameObj.SetFaction(gameObj, faction) + faction = GameObj.GetFaction(gameObj) GameObj.SetHPFull(gameObj, True) gameObj.RefreshView() @@ -531,10 +537,10 @@ objName = GetObjName(gameObj) fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) - GameWorld.DebugLog("【 %s 初始化 %s 】 objID=%s,npcID=%s,atkSpeed=%s,isMainRole=%s" - % (objName, BaseAttack.GetObjAttackName(gameObj), gameObj.GetID(), npcID, GameObj.GetAtkSpeed(gameObj), isMainRole)) - __logGameObjAttr(gameObj) + GameWorld.DebugLog("【 %s 初始化 %s 】 objID=%s,npcID=%s,atkSpeed=%s,faction=%s,mainRolePlace=%s" + % (objName, BaseAttack.GetObjAttackName(gameObj), gameObj.GetID(), npcID, GameObj.GetAtkSpeed(gameObj), faction, mainRolePlace)) + haveXPSkill = False # 重置技能CD、战斗buff if objType == IPY_GameWorld.gotPlayer: skillManager = gameObj.GetSkillManager() @@ -549,6 +555,8 @@ curSkill = skillManager.GetSkillByIndex(i) if not curSkill: continue + if mainRolePlace and curSkill.GetXP(): + haveXPSkill = True skillIDList.append(curSkill.GetSkillID()) if fightPlaceNum: if curSkill.GetSkillType() != ChConfig.Def_SkillType_Revive: @@ -557,12 +565,19 @@ curSkill.SetRemainTime(curSkill.GetCoolDownTime()) GameWorld.DebugLog(" NPC技能: npcID=%s,skillIDList=%s" % (npcID, skillIDList)) + if haveXPSkill: + GameObj.SetMaxXP(gameObj, IpyGameDataPY.GetFuncCfg("TurnFightXP", 1)) + GameObj.SetXP(gameObj, 0) # 进行设置一次通知前端,视为告知前端该实例有XP + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, 0) + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPFullTimeline, 0) + + __logGameObjAttr(gameObj) return def __logGameObjAttr(gameObj): - GameWorld.DebugLog(" HP=%s/%s,atk=%s~%s,Def=%s,atkSpeed=%s" - % (GameObj.GetHP(gameObj), GameObj.GetMaxHP(gameObj), gameObj.GetMinAtk(), gameObj.GetMaxAtk(), - gameObj.GetDef(), GameObj.GetAtkSpeed(gameObj))) + GameWorld.DebugLog(" HP=%s/%s,atk=%s~%s,Def=%s,atkSpeed=%s,XP=%s/%s" + % (GameObj.GetHP(gameObj), GameObj.GetMaxHP(gameObj), gameObj.GetMinAtk(), gameObj.GetMaxAtk(), + gameObj.GetDef(), GameObj.GetAtkSpeed(gameObj), GameObj.GetXP(gameObj), GameObj.GetMaxXP(gameObj))) 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), @@ -582,6 +597,8 @@ # 重置连击、反击数 gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0) gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, 0) + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, 0) + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 0) gameObj.SetDict(ChConfig.Def_PlayerKey_AttrFaintCD, 0) # 击晕CD objType = gameObj.GetGameObjType() @@ -718,7 +735,7 @@ NPCCommon.SetDeadEx(gameObj) return -def AddTurnObjHurtValue(curObj, tagObj, hurtType, hurtValue, curSkill=None): +def AddTurnObjHurtValue(curObj, tagObj, hurtType, hurtValue, lostHP, curSkill=None): if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline): return skillID = curSkill.GetSkillID() if curSkill else 0 @@ -728,13 +745,103 @@ curObj.SetDict(ChConfig.Def_Obj_Dict_TurnTotalHurtEx, totalHurt / ChConfig.Def_PerPointValue) GameWorld.DebugLog(" 伤血: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,totalHurt=%s,tagHP=%s" % (curObj.GetID(), tagObj.GetID(), skillID, hurtType, hurtValue, totalHurt, GameObj.GetHP(tagObj))) + + if lostHP: + AddTurnFightXP(tagObj, __GetAddXP_Defender(tagObj, lostHP), "skillID:%s" % skillID) + AddTurnFightXP(curObj, __GetAddXP_Attack(curObj, curSkill), "skillID:%s" % skillID) return -def DoAttack(curObj, tagObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal): +def __GetAddXP_Attack(attack, curSkill): + ## 攻击方增加的XP值根据主动攻击次数获得 + isAddXPSkill = not curSkill or curSkill.GetSkillType() == ChConfig.Def_SkillType_Atk + if not isAddXPSkill: + return 0 + atkAddXPCount = attack.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount) + addXPList = IpyGameDataPY.GetFuncEvalCfg("TurnFightXP", 2) + if atkAddXPCount >= len(addXPList): + return 0 + attack.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, atkAddXPCount + 1) + return addXPList[atkAddXPCount] + +def __GetAddXP_Defender(defender, lostHP): + ## 掉血方增加的XP值根据掉血百分比获得 + maxXP = GameObj.GetMaxXP(defender) + if not maxXP: + return 0 + maxHP = GameObj.GetMaxHP(defender) + lostHPPer = lostHP / float(maxHP) + #GameWorld.DebugLog(" lostHP=%s,lostHPPer=%s" % (lostHP, lostHPPer)) + return eval(IpyGameDataPY.GetFuncCompileCfg("TurnFightXP", 3)) + +def AddTurnFightXP(gameObj, addXP, reason=""): + ## 回合战斗增加XP + if not addXP: + #GameWorld.DebugLog(" 没有增加XP! curID=%s" % (gameObj.GetID())) + return + maxXP = GameObj.GetMaxXP(gameObj) + if not maxXP: + #GameWorld.DebugLog(" 无最大XP值,不更新! curID=%s" % (gameObj.GetID())) + return + curXP = GameObj.GetXP(gameObj) + if curXP >= maxXP: + #GameWorld.DebugLog(" XP值已满,不更新! curID=%s,curXP=%s" % (gameObj.GetID(), curXP)) + return + updXP = min(curXP + addXP, maxXP) + GameObj.SetXP(gameObj, updXP) + GameWorld.DebugLog(" 更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason)) + return + +def __CheckUseXPSkill(curObj, tagObj, tick): + ## 使用XP技能 - 道法技能 + maxXP = GameObj.GetMaxXP(curObj) + curXP = GameObj.GetXP(curObj) + if not maxXP or curXP < maxXP: + #GameWorld.DebugLog(" 没有XP或XP未满,无法释放XP! curID=%s,curXP=%s" % (curObj.GetID(), curXP)) + return + turnNum = GetTurnNum(curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)) + xpFullTurnNum = GetTurnNum(curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnXPFullTimeline)) + if turnNum <= xpFullTurnNum: + #GameWorld.DebugLog(" XP技能在本回合无法释放! curID=%s, turnNum=%s <= %s" % (curObj.GetID(), turnNum, xpFullTurnNum)) + return + + curObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 1) # 设置可用 + + tagDist = 0 + skillManager = curObj.GetSkillManager() + for index in range(0, skillManager.GetSkillCount()): + curSkill = skillManager.GetSkillByIndex(index) + if not curSkill or curSkill.GetSkillTypeID() == 0: + break + skillID = curSkill.GetSkillID() + #被动技能无法使用 + if SkillCommon.isPassiveSkill(curSkill): + continue + #还在冷却时间内无法释放 + if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0: + continue + needXP = curSkill.GetXP() + if not needXP or needXP < curXP: + continue + curID = curObj.GetID() + tagID = tagObj.GetID() + if not AICommon.DoNPCUseSkill(curObj, tagObj, curSkill, tagDist, tick): + GameWorld.DebugLog(" XP技能攻击失败: curID=%s,tagID=%s,skillID=%s" % (curID, tagID, skillID)) + continue + GameWorld.DebugLog(" XP技能攻击成功: curID=%s,tagID=%s,skillID=%s" % (curID, tagID, skillID)) + curObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 2) # 设置已用 + return skillID + + return + +def DoAttack(curObj, tagObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal, checkUseXP=False): curID = curObj.GetID() tagID = tagObj.GetID() objName = GetObjName(curObj) GameWorld.DebugLog(" ● %s DoAttack: curID=%s,tagID=%s,turnBattleType=%s" % (objName, curID, tagID, turnBattleType)) + if checkUseXP: + if __CheckUseXPSkill(curObj, tagObj, tick): + return True + if turnBattleType == ChConfig.TurnBattleType_AtkBack: PassiveBuffEffMng.OnPassiveSkillTrigger(curObj, tagObj, None, ChConfig.TriggerType_AtkBackBef, tick) @@ -878,7 +985,6 @@ continue if not AICommon.DoNPCUseSkill(playerNPC, tagObj, curSkill, tagDist, tick): - GameWorld.DebugLog(" 技能攻击失败: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) continue GameWorld.DebugLog(" 技能攻击成功: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) return skillID -- Gitblit v1.8.0