From afea2d9d4b9cb6d0982c02a775e8198fc2421c53 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期五, 08 十二月 2023 18:21:28 +0800 Subject: [PATCH] 10019 【砍树】回合战斗(增加抗连击、反击、抗反击、吸血、抗吸血属性,玩家及NPC属性接口通用;连击、反击属性效果支持;) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 157 +++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 136 insertions(+), 21 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 7f2d67d..375d744 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py @@ -97,7 +97,7 @@ curPet = curPlayer.GetPetMgr().GetFightPet() tagPet = None - GameWorld.DebugLog("执行回合制战斗: mapID=%s,funcLineID=%s,tagPlayerID=%s,tagObjID=%s" + GameWorld.DebugLog("===== 执行回合制战斗: mapID=%s,funcLineID=%s,tagPlayerID=%s,tagObjID=%s" % (mapID, funcLineID, tagPlayerID, tagObj.GetID()), playerID) GameWorld.DebugLog("curPlayer.GetSightLevel=%s,tagObj.GetSightLevel=%s" % (curPlayer.GetSightLevel(), tagObj.GetSightLevel()), playerID) @@ -117,16 +117,23 @@ for gameObj in objList: TurnFightObjStartInit(gameObj) - curSpeed = 0 - tagSpeed = 0 - orderList = [1, 2] if curSpeed >= tagSpeed else [2, 1] - GameWorld.DebugLog("playerHP=%s,tagHP=%s,curSpeed=%s,tagSpeed=%s" - % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj), curSpeed, tagSpeed), playerID) + curAtkSpeed = GameObj.GetAtkSpeed(curPlayer) + tagAtkSpeed = GameObj.GetAtkSpeed(tagObj) + orderList = [1, 2] if curAtkSpeed >= tagAtkSpeed else [2, 1] + GameWorld.DebugLog("playerHP=%s,tagHP=%s,curAtkSpeed=%s,tagAtkSpeed=%s" + % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj), curAtkSpeed, tagAtkSpeed), playerID) isWin = None for turnNum in range(1, turnMax + 1): - GameWorld.DebugLog("回合制战斗轮次: %s" % turnNum, playerID) + GameWorld.DebugLog("----- 回合制战斗轮次: %s -----" % turnNum, playerID) SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Fighting, turnNum, turnMax) + + # 回合开始: 做一些每回合重置逻辑或者某些根据回合触发的效果等 + for objList in factionObjDict.values(): + for gameObj in objList: + TurnFightObjTurnStart(gameObj, turnNum) + + # 回合战斗: 轮流依次攻击 for index in range(factionObjMax): for faction in orderList: objList = factionObjDict[faction] @@ -135,7 +142,7 @@ gameObj = objList[index] if not gameObj: continue - gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, turnNum) + tagGameObj = tagObj if faction == 1 else curPlayer objType = gameObj.GetGameObjType() objID = gameObj.GetID() @@ -144,17 +151,13 @@ GameWorld.DebugLog(" 行动: turnNum=%s,index=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s" % (turnNum, index, faction, objType, objID, tagObjType, tagObjID), playerID) - if objType == IPY_GameWorld.gotPlayer: - PlayerAttack(gameObj, tagGameObj, tick) - else: - NPCAttack(gameObj, tagGameObj, tick) - + DoAttack(gameObj, tagGameObj, tick) + if tagGameObj and GameObj.GetHP(tagGameObj) > 0: - GameWorld.DebugLog(" playerHP=%s,tagHP=%s" % (GameObj.GetHP(curPlayer), GameObj.GetHP(tagObj)), playerID) continue isWin = faction == 1 - GameWorld.DebugLog(" tagObjType=%s,tagObjID=%s,被击杀,结束战斗: isWin=%s" % (tagObjType, tagObjID, isWin), playerID) + GameWorld.DebugLog(" tagObjType=%s,tagObjID=%s,被击杀,结束战斗: isWin=%s" % (tagObjType, tagObjID, isWin)) break if isWin != None: @@ -170,7 +173,7 @@ for gameObj in objList: TurnFightObjOverReset(gameObj) - GameWorld.DebugLog("回合制战斗结束: mapID=%s,funcLineID=%s,tagPlayerID=%s,isWin=%s,overState=%s" + GameWorld.DebugLog("===== 回合制战斗结束: mapID=%s,funcLineID=%s,tagPlayerID=%s,isWin=%s,overState=%s" % (mapID, funcLineID, tagPlayerID, isWin, overState), playerID) return @@ -195,11 +198,31 @@ pass return +def TurnFightObjTurnStart(gameObj, turnNum): + ## 回合制战斗实例 - 每回合开始时处理 + if not gameObj: + return + + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, turnNum) + # 重置连击、反击数 + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0) + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, 0) + + objType = gameObj.GetGameObjType() + if objType == IPY_GameWorld.gotPlayer: + pass + + elif objType == IPY_GameWorld.gotNPC: + pass + + return + def TurnFightObjOverReset(gameObj): ## 回合制战斗实例结束重置 if not gameObj: return gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 0) + gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) objType = gameObj.GetGameObjType() if objType == IPY_GameWorld.gotPlayer: @@ -212,17 +235,107 @@ return +def DoAttack(curObj, tagObj, tick): + curID = curObj.GetID() + tagID = tagObj.GetID() + if curObj.GetGameObjType() == IPY_GameWorld.gotPlayer: + atkRet = PlayerAttack(curObj, tagObj, tick) + else: + atkRet = NPCAttack(curObj, tagObj, tick) + + turnBattleType = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnBattleType) + curObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型 + + if not atkRet: + return + + if turnBattleType == ChConfig.TurnBattleType_Combo: + comboNum = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum) + 1 + curObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, comboNum) + GameWorld.DebugLog(" 连击: comboID=%s,comboNum=%s" % (curID, comboNum)) + elif turnBattleType == ChConfig.TurnBattleType_AtkBack: + atkBackNum = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) + 1 + curObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, atkBackNum) + GameWorld.DebugLog(" 反击: atkBackID=%s,atkBackNum=%s" % (curID, atkBackNum)) + + GameWorld.DebugLog(" curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, GameObj.GetHP(curObj), tagID, GameObj.GetHP(tagObj))) + + # 反击,反击可打断连击,所以优先判断 + if CanAtkBack(curObj, tagObj): + DoAttack(tagObj, curObj, tick) + return + + # 连击 + if CanCombo(curObj, tagObj): + DoAttack(curObj, tagObj, tick) + + return + +def CanAtkBack(atkObj, defObj): + ## 可否反击 + + defAtkBackRate = GameObj.GetAtkBackRate(defObj) # 防方反击率 + atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # 已反击次数 + if atkBackNum > 10: + # 内置最高反击数防范 + return False + if atkBackNum > 0: + validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 4) + vaildPer = validPerList[atkBackNum - 1] if len(validPerList) >= atkBackNum else 0 + defAtkBackRate = int(defAtkBackRate * vaildPer / 100.0) + + atkAtkBackDefRate = GameObj.GetAtkBackDefRate(atkObj) # 攻方抵抗反击率 + atkBackRate = max(0, defAtkBackRate - atkAtkBackDefRate) + if atkBackRate <= 0 or not GameWorld.CanHappen(atkBackRate): + GameWorld.DebugLog(" 无法反击: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)" + % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate)) + return False + GameWorld.DebugLog(" 可以反击: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)" + % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate)) + defObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, ChConfig.TurnBattleType_AtkBack) + return True + +def CanCombo(atkObj, defObj): + ## 可否连击 + + atkComboRate = GameObj.GetComboRate(atkObj) # 攻方连击率 + comboNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum) # 已连击次数 + if comboNum > 10: + # 内置最高连击数防范 + return False + if comboNum > 0: + validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 3) + vaildPer = validPerList[comboNum - 1] if len(validPerList) >= comboNum else 0 + atkComboRate = int(atkComboRate * vaildPer / 100.0) + + defComboReduce = GameObj.GetComboDefRate(defObj) # 防方抵抗连击率 + comboRate = max(0, atkComboRate - defComboReduce) + if comboRate <= 0 or not GameWorld.CanHappen(comboRate): + GameWorld.DebugLog(" 无法连击: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)" + % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce)) + return False + GameWorld.DebugLog(" 可以连击: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)" + % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce)) + atkObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, ChConfig.TurnBattleType_Combo) + return True + def NPCAttack(curObj, tagObj, tick): ## NPC攻击 if not curObj: return tagDist = 0 + atkRet = AICommon.DoAutoUseSkill(curObj, tagObj, tagDist, tick) #---优先释放技能--- - if not AICommon.DoAutoUseSkill(curObj, tagObj, tagDist, tick): + if not atkRet: #普通攻击 - isOK = BaseAttack.Attack(curObj, tagObj, None, tick) - GameWorld.DebugLog(" NPC普通攻击: curID=%s,tagID=%s,isOK=%s" % (curObj.GetID(), tagObj.GetID(), isOK)) - return + atkRet = BaseAttack.Attack(curObj, tagObj, None, tick) + if atkRet: + GameWorld.DebugLog(" NPC普通攻击: curID=%s,tagID=%s,atkRet=%s" % (curObj.GetID(), tagObj.GetID(), atkRet)) + else: + GameWorld.DebugLog(" NPC攻击失败: curID=%s,tagID=%s,atkRet=%s" % (curObj.GetID(), tagObj.GetID(), atkRet)) + else: + GameWorld.DebugLog(" NPC技能攻击: curID=%s,tagID=%s,atkRet=%s" % (curObj.GetID(), tagObj.GetID(), atkRet)) + return atkRet def PlayerAttack(curPlayer, tagObj, tick): ## 玩家攻击, 参考技能使用 #def UseSkillEx(index, clientData, tick): @@ -246,6 +359,7 @@ #PlayerControl.SetIsNeedProcess(curPlayer, True) #PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paAttack) + useSkillResult = False skillMgr = curPlayer.GetSkillManager() for skillID in skillList: curSkill = skillMgr.FindSkillBySkillID(skillID) @@ -265,12 +379,13 @@ if not PlayerState.__DoClientUseSkillEx(curPlayer, useSkillData, tick): GameWorld.DebugLog(" 技能攻击失败%s" % skillID, playerID) continue + useSkillResult = True GameWorld.DebugLog(" 技能攻击成功%s" % skillID, playerID) break curPlayer.ClearUseSkillRec() - return + return useSkillResult def SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, state, turnNum=0, turnMax=0): clientPack = ChPyNetSendPack.tagMCTurnFightState() -- Gitblit v1.8.0