From 2e892e272f7aea0a7ffbae81e43731c6b20119e6 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 04 八月 2025 10:46:12 +0800
Subject: [PATCH] 121 【武将】武将系统-服务端(竞技场支持进攻、防守阵容)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 205 +++++++++++++++++++++++++++++++++++----------------
1 files changed, 140 insertions(+), 65 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 f0fb744..e1e95ad 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -35,12 +35,14 @@
import ItemControler
import SkillCommon
import SkillShell
-import BaseAttack
+import AttackCommon
+import FBLogic
import random
import time
import json
+FighterNPCID = 100 # 战斗NPCID,仅后端用,除怪物外,所有玩家武将均使用该NPCID
PosNumMax = 10 # 最大站位编号
ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
@@ -235,6 +237,9 @@
self.startTime = 0 # 开始时间戳,支持毫秒小数
self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
+
+ #玩家武将行动后击杀目标
+ self.playerKillObjIDList = [] # [objID, ...]
return
def setTurn(self, mapID, funcLineID, turnMax, isNeedReport=False, msgDict={}):
@@ -374,6 +379,8 @@
tfObj = ChPyNetSendPack.tagSCTurnFightObj()
tfObj.ObjID = curNPC.GetID()
tfObj.NPCID = curNPC.GetNPCID()
+ tfObj.HeroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
+ tfObj.SkinID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_SkinID)
tfObj.HP = curNPC.GetHP()
tfObj.HPEx = curNPC.GetHPEx()
tfObj.MaxHP = curNPC.GetMaxHP()
@@ -510,14 +517,6 @@
self.turnFight.clearFight()
return
- def playerLogin(self, curPlayer):
- self.turnFight.curPlayer = curPlayer
- return
-
- def playerOffline(self, curPlayer):
- self.turnFight.curPlayer = None
- return
-
def GetMainFightMgr(curPlayer):
## 获取主线战斗管理
olPlayer = PlayerOnline.GetOnlineMgr().GetOnlinePlayer(curPlayer)
@@ -571,12 +570,15 @@
heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
if not heroIpyData:
continue
-
- npcID = heroIpyData.GetSkinNPCIDList()[0]
+ skinIDList = heroIpyData.GetSkinIDList()
+ skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
+ if skinIndex < 0 or skinIndex >= len(skinIDList):
+ continue
+ skinID = skinIDList[skinIndex]
heroDict[str(posNum)] = {
- "ID":heroID,
+ "HeroID":heroID,
+ "SkinID":skinID,
"Data":heroItem.GetUserData(),
- "NPCID":npcID
}
heroCount += 1
@@ -656,27 +658,33 @@
tick = GameWorld.GetGameWorld().GetTick()
initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
+ baseAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
tfMgr = GetTurnFightMgr()
space = 3
for posNumKey, heroInfo in heroDict.items():
posNum = int(posNumKey)
+ heroID, skinID = 0, 0
+ baseAtkSkillID = 0 # 基础普攻ID
skillIDList = []
if lineupPlayerID:
- heroID = heroInfo.get("ID", 0)
- npcID = heroInfo.get("NPCID", 0)
+ heroID = heroInfo.get("HeroID", 0)
+ skinID = heroInfo.get("SkinID", 0)
+ npcID = FighterNPCID
heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
if not heroIpyData:
continue
normalSkillID = heroIpyData.GetNormalSkillID()
angerSkillID = heroIpyData.GetAngerSkillID()
skillIDList += [normalSkillID, angerSkillID]
+ atkDistType = heroIpyData.GetAtkDistType()
else:
npcID = heroInfo.get("NPCID", 0)
npcDataEx = NPCCommon.GetNPCDataEx(npcID)
if not npcDataEx:
continue
skillIDList += npcDataEx.GetSkillIDList()
+ atkDistType = npcDataEx.GetAtkDistType()
if not npcID:
continue
@@ -701,19 +709,28 @@
curSummon.SetVisible(True)
curSummon.SetDict(ChConfig.Def_Obj_Dict_TurnFightPosInfo, num * 100 + posNum)
curSummon.SetDict(ChConfig.Def_Obj_Dict_LineupPlayerID, lineupPlayerID)
+ curSummon.SetDict(ChConfig.Def_Obj_Dict_HeroID, heroID)
+ curSummon.SetDict(ChConfig.Def_Obj_Dict_SkinID, skinID)
GameObj.SetFaction(curSummon, faction)
GameObj.SetXP(curSummon, initXP, False)
+ if atkDistType == ChConfig.AtkDistType_Short:
+ baseAtkSkillID = baseAtkSkillIDList[0] if len(baseAtkSkillIDList) > 0 else 0
+ elif atkDistType == ChConfig.AtkDistType_Long:
+ baseAtkSkillID = baseAtkSkillIDList[1] if len(baseAtkSkillIDList) > 1 else 0
+
skillManager = curSummon.GetSkillManager()
#有指定的技能,重新学习
if skillIDList:
skillManager.ResetSkill()
for skillID in skillIDList:
skillManager.LVUPSkillByID(skillID)
-
+ if baseAtkSkillID:
+ skillManager.LVUPSkillByID(baseAtkSkillID)
+
rebornX = posX - space + (faction - 1) * space * 3 + ((posNum - 1) / 3 * space * 2 * (-1 if faction == 1 else 1))
rebornY = posY + (posNum - 1) % 3 * space
- #GameWorld.DebugLog("Reborn ID:%s, faction:%s,posNum=%s, (%s,%s), %s" % (curSummon.GetID(), faction, posNum, rebornX, rebornY, skillIDList))
+ GameWorld.DebugLog("SummonNPC ID:%s,faction:%s,num=%s,posNum=%s,baseAtkSkillID=%s,%s" % (curSummon.GetID(), faction, num, posNum, baseAtkSkillID, skillIDList))
curSummon.Reborn(rebornX, rebornY, False)
NPCCommon.NPCControl(curSummon).DoNPCRebornCommLogic(tick)
@@ -977,8 +994,7 @@
overLineupList = [] # 本回合已经结束行动的阵容列表 [(faction, num), ...], 所有阵容全部结束代表本回合结束
turnNum = turnFight.turnNum
- unXiantaoCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCnt)
- GameWorld.DebugLog("unXiantaoCnt=%s,turnNum=%s,doMax=%s,actionIndex=%s,%s" % (unXiantaoCnt, turnNum, doMax, turnFight.actionIndex, turnFight.actionSortList))
+ GameWorld.DebugLog("turnNum=%s,doMax=%s,actionIndex=%s,%s" % (turnNum, doMax, turnFight.actionIndex, turnFight.actionSortList))
while doCnt < doMax and len(overLineupList) < len(turnFight.actionSortList):
doCnt += 1
turnNum = turnFight.turnNum
@@ -1001,6 +1017,7 @@
if turnFight.actionIndex >= len(turnFight.actionSortList):
turnFight.actionIndex = 0
+ playerHeroAtk = False # 玩家阵容行动标记
faction, num = turnFight.actionSortList[turnFight.actionIndex]
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
@@ -1047,8 +1064,8 @@
continue
if faction == Def_FactionA:
- if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint, isNotify=False):
- return
+ playerHeroAtk = True
+
break
turnFight.actionIndex += 1
@@ -1061,10 +1078,9 @@
if turnFight.checkOverByKilled():
break
- nowUnXiantaoCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCnt)
- if unXiantaoCnt != nowUnXiantaoCnt:
- # 玩家有消耗战锤则停止,一段段执行
- GameWorld.DebugLog("玩家有消耗战锤则停止,nowUnXiantaoCnt=%s" % (nowUnXiantaoCnt))
+ if playerHeroAtk:
+ # 玩家武将有行动则停止,一段段执行
+ GameWorld.DebugLog("玩家武将有行动则停止!")
break
if turnFight.winFaction:
@@ -1200,8 +1216,10 @@
objName = gameObj.GetName()
faction = GameObj.GetFaction(gameObj)
posInfo = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
- npcID = gameObj.GetNPCID()
- return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), npcID)
+ heroID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
+ if not heroID:
+ heroID = gameObj.GetNPCID()
+ return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), heroID)
def EntryLogic(turnFight):
## 执行进场逻辑
@@ -1317,23 +1335,10 @@
GameWorld.DebugLog(" 自残: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,curHP=%s"
% (curID, tagID, skillID, hurtType, hurtValue, lostHP, GameObj.GetHP(curObj)))
- if lostHP and curID != tagID:
- AddTurnFightXP(tagObj, __GetAddXP_Defender(tagObj, lostHP), "skillID:%s" % skillID)
+ if lostHP > 0 and curID != tagID:
+ addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 4)
+ AddTurnFightXP(tagObj, addXP, "skillID:%s" % skillID)
return
-
-def __GetAddXP_Attack(attack, curSkill):
- ## 攻击方增加的XP值根据主动普攻技能获得
- if not curSkill:
- return 0
- if not SkillCommon.isNormalAtkSkill(curSkill):
- return 0
- return IpyGameDataPY.GetFuncCfg("AngerXP", 3)
-
-def __GetAddXP_Defender(defender, lostHP):
- ## 掉血方增加的XP值根据掉血百分比获得
- if lostHP <= 0:
- return 0
- return IpyGameDataPY.GetFuncCfg("AngerXP", 4)
def AddTurnFightXP(gameObj, addXP, reason=""):
## 回合战斗增加XP
@@ -1363,7 +1368,16 @@
if turnBattleType == ChConfig.TurnBattleType_AtkBack:
if not tagObj:
return
- atkOK = BaseAttack.Attack(curNPC, tagObj, None, tick) # 反击为单体普攻
+ skillManager = curNPC.GetSkillManager()
+ for index in range(0, skillManager.GetSkillCount()):
+ skill = skillManager.GetSkillByIndex(index)
+ #已经到尾部了
+ if not skill or skill.GetSkillTypeID() == 0:
+ break
+ if skill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:
+ useSkill = skill
+ break
+ atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
elif turnBattleType == ChConfig.TurnBattleType_Combo:
if not tagObj:
return
@@ -1373,12 +1387,15 @@
xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
skillManager = curNPC.GetSkillManager()
useSkillList = []
- GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
+ #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
for index in range(0, skillManager.GetSkillCount()):
useSkill = skillManager.GetSkillByIndex(index)
#已经到尾部了
if not useSkill or useSkill.GetSkillTypeID() == 0:
break
+ if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_NormalAttack]:
+ #基础普攻不能主动释放,目前仅用于反击
+ continue
#被动技能无法使用
if SkillCommon.isPassiveSkill(useSkill):
continue
@@ -1387,7 +1404,7 @@
continue
skillTypeID = useSkill.GetSkillTypeID()
# 常规攻击优先xp
- if SkillCommon.isXPSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
+ if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
if curXP < xpMax:
continue
useCnt = -1 # xp技能优先释放
@@ -1400,18 +1417,11 @@
for useInfo in useSkillList:
useSkill = useInfo[-1]
- skillID = useSkill.GetSkillID()
+ #skillID = useSkill.GetSkillID()
atkOK, tagObj = DoNPCUseSkill(curNPC, useSkill, tick)
if atkOK:
- AddTurnFightXP(curNPC, __GetAddXP_Attack(curNPC, useSkill), "skillID:%s" % skillID)
break
- if not atkOK:
- tagObj = GetEnemyObj(curNPC)
- if tagObj:
- GameWorld.DebugLog(' 无技能可攻击,直接使用普攻! tagID=%s(%s)' % (tagObj.GetID(), GetObjName(tagObj)), npcID)
- atkOK = BaseAttack.Attack(curNPC, tagObj, None, tick)
-
curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
tagID = 0
@@ -1454,6 +1464,11 @@
if posNum <= 0:
GameWorld.DebugLog(" 被非主战单位攻击时无法触发反击: atkID=%s,posNum=%s" % (atkObj.GetID(), posNum))
return False
+ atkDistType = AttackCommon.GetAtkDistType(defObj)
+ if atkDistType == ChConfig.AtkDistType_Long:
+ if not IpyGameDataPY.GetFuncCfg("ParryCfg", 2):
+ GameWorld.DebugLog(" 远程单位不可反击: defID=%s" % (defObj.GetID()))
+ return False
defAtkBackRate = GameObj.GetAtkBackRate(defObj) # 防方反击率
atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # 已反击次数
if atkBackNum > 10:
@@ -1640,22 +1655,81 @@
return tagNPC
return
-def SetKilled(gameObj, killer=None):
+def SetTurnObjKilled(gameObj, killer=None):
if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
#GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID())
return
- GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), gameObj.GetID()))
- GameObj.SetHP(gameObj, 0) # 回合制死亡仅设置为0,实例暂时不回收
+ objID = gameObj.GetID()
+ GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), objID))
+ gameObj.SetCurAction(IPY_GameWorld.laNPCDie)
+ if GameObj.GetHP(gameObj) != 0:
+ GameObj.SetHP(gameObj, 0) # 回合制死亡仅设置为0,实例暂时不回收
gameObj.SetVisible(False)
- turnFight = GetTurnFightMgr().getNPCTurnFight(gameObj.GetID())
- if turnFight:
- clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
- clientPack.ObjID = gameObj.GetID()
- turnFight.addBatPack(clientPack)
+ turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
+ if not turnFight:
+ return True
+ clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
+ clientPack.ObjID = objID
+ turnFight.addBatPack(clientPack)
+
+ # 记录主动发起的玩家阵营击杀
+ curPlayer = turnFight.curPlayer
+ if killer and curPlayer and killer.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
+ if objID not in turnFight.playerKillObjIDList:
+ turnFight.playerKillObjIDList.append(objID)
+ GameWorld.DebugLog("玩家单次击杀统计: %s" % turnFight.playerKillObjIDList)
return True
+
+def OnTurnfightAttackSuccess(curObj, tagObj, curSkill):
+ ## 回合战斗攻击成功额外处理,AttackResult之前,一般处理技能相关
+ if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
+ return
+ if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
+ return
+
+ objID = curObj.GetID()
+ turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
+ if not turnFight:
+ return
+
+ skillID = curSkill.GetSkillID() if curSkill else 0
+ isXP = SkillCommon.isAngerSkill(curSkill)
+ if isXP:
+ GameObj.SetXP(curObj, 0)
+ elif curSkill:
+ if SkillCommon.isTurnNormalSkill(curSkill):
+ addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
+ AddTurnFightXP(curObj, addXP, "skillID:%s" % skillID)
+
+ curPlayer = turnFight.curPlayer
+ # 仅主动发起玩家阵容触发
+ if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
+ FBLogic.OnPlayerLineupAttackSuccess(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
+
+ return
+
+def OnTurnfightAttackResult(curObj, tagObj, curSkill):
+ ## 回合战斗攻击结果额外处理,AttackResult 之后,一般处理击杀结算相关
+ if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
+ return
+ if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
+ return
+
+ objID = curObj.GetID()
+ turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
+ if not turnFight:
+ return
+
+ curPlayer = turnFight.curPlayer
+ # 仅主动发起玩家阵容触发
+ if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
+ FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
+
+ turnFight.playerKillObjIDList = []
+ return
def OnTurnAllOver(guid):
## 所有回合已经全部执行完毕
@@ -1707,12 +1781,13 @@
for posNum, curNPC in batLineup.npcPosDict.items():
objID = curNPC.GetID()
npcID = curNPC.GetNPCID()
+ heroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
atkHurt = hurtStatDict.get(objID, 0)
defHurt = defStatDict.get(objID, 0)
cureHP = cureStatDict.get(objID, 0)
- GameWorld.DebugLog(" Pos:%s ID=%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s"
- % (posNum, objID, npcID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
- lineupStatInfo[str(posNum)] = {"ObjID":objID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
+ GameWorld.DebugLog(" Pos:%s ID=%s-%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s"
+ % (posNum, objID, npcID, heroID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
+ lineupStatInfo[str(posNum)] = {"ObjID":objID, "HeroID":heroID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
awardItemList = []
playerID = turnFight.playerID
--
Gitblit v1.8.0