TrinityCore框架_战场设计与实现
最近更新:2024-09-23
|
字数总计:4k
|
阅读估时:14分钟
|
阅读量:次
- 战场设计
- 战场概述
- 战场实现概述
- 数据库表设计
- 代码结构
- Battleground基类封装
- 战歌峡谷
- 战歌峡谷介绍
- 战歌峡谷实现
- 阿拉希盆地
- 阿拉希盆地介绍
- 阿拉希盆地实现
- 奥特兰克山谷
- 奥特兰克山谷介绍
- 奥特兰克山谷实现
- 风暴之眼
- 风暴之眼介绍
- 风暴之眼实现
- 远古海滩
- 远古海滩介绍
- 远古海滩实现
- 征服之岛
- 征服之岛介绍
- 征服之岛实现
战场设计
战场概述
- 战场类型
- BattlegroundWS: 战歌峡谷(Warsong Gulch)
- BattlegroundAB: 阿拉希盆地(Arathi Basin)
- BattlegroundAV: 奥特兰克山谷(Alterac Valley)
- BattlegroundEY: 风暴之眼(Eye of the Storm)
- BattlegroundSA: 远古海滩(Strand of the Ancients)
- BattlegroundIC: 征服之岛(Isle of Conquest)
战场实现概述
数据库表设计
- battleground_template
1
| select ID, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, Comment from battleground_template;
|
- 数据库表设计:
- BattlegroundWS: ID=2, players=5-10, lvl=10-80
- BattlegroundAB: ID=3, players=8-15, lvl=20-80
- BattlegroundAV: ID=1, players=20-40, lvl=51-80
- BattlegroundEY: ID=7, players=8-15, lvl=20-80
- BattlegroundSA: ID=9, players=7-15, lvl=61-80
- BattlegroundIC: ID=30, players=20-40, lvl=71-80
代码结构
- 代码位置:game/battlegraounds
- 核心代码:Battleground.h/Battleground.cpp
- 战场管理:BattlegroundMgr
- 匹配队列:BattlegroundQueue
- 积分计算:BattlegroundScore
- 客户端命令驱动战场逻辑:game/Handlers/BattleGroundHandler.cpp
- 游戏帧驱动战场逻辑:World::Update主线程中更新
Battleground基类封装
- 采用模板方法:基类抽象算法(框架)骨架,通过子类复写骨架的子流程来实现战场的变化
- 算法骨架:Update
- 游戏帧更新前的代码处理:PreUpdateImpl
- 战场阶段更新:
- STATUS_WAIT_QUEUE 仍在队列
- STATUS_WAIT_JOIN 战场已准备开始,等待玩家加入
- _ProcessJoin
- 处理游戏开始时间通知
- StartingEventOpenDoor
- STATUS_IN_PROGRESS 战场正在运行中
- _ProcessOfflineQueue 处理战场中玩家掉线
- _ProcessResurrect 处理战场中玩家重生
- _ProcessProgress 处理游戏进程
- STATUS_WAIT_LEAVE 战场已退出,等待玩家退出
- _ProcessLeave 处理战场结束逻辑
- 游戏帧更新后的代码处理:PostUpdateImpl
- 战场中的重要事件
- DestroyGate 门被损坏
- EndBattleground 战场已结束
- UpdatePlayerScore 玩家积分更新
- CheckWinConditions 检查胜负条件
- HandleAreaTrigger 处理区域触发
- HandleKillPlayer pvp击杀
- HandleKillUnit pve击杀事件
- EventPlayerDroppedFlag 战旗掉落
- EventPlayerClickedOnFlag 战旗拾取
- ProcessEvent/DoAction
- HandlePlayerResurrect 处理玩家重生
- HandlePlayerUnderMap 处理地图异常,跑到地图下面去了
战歌峡谷
战歌峡谷介绍
- 夺旗型战场
- 战场目标:
- 主要是夺取对方的旗帜并带回自己的基地三次,先达到这一目标的阵营将获得胜利。
- 如何进入:
- 10级以上的玩家可以通过各大主城内的战争大师排队进入战歌峡谷
- 等级分段
- 设有不同的等级阶段,不同等级的玩家会被分配到相应的阶段进行匹配,具体分段
- 10-19
- 20-29
- 30-39
- 40-49
- 50-59
- 60-60(或当前最高等级上限)
- 战场地图
- 战歌峡谷地图上下形状对等,双方基地各有一面旗帜
- 基地内会刷新疾驰BUFF,门外两个小屋会刷新狂暴与治疗BUFF
- 旗帜争夺
- 玩家需要将敌方旗帜拔出并带回己方旗帜附近以得分
- 交旗时,己方旗帜必须处于未被偷走的状态
战歌峡谷实现
- 玩法调试
- GM依赖
- .gm off 否则会出现战场逻辑异常
- .debug bg 打开调试模式,不通过匹配队列进入战场
- .modify speed 5 加快测试流程
- .learn 5384 学习假死技能
- 骨架实现(游戏帧增加内容)
- 强制结算逻辑:超过27分钟,进行强制结算
- 围绕战旗定时更新逻辑
- 刷回主营地的定时
- 持有战旗的玩家超过10分钟或15分钟给debuff
- 子流程扩展实现
- AddPlayer 为了结算
- StartingEventCloseDoors 关闭该战场的门
- StartingEventOpenDoors 开启该战场的门
- EventPlayerDroppedFlag 战旗掉落
- EventPlayerClickedOnFlag 玩家点击旗帜
- RemovePlayer 玩家掉线处理(关于旗子处理)
- HandleAreaTrigger 区域触发,判断是否归还旗子
- HandleKillPlayer 击杀玩家,积分判断,旗子处理
- SetupBattleground 初始化GameObject
- 双方阵营战旗
- buff GameObject
- 双方阵营的门
- Reset 战场初始化数据(实现战场私有化成员)
- EndBattleground 处理结算相关
- GetClosestGraveyard 获取出生点
- 游戏开始了,main
- 游戏未开始,flagroom
- 问题:假如要实现一个战场,需要怎么实现?(实现总结)
- 首先看副本系统的整体骨架(基类)
- 游戏规则(跟策划沟通)
- GameObject
- 战旗
- 门
- buff
- 如何确定胜负
- 结算
- 怎么实现
- 战旗拾取-通过技能
- 战旗掉落-通过技能
- 战旗刷新 刷新GameObject
- 战旗状态
- BG_WS_FLAG_STATE_ON_BASE 战旗在主营地中
- BG_WS_FLAG_STATE_WAIT_RESPAWN 战旗等待刷新状态
- BG_WS_FLAG_STATE_ON_PLAYER 战旗在玩家身上
- BG_WS_FLAG_STATE_ON_GROUND 战旗掉落在地面上
阿拉希盆地
阿拉希盆地介绍
- 资源占领型战场
- 战场目标:
- 积累资源点数,首先达到一定资源点数的阵营将获得胜利
- 如何进入:
- 玩家可以通过找到主城内的战场军官或直接前往阿拉希盆地的战场入口来加入战场
- 资源点数获取
- 玩具可以通过占领地图上的五个关键地点(矿洞、农场、伐木场、铁匠铺和马厩)来获得资源点数
- 每当一个地点被完全控制时,占领该地点的阵营将开始获得资源点数
- 玩家还可以通过击杀对方玩家来获得少量的资源点数
- 占领机制
- 占领一个地点需要玩家在该地点内保持人数优势
- 当一个地点被占领时,占领条会开始填充,如果占领方保持控制直到占领条完全填满,该地点将正式被占领
- 如果占领方的玩家数量减少到一定的阈值,占领条将开始倒退
阿拉希盆地实现
- 玩法介绍
- 兽栏
- 金矿
- 铁匠铺
- 伐木场
- 农场
- GM指令
- .gm off GM模式要关闭,否则战场会异常
- .debug bg 通过调试模式进来战场,否则进入匹配队列
- .modify speed 5
- .gm fly on 开启飞行模式
- .gm fly off 关闭飞行模式
- 骨架更新
- 延迟创建资源点的旗帜
- 检查争议旗帜1分钟后转变为 占有旗帜
- 根据资源占有点数来定时更新资源积分
- 子流程扩展部分
- Addplayer
- StartingEventOpenDoors
- 游戏对象的创建:门,旗帜,随机buff
- SetupBattleground
- 将游戏对象添加到地图里面(参与游戏帧更新)
- Reset 阿拉希盆地类私有成员的初始化,另外周末荣誉点会多一些
- EndBattleground 结算处理
- GetClosestGraveyard 选择邻近的占有资源点附近出生
- EventPlayerClickedOnFlag
- 点击旗帜的事件
- 费解点:为什么需要从5个资源点一次判断与玩家的距离
奥特兰克山谷
奥特兰克山谷介绍
- 是一个大型pvp战场
- 战场目的:
- 为了荣誉:通过参与获得荣誉点数
- 为了胜利:可以通过完成战场目标来赢得胜利,包括占领敌方基地,击杀敌方npc和玩家
- 为了杀人
- 为了拉锯:陷入长时间的拉锯战,互相争夺控制点
- 荣耀获取
- 烧毁地方碉堡,每个碉堡被烧毁后,参与的玩家可以获得声望奖励
- 杀死地方npc上尉,击杀敌方npc上尉可以获得大量声望
- 击杀敌方将军,成功击杀敌方将军将直接获得战斗胜利,并为所有参与玩家提供大量声望
- 上交风暴水晶、联盟士兵的血和护甲碎片,这些物品可以交给己方npc以换取声望
- 战场事件
- 碉堡占领:战场中有多个碉堡,占领后可以为己方提供战略优势
- 中尉和指挥官:击杀敌方的中尉和指挥官可以获得荣誉
- 墓地占领:占领特定的墓地可以为己方提供复活点和战略优势
- 空军救援:救援被敌方俘虏的己方空军可以获得荣耀
奥特兰克山谷实现
- 研究思路:判定胜负逻辑
- 增援值
- 双方阵营初始值600
- 击杀玩家-1
- 击杀中尉(NPC)-100
- 占领矿洞后(击杀矿洞里的某些怪物),每45s +1,20min后矿洞回归中立
- 被占领哨塔 -75
- 击杀boss
- 双方阵营:4座哨塔,三个墓地,一名将军
- 击杀将军直接判定胜负
- Boss AI
- 生成怪物时,会读取怪物AI
- script/EasternKingdoms/AlteracValley中描述了AI逻辑
- 战略资源
- 哨塔
- 占领哨塔或墓地需要8s cd,该地点进入4分钟的争夺状态
- 哨塔4分钟过后,会摧毁
- 怎么占领
- 点击旗帜 8s cd
- 4分钟的防御时间
- 时间一过,哨塔销毁,同时里面的npc全部消失
- 墓地
- 总结:根据胜负判定逻辑实现接口
- 击杀玩家 HandleKillPlayer
- 击杀中尉/占领矿洞/击杀boss HandleKillUnit
- 占领哨塔/占领墓地 EventPlayerClickedOnFlag/PostUpdateImpl
- 怪物AI实现
风暴之眼
风暴之眼介绍
- 是一个结合了维持占领和夺旗模式的玩法
- 战场目的:
- 玩家的目标是通过占领地图上的塔楼和夺取旗帜来积累资源点数,首先达到1600资源点数的阵营将获得胜利
- 占领塔楼
- 地图上有四个塔楼(法师塔、德莱尼废墟、恶魔收割场、血精灵塔),分布在地图的四个角
- 玩家需要在塔楼内保持人数优势来占领塔楼,占领后资源点数开始缓慢增长
- 夺取旗帜
- 地图中央有一个旗帜,玩家可以夺取旗帜并带回己方占领的塔楼以增加额外的资源点数
- 资源点数的增长
- 占领塔楼和夺取旗帜都会为阵营增加资源点数
- 每200点资源,玩家可以获得一次荣誉奖励
- 胜利条件
- 阵营的资源点数达到1600时,该阵营将获得战场胜利
- 进入方法
- 玩家通过主城的npc对话进入战场,联盟方找德莱尼军官,部落方找血精灵军官
风暴之眼实现
- 核心点:资源点数
- 塔楼
- 占领的塔楼个数 m_TeamPointsCount
- 资源点数增加步伐配置 BG_EY_TickPoints
- 每隔两秒中根据占领塔楼个数缓慢增加资源点数
- 塔楼占领定时器m_TowerCapCheckTimer
- 每隔2s检测塔楼占领逻辑
- 统计靠近塔楼的玩家的数据结构 m_PlayersNearPoint
- 统计靠近塔楼的双方阵营的玩家 m_CurrentPointPlayersCount
- 检查玩家是否靠近塔楼 CheckSomeoneJoinedPoint
- 检查玩家是否逃离塔楼 CheckSomeoneLeftPoint
- 塔楼占领进度条 m_PointBarStatus
- 部落 0,占领30
- 联盟 100,占领70
- 初始值 50
- 每隔2s,联盟阵营增加进度值或部落阵营减少进度值
- 根据人数差
- 占领塔楼事件 EventTeamCapturedPoint
- 塔楼丢失事件 EventTeamLostPoint
- 旗帜
- 在wait_respawn或on_ground,8s后重新刷新(on_base)
- 移除玩家RemovePlayer
- 维护m_PlayersNearPoint
- 旗帜掉落事件触发 EventPlayerDroppedFlag
- 重新刷新旗帜 RespawnFlag
- 区域触发 HandleAreaTrigger
- 把旗帜放到当前阵营占领的塔楼中央
- 触发夺旗事件 EventPlayerCapturedFlag
- 杀死玩家 HandleKillPlayer
- 旗帜掉落事件触发 EventPlayerDroppedFlag
- 点击旗帜事件 EventPlayerClickedOnFlag
- 更新旗帜状态 BG_EY_FLAG_STATE_ON_PLAYER
- 拾取旗帜通过技能实现 BG_EY_NETHERSTORM_FLAG_SPELL
- 结算逻辑
- 结算逻辑实现 EndBattleground
- 更新阵营的资源点数 UpdateTeamScore
- 增加资源点数 AddPoints
- 占领塔楼后,每隔2s增加资源点数
- 根据占领塔楼的个数,依次获取75,85,100,500个资源点数
- 结算结构体 BattlegroundEYScore
远古海滩
远古海滩介绍
- 进攻方攻破防守方的防线并夺取泰坦圣物,而防守方则需要阻止进攻方取得圣物
- 战场目的:
- 进攻方的目标是攻破防守方的多层防线,最终进入宝库并夺取泰坦圣物
- 防守方的目标是阻止进攻方进入宝库并保护泰坦圣物
- 防线和门
- 远古海滩战场有多层防线,包括四层六道门
- 每攻破一道门,进攻方玩家可以获得当前升级总经验的一定百分比
- 防守方没守住一层防线,也可以获得经验奖励
- 泰坦圣物
- 战场的核心是位于最内层防线的泰坦圣物
- 进攻方需要进入宝库并点击泰坦圣物来开始计时,携带圣物回到起始区域即可获胜
- 防守方需要保护圣物不被夺取,并阻止进攻方携带圣物返回
- 战斗回合
- 一次战斗分为两个回合,双方阵营各进行一次防守和进攻
- 进入战斗后,系统会随机决定哪个阵营首先进行防守
- 胜利条件
- 进攻方成功夺取泰坦圣物并带回起始区域,或者防守方成功组织进攻方在规定时间内夺取圣物
- 经验获取
- 玩家可以通过攻破门和防守防线来获得经验值,具体百分比会根据玩家的当前升级总经验来计算
远古海滩实现
- 两轮攻防
- 状态机在游戏帧更新中进行
- BG_SA_WARMUP 第一轮热身2分钟
- BG_SA_SECOND_WARMUP 第二轮热身1分钟
- BG_SA_ROUND_ONE 第一轮游戏中
- BG_SA_ROUND_TWO 第二轮游戏中
- 泰坦圣物
- 通过GameObject事件机制实现
- GameObject 可以触发事件
- use 接口
- SetDestructibleState接口
- gameobject_template 表
- entry = 192834
- type = 0
- eventid = 22097
- 事件触发 TitanRelicActivated
- 一轮游戏结束
- 城门(绿色)
- 事件触发 damaged
- damagedNumHits 9000
- damagedEvent 19041
- 广播
- 事件触发 destroyed
- destroyedEvent 19046
- 删除GameObject
- 广播
- 攻城车
- 报废时:HandleKillUnit
- 通过creature实现,AI为NullCreature
- 在PostUpdateImpl帧更新中,30s复活逻辑
- 墓地占领 EventPlayerClickedOnFlag
征服之岛
征服之岛介绍
- 胜利条件
- 消灭敌方阵营300名玩家,每个玩家死亡都会减少敌方的人头数
- 摧毁对方二楼的boss,这通常是在对方基地的二楼
- 据点
- 征服之岛有多个据点,包括部落大本营、联盟大本营、精炼厂、码头、工坊、机棚和矿场
- 每占领一个据点,死后则在该据点复活,这为战场提供了战略深度
- 旗帜
- 在保护好己方旗帜的同时,玩家需要将敌人的战旗抢回自己的基地,先到达三次抢旗成功的阵营将取得胜利
- 如果双方阵营旗帜都被控制,持旗玩家将在10分钟后所受伤害将增加50%,15分钟后受伤害将增加100%
- 旗帜被拿起45s后,将可以通过地图追踪持旗玩家的位置
征服之岛实现
- 援兵数
- 双方阵营初始值300
- 占领据点
- 增加援兵值
- 其中两个据点增加15%攻城伤害
- factionReinforcements
- MAX_REINFORCEMENTS 300
- HandleKillPlayer -1
- PostUpdateImpl +1
- boss击杀
- HandleKillUnit
- 阵营三张门被攻破
- BossAI
- 代码位置:scripts/Northrend/IsleOfConquest
- 继承自ScriptedAI
- 骨架更新
- 针对码头和车间 刷新的攻城器械进行重生处理
- 据点旗帜状态更新:争议状态变为占领状态切换(1min)
- 每隔45s根据占领的据点数增加援兵数
- 子流程扩展
- AddPlayer
- HandleAreaTrigger
- 通过技能实现城门传送功能
- 实现原理
- 客户端发送 CMSG_AREATRIGGER
- 服务端响应 HandleAreaTriggerOpcode
- triggerId是否合法
- 玩家是否在触发器内部
- EventPlayerClickedOnFlag
- 处理据点占领的逻辑
- 转化为争议状态
- 如果把敌方阵营的占领据点夺回,会获得夺回成就
2024-07-06
该篇文章被 Cleofwine
归为分类:
Game