From 4ff284edf33cbbfcb123e2ba01dead78793e9dc8 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 11 十二月 2023 16:47:01 +0800
Subject: [PATCH] 10019 【砍树】回合战斗(每回合攻击顺序改为按攻击速度倒序;每个阵营支持多个战斗实例)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 43 ++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 171 +++++++++++++++++++++++++-----------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py | 13 +++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 1
4 files changed, 157 insertions(+), 71 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 375d744..d35b9d4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -77,10 +77,29 @@
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)
+
tagObj = None
if tagPlayerID:
npcID = ChConfig.Def_NPCID_PVP
- tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID, pvpPlayerID=tagPlayerID)
+ tagObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=playerID, pvpPlayerID=tagPlayerID)
+ if not tagObj:
+ return
+ factionListB.append(tagObj)
+
+ # 对手玩家镜像的其他战斗实例...
+
else:
ipyData = IpyGameDataPY.GetIpyGameData("FBTurn", mapID, funcLineID)
if not ipyData:
@@ -88,91 +107,83 @@
npcID = ipyData.GetNPCID()
if not npcID:
return
- tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID)
-
- if not tagObj:
+ 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
- turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1)
- curPet = curPlayer.GetPetMgr().GetFightPet()
- tagPet = None
+ for gameObj in factionListA:
+ GameObj.SetFaction(gameObj, 1)
+ for gameObj in factionListB:
+ GameObj.SetFaction(gameObj, 2)
+
+ #一个回合攻击顺序,由攻击速度决定,攻速相同下阵营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)
- GameWorld.DebugLog("curPlayer.GetSightLevel=%s,tagObj.GetSightLevel=%s"
- % (curPlayer.GetSightLevel(), tagObj.GetSightLevel()), playerID)
-
- #一个回合攻击顺序
- #1. 快方宠物攻击,不存在跳过
- #2. 慢方宠物攻击,不存在跳过
- #3. 快方主体攻击
- #4. 慢方主体攻击
-
# 战斗前初始化
- factionObjMax = 0 # 某个阵营的最大战斗实例数
- factionObjDict = {1:[curPet, curPlayer], 2:[tagPet, tagObj]}
- for objList in factionObjDict.values():
- if factionObjMax < len(objList):
- factionObjMax = len(objList)
- for gameObj in objList:
- TurnFightObjStartInit(gameObj)
-
- 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)
-
+ for gameObj in fightObjList:
+ TurnFightObjStartInit(gameObj)
+
isWin = None
for turnNum in range(1, turnMax + 1):
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 gameObj in fightObjList:
+ TurnFightObjPerTurnStart(gameObj, turnNum)
+
# 回合战斗: 轮流依次攻击
- for index in range(factionObjMax):
- for faction in orderList:
- objList = factionObjDict[faction]
- if index >= len(objList):
- continue
- gameObj = objList[index]
- if not gameObj:
- continue
-
- tagGameObj = tagObj if faction == 1 else curPlayer
- objType = gameObj.GetGameObjType()
- objID = gameObj.GetID()
- tagObjType = tagGameObj.GetGameObjType()
- tagObjID = tagGameObj.GetID()
-
- GameWorld.DebugLog(" 行动: turnNum=%s,index=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s"
- % (turnNum, index, faction, objType, objID, tagObjType, tagObjID), playerID)
- DoAttack(gameObj, tagGameObj, tick)
-
- if tagGameObj and GameObj.GetHP(tagGameObj) > 0:
- continue
-
- isWin = faction == 1
- GameWorld.DebugLog(" tagObjType=%s,tagObjID=%s,被击杀,结束战斗: isWin=%s" % (tagObjType, tagObjID, isWin))
- break
+ for actNum, gameObj in enumerate(fightObjList, 1):
+ if not gameObj:
+ continue
+ faction = GameObj.GetFaction(gameObj)
+ tagGameObj = tagObj if faction == 1 else curPlayer
+ objType = gameObj.GetGameObjType()
+ objID = gameObj.GetID()
+ tagObjType = tagGameObj.GetGameObjType()
+ tagObjID = tagGameObj.GetID()
- if isWin != None:
- break
+ GameWorld.DebugLog(" 行动: turnNum=%s,actNum=%s,faction=%s,objType=%s,objID=%s,tagObjType=%s,tagObjID=%s"
+ % (turnNum, actNum, faction, objType, objID, tagObjType, tagObjID), playerID)
+ DoAttack(gameObj, tagGameObj, tick)
+ playerDead = GameObj.GetHP(curPlayer) <= 0
+ tagObjDead = (not tagObj or GameObj.GetHP(tagObj) <= 0)
+ if not playerDead and not tagObjDead:
+ continue
+
+ if playerDead and tagObjDead:
+ isWin = False # 平局算失败
+ GameWorld.DebugLog(" 双方被击杀,平局算失败: isWin=%s" % isWin)
+ elif playerDead:
+ isWin = False
+ GameWorld.DebugLog(" 玩家被击杀,失败: isWin=%s" % isWin)
+ elif tagObjDead:
+ isWin = True # 胜利
+ GameWorld.DebugLog(" 对手被击杀,胜利: isWin=%s" % isWin)
+ break
+
if isWin != None:
break
overState = FightState_Win if isWin else FightState_Fail
SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, overState, turnNum, turnMax)
- for objList in factionObjDict.values():
- for gameObj in objList:
- TurnFightObjOverReset(gameObj)
-
+ for gameObj in fightObjList:
+ TurnFightObjOverReset(gameObj)
+
GameWorld.DebugLog("===== 回合制战斗结束: mapID=%s,funcLineID=%s,tagPlayerID=%s,isWin=%s,overState=%s"
% (mapID, funcLineID, tagPlayerID, isWin, overState), playerID)
return
@@ -187,6 +198,10 @@
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"
+ % (gameObj.GetID(), npcID, GameObj.GetFaction(gameObj), GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj)))
+
# 重置技能CD、战斗buff
if objType == IPY_GameWorld.gotPlayer:
skillManager = gameObj.GetSkillManager()
@@ -198,7 +213,7 @@
pass
return
-def TurnFightObjTurnStart(gameObj, turnNum):
+def TurnFightObjPerTurnStart(gameObj, turnNum):
## 回合制战斗实例 - 每回合开始时处理
if not gameObj:
return
@@ -223,18 +238,34 @@
return
gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 0)
gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0)
+ GameObj.SetFaction(gameObj, 0)
objType = gameObj.GetGameObjType()
if objType == IPY_GameWorld.gotPlayer:
pass
elif objType == IPY_GameWorld.gotNPC:
- npcObjType = gameObj.GetGameNPCObjType()
- if npcObjType != IPY_GameWorld.gnotPet and GameObj.GetHP(gameObj):
- NPCCommon.SetDeadEx(gameObj)
-
+ RecycleObj(gameObj)
return
+def RecycleObj(gameObj):
+ npcObjType = gameObj.GetGameNPCObjType()
+ if npcObjType == IPY_GameWorld.gnotPet:
+ #GameWorld.DebugLog("RecycleObj 灵宠不回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
+ return
+ if npcObjType == IPY_GameWorld.gnotSummon:
+ curOwner = NPCCommon.GetSummonOwnerDetel(gameObj)
+ if curOwner and curOwner.GetGameObjType() == IPY_GameWorld.gotNPC:
+ #GameWorld.DebugLog("RecycleObj 召唤兽主人是NPC不回收 objID=%s,npcObjType=%s,%s,ownerID=%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID(), curOwner.GetID()))
+ return
+ if GameObj.GetHP(gameObj) <= 0:
+ #GameWorld.DebugLog("RecycleObj 已死亡,不用重复回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
+ return
+ #GameWorld.DebugLog("RecycleObj: objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
+ NPCCommon.SetDeadEx(gameObj)
+ return
+
+
def DoAttack(curObj, tagObj, tick):
curID = curObj.GetID()
tagID = tagObj.GetID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index be5f30c..ad82af4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3060,6 +3060,7 @@
) = range(3)
#---Obj字典-------
+Def_Obj_Dict_Faction = 'Faction' # 所属阵营
Def_Obj_Dict_TurnFightNum = 'TurnFightNum' # 回合制战斗当前轮次
Def_Obj_Dict_TurnComboNum = 'TurnComboNum' # 本回合已累计连击次数
Def_Obj_Dict_TurnAtkBackNum = 'TurnAtkBackNum' # 本回合已累计反击次数
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
index 78078e5..7866691 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
@@ -179,6 +179,19 @@
gameObj.SetDict(ChConfig.Def_PlayerKey_BloodShiledHurtEx, value / ShareDefine.Def_PerPointValue)
return
+def GetFaction(gameObj):
+ faction = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_Faction)
+ if faction:
+ return faction
+ if gameObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
+ return gameObj.GetFaction()
+ return gameObj.GetCountry()
+def SetFaction(gameObj, value):
+ gameObj.SetDict(ChConfig.Def_Obj_Dict_Faction, value)
+ if gameObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
+ gameObj.SetFaction(value)
+ return
+
def GetAtkSpeed(gameObj):
if gameObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
return gameObj.GetBattleValEx1()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
index b517a41..2f74743 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -148,7 +148,7 @@
def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord))
def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # 火防代表推荐战力
def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # 雷攻代表掉落归属类型
-def GetFaction(curNPC): return curNPC.GetCountry()
+def GetFaction(curNPC): return GameObj.GetFaction(curNPC)
def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率
def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果
def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果
@@ -2269,6 +2269,10 @@
# @return 如果召唤失败返回None 否则返回召唤的NPC的实例
# @remarks 在地图里召唤NPC 根据NPCID 出生点 AI类型 和TICK
def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0, sightLevel=0, refreshID=0, pvpPlayerID=0):
+ npcData = GameWorld.GetGameData().FindNPCDataByID(npcId)
+ if not npcData:
+ GameWorld.ErrLog("找不到该NPCID: %s" % npcId)
+ return
curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()
if not curSummon:
return
@@ -2306,6 +2310,43 @@
#__NotifyMapPlayerSummonMapNPC(npcId, rebornX, rebornY)
return curSummon
+def SummonNPC(gameObj, npcID, rebornX, rebornY):
+ ''' 某个实例进行召唤,有从属关系
+ '''
+ npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
+ if not npcData:
+ GameWorld.ErrLog("找不到该NPCID: %s" % npcID)
+ return
+ if gameObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
+ curSummon = gameObj.SummonNewNPC()
+ curSummon.SetLV(gameObj.GetLV())
+ curSummon.SetCountry(gameObj.GetCountry())
+ curSummon.GetNPCAngry().Init(ChConfig.Def_SummonNPC_Angry_Count)
+ curSummon.SetOwner(gameObj)
+ else:
+ sumCount, angryCount = 1, 3
+ if not gameObj.AddSummonCount(sumCount, npcID, angryCount):
+ return
+ #取新增的一只,最后一个
+ index = gameObj.GetSummonCount() - 1
+ if index < 0:
+ return
+ curSummon = gameObj.GetSummonNPCAt(index)
+
+ if not curSummon:
+ return
+
+ tick = GameWorld.GetGameWorld().GetTick()
+ curSummon.SetNPCTypeID(npcID)
+ curSummon.SetBornTime(tick)
+ InitNPC(curSummon)
+ curSummon.SetSightLevel(gameObj.GetSightLevel())
+
+ curSummon.Reborn(rebornX, rebornY, False)
+ NPCControl(curSummon).DoNPCRebornCommLogic(tick)
+ #curSummon.RefreshView()
+ return curSummon
+
## 通知地图内玩家,地图出现召唤NPC
# @param npcId: NPCID
# @param rebornX: 出生点X
--
Gitblit v1.8.0