UNPKG

@bot-shiki/koishi-plugin-werewolf

Version:
109 lines (108 loc) 4.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const koishi_1 = require("koishi"); const _1 = require("."); const utils_1 = require("../utils"); class DeathAction extends _1.Action { async action(speakers = []) { this.game.check(); const dying = this.game.seats.filter(c => !c.isDead && c.killer); if (!dying.length) return this.lastWords(speakers); dying.forEach((char) => { char.scapegoat = null; }); const revengers = new Map(); const others = this.game.room.filter((p) => { const char = this.game.chars.get(p); return !char || char.isDead; }); const tasks = [others.broadcast(this.game.weather === 'souten' ? (0, utils_1.t)('death.souten') : (0, utils_1.t)('death.confirm'))]; tasks.push(...this.game.seats.filter(c => !c.isDead).map(async (char) => { if (char.killer) { if (char.killer !== 'yukari' && char.isRevenger) { await char.player.send((0, utils_1.t)('death.revenge-hint')); const target = await char.select((c) => ({ disabled: !!c.killer, }), 60000, true); if (target) revengers.set(char, target); } else { await char.player.pause(60000, null, true); } } else { if (this.game.weather !== 'souten') { await char.player.pause(60000, null, true); } else { await char.player.send((0, utils_1.t)('death.souten-hint')); const result = await char.select((c) => ({ disabled: !c.killer || c.isOut, }), 60000, true); const target = this.game.seats[+result - 1]; if (!target) return; if (!target.scapegoat || this.getDistance(target, char) < this.getDistance(target, target.scapegoat)) { target.scapegoat = char; } } } })); await Promise.all(tasks); const output = dying.map((char) => { if (char.scapegoat) { revengers.delete(char); char.scapegoat.killer = char.killer; char.scapegoat.isOut = true; speakers.push(char.scapegoat); char.killer = null; return (0, utils_1.t)('death.souten-result-1', [char.player.name, char.scapegoat.player.name]); } else if (revengers.has(char)) { char.isOut = true; char.isWellKnown = true; speakers.push(char); revengers.get(char).killer = char.identity; return (0, utils_1.t)('death.revenge', [char.player.name, (0, utils_1.t)(`character.${char.identity}.name`)]); } else if (this.game.weather === 'souten') { char.isOut = true; speakers.push(char); return (0, utils_1.t)('death.souten-result-0', [char.player.name]); } else { char.isOut = true; speakers.push(char); } }).filter(Boolean); await this.game.room.broadcast(output.map(el => (0, koishi_1.h)('p', el))); return this.action(speakers); } getDistance(char1, char2) { const chars = this.game.seats.filter(c => !c.isDead); const index1 = chars.indexOf(char1); const index2 = chars.indexOf(char2); const dist = Math.abs(index1 - index2); return Math.min(dist, chars.length - dist); } async lastWords(speakers) { if (this.game.dayCount > 2 || !speakers.length) return; const others = this.game.room.filter(p => !speakers.includes(this.game.chars.get(p))); speakers.forEach(c => c.player.allowSpeech = true); await Promise.all([ others.broadcast((0, utils_1.t)('death.last-words')), ...speakers.map(async (char) => { await char.player.send((0, utils_1.t)('death.last-words-hint')); await char.player.select(['.', '。'], 60000); }), ]); speakers.forEach(c => c.player.allowSpeech = false); if (speakers.some(c => c.isSage)) { await this.game.sage.transfer(); } } } exports.default = DeathAction;