5e dmg中有如下战斗选用项,而其他d20系规则如pf等,也有关于士气的规则。
一些战斗人员可能会在一场战斗对自己不利时逃跑。你可以使用该选用规则来判定怪物和 NPC什么时候决定弃逃。
单个生物可能会在下列情况里选择逃跑:
该生物被突袭。
该生物在战斗中第一次被减少至一半或更少的生命值。
该生物无法在其自己的回合里伤害敌方人员。
一群生物可能会在以下情况里选择逃跑:
团体里所有生物都被突袭。
团体的领袖生命值被降至0,陷入失能,被俘虏或被从战斗中移除。
团体人员减少为原来的一半,而对方却没有人员损失。
为判定单个生物或一群生物是否决定逃走,你可以为该生物或该团体的领袖进行一次DC 10的感知豁免。如果对方势力碾压,则该豁免具有劣势,或者你也可以判定该豁免直接失败。如果团队的领袖因某些原因无法进行豁免,则团队中拥有最高魅力值的生物代为进行该豁免。
若豁免失败,则受影响的生物或团体依最快捷的路线逃跑。若无法实现逃离,则该生物或团体投降。已投降的生物或团体若受其投降方攻击,则双方战斗会重新展开,且此后不太可能再次作逃跑或投降的尝试。
这样的豁免失败在冒险者们看来不一定都是好事。例如,一个食人魔从战斗中逃跑,可能会导致地下城的其他地区敲响警报,或是它可能直接带着角色们要夺取的财宝逃之夭夭。
近期游玩《行商浪人》有所启发,这款采用战锤桌游规则游戏的战斗机制具有一个根据敌我状态或行动变动的士气机制,如果士气过高或过低,都可以发动对应的“英雄壮举”或者“背水一战”。
由此,本人草草撰写了一个简单的规则选用项,希望观者能给出意见。
需要预先说明的是,此规则选用项的使用场景为“配合融洽的长团”或“有一定默契的固桌”,其适用的跑团风格为“英雄奇幻”、“神话奇幻”、“史诗奇幻”或与之类似的故事,但并不适用于“暗黑奇幻”或“阴谋与悬疑”类型。
一支互相熟悉的冒险者小队的战斗热情可以用士气来衡量,而它的积攒或丧失可以一定程度上影响战局。例如,全队齐心协力积攒的,可以扭转战局的绝招,或是背水一战的勇气,甚至是寻找逃离出路的敏锐目光。
身为主角的小队具有一个士气槽,士气的范围为0-30,dm可以适当调整这个范围阈值,以影响士气类技能触发的频率。在战斗开始时,士气的初始值为士气范围的中位数(即15)。
当一个生物的回合开始,且己方小队士气值达到最大时,可以使用极限技,如果低于某个阈值,则可以使用奋战技。dm也可以设置一些用反应触发的士气技能。
使用极限技或奋战技后,士气将回落至初始值重新积攒。
极限技与奋战技具体的效果可以由DM为每个角色量身定制,在本选用规则的末尾会给出一些范例。
一些英勇、取得胜果、控制敌人的行动会激励盟友,提高士气值。
将一个敌人的生命值降低至0(每回合一次,提高2),将敌人生命值降低至一半(每回合一次,提高1),对敌人成功施加状态表中的负面效果(每回合一次,提高1),在d20挑战的最终判定结果骰出20(提高1),一个生物的回合结束时在回合内造成过伤害(提高1),为盟友施加了增益效果(每回合一次,提高1)。
一些怯懦、战斗失利、被控制的行动会积蓄战斗的焦虑,降低士气值。
盟友的生命值被降低至0(每回合一次,降低2),盟友的生命值被降低至0(每回合一次,降低1),盟友被施加状态表中的负面效果(每回合一次,降低1),在d20挑战的最终判定结果骰出1(降低1),一个生物的回合结束时,在回合时进行的攻击检定半数失手(降低1),盟友被施加了减益效果(每回合一次,降低1)。
士气技能示例:
战斗怒吼 [极限技]
需求:士气值达到最大时
消耗:1附赠动作
你以战斗激励盟友,指定一个你能看到的目标,直到你的下一个回合开始前,你和你的盟友对所有能听见你的敌人进行的攻击检定具有优势,且优势始终被应用,无法被劣势抵消。
寻找出路 [奋战技]
需求:士气值低于3
消耗:1动作
鉴于战局不利,你开始寻找撤退的路线,你进行一次调查(智力)或察觉(感知)检定,其DC由dm设定,越难以逃脱的战斗环境,这个DC越高。如果你检定未成功,士气值不会回复,且再降低1,如果你检定成功,你与你的所有盟友可以立刻向远离敌人的方向移动等同于自己行动力的距离,且不会引发借机攻击。被受到速度降低效果影响,但仍保有神志的生物可以立即进行一次具有优势的检定以摆脱对应效应。
若盟友移动的距离路线上有陷入失能状态(但未被擒抱或束缚)的盟友,则可以将其拉走,与自身一起移动。
殉道者的干涉 [奋战技]
先决:拥有提供生命值回复的能力
需求:士气值低于7
触发:射程中的生物即将受到伤害导致其生命值减少至0
消耗:1反应
你的小队落入了危险的境地,你暗暗积蓄着治愈能量,让盟友不会倒地,尽管这会对你造成伤势。你用自己的生命能量保护一个陷入危机的生物,自己承担伤害来拯救它的生命。目标生命值减少至1,而不是0。该次伤害中被阻止的部分全部被转移给你。
作为反应的一部分,你还可以立即激活一次提供生命值回复的能力。如果这个能力是依靠消耗法术位运作的,那么它的有效法术环级等同于你的熟练加值。
这种规则会增加战斗的判定数据,但可以编写骰子插件,或FVTT的MOD来进行辅助。
海豹骰插件↓
// ==UserScript==
// @name 士气系统(星尘的DND房规
// @author 星尘
// @version 1.0.0
// @description 士气系统,默认士气为0-20,可用指令如下\n .bp setmax < 整数 > 设置最大士气\n .bp set < 整数 > 直接设定士气\n .bp < 变化 >(如 + 1、-1) 士气变化.bp re 重置士气 .bp 查看当前士气
// @timestamp 1710647207
// 2024-03-17
// @license Apache-2
// @homepageURL https://github.com/sealdice/javascript
// ==/UserScript==
// 编写一条自定义指令
// 先将扩展模块创建出来,如果已创建就直接使用
let ext = seal.ext.find('士气');
if (!ext) {
ext = seal.ext.new('士气', '星尘', '1.0.0');
seal.ext.register(ext);
}
// 创建指令 .seal
// 这个命令的功能为,显示「抓到一只海豹」的文案;
// 如果命令写 .seal ABC,那么文案中将海豹命名为「ABC」;
// 如果命令中没写名字,那么命名为默认值「氪豹」。
const cmdBp = seal.ext.newCmdItemInfo();
cmdBp.name = 'bp'; // 指令名字,可用中文
cmdBp.help = `士气系统,默认士气为0-20,可用指令如下\n
.bp setmax <整数> 设置最大士气\n
.bp set <整数> 直接设定士气\n
.bp <变化>(如+1、-1) 士气变化
.bp re 重置士气\n
.bp help 查看帮助\n
.bp 查看当前士气`;
let bpMin = 0;
let bp = 10;
let bpMax = 20;
let bpMedian = 10;
let bpMaxConfigMap = new Map();
let bpDataMap = new Map();
let bpMedianMap = new Map();
/* 士气值打印函数,参数为当前士气与最大士气,返回值为美观的士气值字符串 ,例如 (Min<===|========>Max)*/
function printBP(bp, bpMax) {
let bpStr = '\(Min<';
for (let i = bpMin; i < bp - 1; i = i + 2) {
bpStr += '=';
}
bpStr += '|';
for (let i = bp; i < bpMax; i = i + 2) {
bpStr += '=';
}
bpStr += '>Max\)';
return bpStr;
}
// 主函数,指令解析器会将指令信息解析,并储存在几个参数中
// ctx 主要是和当前环境以及用户相关的内容,如当前发指令用户,当前群组信息等
// msg 为原生态的指令内容,如指令文本,发送平台,发送时间等
// cmdArgs 为指令信息,会将用户发的信息进行分段,方便快速取用
cmdBp.solve = (ctx, msg, cmdArgs) => {
// 获取第一个参数,例如 .seal A B C
// 这里 cmdArgs.getArgN(1) 的结果即是 A,传参为 2 的话结果是 B
let val = cmdArgs.getArgN(1);
switch (val) {
case 'help': {
// 命令为 .seal help
// 创建一个结果对象,并将 showHelp 标记为 true,这会自动给用户发送帮助
const ret = seal.ext.newCmdExecuteResult(true);
ret.showHelp = true;
return ret;
}
case 'setmax': {
// 检测该群组是否已设置最大士气值,没有则初始化
if (!(bpMaxConfigMap.has(ctx.group.groupId)) && !(bpDataMap.has(ctx.group.groupId))) {
bpMaxConfigMap.set(ctx.group.groupId, 20);
bpDataMap.set(ctx.group.groupId, 10);
bpMedianMap.set(ctx.group.groupId, 10);
}
bpMax = parseInt(cmdArgs.getArgN(2));
bpMedian = Math.round(bpMax / 2);
bpMaxConfigMap.set(ctx.group.groupId, bpMax);
bpMedianMap.set(ctx.group.groupId, bpMedian);
bpDataMap.set(ctx.group.groupId, bpMedian);
seal.replyToSender(ctx, msg, `\(最大士气值已设置为${bpMax}\)`);
return seal.ext.newCmdExecuteResult(true);
}
case 'maxset': {
// 检测该群组是否已设置最大士气值,没有则初始化
if (!(bpMaxConfigMap.has(ctx.group.groupId)) && !(bpDataMap.has(ctx.group.groupId))) {
bpMaxConfigMap.set(ctx.group.groupId, 20);
bpDataMap.set(ctx.group.groupId, 10);
bpMedianMap.set(ctx.group.groupId, 10);
}
bpMax = parseInt(cmdArgs.getArgN(2));
bpMaxConfigMap.set(ctx.group.groupId, bpMax);
bpMedianMap.set(ctx.group.groupId, Math.round(bpMax / 2));
seal.replyToSender(ctx, msg, `\(最大士气值已设置为${bpMax}\)`);
return seal.ext.newCmdExecuteResult(true);
}
case 'set': {
if (!(bpMaxConfigMap.has(ctx.group.groupId)) && !(bpDataMap.has(ctx.group.groupId))) {
bpMaxConfigMap.set(ctx.group.groupId, 20);
bpDataMap.set(ctx.group.groupId, 10);
bpMedianMap.set(ctx.group.groupId, 10);
}
bpMax = bpMaxConfigMap.get(ctx.group.groupId);
bp = parseInt(cmdArgs.getArgN(2));
if (bp > bpMax || bp < 0) {
seal.replyToSender(ctx, msg, `超出解限或为负数,最大士气为${bpMax}`);
return seal.ext.newCmdExecuteResult(true);
}
bpDataMap.set(ctx.group.groupId, bp);
seal.replyToSender(ctx, msg, printBP(bp, bpMax) + `\n\(士气值变化至${bp}\)`);
if (parseInt(bp) === parseInt(bpMax)) {
seal.replyToSender(ctx, msg, `(士气已经上升至最大!)`);
}
return seal.ext.newCmdExecuteResult(true);
}
case 're': {
if (!(bpMaxConfigMap.has(ctx.group.groupId)) && !(bpDataMap.has(ctx.group.groupId))) {
bpMaxConfigMap.set(ctx.group.groupId, 20);
bpDataMap.set(ctx.group.groupId, 10);
bpMedianMap.set(ctx.group.groupId, 10);
}
bpMax = bpMaxConfigMap.get(ctx.group.groupId);
bp = bpMedianMap.get(ctx.group.groupId);
bpDataMap.set(ctx.group.groupId, bp);
seal.replyToSender(ctx, msg, printBP(bp, bpMax) + `\n\(士气值已重置\)`);
return seal.ext.newCmdExecuteResult(true);
}
default: {
if (!(bpMaxConfigMap.has(ctx.group.groupId)) && !(bpDataMap.has(ctx.group.groupId))) {
bpMaxConfigMap.set(ctx.group.groupId, 20);
bpDataMap.set(ctx.group.groupId, 10);
bpMedianMap.set(ctx.group.groupId, 10);
}
bp = bpDataMap.get(ctx.group.groupId);
bpMax = bpMaxConfigMap.get(ctx.group.groupId);
// 如果是类似于-1 +1 *2 /2 这样的算式,就对bp的数值进行计算
if (val.match(/^[\+\-\*\/]\d+$/)) {
let op = val.charAt(0);
let num = parseInt(val.substring(1));
switch (op) {
case '+':
bp += num;
if (bp > bpMax) bp = bpMax;
break;
case '-':
bp -= num;
if (bp < 0) bp = 0;
break;
case '*':
bp *= num;
if (bp > bpMax) bp = bpMax;
break;
case '/':
bp /= num;
bp = Math.round(bp);
break;
}
bpDataMap.set(ctx.group.groupId, bp);
seal.replyToSender(ctx, msg, printBP(bp, bpMax) + `\n\(士气值${op}${num},变化至${bp}\)`);
if (parseInt(bp) === parseInt(bpMax)) {
seal.replyToSender(ctx, msg, `(士气已经上升至最大!)`);
return seal.ext.newCmdExecuteResult(true);
}
return seal.ext.newCmdExecuteResult(true);
}
// 如果为空则直接打印士气值
if (val === '') {
seal.replyToSender(ctx, msg, printBP(bp, bpMax) + `\n\(当前士气值为${bp}\)`);
return seal.ext.newCmdExecuteResult(true);
}
// 命令为 .seal XXXX,取第一个参数为名字
// if (!val) val = '氪豹';
// // 进行回复,如果是群聊发送那么在群里回复,私聊发送则在私聊回复 (听起来是废话文学,但详细区别见暗骰例子)
// seal.replyToSender(ctx, msg, `你抓到一只海豹!取名为${val}\n它的逃跑意愿为${Math.ceil(Math.random() * 100)}`);
// return seal.ext.newCmdExecuteResult(true);
}
}
};
// 将命令注册到扩展中
ext.cmdMap['bp'] = cmdBp;
我以前写过一个以DMG为基础的士气房规。
一开始士气数值=玩家队伍最高魅力数值,后来发现基本没有精力去追踪数值。
之后改成了3点(等于魅调的话变相需要玩家有一个魅力人,对玩家的队伍构筑颇有影响),并且简化士气变动。
体验还行,但也是老问题,没有精力去追踪数值的变化(哪怕只有1点)。
最后我把这条房规删了 :em006其实我觉得自己写的还不错来着
士气规则带给我的教训总结成一句话:以血量变化为基础的规则确实不需要第二种胜负条件,除非你给玩家看过后他们主动提出想用。
士气凡兵,有以道胜,有以威胜,有以力胜。讲武料敌,使敌之气失而师散,虽形全而不为之用,此道胜也。审法制,明赏罚,便器用,使民有必战之心,此威胜也。破军杀将,乘闉发机,溃众夺地,成功乃返,此力胜也。王侯如此,[所]以三胜者毕矣。
——《尉缭子》士气是维持战斗的根本,保持队伍旺盛的士气才能保证队伍的活力。一些能判断局势的生物可能会在战斗对自己不利时选择逃跑,或者在巨大的压力下坚持战斗。但并不是所有角色或敌人都会被士气影响(例如只懂服从命令的不死生物或构装体)。以下规则用于衡量战斗中的士气所带来的影响。
士气点士气点是衡量士气高低的标准,玩家队伍和敌方队伍都有各自的士气点,团队的士气点上限为3。每次长休后都会回满队伍的士气点。后文列举了一些会改变士气的事件,以及士气点能做的事情。
领袖
领袖默认为魅力最高者,也可以由队伍自行决定,其承担感知豁免维持士气的职责。一个队伍只能有一个领袖。
当士气点跌落到0时,领袖需立刻进行一次DC 15的感知豁免。如果敌人实力碾压或领袖处于恐惧或魅惑状态,则该豁免具有劣势,或者DM也可以判定该豁免直接失败(仅敌人)。如果领袖因某些原因无法进行豁免(如失能,被放逐),则团队中其他拥有最高魅力值的生物代为进行该豁免。
若感知豁免成功,则回复1士气点;若豁免失败,则受影响的生物或团体的所有成员进入士气低迷状态,并记录士气低迷次数+1。
士气低迷 当士气跌落到0,且领袖没能很好调整队伍时,整个队伍都会进入士气低迷状态。士气低迷状态的角色回合开始时有两种选择:
- 坚持战斗,但是攻击、属性检定获得劣势。
- 逃跑,若无法逃跑则投降或坚持战斗。
处于士气低迷状态的领袖的回合内,他有以下方式提升队伍的士气点:
- 以一个动作进行一次契合实际场景和扮演的技能检定*,将检定结果除以10(向下取整),回复对应的士气点(最大为2)。
*通常为魅力系技能,但偶有例外(如以宗教名义的战斗中可用智力(宗教)代替) - 回合结束时,进行一次DC为10的感知豁免,若成功则回复1士气点。
无论选择哪种方式,回合内只有一次成功回复士气点的机会。如果领袖的回合结束后士气点仍为0,那么该团队继续保持士气低迷状态,并且士气低迷次数+1,该团队领袖在下一回合开始才能重新获得回复士气值的机会。
已投降的生物或团体若受其投降方攻击,则双方战斗会重新展开,且此后不太可能再次作逃跑或投降的尝试。
若士气低迷次数达到3,则该生物或团队视为士气崩溃且无条件投降。士气低迷次数会在长休后重置。
士气下降事件 - 团队所有生物被突袭。-1士气点
- 团队触发危险等级的陷阱。-1士气点
- 团体领袖生命值被降至0,被俘虏或被从战斗中移除,该项每场战斗仅生效一次。-1士气点
- 团体昏迷(自然睡眠除外)和死亡角色达到满编制的一半(向上取整),该项每场战斗仅生效一次。-1士气点
- 任一角色回合开始时,所属团体一半(向上取整)以上的角色处于恐慌、魅惑、失能状态,该项每战斗轮仅生效一次。-1士气点
- 剧情或特殊事件可能会触发的效果。
士气回复事件 战术指挥 队长可以消耗士气点进行下文中列出的传奇动作,此传奇动作必须在另一生物结束其回合时使用,目标必须为60尺范围内可见的其他盟友。盟友可以选择是否听从指挥并执行相应行动。如果战术指挥会导致士气点降至0 以下,那么无法执行战术指挥。只有上下级关系明确的敌人会使用战术指挥。
- 疾驰(消耗1士气点):你指挥一个盟友疾驰,该盟友可以消耗反应并移动不超过该盟友速度两倍的距离。
- 撤退(消耗1士气点):你指挥一个盟友撤退,该盟友可以消耗反应并移动不超过该盟友速度的距离,这次移动不会引发借机攻击。
- 进攻(消耗1士气点):你指挥一个盟友进攻,该盟友可以消耗反应并对其攻击范围内的单一生物或物件进行一次武器攻击,这次攻击检定获得优势。。
- 坚守(消耗1士气点):你指挥一个盟友坚守,该盟友可以消耗反应并执行回避,且获得你的等级+你的魅力调整值的临时生命值。
- 重振旗鼓(消耗X士气点):你指挥一个盟友重振旗鼓,该盟友如果被X种豁免成功就能结束的效应所影响,其立刻进行X次豁免检定以对抗这些效应。
特殊士气事件 因为某种原因(如领袖的发言或行动),所有角色决定死战。士气点最低为1,士气低迷时无法选择逃跑或投降,不会士气崩溃,持续战斗到全体死亡或战斗胜利。特殊士气事件只会在某些剧情中有条件的触发。