lib/gamefic/scriptable/responses.rb
# frozen_string_literal: true module Gamefic module Scriptable module Responses include Queries include Syntaxes # Create a response to a command. # A Response uses the `verb` argument to identify the imperative verb # that triggers the action. It can also accept queries to tokenize the # remainder of the input and filter for particular entities or # properties. The `block`` argument is the proc to execute when the input # matches all of the Response's criteria (i.e., verb and queries). # # @example A simple Response. # respond :wave do |actor| # actor.tell "Hello!" # end # # The command "wave" will respond "Hello!" # # @example A Response that accepts a Character # respond :salute, available(Character) do |actor, character| # actor.tell "#{The character} returns your salute." # end # # @param verb [Symbol, String, nil] An imperative verb for the command # @param args [Array<Object>] Filters for the command's tokens # @yieldparam [Gamefic::Actor] # @yieldreceiver [Object<self>] # @return [Response] def respond verb, *args, &proc response = Response.new(verb&.to_sym, *args, &proc) responses.push response syntaxes.push response.syntax response end # Create a meta response to a command. # # @param verb [Symbol, String, nil] An imperative verb for the command # @param args [Array<Object>] Filters for the command's tokens # @yieldparam [Gamefic::Actor] # @yieldreceiver [Object<self>] # @return [Response] def meta verb, *args, &proc response = Response.new(verb&.to_sym, *args, meta: true, &proc) responses.push response syntaxes.push response.syntax response end # @return [Array<Response>] def responses @responses ||= [] end # @return [Array<Response>] def responses_for(*verbs) symbols = verbs.map { |verb| verb&.to_sym } responses.select { |response| symbols.include? response.verb } end # @return [Array<Symbol>] def verbs responses.select(&:verb).uniq(&:verb) end end end end