bcdice 3.13.0 → 3.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/i18n/Arianrhod/ko_kr.yml +3 -0
  4. data/i18n/Cthulhu/en_us.yml +11 -0
  5. data/i18n/CyberpunkRed/ja_jp.yml +389 -0
  6. data/i18n/FinalFantasyXIV/en_us.yml +4 -0
  7. data/i18n/FinalFantasyXIV/ja_jp.yml +4 -0
  8. data/i18n/FutariSousa/ja_jp.yml +158 -1
  9. data/i18n/KizunaBullet/ja_jp.yml +653 -0
  10. data/i18n/MonotoneMuseum/ja_jp.yml +246 -14
  11. data/i18n/SkynautsBouken/ja_jp.yml +114 -0
  12. data/i18n/TensaiGunshiNiNaro/ja_jp.yml +126 -0
  13. data/i18n/UnsungDuet/ja_jp.yml +62 -0
  14. data/i18n/UnsungDuet/ko_kr.yml +62 -0
  15. data/i18n/en_us.yml +5 -0
  16. data/lib/bcdice/dice_table/range_table.rb +24 -0
  17. data/lib/bcdice/game_system/Agnostos.rb +248 -0
  18. data/lib/bcdice/game_system/AniMalus.rb +99 -59
  19. data/lib/bcdice/game_system/Arianrhod_Korean.rb +30 -0
  20. data/lib/bcdice/game_system/BlackJacket.rb +244 -0
  21. data/lib/bcdice/game_system/ConvictorDrive.rb +5 -4
  22. data/lib/bcdice/game_system/Cthulhu_English.rb +59 -0
  23. data/lib/bcdice/game_system/CyberpunkRed.rb +14 -4
  24. data/lib/bcdice/game_system/DivineCharger.rb +841 -0
  25. data/lib/bcdice/game_system/FinalFantasyXIV.rb +115 -0
  26. data/lib/bcdice/game_system/FinalFantasyXIV_English.rb +39 -0
  27. data/lib/bcdice/game_system/FullFace.rb +39 -10
  28. data/lib/bcdice/game_system/FutariSousa.rb +88 -8
  29. data/lib/bcdice/game_system/Insane_Korean.rb +1 -1
  30. data/lib/bcdice/game_system/InvisibleLiar.rb +79 -0
  31. data/lib/bcdice/game_system/KizunaBullet.rb +240 -0
  32. data/lib/bcdice/game_system/KyokoShinshoku.rb +51 -8
  33. data/lib/bcdice/game_system/MonotoneMuseum.rb +14 -1
  34. data/lib/bcdice/game_system/NRR.rb +2 -2
  35. data/lib/bcdice/game_system/ShuumatsuBargainWars.rb +203 -0
  36. data/lib/bcdice/game_system/SkynautsBouken.rb +45 -130
  37. data/lib/bcdice/game_system/SwordWorld.rb +1 -1
  38. data/lib/bcdice/game_system/TensaiGunshiNiNaro.rb +228 -0
  39. data/lib/bcdice/game_system/TheOneRing2nd.rb +406 -0
  40. data/lib/bcdice/game_system/TheUnofficialHollowKnightRPG.rb +185 -0
  41. data/lib/bcdice/game_system/TrailOfCthulhu.rb +139 -0
  42. data/lib/bcdice/game_system/UnsungDuet.rb +17 -75
  43. data/lib/bcdice/game_system/UnsungDuet_Korean.rb +41 -0
  44. data/lib/bcdice/game_system/Utakaze.rb +55 -2
  45. data/lib/bcdice/game_system/Warhammer4.rb +124 -3
  46. data/lib/bcdice/game_system/Yotabana.rb +62 -0
  47. data/lib/bcdice/game_system/cyberpunk_red/tables.rb +111 -473
  48. data/lib/bcdice/game_system/kizuna_bullet/tables.rb +171 -0
  49. data/lib/bcdice/game_system.rb +16 -0
  50. data/lib/bcdice/version.rb +1 -1
  51. metadata +30 -2
@@ -0,0 +1,126 @@
1
+ ja_jp:
2
+ TensaiGunshiNiNaro:
3
+ JUDGE:
4
+ critical: スペシャル
5
+ fumble: ファンブル
6
+ NORMAL:
7
+ critical: 【戦略ポイント】が1点上昇する。
8
+ fumble: 天才軍師のプレイヤーは、【イレギュラー】を山札から1枚引く。
9
+ BLADE:
10
+ critical: そのラウンドの間、自分の【攻撃力】が1点上昇する。この効果は2回まで重複する。
11
+ YOU:
12
+ critical: 獲得した準英傑に好きな英傑汎用スキルを1つ選んで獲得させることができる。
13
+ DAMAGE:
14
+ success: "%{damage}ダメージ, 成功, 【HP】が%{dec}点減少する"
15
+ failure: "%{damage}ダメージ, 失敗, 【HP】はそのまま"
16
+ table:
17
+ RELA:
18
+ name: 関係決定表
19
+ d66_sort_type: ASC
20
+ items:
21
+ 11: おじやおばのような関係/遠い親戚
22
+ 12: 尊敬できる存在/嫉妬した相手
23
+ 13: その能力に心を打たれた/その能力は危険だと感じた
24
+ 14: いつも助かっている/もっと頑張ってほしい
25
+ 15: いっしょにいると楽しい/鬱陶しい
26
+ 16: 国のために働いている忠臣/油断ならない人物
27
+ 22: 私の宝物/俗物
28
+ 23: 死ぬときは一緒だ/一緒に生き残ろう
29
+ 24: この剣を預ける/共に研鑽しよう
30
+ 25: すべてを捧げたい/恩に報いたい
31
+ 26: 守ると決めた/幸せになってほしい
32
+ 33: 自分にはできない/自分でもできそうだと思う
33
+ 34: からかいがいのある相手/真面目な話ばかりする
34
+ 35: 盟友!/友達
35
+ 36: いい人/怖い人
36
+ 44: 半身/仇敵
37
+ 45: 幼いころからの親友/知り合ったばかりでよくわからない
38
+ 46: 兄弟姉妹(のようなもの)/仕事仲間
39
+ 55: 憧れる/同類と思われると困る
40
+ 56: いいところを知っている/皆に隠している顔を知っているのは自分だけ
41
+ 66: 生き別れのきょうだいに似ている……/同郷
42
+ PTGS:
43
+ name: 平時天才軍師表
44
+ d66_sort_type: ASC
45
+ items:
46
+ 11: サボっている
47
+ 12: 内政の改革を進めている
48
+ 13: 軍の様子を見ている
49
+ 14: 山のような書類を片付けている
50
+ 15: 密偵と影の中で会話をしている
51
+ 16: 戦術書を読んでいる
52
+ 22: 釣りをしている
53
+ 23: 街に出て人々の様子を見ている
54
+ 24: 芸術を嗜んでいる
55
+ 25: 音楽を聴いてリラックスしている
56
+ 26: よい食事を求めて町を彷徨っている
57
+ 33: 王族や貴族のパーティに参加している
58
+ 34: 近隣諸国を観光しつつ内情を探る
59
+ 35: 自国の経済状況を見つめ直している
60
+ 36: 自国の歴史を改めて確かめている
61
+ 44: 頭を休めるため寝ている
62
+ 45: 一人自然の中に身を置いている
63
+ 46: 自分の軍略を書籍にまとめている
64
+ 55: 不敵な笑みを浮かべているが何をしているかは秘密
65
+ 56: 次なる計略を考えてニヤついている
66
+ 66: よからぬことをしていると噂されている
67
+ PTHE:
68
+ name: 平時英傑表
69
+ d66_sort_type: ASC
70
+ items:
71
+ 11: 堂々とサボっている
72
+ 12: 村同士の諍いを収めている
73
+ 13: 軍の指南をしている
74
+ 14: 自らの技を磨いている
75
+ 15: 仲間と国の未来について話している
76
+ 16: 書類仕事をこなしている
77
+ 22: 狩りをしている
78
+ 23: 街に出て人々と触れ合っている
79
+ 24: 街の食事を楽しんでいる
80
+ 25: 街で買い物を楽しんでいる
81
+ 26: 話を聞き困りごとを解決している
82
+ 33: 自分にできることは何か考えている
83
+ 34: 教師のような立場となって人に教えている
84
+ 35: 趣味に走っている
85
+ 36: 誰かと一緒に出かけている
86
+ 44: 自国の観光地を回って楽しむ
87
+ 45: 自分たちが置かれている状況を再確認する
88
+ 46: 周辺国を回りどんな状況下確認する
89
+ 55: 自然の中に身を置いて集中する
90
+ 56: 一人で静かに過ごしている
91
+ 66: 軍師のことを見張っている
92
+ SCOU:
93
+ name: スカウト表
94
+ d66_sort_type: ASC
95
+ items:
96
+ 11: 仮面で顔を隠した怪しげな騎士が仲間に入れてほしいと言ってきた。その素性はわからない。いったい何者なんだ……。
97
+ 12: 酒場や飯屋で出会った人物と国や世界について語り合う機会があり、その問答によって同志になりえると確信した。
98
+ 13: 兵の中に、目立つ者がいたので実力を試してみた。試験の結果は散々だったが、一点だけ優れたところがあり、これは使えるかもしれないと考えた。
99
+ 14: PCや準英傑の師匠や先生が自分にもできることはないかとやってきた。現役を退いて長い人物ではあるが、その経験は役に立つだろう。
100
+ 15: PCの親戚を名乗る者がやってきた。その真偽はともかく(PCが真偽を決めても構いません)、実力はあるようだ。
101
+ 16: 見聞を広めるために旅行に出かけていた者が帰ってきた。外の世界で身につけた技能を使い、この国に尽くしたいという。
102
+ 22: 王族が前線で働きたいと申し出てきた。覚悟は本物のようで、何度言っても申し出を変えなかった。
103
+ 23: 準英傑の一族の者が現れた。その人物は自分も準英傑のように働きたいという。
104
+ 24: 暴れっぷりで街で噂になっていた人物がいたので、会いに行ってみると中々気持ちの良い人物であった。声をかけてみることにする。
105
+ 25: 賊のアジトを殲滅したら、その賊に囚われていた者が感謝をしながら協力を申し出てきた。賊を一人でなんとかしようとしていたらしい。
106
+ 26: 敵軍に雇われていた部隊の中に、PCや準英傑の親族がいた。PCや準英傑の説得によって、仲間になってくれた。
107
+ 33: 釣りをしていると、声をかけてきた人がいた。その人物との問答でただ者ではないと直感し、軍に誘った。
108
+ 34: 古い知り合いが危機のただ中にいるPCを心配して訪ねてきた。逃げ出すことを勧めているが、逆に協力を要請できないだろうか。
109
+ 35: 敵や賊の奇襲に遭ったが、腕の立つ傭兵に偶然にも助けられた。その人物の腕を見込んで、これからも協力してもらえないか交渉する。
110
+ 36: 若い騎士たちの中で、頭角を現した者がいる。会ってみると中々気が利く真面目な人物で、好意が持てた。
111
+ 44: (海や湖に近いなら)漁師や船員と出会い、(山に近いなら)山師や山に住む者たちと出会い、彼の助力を受けた。
112
+ 45: 義憤に燃えてやってきた国民がいた。情熱は確かだが、ただの農民で本当に役に立つのかはまだわからない。
113
+ 46: 国の貴族が自ら志願をしてきてくれた。高貴な精神を持っており、その精神は誉れ高い。ただ、少しお坊ちゃん(お嬢様)育ちすぎる。
114
+ 55: 「あえて不利な方につきたい」と言う物好きな人がやってきて、協力を願い出てくれた。変わった人物だが、助かる申し出だ。
115
+ 56: 敵国の兵だったが、こちらの行動に胸を打たれてやって来た者がいる。こちら側に歩み寄ってくれたこの人物を説得して仲間にできないだろうか。
116
+ 66: PCや準英傑に惚れているという人物がやってきて、協力を約束してくれた。その想いはまだ秘めいているようだが、いつか明かす日が来るのだろうか。
117
+ BDST:
118
+ name: 変調表
119
+ type: 1D6
120
+ items:
121
+ - "加重:決戦フェイズ中、自分は「移動」を行えない。スキルの効果によってエリアを移動することはできる。"
122
+ - "毒:ラウンド終了時に、自分は【HP】が1点減少する。また、自分が参加した判定ではスペシャルが発生しない"
123
+ - "暴走:自分キャラクターがこの変調を受けている場合、天才軍師が【イレギュラー】を公開するとき、「好きな【イレギュラー】を1枚選んで公開する」ではなく「ランダムに1枚選んで公開する」となる。敵軍がこの変調を受けている場合、【防御力】が2点減少する。"
124
+ - "激昂:自分が参加した判定でファンブルが発生した場合、通常のファンブルの処理に加え山札から【イレギュラー】を1枚引いて公開する。敵軍がこの変調を受けている場合、【攻撃力】が1点減少する。"
125
+ - "猛暑:自分は【防御力】が2点減少する。また、自分が使用するスキルはコストが1点上昇する。"
126
+ - "凍え:自分は【攻撃力】が1点減少する。また、自分は「移動」を行うたびに【戦略ポイント】が1点減少する。"
@@ -0,0 +1,62 @@
1
+ ja_jp:
2
+ UnsungDuet:
3
+ MutatingInjuryTable:
4
+ name: "変異表:外傷"
5
+ type: "1D6"
6
+ items:
7
+ - "顔の傷 → 顔にできた傷。じわりと血がにじむ"
8
+ - "大きな怪我 → 早く手当てをしないと命に関わる"
9
+ - "痛みのない傷 → 大きな傷なのに、なぜか痛くない"
10
+ - "喪失 → 身体のどこかが消えてしまった"
11
+ - "文字のような傷跡 → 読めない文字のような傷"
12
+ - "模様を描くアザ → 模様のような、身体にできたアザ"
13
+ MutatingPhysicalConditionTable:
14
+ name: "変異表:体調の変化"
15
+ type: "1D6"
16
+ items:
17
+ - "視界がぼやける → 目の焦点が合わない"
18
+ - "耳鳴り → ずっと甲高い音が鳴り続けている気がする"
19
+ - "異様な寒気 → 凍えそうなほどに寒く感じる"
20
+ - "発汗 → 暑いわけでもないのに、汗がだらだらと"
21
+ - "幻覚 → それが本物か幻か、区別がつかない"
22
+ - "走馬灯 → 過去のことを次々と思い出してしまう"
23
+ MutatingFearTable:
24
+ name: "変異表:恐怖"
25
+ type: "1D6"
26
+ items:
27
+ - "不安 → 漠然とした不安が心を蝕む"
28
+ - "狭い場所が怖い → 狭い場所に入りたくない"
29
+ - "震えが止まらない → どうしても落ち着かない"
30
+ - "物音が怖い → ほんの小さな物音にも怯えてしまう"
31
+ - "暗い場所が怖い → 灯りのない場所がひどく恐ろしい"
32
+ - "誰かがついてくる → 誰かが後ろにいる気がする……"
33
+ MutatingFantasyTable:
34
+ name: "変異表:幻想化"
35
+ type: "1D6"
36
+ items:
37
+ - "硝子化 → 身体の一部がガラスのように透明に"
38
+ - "羽毛化 → 身体のどこかから羽毛が生えてくる"
39
+ - "植物化 → ツタや葉が身体から生えてくる"
40
+ - "動物の瞳 → 瞳の形が動物のそれに変わってしまう"
41
+ - "有角化 → 額や側頭部から角が生えてくる"
42
+ - "陶器化 → 皮膚が陶器のようなものに変わっていく"
43
+ MutatingMindTable:
44
+ name: "変異表:精神"
45
+ type: "1D6"
46
+ items:
47
+ - "記憶の混乱 → ここはどこ、どうしてこんなところに?"
48
+ - "幼少期の記憶 → 口調や態度が幼くなってしまう"
49
+ - "素直 → 思ったことを全部言ってしまう"
50
+ - "蛮勇 → パートナーを守るために無茶ばかりする"
51
+ - "疑心暗鬼 → 何もかもが悪い方向にしか考えられない"
52
+ - "食べちゃいたい → パートナーをかじりたくなる"
53
+ MutatingOtherTable:
54
+ name: "変異表:そのほか"
55
+ type: "1D6"
56
+ items:
57
+ - "影絵化 → 身体の一部が影のようになる"
58
+ - "水槽化 → 身体の一部が水槽のようなものになる"
59
+ - "涙が止まらない → なぜか涙が流れ続ける"
60
+ - "鉤爪 → 手や足が、獣のような鉤爪になる"
61
+ - "未来視 → 未来が見えてしまう。本当かどうかは不明"
62
+ - "帰りたくない → 現実に帰りたくないと微かに思う"
@@ -0,0 +1,62 @@
1
+ ko_kr:
2
+ UnsungDuet:
3
+ MutatingInjuryTable:
4
+ name: "변이표: 상처"
5
+ type: "1D6"
6
+ items:
7
+ - "얼굴의 상처 → 얼굴에 생긴 상처. 천천히 피가 배어 나온다"
8
+ - "큰 부상 → 빨리 조치를 취하지 않으면 생명이 위험"
9
+ - "아프지 않은 상처 → 큰 상처인데 왠지 아프지 않다"
10
+ - "상실 → 몸의 어딘가가 사라져 버린다"
11
+ - "글씨 같은 상처 → 읽을 수 없는 글씨 같은 상처"
12
+ - "문양 같은 멍 → 무늬나 모양 같은 멍"
13
+ MutatingPhysicalConditionTable:
14
+ name: "변이표: 몸 상태의 변화"
15
+ type: "1D6"
16
+ items:
17
+ - "눈 앞이 흐려짐 → 눈의 초점이 맞지 않는다"
18
+ - "이명 → 고음이 계속 울리는 것 같다"
19
+ - "이상한 한기 → 얼어버릴 것처럼 춥게 느껴진다"
20
+ - "발한 → 덥지도 않은데 땀이 잔뜩 난다"
21
+ - "환각 → 이것이 진짜인지 환상인지 구별이 가지 않는다"
22
+ - "주마등 → 과거의 일을 계속해서 떠올리게 된다"
23
+ MutatingFearTable:
24
+ name: "변이표: 공포"
25
+ type: "1D6"
26
+ items:
27
+ - "불안 → 막연한 불안감이 마음을 좀먹는다"
28
+ - "좁은 장소가 두려움 → 좁은 곳에 들어가고 싶지 않다"
29
+ - "몸이 떨림 → 도무지 진정이 되지 않는다"
30
+ - "소리가 두려움 → 정말 작은 소리에도 겁이 난다"
31
+ - "어두운 곳이 두려움 → 빛이 없는 장소가 엄청나게 무섭다"
32
+ - "누가 뒤따라 옴 → 누군가가 뒤에 있는 것만 같다…"
33
+ MutatingFantasyTable:
34
+ name: "변이표: 환상화"
35
+ type: "1D6"
36
+ items:
37
+ - "유리화 → 몸의 일부가 유리처럼 투명해진다"
38
+ - "깃털 → 몸의 어딘가에서 깃털이 자라난다"
39
+ - "식물화 → 몸에서 덩굴이나 잎이 자라난다"
40
+ - "동물의 눈 → 눈 모양이 동물처럼 변한다"
41
+ - "뿔 → 이마나 머리 옆쪽에 뿔이 돋아난다"
42
+ - "도기화 → 피부가 도자기처럼 변한다"
43
+ MutatingMindTable:
44
+ name: "변이표: 정신"
45
+ type: "1D6"
46
+ items:
47
+ - "기억의 혼란 → 여기는 어디? 어쩌다 이런 데 왔지?"
48
+ - "유년기의 기억 → 말투나 태도가 어려진다"
49
+ - "솔직 → 생각한 것을 전부 말해 버린다"
50
+ - "만용 → 파트너를 지키기 위해 무모한 짓만 한다"
51
+ - "의심 → 무엇이든 안 좋은 방향으로만 생각한다"
52
+ - "먹어버리고 싶다 → 파트너를 베어 먹고 싶어진다"
53
+ MutatingOtherTable:
54
+ name: "변이표: 기타"
55
+ type: "1D6"
56
+ items:
57
+ - "그림자 → 몸의 일부가 그림자가 된다"
58
+ - "어항 → 몸의 일부가 어항처럼 된다"
59
+ - "눈물이 멈추지 않음 → 왠지 계속 눈물이 난다"
60
+ - "갈퀴 → 손이나 발에 짐승 같은 갈퀴손톱/발톱이 난다"
61
+ - "미래가 보임 → 앞일이 보이지만 진짜인지는 불명"
62
+ - "돌아가고 싶지 않다 → 현실에 돌아가기 싫다는 생각이 어렴풋이 든다"
data/i18n/en_us.yml ADDED
@@ -0,0 +1,5 @@
1
+ en_us:
2
+ success: Success
3
+ failure: Failure
4
+ critical: Critical
5
+ fumble: Fumble
@@ -67,6 +67,30 @@ module BCDice
67
67
  # @return [Integer] 振るダイスの面数
68
68
  attr_reader :num_of_sides
69
69
 
70
+ class << self
71
+ def from_i18n(key, locale)
72
+ table = I18n.t(key, locale: locale)
73
+ converted_items = table[:items].map do |item|
74
+ [conv_string_range(item[0]), item[1]]
75
+ end
76
+ new(table[:name], table[:type], converted_items)
77
+ end
78
+
79
+ def conv_string_range(x)
80
+ case x
81
+ when Integer
82
+ return x
83
+ when String
84
+ return x.include?("..") ? Range.new(*x.split("..", 2).map { |n| Integer(n) }) : Integer(x)
85
+ end
86
+
87
+ raise(
88
+ TypeError,
89
+ "#{@name}: #{x} (#{x.class}) must be a String or an Integer"
90
+ )
91
+ end
92
+ end
93
+
70
94
  # 表を初期化する
71
95
  #
72
96
  # ブロックを与えると、独自の結果整形処理を指定できる。
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BCDice
4
+ module GameSystem
5
+ class Agnostos < Base
6
+ # ゲームシステムの識別子
7
+ ID = "Agnostos"
8
+
9
+ # ゲームシステム名
10
+ NAME = "アグノストス"
11
+
12
+ # ゲームシステム名の読みがな
13
+ SORT_KEY = "あくのすとす"
14
+
15
+ # ダイスボットの使い方
16
+ HELP_MESSAGE = <<~MESSAGETEXT
17
+ ■ 行為判定
18
+ CDx>=t
19
+ x: コンディションレベル(A~E もしくは 5~1)
20
+ t: 目標値
21
+ の成否とコンディションの変動量を判定します。
22
+
23
+ ■ 心拍のコンディションチェック
24
+ HCDx
25
+ x: コンディションレベル(C+, B+, A, B-, C-, もしくは 5~1)
26
+ 酸素の消費量、コンディションの変動量、気絶したかを判定します。
27
+
28
+ ■ 必殺技
29
+ xSPy
30
+ x: メインコンディション(A~E もしくは 5~1)
31
+ y: サブコンディション(A~E もしくは 5~1)
32
+ 必殺技のダメージ量を判定します。
33
+ MESSAGETEXT
34
+
35
+ register_prefix('CD', 'HCD', '[A-E1-5]SP[A-E1-5]')
36
+
37
+ def eval_game_system_specific_command(command)
38
+ condition_roll(command) || heart_condition_roll(command) || special_roll(command)
39
+ end
40
+
41
+ private
42
+
43
+ # コンディションチェック
44
+ def condition_roll(command)
45
+ parser = Command::Parser.new(/CD[A-E1-5]/, round_type: @round_type).disable_modifier.restrict_cmp_op_to(:>=)
46
+ parsed = parser.parse(command)
47
+ unless parsed
48
+ return nil
49
+ end
50
+
51
+ condition_level = to_condition_level(parsed.command[-1])
52
+ sides = to_sides(condition_level)
53
+ value = @randomizer.roll_once(sides)
54
+
55
+ Result.new.tap do |r|
56
+ r.critical = critical?(sides, value)
57
+ r.fumble = fumble?(sides, value)
58
+ r.condition = value >= parsed.target_number
59
+
60
+ r.text = [
61
+ "(CD#{condition_level}>=#{parsed.target_number})",
62
+ "(1D#{sides}>=#{parsed.target_number})",
63
+ value.to_s(),
64
+ r.success? ? "成功" : "失敗",
65
+ condition_change(sides, value),
66
+ ].join(" > ")
67
+ end
68
+ end
69
+
70
+ def to_condition_level(char)
71
+ case char
72
+ when "5"
73
+ "A"
74
+ when "4"
75
+ "B"
76
+ when "3"
77
+ "C"
78
+ when "2"
79
+ "D"
80
+ when "1"
81
+ "E"
82
+ else
83
+ char
84
+ end
85
+ end
86
+
87
+ def to_sides(condition)
88
+ case condition
89
+ when "A"
90
+ 12
91
+ when "B"
92
+ 10
93
+ when "C"
94
+ 8
95
+ when "D"
96
+ 6
97
+ else # "E"
98
+ 4
99
+ end
100
+ end
101
+
102
+ def condition_change(sides, value)
103
+ if critical?(sides, value)
104
+ "コンディション:2段階上昇(クリティカル)"
105
+ elsif fumble?(sides, value)
106
+ "コンディション:2段階下降(ファンブル)"
107
+ elsif sides != 12 && sides - value <= 1
108
+ "コンディション:1段階上昇"
109
+ elsif sides == 12 && value <= 6
110
+ "コンディション:1段階下降"
111
+ elsif sides == 10 && value <= 3
112
+ "コンディション:1段階下降"
113
+ elsif sides == 8 && value <= 2
114
+ "コンディション:1段階下降"
115
+ else
116
+ "コンディション:変動なし"
117
+ end
118
+ end
119
+
120
+ def critical?(sides, value)
121
+ sides != 12 && sides == value
122
+ end
123
+
124
+ def fumble?(sides, value)
125
+ sides != 4 && value == 1
126
+ end
127
+
128
+ # 心拍のコンディションチェック
129
+ def heart_condition_roll(command)
130
+ m = /^HCD([A1-5]|[BC][+-])$/.match(command)
131
+ unless m
132
+ return nil
133
+ end
134
+
135
+ suffix = m[1]
136
+ condition_level = to_heart_condition_level(suffix)
137
+ sides = to_heart_sides(condition_level)
138
+ value = @randomizer.roll_once(sides)
139
+
140
+ Result.new.tap do |r|
141
+ r.critical = critical?(sides, value)
142
+ r.fumble = fumble?(sides, value)
143
+
144
+ r.text = [
145
+ "(HCD#{condition_level})",
146
+ "(1D#{sides})",
147
+ value.to_s(),
148
+ heart_condition_change(sides, value),
149
+ ].join(" > ")
150
+ end
151
+ end
152
+
153
+ def to_heart_condition_level(char)
154
+ case char
155
+ when "5"
156
+ "C+"
157
+ when "4"
158
+ "B+"
159
+ when "3"
160
+ "A"
161
+ when "2"
162
+ "B-"
163
+ when "1"
164
+ "C-"
165
+ else
166
+ char
167
+ end
168
+ end
169
+
170
+ def to_heart_sides(condition)
171
+ case condition
172
+ when "C+"
173
+ 12
174
+ when "B+"
175
+ 10
176
+ when "A"
177
+ 8
178
+ when "B-"
179
+ 6
180
+ else # "C-"
181
+ 4
182
+ end
183
+ end
184
+
185
+ def fainted?(sides, value)
186
+ case sides
187
+ when 12
188
+ value >= 7
189
+ when 10
190
+ value >= 10
191
+ when 8
192
+ false
193
+ when 6
194
+ value <= 1
195
+ else # 4
196
+ value <= 2
197
+ end
198
+ end
199
+
200
+ def heart_condition_change(sides, value)
201
+ if fainted?(sides, value)
202
+ "気絶"
203
+ else
204
+ condition_change(sides, value)
205
+ end
206
+ end
207
+
208
+ # 必殺技
209
+ def special_roll(command)
210
+ m = /^([A-E1-5])SP([A-E1-5])$/.match(command)
211
+ unless m
212
+ return nil
213
+ end
214
+
215
+ times_conditon_level = to_condition_level(m[1])
216
+ sides_conditon_level = to_condition_level(m[2])
217
+
218
+ times = to_times(times_conditon_level)
219
+ sides = to_sides(sides_conditon_level)
220
+
221
+ dice_list = @randomizer.roll_barabara(times, sides)
222
+ value = dice_list.sum()
223
+
224
+ return [
225
+ "(#{times_conditon_level}SP#{sides_conditon_level})",
226
+ "(#{times}D#{sides})",
227
+ "#{value}[#{dice_list.join(',')}]",
228
+ value.to_s(),
229
+ ].join(" > ")
230
+ end
231
+
232
+ def to_times(condition)
233
+ case condition
234
+ when "A"
235
+ 5
236
+ when "B"
237
+ 4
238
+ when "C"
239
+ 3
240
+ when "D"
241
+ 2
242
+ else # "E"
243
+ 1
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end