bcdice 3.0.0.pre.alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.editorconfig +21 -0
- data/.github/.codecov.yaml +10 -0
- data/.github/workflows/coverage.yaml +21 -0
- data/.github/workflows/lint.yaml +13 -0
- data/.github/workflows/test.yml +20 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +96 -0
- data/.rubocop_todo.yml +113 -0
- data/CHANGELOG.md +868 -0
- data/Gemfile +11 -0
- data/LICENSE +29 -0
- data/README.md +38 -0
- data/ROADMAP.md +30 -0
- data/Rakefile +118 -0
- data/bcdice.gemspec +27 -0
- data/bin/repl.rb +21 -0
- data/docs/README.txt +2028 -0
- data/docs/dicebot_sort_key.md +72 -0
- data/docs/how_to_make_dicebot.md +453 -0
- data/lib/bcdice.rb +8 -0
- data/lib/bcdice/arithmetic_evaluator.rb +167 -0
- data/lib/bcdice/base.rb +423 -0
- data/lib/bcdice/command_parser.rb +242 -0
- data/lib/bcdice/common_command.rb +23 -0
- data/lib/bcdice/common_command/add_dice.rb +54 -0
- data/lib/bcdice/common_command/add_dice/node.rb +488 -0
- data/lib/bcdice/common_command/add_dice/parser.rb +282 -0
- data/lib/bcdice/common_command/add_dice/randomizer.rb +48 -0
- data/lib/bcdice/common_command/barabara_dice.rb +57 -0
- data/lib/bcdice/common_command/calc.rb +39 -0
- data/lib/bcdice/common_command/choice.rb +35 -0
- data/lib/bcdice/common_command/d66_dice.rb +63 -0
- data/lib/bcdice/common_command/reroll_dice.rb +190 -0
- data/lib/bcdice/common_command/upper_dice.rb +165 -0
- data/lib/bcdice/common_command/version.rb +26 -0
- data/lib/bcdice/dice_table.rb +8 -0
- data/lib/bcdice/dice_table/chain_table.rb +33 -0
- data/lib/bcdice/dice_table/d66_grid_table.rb +26 -0
- data/lib/bcdice/dice_table/d66_range_table.rb +26 -0
- data/lib/bcdice/dice_table/d66_table.rb +34 -0
- data/lib/bcdice/dice_table/range_table.rb +267 -0
- data/lib/bcdice/dice_table/roll_result.rb +43 -0
- data/lib/bcdice/dice_table/sai_fic_skill_table.rb +32 -0
- data/lib/bcdice/dice_table/table.rb +35 -0
- data/lib/bcdice/enum.rb +15 -0
- data/lib/bcdice/format.rb +36 -0
- data/lib/bcdice/game_system.rb +187 -0
- data/lib/bcdice/game_system/AFF2e.rb +141 -0
- data/lib/bcdice/game_system/AceKillerGene.rb +55 -0
- data/lib/bcdice/game_system/Airgetlamh.rb +117 -0
- data/lib/bcdice/game_system/Alsetto.rb +124 -0
- data/lib/bcdice/game_system/Alshard.rb +27 -0
- data/lib/bcdice/game_system/AlterRaise.rb +282 -0
- data/lib/bcdice/game_system/Amadeus.rb +622 -0
- data/lib/bcdice/game_system/Amadeus_Korean.rb +501 -0
- data/lib/bcdice/game_system/AnimaAnimus.rb +96 -0
- data/lib/bcdice/game_system/Arianrhod.rb +50 -0
- data/lib/bcdice/game_system/ArsMagica.rb +149 -0
- data/lib/bcdice/game_system/Avandner.rb +101 -0
- data/lib/bcdice/game_system/BBN.rb +143 -0
- data/lib/bcdice/game_system/BadLife.rb +435 -0
- data/lib/bcdice/game_system/BarnaKronika.rb +188 -0
- data/lib/bcdice/game_system/BattleTech.rb +530 -0
- data/lib/bcdice/game_system/BeastBindTrinity.rb +348 -0
- data/lib/bcdice/game_system/BeginningIdol.rb +2527 -0
- data/lib/bcdice/game_system/BeginningIdol_Korean.rb +2378 -0
- data/lib/bcdice/game_system/BladeOfArcana.rb +252 -0
- data/lib/bcdice/game_system/BlindMythos.rb +460 -0
- data/lib/bcdice/game_system/BloodCrusade.rb +423 -0
- data/lib/bcdice/game_system/BloodMoon.rb +213 -0
- data/lib/bcdice/game_system/CardRanker.rb +249 -0
- data/lib/bcdice/game_system/ChaosFlare.rb +181 -0
- data/lib/bcdice/game_system/Chill.rb +163 -0
- data/lib/bcdice/game_system/Chill3.rb +52 -0
- data/lib/bcdice/game_system/CodeLayerd.rb +132 -0
- data/lib/bcdice/game_system/ColossalHunter.rb +569 -0
- data/lib/bcdice/game_system/CrashWorld.rb +81 -0
- data/lib/bcdice/game_system/Cthulhu.rb +252 -0
- data/lib/bcdice/game_system/Cthulhu7th.rb +767 -0
- data/lib/bcdice/game_system/Cthulhu7th_ChineseTraditional.rb +386 -0
- data/lib/bcdice/game_system/Cthulhu7th_Korean.rb +383 -0
- data/lib/bcdice/game_system/CthulhuTech.rb +263 -0
- data/lib/bcdice/game_system/Cthulhu_ChineseTraditional.rb +243 -0
- data/lib/bcdice/game_system/Cthulhu_Korean.rb +240 -0
- data/lib/bcdice/game_system/DarkBlaze.rb +207 -0
- data/lib/bcdice/game_system/DarkDaysDrive.rb +425 -0
- data/lib/bcdice/game_system/DarkSouls.rb +91 -0
- data/lib/bcdice/game_system/DeadlineHeroes.rb +583 -0
- data/lib/bcdice/game_system/DemonParasite.rb +524 -0
- data/lib/bcdice/game_system/DetatokoSaga.rb +310 -0
- data/lib/bcdice/game_system/DetatokoSaga_Korean.rb +310 -0
- data/lib/bcdice/game_system/DiceBot.rb +17 -0
- data/lib/bcdice/game_system/DiceOfTheDead.rb +111 -0
- data/lib/bcdice/game_system/DoubleCross.rb +373 -0
- data/lib/bcdice/game_system/DoubleCross_Korean.rb +371 -0
- data/lib/bcdice/game_system/Dracurouge.rb +1856 -0
- data/lib/bcdice/game_system/Dracurouge_Korean.rb +310 -0
- data/lib/bcdice/game_system/DungeonsAndDragons.rb +19 -0
- data/lib/bcdice/game_system/EarthDawn.rb +225 -0
- data/lib/bcdice/game_system/EarthDawn3.rb +275 -0
- data/lib/bcdice/game_system/EarthDawn4.rb +272 -0
- data/lib/bcdice/game_system/EclipsePhase.rb +51 -0
- data/lib/bcdice/game_system/Elric.rb +36 -0
- data/lib/bcdice/game_system/Elysion.rb +1213 -0
- data/lib/bcdice/game_system/EmbryoMachine.rb +227 -0
- data/lib/bcdice/game_system/EndBreaker.rb +132 -0
- data/lib/bcdice/game_system/EtrianOdysseySRS.rb +27 -0
- data/lib/bcdice/game_system/Fiasco.rb +123 -0
- data/lib/bcdice/game_system/Fiasco_Korean.rb +122 -0
- data/lib/bcdice/game_system/FilledWith.rb +1543 -0
- data/lib/bcdice/game_system/FullMetalPanic.rb +27 -0
- data/lib/bcdice/game_system/FutariSousa.rb +994 -0
- data/lib/bcdice/game_system/FutariSousa_Korean.rb +994 -0
- data/lib/bcdice/game_system/Garako.rb +559 -0
- data/lib/bcdice/game_system/GardenOrder.rb +451 -0
- data/lib/bcdice/game_system/GehennaAn.rb +136 -0
- data/lib/bcdice/game_system/GeishaGirlwithKatana.rb +120 -0
- data/lib/bcdice/game_system/GoblinSlayer.rb +168 -0
- data/lib/bcdice/game_system/GoldenSkyStories.rb +77 -0
- data/lib/bcdice/game_system/Gorilla.rb +44 -0
- data/lib/bcdice/game_system/GranCrest.rb +518 -0
- data/lib/bcdice/game_system/Gundog.rb +52 -0
- data/lib/bcdice/game_system/GundogRevised.rb +294 -0
- data/lib/bcdice/game_system/GundogZero.rb +261 -0
- data/lib/bcdice/game_system/Gurps.rb +403 -0
- data/lib/bcdice/game_system/GurpsFW.rb +2330 -0
- data/lib/bcdice/game_system/HarnMaster.rb +208 -0
- data/lib/bcdice/game_system/HatsuneMiku.rb +706 -0
- data/lib/bcdice/game_system/Hieizan.rb +48 -0
- data/lib/bcdice/game_system/HouraiGakuen.rb +270 -0
- data/lib/bcdice/game_system/HuntersMoon.rb +503 -0
- data/lib/bcdice/game_system/Illusio.rb +89 -0
- data/lib/bcdice/game_system/InfiniteFantasia.rb +51 -0
- data/lib/bcdice/game_system/Insane.rb +822 -0
- data/lib/bcdice/game_system/Insane_Korean.rb +773 -0
- data/lib/bcdice/game_system/IthaWenUa.rb +38 -0
- data/lib/bcdice/game_system/JamesBond.rb +45 -0
- data/lib/bcdice/game_system/Kamigakari.rb +394 -0
- data/lib/bcdice/game_system/Kamigakari_Korean.rb +428 -0
- data/lib/bcdice/game_system/KanColle.rb +938 -0
- data/lib/bcdice/game_system/KemonoNoMori.rb +258 -0
- data/lib/bcdice/game_system/KillDeathBusiness.rb +1420 -0
- data/lib/bcdice/game_system/KillDeathBusiness_Korean.rb +1510 -0
- data/lib/bcdice/game_system/KurayamiCrying.rb +49 -0
- data/lib/bcdice/game_system/LiveraDoll.rb +375 -0
- data/lib/bcdice/game_system/LogHorizon.rb +3567 -0
- data/lib/bcdice/game_system/LogHorizon_Korean.rb +1407 -0
- data/lib/bcdice/game_system/LostRecord.rb +30 -0
- data/lib/bcdice/game_system/LostRoyal.rb +242 -0
- data/lib/bcdice/game_system/MagicaLogia.rb +1148 -0
- data/lib/bcdice/game_system/MeikyuDays.rb +415 -0
- data/lib/bcdice/game_system/MeikyuKingdom.rb +466 -0
- data/lib/bcdice/game_system/MeikyuKingdomBasic.rb +269 -0
- data/lib/bcdice/game_system/MetalHead.rb +249 -0
- data/lib/bcdice/game_system/MetalHeadExtream.rb +917 -0
- data/lib/bcdice/game_system/MetallicGuardian.rb +31 -0
- data/lib/bcdice/game_system/MonotoneMuseum.rb +354 -0
- data/lib/bcdice/game_system/MonotoneMuseum_Korean.rb +304 -0
- data/lib/bcdice/game_system/Nechronica.rb +211 -0
- data/lib/bcdice/game_system/Nechronica_Korean.rb +160 -0
- data/lib/bcdice/game_system/NeverCloud.rb +74 -0
- data/lib/bcdice/game_system/NightWizard.rb +231 -0
- data/lib/bcdice/game_system/NightWizard3rd.rb +24 -0
- data/lib/bcdice/game_system/NightmareHunterDeep.rb +117 -0
- data/lib/bcdice/game_system/NinjaSlayer.rb +274 -0
- data/lib/bcdice/game_system/NjslyrBattle.rb +54 -0
- data/lib/bcdice/game_system/Nuekagami.rb +293 -0
- data/lib/bcdice/game_system/OneWayHeroics.rb +134 -0
- data/lib/bcdice/game_system/OracleEngine.rb +265 -0
- data/lib/bcdice/game_system/OrgaRain.rb +77 -0
- data/lib/bcdice/game_system/Oukahoushin3rd.rb +162 -0
- data/lib/bcdice/game_system/Paradiso.rb +323 -0
- data/lib/bcdice/game_system/Paranoia.rb +64 -0
- data/lib/bcdice/game_system/ParanoiaRebooted.rb +109 -0
- data/lib/bcdice/game_system/ParasiteBlood.rb +231 -0
- data/lib/bcdice/game_system/Pathfinder.rb +21 -0
- data/lib/bcdice/game_system/Peekaboo.rb +324 -0
- data/lib/bcdice/game_system/Pendragon.rb +39 -0
- data/lib/bcdice/game_system/PhantasmAdventure.rb +73 -0
- data/lib/bcdice/game_system/Postman.rb +185 -0
- data/lib/bcdice/game_system/PulpCthulhu.rb +184 -0
- data/lib/bcdice/game_system/Raisondetre.rb +171 -0
- data/lib/bcdice/game_system/RecordOfLodossWar.rb +58 -0
- data/lib/bcdice/game_system/RecordOfSteam.rb +149 -0
- data/lib/bcdice/game_system/RokumonSekai2.rb +110 -0
- data/lib/bcdice/game_system/RoleMaster.rb +24 -0
- data/lib/bcdice/game_system/RuneQuest.rb +47 -0
- data/lib/bcdice/game_system/RyuTuber.rb +266 -0
- data/lib/bcdice/game_system/Ryutama.rb +199 -0
- data/lib/bcdice/game_system/SRS.rb +348 -0
- data/lib/bcdice/game_system/SamsaraBallad.rb +111 -0
- data/lib/bcdice/game_system/Satasupe.rb +1173 -0
- data/lib/bcdice/game_system/ScreamHighSchool.rb +128 -0
- data/lib/bcdice/game_system/SevenFortressMobius.rb +34 -0
- data/lib/bcdice/game_system/ShadowRun.rb +26 -0
- data/lib/bcdice/game_system/ShadowRun4.rb +49 -0
- data/lib/bcdice/game_system/ShadowRun5.rb +80 -0
- data/lib/bcdice/game_system/SharedFantasia.rb +69 -0
- data/lib/bcdice/game_system/ShinMegamiTenseiKakuseihen.rb +85 -0
- data/lib/bcdice/game_system/ShinkuuGakuen.rb +506 -0
- data/lib/bcdice/game_system/ShinobiGami.rb +680 -0
- data/lib/bcdice/game_system/ShoujoTenrankai.rb +677 -0
- data/lib/bcdice/game_system/Skynauts.rb +324 -0
- data/lib/bcdice/game_system/SteamPunkers.rb +485 -0
- data/lib/bcdice/game_system/StellarKnights.rb +856 -0
- data/lib/bcdice/game_system/SterileLife.rb +452 -0
- data/lib/bcdice/game_system/StrangerOfSwordCity.rb +103 -0
- data/lib/bcdice/game_system/StratoShout.rb +316 -0
- data/lib/bcdice/game_system/StratoShout_Korean.rb +314 -0
- data/lib/bcdice/game_system/Strave.rb +223 -0
- data/lib/bcdice/game_system/SwordWorld.rb +491 -0
- data/lib/bcdice/game_system/SwordWorld2_0.rb +295 -0
- data/lib/bcdice/game_system/SwordWorld2_5.rb +121 -0
- data/lib/bcdice/game_system/TherapieSein.rb +93 -0
- data/lib/bcdice/game_system/TokumeiTenkousei.rb +96 -0
- data/lib/bcdice/game_system/TokyoGhostResearch.rb +122 -0
- data/lib/bcdice/game_system/TokyoNova.rb +19 -0
- data/lib/bcdice/game_system/Torg.rb +364 -0
- data/lib/bcdice/game_system/Torg1_5.rb +139 -0
- data/lib/bcdice/game_system/TorgEternity.rb +414 -0
- data/lib/bcdice/game_system/TrinitySeven.rb +364 -0
- data/lib/bcdice/game_system/TunnelsAndTrolls.rb +287 -0
- data/lib/bcdice/game_system/TwilightGunsmoke.rb +527 -0
- data/lib/bcdice/game_system/Utakaze.rb +153 -0
- data/lib/bcdice/game_system/VampireTheMasquerade5th.rb +132 -0
- data/lib/bcdice/game_system/Villaciel.rb +555 -0
- data/lib/bcdice/game_system/WARPS.rb +33 -0
- data/lib/bcdice/game_system/WaresBlade.rb +34 -0
- data/lib/bcdice/game_system/Warhammer.rb +336 -0
- data/lib/bcdice/game_system/WitchQuest.rb +275 -0
- data/lib/bcdice/game_system/WorldOfDarkness.rb +135 -0
- data/lib/bcdice/game_system/YankeeYogSothoth.rb +440 -0
- data/lib/bcdice/game_system/YearZeroEngine.rb +134 -0
- data/lib/bcdice/game_system/ZettaiReido.rb +142 -0
- data/lib/bcdice/game_system/meikyu_kingdom/item_table.rb +383 -0
- data/lib/bcdice/game_system/meikyu_kingdom/kingdom_name_table.rb +89 -0
- data/lib/bcdice/game_system/meikyu_kingdom/landscape_table.rb +196 -0
- data/lib/bcdice/game_system/meikyu_kingdom/name_tables.rb +223 -0
- data/lib/bcdice/game_system/meikyu_kingdom/placename_table.rb +214 -0
- data/lib/bcdice/game_system/meikyu_kingdom/tables.rb +610 -0
- data/lib/bcdice/game_system/meikyu_kingdom/word_table.rb +117 -0
- data/lib/bcdice/game_system/meikyu_kingdom_basic/item_table.rb +380 -0
- data/lib/bcdice/game_system/meikyu_kingdom_basic/kingdom_table.rb +184 -0
- data/lib/bcdice/game_system/meikyu_kingdom_basic/name_table.rb +417 -0
- data/lib/bcdice/game_system/meikyu_kingdom_basic/table.rb +912 -0
- data/lib/bcdice/game_system/meikyu_kingdom_basic/word_table.rb +121 -0
- data/lib/bcdice/game_system/one_way_heroics/dungeon_table.rb +67 -0
- data/lib/bcdice/game_system/one_way_heroics/random_event_table.rb +166 -0
- data/lib/bcdice/game_system/one_way_heroics/tables.rb +668 -0
- data/lib/bcdice/loader.rb +37 -0
- data/lib/bcdice/normalize.rb +38 -0
- data/lib/bcdice/preprocessor.rb +87 -0
- data/lib/bcdice/randomizer.rb +137 -0
- data/lib/bcdice/repl.rb +155 -0
- data/lib/bcdice/user_defined_dice_table.rb +153 -0
- data/lib/bcdice/version.rb +3 -0
- metadata +304 -0
@@ -0,0 +1,348 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bcdice/arithmetic_evaluator'
|
4
|
+
|
5
|
+
# スタンダードRPGシステムのダイスボット
|
6
|
+
#
|
7
|
+
# スタンダードRPGシステムにおいて共通な2D6成功判定を実装している。
|
8
|
+
# また、各ゲームシステムに合わせた2D6成功判定のエイリアスコマンドを
|
9
|
+
# 登録するクラスメソッド set_aliases_for_srs_roll を持つ。
|
10
|
+
module BCDice
|
11
|
+
module GameSystem
|
12
|
+
class SRS < Base
|
13
|
+
# ゲームシステムの識別子
|
14
|
+
ID = 'SRS'
|
15
|
+
|
16
|
+
# ゲームシステム名
|
17
|
+
NAME = 'スタンダードRPGシステム'
|
18
|
+
|
19
|
+
# ゲームシステム名の読みがな
|
20
|
+
SORT_KEY = 'すたんたあとRPGしすてむ'
|
21
|
+
|
22
|
+
HELP_MESSAGE_1 = <<~HELP_MESSAGE
|
23
|
+
・判定
|
24
|
+
・通常判定:2D6+m>=t[c,f]
|
25
|
+
修正値m、目標値t、クリティカル値c、ファンブル値fで判定ロールを行います。
|
26
|
+
修正値、クリティカル値、ファンブル値は省略可能です([]ごと省略可)。
|
27
|
+
クリティカル値、ファンブル値の既定値は、それぞれ12、2です。
|
28
|
+
自動成功、自動失敗、成功、失敗を自動表示します。
|
29
|
+
|
30
|
+
例) 2d6>=10 修正値0、目標値10で判定
|
31
|
+
例) 2d6+2>=10 修正値+2、目標値10で判定
|
32
|
+
例) 2d6+2>=10[11] ↑をクリティカル値11で判定
|
33
|
+
例) 2d6+2>=10[12,4] ↑をクリティカル値12、ファンブル値4で判定
|
34
|
+
HELP_MESSAGE
|
35
|
+
|
36
|
+
HELP_MESSAGE_2 = <<~HELP_MESSAGE
|
37
|
+
・クリティカルおよびファンブルのみの判定:2D6+m[c,f]
|
38
|
+
目標値を指定せず、修正値m、クリティカル値c、ファンブル値fで判定ロールを行います。
|
39
|
+
修正値、クリティカル値、ファンブル値は省略可能です([]は省略不可)。
|
40
|
+
自動成功、自動失敗を自動表示します。
|
41
|
+
|
42
|
+
例) 2d6[] 修正値0、クリティカル値12、ファンブル値2で判定
|
43
|
+
例) 2d6+2[11] 修正値+2、クリティカル値11、ファンブル値2で判定
|
44
|
+
例) 2d6+2[12,4] 修正値+2、クリティカル値12、ファンブル値4で判定
|
45
|
+
HELP_MESSAGE
|
46
|
+
|
47
|
+
HELP_MESSAGE_3 = <<~HELP_MESSAGE
|
48
|
+
・D66ダイスあり(入れ替えなし)
|
49
|
+
HELP_MESSAGE
|
50
|
+
|
51
|
+
# 既定のダイスボット説明文
|
52
|
+
DEFAULT_HELP_MESSAGE = "#{HELP_MESSAGE_1}\n#{HELP_MESSAGE_2}\n#{HELP_MESSAGE_3}"
|
53
|
+
|
54
|
+
HELP_MESSAGE = DEFAULT_HELP_MESSAGE
|
55
|
+
|
56
|
+
# 成功判定のエイリアスコマンド定義用のクラスメソッドを提供するモジュール
|
57
|
+
module ClassMethods
|
58
|
+
# ダイスボットの説明文を返す
|
59
|
+
# @return [String]
|
60
|
+
attr_reader :help_message
|
61
|
+
|
62
|
+
# 目標値あり成功判定のエイリアスコマンドの正規表現を返す
|
63
|
+
# @return [Regexp, nil]
|
64
|
+
attr_reader :aliases_re_for_srs_roll_with_target_value
|
65
|
+
|
66
|
+
# 目標値なし成功判定のエイリアスコマンドの正規表現を返す
|
67
|
+
# @return [Regexp, nil]
|
68
|
+
attr_reader :aliases_re_for_srs_roll_without_target_value
|
69
|
+
|
70
|
+
# 成功判定のエイリアスコマンドを設定する
|
71
|
+
# @param [String] aliases エイリアスコマンド(可変長引数)
|
72
|
+
# @return [self]
|
73
|
+
#
|
74
|
+
# エイリアスコマンドとして指定した文字列がコマンドの先頭にあれば、
|
75
|
+
# 実行時にそれが2D6に置換されるようになる。
|
76
|
+
def set_aliases_for_srs_roll(*aliases)
|
77
|
+
aliases_upcase = aliases.map(&:upcase)
|
78
|
+
aliases_part = aliases_upcase
|
79
|
+
.map { |a| Regexp.escape(a) }
|
80
|
+
.join('|')
|
81
|
+
|
82
|
+
@aliases_re_for_srs_roll_with_target_value = Regexp.new(
|
83
|
+
'\A' \
|
84
|
+
"(?:#{aliases_part})" \
|
85
|
+
'((?:[-+][-+\d]+)?>=\d+(?:\[\d*(?:,\d+)?\])?)\z'
|
86
|
+
)
|
87
|
+
|
88
|
+
@aliases_re_for_srs_roll_without_target_value = Regexp.new(
|
89
|
+
'\A' \
|
90
|
+
"(?:#{aliases_part})" \
|
91
|
+
'([-+][-+\d]+)?(\[\d*(?:,\d+)?\])?\z'
|
92
|
+
)
|
93
|
+
|
94
|
+
prepare_help_msg_for_aliases_for_srs_roll(aliases_upcase)
|
95
|
+
@help_message = concatenate_help_messages
|
96
|
+
|
97
|
+
return self
|
98
|
+
end
|
99
|
+
|
100
|
+
# 成功判定のエイリアスコマンドを未設定にする
|
101
|
+
# @return [self]
|
102
|
+
def clear_aliases_for_srs_roll
|
103
|
+
@aliases_re_for_srs_roll_with_target_value = nil
|
104
|
+
@aliases_re_for_srs_roll_without_target_value = nil
|
105
|
+
@help_message = SRS::DEFAULT_HELP_MESSAGE
|
106
|
+
|
107
|
+
return self
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# 成功判定のエイリアスコマンドの説明文を用意する
|
113
|
+
# @param [Array<String>] aliases エイリアスコマンドの配列
|
114
|
+
# @return [self]
|
115
|
+
# @todo 現在は2文字のエイリアスコマンドに幅を合わせてある。
|
116
|
+
# エイリアスコマンドの文字数が変わる場合があれば、位置を調整するコードが
|
117
|
+
# 必要。
|
118
|
+
def prepare_help_msg_for_aliases_for_srs_roll(aliases)
|
119
|
+
@help_msg_for_aliases_for_srs_roll_with_target_value =
|
120
|
+
aliases
|
121
|
+
.map { |a| " 例) #{a}+2>=10 2d6+2>=10と同じ(#{a}が2D6のショートカットコマンド)\n" }
|
122
|
+
.join()
|
123
|
+
|
124
|
+
@help_msg_for_aliases_for_srs_roll_without_target_value =
|
125
|
+
aliases
|
126
|
+
.map do |a|
|
127
|
+
" 例) #{a} 2d6[]と同じ(#{a}が2D6のショートカットコマンド)\n" \
|
128
|
+
" 例) #{a}+2[12,4] 2d6+2[12,4]と同じ(#{a}が2D6のショートカットコマンド)\n"
|
129
|
+
end
|
130
|
+
.join()
|
131
|
+
|
132
|
+
return self
|
133
|
+
end
|
134
|
+
|
135
|
+
# ダイスボットの説明文を結合する
|
136
|
+
# @return [String] 結合された説明文
|
137
|
+
def concatenate_help_messages
|
138
|
+
"#{SRS::HELP_MESSAGE_1}" \
|
139
|
+
"#{@help_msg_for_aliases_for_srs_roll_with_target_value}\n" \
|
140
|
+
"#{SRS::HELP_MESSAGE_2}" \
|
141
|
+
"#{@help_msg_for_aliases_for_srs_roll_without_target_value}\n" \
|
142
|
+
"#{SRS::HELP_MESSAGE_3}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class << self
|
147
|
+
# クラスが継承されたときに行う処理
|
148
|
+
# @return [void]
|
149
|
+
def inherited(subclass)
|
150
|
+
subclass
|
151
|
+
.extend(ClassMethods)
|
152
|
+
.clear_aliases_for_srs_roll
|
153
|
+
end
|
154
|
+
|
155
|
+
# ダイスボットの説明文を返す
|
156
|
+
# @return [String] 既定のダイスボット説明文
|
157
|
+
def help_message
|
158
|
+
DEFAULT_HELP_MESSAGE
|
159
|
+
end
|
160
|
+
|
161
|
+
# 目標値あり成功判定のエイリアスコマンドの正規表現を返す
|
162
|
+
# @return [nil]
|
163
|
+
def aliases_re_for_srs_roll_with_target_value
|
164
|
+
nil
|
165
|
+
end
|
166
|
+
|
167
|
+
# 目標値なし成功判定のエイリアスコマンドの正規表現を返す
|
168
|
+
# @return [nil]
|
169
|
+
def aliases_re_for_srs_roll_without_target_value
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# 固有のコマンドの接頭辞を設定する
|
175
|
+
register_prefix(['2D6.*'])
|
176
|
+
|
177
|
+
# ダイスボットを初期化する
|
178
|
+
def initialize(command)
|
179
|
+
super(command)
|
180
|
+
|
181
|
+
# 式、出目ともに送信する
|
182
|
+
|
183
|
+
# バラバラロール(Bコマンド)でソートする
|
184
|
+
@sort_add_dice = true
|
185
|
+
# D66ダイスあり(出目をソートしない)
|
186
|
+
@enabled_d66 = true
|
187
|
+
@d66_sort_type = D66SortType::NO_SORT
|
188
|
+
end
|
189
|
+
|
190
|
+
# ダイスボットの説明文を返す
|
191
|
+
# @return [String]
|
192
|
+
def help_message
|
193
|
+
self.class.help_message
|
194
|
+
end
|
195
|
+
|
196
|
+
# 既定のクリティカル値
|
197
|
+
DEFAULT_CRITICAL_VALUE = 12
|
198
|
+
# 既定のファンブル値
|
199
|
+
DEFAULT_FUMBLE_VALUE = 2
|
200
|
+
|
201
|
+
# 目標値あり成功判定の正規表現
|
202
|
+
SRS_ROLL_WITH_TARGET_VALUE_RE =
|
203
|
+
/\A2D6([-+][-+\d]+)?>=(\d+)(?:\[(\d+)?(?:,(\d+))?\])?\z/.freeze
|
204
|
+
# 目標値なし成功判定の正規表現
|
205
|
+
SRS_ROLL_WITHOUT_TARGET_VALUE_RE =
|
206
|
+
/\A2D6([-+][-+\d]+)?\[(\d+)?(?:,(\d+))?\]\z/.freeze
|
207
|
+
|
208
|
+
# 既定の閾値指定表記
|
209
|
+
SRS_ROLL_DEFAULT_THRESHOLDS =
|
210
|
+
"[#{DEFAULT_CRITICAL_VALUE},#{DEFAULT_FUMBLE_VALUE}]"
|
211
|
+
|
212
|
+
# 成功判定コマンドのノード
|
213
|
+
SRSRollNode = Struct.new(
|
214
|
+
:modifier, :critical_value, :fumble_value, :target_value
|
215
|
+
) do
|
216
|
+
# 成功判定の文字列表記を返す
|
217
|
+
# @return [String]
|
218
|
+
def to_s
|
219
|
+
lhs = "2D6#{Format.modifier(modifier)}"
|
220
|
+
expression = target_value ? "#{lhs}>=#{target_value}" : lhs
|
221
|
+
|
222
|
+
return "#{expression}[#{critical_value},#{fumble_value}]"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# 固有のダイスロールコマンドを実行する
|
227
|
+
# @param [String] command 入力されたコマンド
|
228
|
+
# @return [String, nil] ダイスロールコマンドの実行結果
|
229
|
+
def eval_game_system_specific_command(command)
|
230
|
+
alias_replaced_with_2d6 = replace_alias_for_srs_roll_with_2d6(command)
|
231
|
+
|
232
|
+
if (node = parse(alias_replaced_with_2d6))
|
233
|
+
return execute_srs_roll(node)
|
234
|
+
end
|
235
|
+
|
236
|
+
return nil
|
237
|
+
end
|
238
|
+
|
239
|
+
private
|
240
|
+
|
241
|
+
# 成功判定のエイリアスコマンドを2D6に置換する
|
242
|
+
# @param [String] input 入力文字列
|
243
|
+
# @return [String]
|
244
|
+
def replace_alias_for_srs_roll_with_2d6(input)
|
245
|
+
case input
|
246
|
+
when self.class.aliases_re_for_srs_roll_with_target_value
|
247
|
+
return "2D6#{Regexp.last_match(1)}"
|
248
|
+
when self.class.aliases_re_for_srs_roll_without_target_value
|
249
|
+
modifier = Regexp.last_match(1)
|
250
|
+
thresholds = Regexp.last_match(2) || SRS_ROLL_DEFAULT_THRESHOLDS
|
251
|
+
|
252
|
+
return "2D6#{modifier}#{thresholds}"
|
253
|
+
else
|
254
|
+
return input
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# 構文解析する
|
259
|
+
# @param [String] command コマンド文字列
|
260
|
+
# @return [SRSRollNode, nil]
|
261
|
+
def parse(command)
|
262
|
+
case command
|
263
|
+
when SRS_ROLL_WITH_TARGET_VALUE_RE
|
264
|
+
return parse_srs_roll_with_target_value(Regexp.last_match)
|
265
|
+
when SRS_ROLL_WITHOUT_TARGET_VALUE_RE
|
266
|
+
return parse_srs_roll_without_target_value(Regexp.last_match)
|
267
|
+
else
|
268
|
+
return nil
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# 修正値を評価する
|
273
|
+
# @param [String, nil] modifier_str 修正値部分の文字列
|
274
|
+
# @return [Integer] 修正値
|
275
|
+
def eval_modifier(modifier_str)
|
276
|
+
return 0 unless modifier_str
|
277
|
+
|
278
|
+
return ArithmeticEvaluator.eval(modifier_str, round_type: @round_type)
|
279
|
+
end
|
280
|
+
|
281
|
+
# 目標値あり成功判定の正規表現マッチ情報からノードを作る
|
282
|
+
# @param [MatchData] m 正規表現のマッチ情報
|
283
|
+
# @return [SRSRollNode]
|
284
|
+
def parse_srs_roll_with_target_value(m)
|
285
|
+
modifier = eval_modifier(m[1])
|
286
|
+
target_value = m[2].to_i
|
287
|
+
critical_value = m[3]&.to_i || DEFAULT_CRITICAL_VALUE
|
288
|
+
fumble_value = m[4]&.to_i || DEFAULT_FUMBLE_VALUE
|
289
|
+
|
290
|
+
return SRSRollNode.new(modifier, critical_value, fumble_value, target_value)
|
291
|
+
end
|
292
|
+
|
293
|
+
# 目標値なし成功判定の正規表現マッチ情報からノードを作る
|
294
|
+
# @param [MatchData] m 正規表現のマッチ情報
|
295
|
+
# @return [SRSRollNode]
|
296
|
+
def parse_srs_roll_without_target_value(m)
|
297
|
+
modifier = eval_modifier(m[1])
|
298
|
+
critical_value = m[2]&.to_i || DEFAULT_CRITICAL_VALUE
|
299
|
+
fumble_value = m[3]&.to_i || DEFAULT_FUMBLE_VALUE
|
300
|
+
|
301
|
+
return SRSRollNode.new(modifier, critical_value, fumble_value, nil)
|
302
|
+
end
|
303
|
+
|
304
|
+
# 成功判定を実行する
|
305
|
+
# @param [SRSRollNode] srs_roll 成功判定ノード
|
306
|
+
# @return [String] 成功判定結果
|
307
|
+
def execute_srs_roll(srs_roll)
|
308
|
+
dice_list = @randomizer.roll_barabara(2, 6)
|
309
|
+
dice_list.sort! if @sort_add_dice
|
310
|
+
|
311
|
+
sum = dice_list.sum()
|
312
|
+
dice_str = dice_list.join(",")
|
313
|
+
|
314
|
+
modified_sum = sum + srs_roll.modifier
|
315
|
+
|
316
|
+
parts = [
|
317
|
+
"(#{srs_roll})",
|
318
|
+
"#{sum}[#{dice_str}]#{Format.modifier(srs_roll.modifier)}",
|
319
|
+
modified_sum,
|
320
|
+
compare_result(srs_roll, sum, modified_sum)
|
321
|
+
]
|
322
|
+
|
323
|
+
return parts.compact.join(' > ')
|
324
|
+
end
|
325
|
+
|
326
|
+
# ダイスロール結果を目標値、クリティカル値、ファンブル値と比較する
|
327
|
+
# @param [SRSRollNode] srs_roll 成功判定ノード
|
328
|
+
# @param [Integer] sum 出目の合計
|
329
|
+
# @param [Integer] modified_sum 修正後の値
|
330
|
+
# @return [String, nil] 比較結果
|
331
|
+
def compare_result(srs_roll, sum, modified_sum)
|
332
|
+
if sum >= srs_roll.critical_value
|
333
|
+
return '自動成功'
|
334
|
+
end
|
335
|
+
|
336
|
+
if sum <= srs_roll.fumble_value
|
337
|
+
return '自動失敗'
|
338
|
+
end
|
339
|
+
|
340
|
+
if srs_roll.target_value
|
341
|
+
return modified_sum >= srs_roll.target_value ? '成功' : '失敗'
|
342
|
+
end
|
343
|
+
|
344
|
+
return nil
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bcdice/command_parser"
|
4
|
+
|
5
|
+
module BCDice
|
6
|
+
module GameSystem
|
7
|
+
class SamsaraBallad < Base
|
8
|
+
# ゲームシステムの識別子
|
9
|
+
ID = 'SamsaraBallad'
|
10
|
+
|
11
|
+
# ゲームシステム名
|
12
|
+
NAME = 'サンサーラ・バラッド'
|
13
|
+
|
14
|
+
# ゲームシステム名の読みがな
|
15
|
+
#
|
16
|
+
# 「ゲームシステム名の読みがなの設定方法」(docs/dicebot_sort_key.md)を参考にして
|
17
|
+
# 設定してください
|
18
|
+
SORT_KEY = 'さんさあらはらつと'
|
19
|
+
|
20
|
+
# ダイスボットの使い方
|
21
|
+
HELP_MESSAGE = <<~MESSAGETEXT
|
22
|
+
SB 通常のD100ロールを行う
|
23
|
+
SBS スワップロールでD100ロールを行う
|
24
|
+
SB#x@y F値をx、C値をyとして通常のD100ロールを行う
|
25
|
+
SBS#x@y F値をx、C値をyとしてスワップロールでD100ロールを行う
|
26
|
+
|
27
|
+
例:
|
28
|
+
SB<=85 通常の技能で成功率85%の判定
|
29
|
+
SBS<=70 習熟を得た技能で成功率70%の判定
|
30
|
+
SBS#3@7<=80 習熟を得た技能で、F値3、C値7で成功率80%の攻撃判定
|
31
|
+
SB<57 通常の技能で、能動側の達成値が57の受動判定
|
32
|
+
SBS<70 習熟を得た技能で、能動側の達成値が70の受動判定
|
33
|
+
MESSAGETEXT
|
34
|
+
|
35
|
+
# ダイスボットで使用するコマンドを配列で列挙する
|
36
|
+
register_prefix(['SBS?.*'])
|
37
|
+
|
38
|
+
def eval_game_system_specific_command(command)
|
39
|
+
debug("eval_game_system_specific_command Begin")
|
40
|
+
|
41
|
+
parser = CommandParser.new('SB', 'SBS')
|
42
|
+
cmd = parser.parse(command)
|
43
|
+
|
44
|
+
unless cmd
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
|
48
|
+
if cmd.command == 'SB'
|
49
|
+
places_text = nil
|
50
|
+
total = @randomizer.roll_once(100)
|
51
|
+
else
|
52
|
+
a = @randomizer.roll_once(10)
|
53
|
+
b = @randomizer.roll_once(10)
|
54
|
+
places_text = "#{a},#{b}"
|
55
|
+
places = [a, b].map { |n| n == 10 ? 0 : n }.sort
|
56
|
+
|
57
|
+
total = places[0] * 10 + places[1]
|
58
|
+
total = 100 if total == 0
|
59
|
+
end
|
60
|
+
|
61
|
+
cmp_result = compare(total, cmd)
|
62
|
+
|
63
|
+
sequence = [
|
64
|
+
"(D100#{cmd.cmp_op}#{cmd.target_number})",
|
65
|
+
places_text,
|
66
|
+
total.to_s,
|
67
|
+
cmp_result,
|
68
|
+
].compact
|
69
|
+
|
70
|
+
return sequence.join(" > ")
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# @return [String]
|
76
|
+
# @return [nil]
|
77
|
+
def compare(total, cmd)
|
78
|
+
if [:<=, :<].include?(cmd.cmp_op)
|
79
|
+
if !total.send(cmd.cmp_op, cmd.target_number)
|
80
|
+
"失敗"
|
81
|
+
elsif fumble_?(total, cmd.fumble)
|
82
|
+
"ファンブル"
|
83
|
+
elsif critical_?(total, cmd.critical)
|
84
|
+
"クリティカル"
|
85
|
+
else
|
86
|
+
"成功"
|
87
|
+
end
|
88
|
+
elsif fumble_?(total, cmd.fumble)
|
89
|
+
# ファンブル優先
|
90
|
+
"ファンブル"
|
91
|
+
elsif critical_?(total, cmd.critical)
|
92
|
+
"クリティカル"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param total [Integer]
|
97
|
+
# @param fumble [Integer, nil]
|
98
|
+
# @return [Boolean]
|
99
|
+
def fumble_?(total, fumble)
|
100
|
+
fumble && (total % 10 <= fumble)
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param total [Integer]
|
104
|
+
# @param critical [Integer, nil]
|
105
|
+
# @return [Boolean]
|
106
|
+
def critical_?(total, critical)
|
107
|
+
critical && (total % 10 >= critical)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|