105 lines
2.7 KiB
Ruby
105 lines
2.7 KiB
Ruby
require "rubygems/text"
|
|
class MetalAdventuresDiscord::ScenesPlugin
|
|
include Gem::Text # #levenshtein_distance/2
|
|
|
|
def initialize(bot)
|
|
@bot = bot
|
|
@playing = {}
|
|
hook_scene!
|
|
end
|
|
|
|
def hook_scene!
|
|
@bot.message(with_text: /^!scene.+/) do |event|
|
|
handle_scene(event)
|
|
end
|
|
|
|
@bot.message(with_message: /^[^!]/) do |event|
|
|
handle_not_command(event)
|
|
end
|
|
end
|
|
|
|
def _error_invalid_scene_syntax
|
|
<<EOF
|
|
Invalid syntax (!scene <action> [params]).
|
|
Action can be:
|
|
- **start**: start a new session. impossible if another scene is already started on the current channel
|
|
- **stop**: close the current scene, stop the bot from asking things
|
|
EOF
|
|
end
|
|
|
|
def _error_not_implemented(method)
|
|
"Not implemented: #{self.class}##{method}"
|
|
end
|
|
|
|
def handle_scene(event)
|
|
match = event.content.match(/^!scene (?<event_name>start|stop) (?<params>.+)/)
|
|
if match.nil?
|
|
event.message.respond _error_invalid_scene_syntax
|
|
return nil
|
|
end
|
|
|
|
event_handler = "handle_event_#{match['event_name']}"
|
|
if !respond_to?(event_handler)
|
|
event.message.respond _error_not_implemented(event_handler)
|
|
logger.error _error_not_implemented(event_handler)
|
|
return nil
|
|
end
|
|
|
|
send(event_handler, event, match["params"])
|
|
end
|
|
|
|
def handle_event_start(event, params)
|
|
if @playing[event.message.channel.id]
|
|
event.message.respond "Scene #{@playing[event.message.channel.id].name} already running"
|
|
return nil
|
|
end
|
|
|
|
new_scene = MetalAdventures::Scene.load!(params)
|
|
@playing[event.message.channel.id] = new_scene
|
|
|
|
run_current_action(event)
|
|
end
|
|
|
|
def handle_event_stop(_event, _match)
|
|
@playing.delete event.message.channel.id
|
|
end
|
|
|
|
# handle all message that are not a !command
|
|
# while we are playing on the channel
|
|
def handle_not_command(event)
|
|
return if !@playing[event.message.channel.id]
|
|
|
|
scene = current_scene(event)
|
|
if event.message.content == "next" || event.message.content.downcase.end_with?(scene.current_action.name.downcase)
|
|
scene.next!
|
|
run_current_action(event)
|
|
end
|
|
end
|
|
|
|
def _options_strings(scene)
|
|
scene.current_action.options.map { _option_string(_1) }
|
|
end
|
|
|
|
def _option_string(option)
|
|
"- **#{option.name}** (#{option.duration}): compétence #{option.skill}"
|
|
end
|
|
|
|
def _scene_current_action(scene)
|
|
<<EOF
|
|
Action en cours à jouer: **#{scene.current_action.name}**.
|
|
Executez une option avec un jet de dès du même nom:
|
|
#{_options_strings(scene).join("\n")}
|
|
EOF
|
|
end
|
|
|
|
# do the bot job for the curren action
|
|
def run_current_action(event)
|
|
scene = current_scene(event)
|
|
event.message.respond _scene_current_action(scene)
|
|
end
|
|
|
|
private def current_scene(event)
|
|
@playing[event.message.channel.id]
|
|
end
|
|
end
|