lib/bcdice/game_system/BeginningIdol.rb
# frozen_string_literal: true
require 'bcdice/game_system/beginning_idol/table'
module BCDice
module GameSystem
class BeginningIdol < Base
# ゲームシステムの識別子
ID = 'BeginningIdol'
# ゲームシステム名
NAME = 'ビギニングアイドル'
# ゲームシステム名の読みがな
SORT_KEY = 'ひきにんくあいとる'
# ダイスボットの使い方
HELP_MESSAGE = <<~INFO_MESSAGE_TEXT
これは、2015年に新書サイズで発売された『駆け出しアイドルRPG ビギニングアイドル チャレンジガールズ』およびそのサプリメントに対応したコマンドです。
・パフォーマンス [r]PDn[+m/-m](r:場に残った出目 n:振る数 m:修正値)
・ワールドセッティング仕事表 BWT:大手芸能プロ LWT:弱小芸能プロ
TWT:ライブシアター CWT:アイドル部 LO[n]:地方アイドル(n:チャンス)
SU:情熱の夏 WI:ぬくもりの冬 NA:大自然 GA:女学園 BA:アカデミー
・仕事表 WT VA:バラエティ MU:音楽関係 DR:ドラマ関係
VI:ビジュアル関係 SP:スポーツ CHR:クリスマス PAR:パートナー関係
SW:お菓子 AN:動物 MOV:映画 FA:ファンタジー
・ランダムイベント RE
・ハプニング表 HA
・特技リスト AT[n](n:分野No.)
・アイドルスキル修得表 SGT:チャレンジガールズ RS:ロードトゥプリンス
・変調 BT[n](n:発生数)
・アイテム IT[n](n:獲得数)
・アクセサリー ACT:種別決定 ACB:ブランド決定 ACE:効果表
・衣装 DT:チャレンジガールズ RC:ロードトゥプリンス FC:フォーチュンスターズ
・無茶ぶり表 LUR:地方アイドル SUR:情熱の夏 WUR:ぬくもりの冬
NUR:大自然 GUR:女学園 BUR:アカデミー
・センタールール HW:向かい風シーン表 FL:駆け出しシーン表 LN:孤独表
マイスキル【MS:名前決定 MSE:効果表】 演出表【ST FST:ファンタジー】
・合宿ルール 散策表【SH:ショッピングモール MO:山 SEA:海 SPA:温泉街】
TN:夜語りシチュエーション表 成長表【CG:コモン GG:ゴールド】
・サビ表 CHO SCH:情熱の夏 WCH:ぬくもりの冬 NCH:大自然
GCH:女性向け PCH:力強い
・キャラ空白表 CBT:チャレンジガールズ RCB:ロードトゥプリンス
・趣味空白表 HBT:チャレンジガールズ RHB:ロードトゥプリンス
・マスコット暴走表 RU
・アイドル熱湯風呂 nC:バーストタイム(n:温度) BU:バースト表
・攻撃 n[S]A[r][+m/-m](n:振る数 S:失敗しない r:取り除く出目 m:修正値)
・かんたんパーソン表 SIP
・会場表
BVT:大手芸能プロ LVT:弱小芸能プロ TVT:ライブシアター CVT:アイドル部
・場所表
BST:大手芸能プロ LST:弱小芸能プロ TST:ライブシアター CST:アイドル部
・プレッシャー種別決定表
BPT:大手芸能プロ LPT:弱小芸能プロ TPT:ライブシアター CPT:アイドル部
・道具表
BIT:大手芸能プロ LIT:弱小芸能プロ TIT:ライブシアター CIT:アイドル部
[]内は省略可 D66入れ替えあり
INFO_MESSAGE_TEXT
register_prefix(
SKILL_TABLE.prefixes,
'IT',
'BT',
'\d{2}C',
'\d+S?A',
'[1-7]*PD'
)
def initialize(command)
super(command)
@sort_add_dice = true
@d66_sort_type = D66SortType::ASC
end
def result_nd6(total, dice_total, _value_list, cmp_op, target)
return nil if target == '?'
return nil unless cmp_op == :>=
if dice_total <= 2
Result.fumble(translate("BeginningIdol.fumble"))
elsif dice_total >= 12
Result.critical(translate("BeginningIdol.special"))
elsif total >= target
Result.success(translate("success"))
else
Result.failure(translate("failure"))
end
end
alias check_2D6 check_nD6
def eval_game_system_specific_command(command)
roll_attack(command) ||
roll_burst(command) ||
roll_performance(command) ||
self.class::SKILL_TABLE.roll_command(@randomizer, command) ||
self.class::ITEM_TABLE.roll_command(@randomizer, command) ||
self.class::BAD_STATUS_TABLE.roll_command(@randomizer, command) ||
self.class::LOCAL_WORK_TABLE.roll_command(@randomizer, command) ||
roll_tables(command, self.class::TABLES)
end
private
def roll_burst(command)
m = /^(\d{2})C$/.match(command)
unless m
return nil
end
degrees = m[1].to_i
if (degrees < 45) || (degrees > 55)
return nil
end
counts =
if degrees <= 49
3
elsif degrees <= 52
4
elsif degrees <= 54
5
else
6
end
dice_list = @randomizer.roll_barabara(counts, 6).sort
total = dice_list.sum() + degrees
result =
if total >= 80
translate("BeginningIdol.burst.burst")
elsif total >= 75
translate("BeginningIdol.burst.critical_success")
elsif total >= 65
translate("BeginningIdol.burst.success")
else
translate("failure")
end
name = translate("BeginningIdol.burst.name")
return "#{name} > #{degrees}+[#{dice_list.join(',')}] > #{total} > #{result}"
end
def roll_attack(command)
m = /^(\d+)(S?)A([1-6]*)([+-]\d+)?$/.match(command)
unless m
return nil
end
counts = m[1].to_i
return nil if counts <= 0
sure = !m[2].empty?
remove = m[3].each_char.map(&:to_i)
adjust = m[4].to_i
adjust_str = Format.modifier(adjust)
dice = @randomizer.roll_barabara(counts, 6).sort
dice_str = dice.join(",")
dice -= remove
text = "#{translate('BeginningIdol.attack.name')} > [#{dice_str}]#{adjust_str} > "
unless (dice.count == counts) || dice.empty?
text += "[#{dice.join(',')}]#{adjust_str} > "
end
if sure || (dice.count == dice.uniq.count)
total = [dice.sum() + adjust.to_i, 0].max
text += format(translate('BeginningIdol.attack.damage'), total: total)
else
text += translate('failure')
end
return text
end
def roll_performance(command)
m = /^([1-7]*)PD(\d+)([+-]\d+)?$/.match(command)
unless m
return nil
end
counts = m[2].to_i
return nil if counts <= 0
carry = m[1].chars.map(&:to_i).sort
modifier = m[3].to_i
dice_list = @randomizer.roll_barabara(counts, 6).sort
all_dice = (dice_list + carry).sort
filtered = select_uniqs(all_dice)
title = carry.empty? ? translate("BeginningIdol.PD.paformance") : translate("BeginningIdol.PD.symphony")
result =
if carry.empty?
result_performance(filtered, modifier, all_dice)
else
result_symphony(filtered, modifier)
end
sequence = [
title,
format_dice_list(dice_list, carry, modifier),
result,
]
return sequence.join(" > ")
end
def select_uniqs(dice_list)
dice_list.group_by(&:itself).to_a
.select { |_, arr| arr.size == 1 }
.map { |dice, _| dice }
.sort
end
def format_dice_list(dice_list, carry, modifier)
if carry.empty?
"[#{dice_list.join(',')}]#{Format.modifier(modifier)}"
else
"[#{dice_list.join(',')}],[#{carry.join(',')}]#{Format.modifier(modifier)}"
end
end
def result_performance(list, modifier, all_list)
if list.empty?
format(translate("BeginningIdol.PD.miracle"), value: modifier + 10)
elsif list == [1, 2, 3, 4, 5, 6]
format(translate("BeginningIdol.PD.perfect_miracle"), value: modifier + 30)
elsif list.size != all_list.size
"[#{list.join(',')}]#{Format.modifier(modifier)} > #{list.sum() + modifier}"
else
(list.sum() + modifier).to_s
end
end
def result_symphony(list, modifier)
if list.empty?
format(translate("BeginningIdol.PD.miracle_synchro"), value: modifier + 15)
elsif list == [1, 2, 3, 4, 5, 6]
perfect_miracle = format(translate("BeginningIdol.PD.perfect_miracle"), value: modifier + 30)
"[#{list.join(',')}]#{Format.modifier(modifier)} > #{perfect_miracle}"
else
"[#{list.join(',')}]#{Format.modifier(modifier)} > #{list.sum() + modifier}"
end
end
end
end
end