forked from crowbartools/Firebot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ゲームとしておみくじを追加 * 翻訳を追加
- Loading branch information
Showing
8 changed files
with
316 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
"use strict"; | ||
|
||
const util = require("../../../utility"); | ||
const twitchChat = require("../../../chat/twitch-chat"); | ||
const commandManager = require("../../../chat/commands/CommandManager"); | ||
const gameManager = require("../../game-manager"); | ||
const currencyDatabase = require("../../../database/currencyDatabase"); | ||
const customRolesManager = require("../../../roles/custom-roles-manager"); | ||
const teamRolesManager = require("../../../roles/team-roles-manager"); | ||
const twitchRolesManager = require("../../../../shared/twitch-roles"); | ||
const omikujiMachine = require("./omikuji-machine"); | ||
const logger = require("../../../logwrapper"); | ||
const moment = require("moment"); | ||
const NodeCache = require("node-cache"); | ||
|
||
const activeOmikuji = new NodeCache({checkperiod: 2}); | ||
const cooldownCache = new NodeCache({checkperiod: 5}); | ||
|
||
const OMIKUJI_COMMAND_ID = "firebot:omikuji"; | ||
|
||
const omikujiCommand = { | ||
definition: { | ||
id: OMIKUJI_COMMAND_ID, | ||
name: "おみくじをひく", | ||
active: true, | ||
trigger: "!omikuji", | ||
description: "おみくじを開始します", | ||
autoDeleteTrigger: false, | ||
scanWholeMessage: false, | ||
hideCooldowns: true, | ||
subCommands: [ | ||
] | ||
}, | ||
onTriggerEvent: async event => { | ||
|
||
const { userCommand } = event; | ||
|
||
const omikujiSettings = gameManager.getGameSettings("firebot-omikuji"); | ||
const chatter = omikujiSettings.settings.chatSettings.chatter; | ||
const username = userCommand.commandSender; | ||
|
||
let wagerAmount = omikujiSettings.settings.currencySettings.defaultWager; | ||
|
||
if (activeOmikuji.get(username)) { | ||
if (omikujiSettings.settings.generalMessages.alreadySpinning) { | ||
const alreadySpinningMsg = omikujiSettings.settings.generalMessages.alreadySpinning | ||
.replace("{username}", username); | ||
|
||
await twitchChat.sendChatMessage(alreadySpinningMsg, null, chatter); | ||
} | ||
|
||
return; | ||
} | ||
|
||
const cooldownExpireTime = cooldownCache.get(username); | ||
if (cooldownExpireTime && moment().isBefore(cooldownExpireTime)) { | ||
if (omikujiSettings.settings.generalMessages.onCooldown) { | ||
const timeRemainingDisplay = util.secondsForHumans(Math.abs(moment().diff(cooldownExpireTime, 'seconds'))); | ||
const cooldownMsg = omikujiSettings.settings.generalMessages.onCooldown | ||
.replace("{username}", username).replace("{timeRemaining}", timeRemainingDisplay); | ||
|
||
await twitchChat.sendChatMessage(cooldownMsg, null, chatter); | ||
} | ||
|
||
return; | ||
} | ||
|
||
|
||
const currencyId = omikujiSettings.settings.currencySettings.currencyId; | ||
let userBalance; | ||
try { | ||
userBalance = await currencyDatabase.getUserCurrencyAmount(username, currencyId); | ||
} catch (error) { | ||
logger.error(error); | ||
userBalance = 0; | ||
} | ||
|
||
if (userBalance < wagerAmount) { | ||
if (omikujiSettings.settings.generalMessages.notEnough) { | ||
const notEnoughMsg = omikujiSettings.settings.generalMessages.notEnough | ||
.replace("{username}", username); | ||
|
||
await twitchChat.sendChatMessage(notEnoughMsg, null, chatter); | ||
} | ||
|
||
return; | ||
} | ||
|
||
activeOmikuji.set(username, true); | ||
|
||
const cooldownSecs = omikujiSettings.settings.cooldownSettings.cooldown; | ||
if (cooldownSecs && cooldownSecs > 0) { | ||
const expireTime = moment().add(cooldownSecs, 'seconds'); | ||
cooldownCache.set(username, expireTime, cooldownSecs); | ||
} | ||
|
||
try { | ||
await currencyDatabase.adjustCurrencyForUser(username, currencyId, -Math.abs(wagerAmount)); | ||
} catch (error) { | ||
logger.error(error); | ||
await twitchChat.sendChatMessage(`Sorry ${username}, there was an error deducting currency from your balance so the spin has been canceled.`, null, chatter); | ||
activeOmikuji.del(username); | ||
return; | ||
} | ||
|
||
const spinInActionMsg = omikujiSettings.settings.generalMessages.spinInAction | ||
.replace("{username}", username); | ||
const omikujiList = omikujiSettings.settings.omikujiSettings.OmikujiSpec; | ||
const showSpinInActionMsg = !!omikujiSettings.settings.generalMessages.spinInAction; | ||
const successfulResult = await omikujiMachine.omikuji(showSpinInActionMsg, spinInActionMsg, omikujiList, chatter); | ||
|
||
if (omikujiSettings.settings.generalMessages.spinSuccessful) { | ||
const spinSuccessfulMsg = omikujiSettings.settings.generalMessages.spinSuccessful | ||
.replace("{username}", username) | ||
.replace("{omikujiResult}", successfulResult); | ||
await twitchChat.sendChatMessage(spinSuccessfulMsg, null, chatter); | ||
} | ||
|
||
activeOmikuji.del(username); | ||
|
||
} | ||
}; | ||
|
||
function registerSpinCommand() { | ||
if (!commandManager.hasSystemCommand(OMIKUJI_COMMAND_ID)) { | ||
commandManager.registerSystemCommand(omikujiCommand); | ||
} | ||
} | ||
|
||
function unregisterSpinCommand() { | ||
commandManager.unregisterSystemCommand(OMIKUJI_COMMAND_ID); | ||
} | ||
|
||
function purgeCaches() { | ||
cooldownCache.flushAll(); | ||
activeOmikuji.flushAll(); | ||
} | ||
|
||
exports.purgeCaches = purgeCaches; | ||
exports.registerSpinCommand = registerSpinCommand; | ||
exports.unregisterSpinCommand = unregisterSpinCommand; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
"use strict"; | ||
const twitchChat = require("../../../chat/twitch-chat"); | ||
const util = require("../../../utility"); | ||
|
||
async function omikuji(showSpinInActionMsg, spinInActionMsg, OmikujiSpec, chatter) { | ||
|
||
let successCount = 0; | ||
|
||
if (showSpinInActionMsg) { | ||
await twitchChat.sendChatMessage(spinInActionMsg, null, chatter); | ||
} | ||
|
||
await util.wait(2000); | ||
|
||
var omikujiSpecArray = OmikujiSpec.split('\n'); | ||
|
||
var seed = Date.now(); | ||
var randomIndex = Math.floor(seed % omikujiSpecArray.length); | ||
var randomElement = omikujiSpecArray[randomIndex]; | ||
return randomElement; | ||
} | ||
|
||
exports.omikuji = omikuji; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
"use strict"; | ||
|
||
const spinCommand = require("./omikuji-command"); | ||
|
||
/** | ||
* @type {import('../../game-manager').FirebotGame} | ||
*/ | ||
module.exports = { | ||
id: "firebot-omikuji", | ||
name: "おみくじ", | ||
subtitle: "おみくじを引きます", | ||
description: "おみくじをひきます。「!omikuji」と入力して、おみくじと賞金を決定します!", | ||
icon: "fa-solid fa-ticket", | ||
settingCategories: { | ||
currencySettings: { | ||
title: "通貨設定", | ||
sortRank: 1, | ||
settings: { | ||
currencyId: { | ||
type: "currency-select", | ||
title: "通貨", | ||
description: "このゲームで使用する通貨", | ||
sortRank: 1, | ||
validation: { | ||
required: true | ||
} | ||
}, | ||
defaultWager: { | ||
type: "number", | ||
title: "おみくじ金額", | ||
description: "おみくじを引くのに必要な金額。", | ||
placeholder: "金額を入れる", | ||
tip: "必須", | ||
sortRank: 2, | ||
validation: { | ||
min: 0 | ||
} | ||
} | ||
} | ||
}, | ||
omikujiSettings: { | ||
title: "回転設定", | ||
sortRank: 2, | ||
settings: { | ||
OmikujiSpec: { | ||
type: "string", | ||
title: "おみくじの種類", | ||
description: "おみくじの役名を1行1役でいれます", | ||
useTextArea: true, | ||
default: "大吉\n小吉\n吉\n末吉\n凶\n大凶", | ||
tip: "2つ以上いれましょう", | ||
sortRank: 1 | ||
} | ||
} | ||
}, | ||
cooldownSettings: { | ||
title: "再実行までの待ち時間", | ||
sortRank: 3, | ||
settings: { | ||
cooldown: { | ||
type: "number", | ||
title: "待ち時間 (秒)", | ||
placeholder: "時間を入れる", | ||
tip: "待ち時間は視聴者ごとに適用されます", | ||
default: 300, | ||
validation: { | ||
min: 0 | ||
} | ||
} | ||
} | ||
}, | ||
generalMessages: { | ||
title: "一般メッセージ", | ||
sortRank: 5, | ||
settings: { | ||
alreadySpinning: { | ||
type: "string", | ||
title: "すでに、おみくじ中", | ||
description: "おみくじの指示が速すぎる場合(メッセージが不要な場合は空白にします)", | ||
useTextArea: true, | ||
default: "{username}、今おみくじ引いているところですよ", | ||
tip: "有効な変数 variables: {username}", | ||
sortRank: 1 | ||
}, | ||
onCooldown: { | ||
type: "string", | ||
title: "再実行までの待ち時間中", | ||
description: "ユーザーが待ち時間を満了していない時(メッセージが不要な場合は空白にします)", | ||
useTextArea: true, | ||
default: "{username}, 再度おみくじを引くまでの残り時間: {timeRemaining}", | ||
tip: "有効な変数: {username}, {timeRemaining}", | ||
sortRank: 2 | ||
}, | ||
notEnough: { | ||
type: "string", | ||
title: "不十分", | ||
description: "選択した金額を賭けるだけの十分な資金がない場合(メッセージなしの場合は空欄のまま)。", | ||
useTextArea: true, | ||
default: "{username}, この金額を賭けるだけの資金がありません", | ||
tip: "有効な変数: {username}", | ||
sortRank: 8 | ||
}, | ||
spinInAction: { | ||
type: "string", | ||
title: "おみくじ中", | ||
description: "おみくじが行われている時(メッセージなしの場合は空欄のまま)", | ||
useTextArea: true, | ||
default: "{username}の運勢は...", | ||
tip: "有効な変数: {username}", | ||
sortRank: 9 | ||
}, | ||
spinSuccessful: { | ||
type: "string", | ||
title: "おみくじ完了", | ||
description: "おみくじが終了した時(メッセージなしの場合は空欄のまま)", | ||
useTextArea: true, | ||
default: "{username}の運勢は {omikujiResult} でした!", | ||
tip: "有効な変数: {username}, {omikujiResult}", | ||
sortRank: 10 | ||
} | ||
} | ||
}, | ||
chatSettings: { | ||
title: "チャット設定", | ||
sortRank: 6, | ||
settings: { | ||
chatter: { | ||
type: "chatter-select", | ||
title: "アカウント" | ||
} | ||
} | ||
} | ||
}, | ||
onLoad: () => { | ||
spinCommand.registerSpinCommand(); | ||
}, | ||
onUnload: () => { | ||
spinCommand.unregisterSpinCommand(); | ||
spinCommand.purgeCaches(); | ||
}, | ||
onSettingsUpdate: () => { | ||
spinCommand.purgeCaches(); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters