module Rooms class Room def initialize engine @engine = engine end def damage_with_bonus damage, bonus [damage - bonus, 0].max end def health_damage damage damage_with_bonus damage, @engine.magic_armor end def endurance_damage damage damage_with_bonus damage, @engine.magic_weapon end def resolve command @command = command if @engine.state == 'invalid' @engine.state = 'play' end if @engine.state == 'play' _do_resolve end end def check_death if @engine.health <= 0 @engine.state = 'dead' elsif @engine.endurance <= 0 @engine.state = 'dead' end end def _do_resolve do_resolve check_death if !instant_resolve @engine.add_message resolve_message end end # TODO: limit weapon/armor levels def do_resolve case @command when 'c' else do_invalid end end def do_invalid @engine.state = 'invalid' @engine.add_message "Invalid command: #{@command}" if !instant_resolve enter else list_options end end def resolve_message if @engine.state == 'dead' if @engine.health <= 0 death_message elsif @engine.endurance <= 0 exhaust_message end else success_message end end def enter_message '' end def death_message 'You die' end def exhaust_message 'You fall over exhausted' end def success_message '' end def options [ 'continue', ] end def list_options options.each do |option| @engine.add_message ">[#{option[0]}]#{option[1..]}" end end def enter @engine.add_message enter_message if instant_resolve do_instant_resolve check_death @engine.add_message resolve_message end list_options end end class Welcome < Room def instant_resolve false end def do_resolve end def success_message <<~MSG.chomp A curse has infested an ancient keep near your town. The evil magic has filled the keep with monsters. Can you save your home from this Hex? MSG end def to_s 'welcome' end end class Store < Room def instant_resolve false end def enter_message 'You have enough XP to upgrade your equipment!' end def options [ 'weapon upgrade (-50 X)', 'armor upgrade (-50 X)' ] end def do_resolve case @command when 'a' @engine.xp -= 50 @engine.magic_armor += 1 @message = "You've upgraded your magic armor!" when 'w' @engine.xp -= 50 @engine.magic_weapon += 1 @message = "You've upgraded your magic weapon!" else do_invalid end end def to_s 'store' end end class Empty < Room def initialize engine super engine @endurance_damage = endurance_damage 1 end def instant_resolve false end def do_resolve case @command when 'r' @engine.update_hex 1, 3, 0 when 's' @engine.update_hex 3, -@endurance_damage, 0 when 'm' else do_invalid end end def enter_message 'You enter an empty room. Nothing dangerous or interesting happening here.' end def success_message case @command when 'r' 'You rest for a bit. You feel refreshed!' when 's' 'After a while, you find some dried meat. It looks good to eat' when 'm' "You decide there's no time to waste. You continue down the corridor." end end def options [ 'rest (+1 H, +3 E)', "scavenge for food (+3 H, #{-@endurance_damage} E)" ] end def to_s 'empty' end end class Trap < Room def initialize engine super engine @health_damage = health_damage @engine.level @endurance_damage = endurance_damage @engine.level end def instant_resolve false end def do_resolve case @command when 't' @engine.update_hex -@health_damage, 0, 0 when 'd' @engine.update_hex 0, -@endurance_damage, 0 else do_invalid end end def success_message case @command when 't' 'Ouch!' when 'd' 'Very carefully, you manage to disable the trap.' end end def enter_message 'You stop yourself short. Your foot was about to brush a tripwire!' end def options [ "trigger trap (#{-@health_damage} H)", "disable trap (#{-@endurance_damage} E)" ] end def to_s 'trap' end end class Monster < Room def initialize engine super engine @health_damage = health_damage @engine.level @endurance_damage = endurance_damage @engine.level end def instant_resolve false end def do_resolve case @command when 'r' when 'f' @engine.update_hex -@health_damage, -@endurance_damage, @engine.level else do_invalid end end def enter_message 'You turn the corner and see an ugly monster!' end def success_message case @command when 'r' 'You book it from there, heart beating fast. But you manage to lose the monster.' when 'f' 'The monster is defeated, your clothes still wet with blood, its and yours.' end end def options [ "run away", "fight (#{-@health_damage} H, #{-@endurance_damage} E, #{@engine.level} X)" ] end def to_s 'monster' end end class Treasure < Room def instant_resolve true end def do_instant_resolve roll = 1 + rand(6) case roll + @engine.level when 1..3 @found = 'key' @engine.keys += 1 else @found = 'gold' @engine.update_hex 0, 0, @engine.level end end def enter_message 'You enter a dusty room. Something shiny on the ground catches your eye.' end def success_message case @found when 'key' 'You find a key!' when 'gold' "You found some gold! (+#{@engine.level} X)" end end def to_s 'treasure' end end class Stairs < Room def instant_resolve true end def do_instant_resolve @engine.level += 1 end def enter_message 'You come across a set of cracked stairs.' end def success_message 'You journey downwards.' end def to_s 'stairs' end end class Boss < Room def initialize engine super engine @health_damage = health_damage(2 * @engine.level) @endurance_damage = endurance_damage(2 * @engine.level) end def instant_resolve true end def do_instant_resolve @engine.update_hex -@health_damage, -@endurance_damage, 2 * @engine.level end def enter_message "You encounter a giant boss monster. There's no escape routes, it's live or die!" end def success_message 'You defeat the fiend!' end def to_s 'boss' end end class Exit < Room def instant_resolve true end def do_instant_resolve @engine.state = 'win' end def success_message 'You won! Congratulations!' end def to_s 'exit' end end end