class Natural20::EventManager
Public Class Methods
clear()
click to toggle source
# File lib/natural_20/event_manager.rb, line 15 def self.clear @event_listeners = {} end
decorate_name(entity)
click to toggle source
@param event [Hash]
# File lib/natural_20/event_manager.rb, line 277 def self.decorate_name(entity) if @battle && @current_entity_context && entity seen_attacker = @current_entity_context.detect do |c| c == entity || @battle.map.can_see?(c, entity) end color = @battle.entity_group_for(seen_attacker) != @battle.entity_group_for(entity) ? :red : :blue seen_attacker ? entity.name&.colorize(color) : I18n.t('event.something') else entity.name&.colorize(:blue) end end
logger()
click to toggle source
@return [EventLogger]
# File lib/natural_20/event_manager.rb, line 48 def self.logger @logger ||= EventLogger.new(ENV['NAT20_LOG_LEVEL'].presence || '1') @logger end
output(string)
click to toggle source
# File lib/natural_20/event_manager.rb, line 272 def self.output(string) puts "[#{Session.current_session&.game_time || 0}] #{string}" end
received_event(event)
click to toggle source
# File lib/natural_20/event_manager.rb, line 31 def self.received_event(event) return if @event_listeners.nil? @event_listeners[event[:event]]&.each do |callable| callable.call(event) end end
register_event_listener(events, callable)
click to toggle source
Registers an event listener @param events [Symbol,Array<Symbol>] list of event types @param callable [Proc] handler
# File lib/natural_20/event_manager.rb, line 22 def self.register_event_listener(events, callable) events = [events] unless events.is_a?(Array) @event_listeners ||= {} events.each do |event| @event_listeners[event] ||= [] @event_listeners[event] << callable unless @event_listeners[event].include?(callable) end end
set_context(battle, entities = [])
click to toggle source
Sets the current player so that event text can be customized @param battle [Natural20::Battle] Current battle @param entites [Array] An array of entities
# File lib/natural_20/event_manager.rb, line 42 def self.set_context(battle, entities = []) @battle = battle @current_entity_context = entities end
show_name(event)
click to toggle source
@param event [Hash]
# File lib/natural_20/event_manager.rb, line 268 def self.show_name(event) decorate_name(event[:source]) end
standard_cli()
click to toggle source
# File lib/natural_20/event_manager.rb, line 53 def self.standard_cli Natural20::EventManager.clear event_handlers = { died: lambda { |event| output "#{show_name(event)} died." }, unconscious: lambda { |event| output "#{show_name(event)} unconscious." }, attacked: lambda { |event| advantage_mod = event[:advantage_mod] advantage, disadvantage = event[:adv_info] sneak = event[:sneak_attack] ? (event[:sneak_attack]).to_s : nil damage = (event[:damage_roll]).to_s damage_str = "#{[damage, sneak].compact.join(' + sneak ')} = #{event[:value]} #{event[:damage_type]}" if event[:cover_ac].try(:positive?) cover_str = " (behind cover +#{event[:cover_ac]} ac)" end Time.at(82800).utc.strftime("%I:%M%p") advantage_str = if advantage_mod&.positive? ' with advantage'.colorize(:green) elsif advantage_mod&.negative? ' with disadvantage'.colorize(:red) else '' end str_token = event[:attack_roll] ? 'event.attack' : 'event.attack_no_roll' output t(str_token, opportunity: event[:as_reaction] ? 'Opportunity Attack: ' : '', source: show_name(event), target: "#{event[:target].name}#{cover_str}", attack_name: event[:attack_name], advantage: advantage_str, attack_roll: event[:attack_roll].to_s.colorize(:green), attack_value: event[:attack_roll]&.result, damage: damage_str) }, damage: lambda { |event| output "#{show_name(event)} #{event[:source].describe_health}" }, miss: lambda { |event| advantage_mod = event[:advantage_mod] advantage_str = if advantage_mod&.positive? ' with advantage'.colorize(:green) elsif advantage_mod&.negative? ' with disadvantage'.colorize(:red) else '' end output "#{event[:as_reaction] ? 'Opportunity Attack: ' : ''} rolled #{advantage_str} #{event[:attack_roll]} ... #{event[:source].name&.colorize(:blue)} missed his attack #{event[:attack_name].colorize(:red)} on #{event[:target].name.colorize(:green)}" }, initiative: lambda { |event| output "#{show_name(event)} rolled a #{event[:roll]} = (#{event[:value]}) with dex tie break for initiative." }, move: lambda { |event| output "#{show_name(event)} moved #{(event[:path].size - 1) * event[:feet_per_grid]}ft." }, dodge: lambda { |event| output t('event.dodge', name: show_name(event)) }, help: lambda { |event| output "#{show_name(event)} is helping to attack #{event[:target].name&.colorize(:red)}" }, second_wind: lambda { |event| output SecondWindAction.describe(event) }, heal: lambda { |event| output "#{show_name(event)} heals for #{event[:value]}hp" }, hit_die: lambda { |event| output t('event.hit_die', source: show_name(event), roll: event[:roll].to_s, value: event[:roll].result) }, object_interaction: lambda { |event| if event[:roll] output "#{event[:roll]} = #{event[:roll].result} -> #{event[:reason]}" else output (event[:reason]).to_s end }, perception: lambda { |event| output "#{show_name(event)} rolls #{event[:perception_roll]} on perception" }, death_save: lambda { |event| output t('event.death_save', name: show_name(event), roll: event[:roll].to_s, value: event[:roll].result, saves: event[:saves], fails: event[:fails]).colorize(:blue) }, death_fail: lambda { |event| if event[:roll] output t('event.death_fail', name: show_name(event), roll: event[:roll].to_s, value: event[:roll].result, saves: event[:saves], fails: event[:fails]).colorize(:red) else output t('event.death_fail_hit', name: show_name(event), saves: event[:saves], fails: event[:fails]).colorize(:red) end }, great_weapon_fighting_roll: lambda { |event| output t('event.great_weapon_fighting_roll', name: show_name(event), roll: event[:roll], prev_roll: event[:prev_roll]) }, feature_protection: lambda { |event| output t('event.feature_protection', source: event[:source]&.name, target: event[:target]&.name, attacker: event[:attacker]&.name) }, prone: lambda { |event| output t('event.status.prone', name: show_name(event)) }, stand: lambda { |event| output t('event.status.stand', name: show_name(event)) }, %i[acrobatics athletics] => lambda { |event| if event[:success] output t("event.#{event[:event]}.success", name: show_name(event), roll: event[:roll], value: event[:roll].result) else output t("event.#{event[:event]}.failure", name: show_name(event), roll: event[:roll], value: event[:roll].result) end }, start_of_combat: lambda { |event| output t('event.combat_start') event[:combat_order].each_with_index do |entity_and_initiative, index| entity, initiative = entity_and_initiative output "#{index + 1}. #{decorate_name(entity)} #{initiative}" end }, spell_buff: lambda { |event| output t('event.spell_buff', source: show_name(event), spell: event[:spell].label, target: event[:target]&.name) }, end_of_combat: lambda { |_event| output t('event.combat_end') }, grapple_success: lambda { |event| if event[:target_roll] output t('event.grapple_success', source: show_name(event), target: event[:target]&.name, source_roll: event[:source_roll], source_roll_value: event[:source_roll].result, target_roll: event[:target_roll], target_roll_value: event[:target_roll].result) else output t('event.grapple_success_no_roll', source: show_name(event), target: event[:target]&.name) end }, first_aid: lambda { |event| output t('event.first_aid', name: show_name(event), target: event[:target]&.name, roll: event[:roll], value: event[:roll].result) }, first_aid_failure: lambda { |event| output t('event.first_aid_failure', name: show_name(event), target: event[:target]&.name, roll: event[:roll], value: event[:roll].result) }, grapple_failure: lambda { |event| output t('event.grapple_failure', source: show_name(event), target: event[:target]&.name, source_roll: event[:source_roll], source_roll_value: event[:source_roll].result, target_roll: event[:target_roll], target_roll_value: event[:target_roll_value].result) }, drop_grapple: lambda { |event| output t('event.drop_grapple', source: show_name(event), target: event[:target]&.name) }, flavor: lambda { |event| output t("event.flavor.#{event[:text]}", source: event[:source]&.name, target: event[:target]&.name) }, shove_success: lambda do |event| opts = { source: event[:source]&.name, target: event[:target]&.name, source_roll: event[:source_roll], source_roll_value: event[:source_roll].result, target_roll: event[:target_roll], target_roll_value: event[:target_roll].result } if event[:knock_prone] output t('event.knock_prone_success', opts) else output t('event.shove_success', opts) end end, shove_failure: lambda do |event| opts = { source: event[:source]&.name, target: event[:target]&.name, source_roll: event[:source_roll], source_roll_value: event[:source_roll].result, target_roll: event[:target_roll], target_roll_value: event[:target_roll].result } if event[:knock_prone] output t('event.knock_prone_failure', opts) else output t('event.shove_failure', opts) end end, %i[escape_grapple_success escape_grapple_failure] => lambda { |event| output t("event.#{event[:event]}", source: show_name(event), target: event[:target]&.name, source_roll: event[:source_roll], source_roll_value: event[:source_roll].result, target_roll: event[:target_roll], target_roll_value: event[:target_roll].result) } } event_handlers.each do |k, v| EventManager.register_event_listener(k, v) end end
t(token, options = {})
click to toggle source
# File lib/natural_20/event_manager.rb, line 290 def self.t(token, options = {}) I18n.t(token, **options) end