Changeset 251

Show
Ignore:
Timestamp:
01/04/06 05:06:22 (3 years ago)
Author:
ged
Message:

- A bit more work on the Observation epic.

Location:
trunk
Files:
13 modified

Legend:

Unmodified
Added
Removed
  • trunk/acceptance/epic5.rb

    r218 r251  
    11#!/usr/bin/env ruby 
    22# 
    3 #   FaerieMUD - The Hidden Path - Epic 5: Volition 
     3#   FaerieMUD - The Hidden Path - Epic 5: Observation 
     4# 
     5#   As a player, I want to be able to observe the world around me, so that I can 
     6#   distinguish between myself and other things. 
    47# 
    58# == Authors 
     
    912# == Legal 
    1013#  
    11 # Copyright (c) 2000-2005 The FaerieMUD Consortium. Some rights reserved. 
     14# Copyright (c) 2000-2006 The FaerieMUD Consortium. Some rights reserved. 
    1215#  
    1316# This is free software. You may use, modify, and/or redistribute this software 
     
    3134require "fm" 
    3235 
     36 
  • trunk/bin/faeriemud.rb

    r218 r251  
    1111end 
    1212 
    13 require 'optparse' 
    14 require 'fm' 
     13verboseOff { 
     14    require 'optparse' 
     15    require 'fm' 
     16} 
    1517 
    1618 
     
    3436} 
    3537 
     38class SimpleVerb < FaerieMUD::Verb 
     39    @event_class = nil 
     40    class << self 
     41        attr_reader :event_class 
     42    end 
     43 
     44    def self::set_event_class( klass ) 
     45        # $deferr.puts "Setting %s's event class to %p" % [ self, klass ] 
     46        @event_class = klass 
     47    end 
     48 
     49    def self::inherited( mod ) 
     50        super 
     51        # $deferr.puts "Setting %s's event class to %p" % [ mod, @event_class ] 
     52        mod.instance_variable_set( :@event_class, @event_class ) 
     53    end 
     54 
     55    def invoke( instigator, origin, target=nil ) 
     56        eclass = self.class.event_class or 
     57            return super 
     58 
     59        return eclass.new( 
     60            :instigator => instigator,  
     61            :origin => origin, 
     62            :target => target, 
     63            :verb => self ) 
     64    end 
     65end 
     66 
     67# I know, I know -- at least I didn't call it a Heartbeat 
     68class TickEvent < FaerieMUD::Event 
     69end 
     70class TickVerb < SimpleVerb 
     71    set_event_class TickEvent 
     72end 
     73 
     74# Little world class 
     75class World < FaerieMUD::Area 
     76    def start 
     77        @thread = Thread::new do 
     78            Thread.current[:running] = true 
     79            Thread.current.abort_on_exception = true 
     80 
     81            while Thread.current[:running] 
     82                tick = TickVerb.instance.invoke( self, self ) 
     83                immerseEvents( tick ) 
     84                sleep 0.5 
     85            end 
     86        end 
     87 
     88        trap( 'INT' ) { stop } 
     89        trap( 'HUP' ) { stop } 
     90        trap( 'TERM' ) { stop } 
     91 
     92        @thread.join 
     93    end 
     94 
     95    def stop 
     96        return unless @thread 
     97        @thread[:running] = false 
     98    end 
     99 
     100end 
     101 
     102# Stuff for a Spark to do 
     103class TwinkleVerb < SimpleVerb 
     104    set_event_class FaerieMUD::VisualEvent 
     105end 
     106 
     107# An active object to occasionally generate observable events 
     108class Spark < FaerieMUD::Locus 
     109    def noun 
     110        'spark' 
     111    end 
     112 
     113    def handleTickEvent( event ) 
     114        if ( rand(100) < 5 ) 
     115            return TwinkleVerb.instance.invoke( self, self ) 
     116        else 
     117            return [] 
     118        end 
     119    end 
     120end 
     121 
    36122 
    37123# Create the world 
    38124header "FaerieMUD Explorer" 
    39 message "Setting up the world...\n" 
    40 world = FaerieMUD::Area::new 
    41125 
    42126# Create the character 
     
    50134spirit = FaerieMUD::Spirit::new 
    51135 
    52 # Hook up the CommandParser's IO callbacks 
     136# Hook up the Spirit's IO callbacks 
    53137message "Setting the Spirit's IO callbacks...\n" 
    54138spirit.onInputReady do |promptText| 
     
    65149 
    66150# Stick the character's body into the world Area 
    67 message "Placing the Character's body in the World...\n" 
     151message "Setting up the world...\n" 
     152world = World::new 
     153spark = Spark::new 
     154world << spark 
     155 
     156message "Placing the Character's body in the world...\n" 
    68157world << character.body 
    69158 
     159$defout.sync = true 
     160$deferr.sync = true 
     161 
     162world.start 
     163 
     164 
  • trunk/lib/fm/character.rb

    r247 r251  
    7474    ############################################################# 
    7575 
     76    ### Create a new FaerieMUD::Character object. 
     77    def initialize( args={} ) 
     78        @verbs = [] 
     79 
     80        super 
     81    end 
     82 
    7683 
    7784    ###### 
     
    7986    ###### 
    8087 
     88    ### The Array of FaerieMUD::Verb objects which define this character's 
     89    ### abilities. 
     90    attr_reader :verbs 
    8191     
    8292 
     
    129139 
    130140 
    131     ######### 
    132     protected 
    133     ######### 
    134  
    135  
    136141end # class FaerieMUD::Character 
    137142 
  • trunk/lib/fm/entity.rb

    r250 r251  
    111111        debugMsg( 1, "Handling a #{event.class.name} event." ) 
    112112        handler = self.getHandlerForEvent( event ) 
    113         return handler.call( event ) 
     113        result = handler.call( event ) 
     114 
     115        return Array( result ) 
    114116    end 
    115117 
  • trunk/lib/fm/event.rb

    r250 r251  
    133133 
    134134        return sentence.join( " " ) 
    135          
    136135    end 
    137136 
  • trunk/lib/fm/events/astronomical.rb

    r198 r251  
    3434        # SVN Id 
    3535        SVNId = %q$Id$ 
    36  
    37         # SVN URL 
    38         SVNURL = %q$URL$ 
    3936 
    4037    end # class AstronomicalEvent 
  • trunk/lib/fm/events/meteorological.rb

    r247 r251  
    3737 
    3838 
     39### Object which represents a timeslice of precipitation of some kind. They will 
     40### most probably be generated by a precipitation activity of a weather system, 
     41### which propagates these events to simulate the ongoing rainfall, snowfall, 
     42### etc. 
     43class FaerieMUD::PrecipitationEvent < FaerieMUD::MeteorologicalEvent 
     44    contributors :ged 
     45 
     46    # SVN Revision 
     47    SVNRev = %q$Rev$ 
     48 
     49    # SVN Id 
     50    SVNId = %q$Id$ 
     51 
     52    # The default amount of water in a slice of rainfall, in cubic meters. 
     53    DefaultAmount = 0.01 
     54 
     55    # The default temperature of a slice of rainfall 
     56    DefaultTemperature = 25 
     57 
     58 
     59    ### Create a RainEvent which represents the falling of a collection of 
     60    ### drops. The amount, temperature, and intensity can be specified with 
     61    ### optional hash +args+. 
     62    def initialize( args={} ) 
     63        @amount = args[:amount] || DefaultAmount 
     64        @temperature = args[:temperature] || DefaultTemperature 
     65    end 
     66 
     67     
     68    ###### 
     69    public 
     70    ###### 
     71 
     72    # The amount of water in this slice of rainfall.  Value may be between 
     73    # 0.01 (mist) to 1.0 (deluge). 
     74    attr_accessor :amount 
     75 
     76    # The temperature of the water in this slice of rainfall. Value may be between  
     77    attr_accessor :temperature 
     78 
     79end 
  • trunk/lib/fm/events/science.rb

    r172 r251  
    3434    SVNId = %q$Id$ 
    3535 
    36     # SVN URL 
    37     SVNURL = %q$URL$ 
    3836 
    3937end # class FaerieMUD::ScienceEvent 
  • trunk/lib/fm/linguistics.rb

    r250 r251  
    9191 
    9292 
     93    ### Linguistic sentence class -- instances of this class are used to 
     94    ### encapsulate single-sentence chunks of linguistic content in the 
     95    ### natural-language system. 
    9396    class Sentence 
    9497        include FaerieMUD::Linguistics 
  • trunk/lib/fm/perception.rb

    r250 r251  
    4848    ################################################################# 
    4949 
    50     # GWRN: 44975 
    51     ### Create a new Perception for the given +perceiver+, which  
     50    ### Create a new Perception for the given +perceiver+, which will be the 
     51    ### deleated describer of any PerceptualEvents which are handled. 
    5252    def initialize( perceiver, args={} ) 
    5353        @perceiver = perceiver 
  • trunk/tests/entity.tests.rb

    r250 r251  
    44# $Id$ 
    55# 
    6 # Copyright (c) 2003, 2004, 2005 The FaerieMUD Consortium. 
     6# Copyright (c) 2003-2006 The FaerieMUD Consortium. 
    77#  
    88 
     
    3838    class DerivTestingEvent < TestingEvent; end 
    3939    class DerivDerivTestingEvent < DerivTestingEvent; end 
     40    class ResultEvent < FaerieMUD::Event 
     41        def initialize; end 
     42    end 
     43 
    4044 
    4145 
     
    4347    def setup 
    4448        @entity = TestingEntity::new 
     49        @testingEvent = TestingEvent::new 
     50        @derivTestingEvent = DerivTestingEvent::new 
     51        @derivDerivTestingEvent = DerivDerivTestingEvent::new 
    4552    end 
    4653 
     
    5865    def test_unhandled_events_should_raise_an_exception 
    5966        rval = nil 
    60         te = TestingEvent::new 
    61         dte = DerivTestingEvent::new 
    6267 
    6368        # Passing an event without a specific handler should cause an exception 
    6469        # to be raised. 
    6570        assert_raises( FaerieMUD::UnhandledEventError ) { 
    66             @entity.handleEvents( te ) 
     71            @entity.handleEvents( @testingEvent ) 
    6772        } 
    6873        assert_raises( FaerieMUD::UnhandledEventError ) { 
    69             @entity.handleEvents( dte ) 
     74            @entity.handleEvents( @derivTestingEvent ) 
    7075        } 
    7176    end 
     
    7580    def test_entities_which_define_fallback_handler_should_handle_any_event 
    7681        rval = nil 
    77         te = TestingEvent::new 
    78         dte = DerivTestingEvent::new 
    7982 
    8083        # Add a fallback handler 
     
    8689        # Now try again -- both kinds of event should be handled by the fallback 
    8790        # handler now. 
    88         assert_nothing_raised { @entity.handleEvents( te ) } 
    89         assert_same te, @entity.lastSeenEvent, "last seen event" 
     91        assert_nothing_raised { @entity.handleEvents(@testingEvent) } 
     92        assert_same @testingEvent, @entity.lastSeenEvent, "last seen event" 
    9093        assert_equal :handleAnyEvent, @entity.lastHandler 
    91         assert_nothing_raised { @entity.handleEvents( dte ) } 
    92         assert_same dte, @entity.lastSeenEvent, "last seen event" 
     94        assert_nothing_raised { @entity.handleEvents(@derivTestingEvent) } 
     95        assert_same @derivTestingEvent, @entity.lastSeenEvent, "last seen event" 
    9396        assert_equal :handleAnyEvent, @entity.lastHandler 
    9497 
     
    99102    def test_entities_should_handle_derivative_events_with_more_general_handlers 
    100103        rval = nil 
    101         te = TestingEvent::new 
    102         dte = DerivTestingEvent::new 
    103         ddte = DerivDerivTestingEvent::new 
    104104 
    105105        def @entity.handleTestingEvent( ev ) 
     
    108108        end 
    109109 
    110         assert_nothing_raised { @entity.handleEvents(te) } 
    111         assert_same te, @entity.lastSeenEvent, 
     110        assert_nothing_raised { @entity.handleEvents(@testingEvent) } 
     111        assert_same @testingEvent, @entity.lastSeenEvent, 
    112112            "last seen event for TestingEvent" 
    113113        assert_equal :handleTestingEvent, @entity.lastHandler, 
    114114            "last handler for TestingEvent" 
    115115 
    116         assert_nothing_raised { @entity.handleEvents(dte) } 
    117         assert_same dte, @entity.lastSeenEvent, 
     116        assert_nothing_raised { @entity.handleEvents(@derivTestingEvent) } 
     117        assert_same @derivTestingEvent, @entity.lastSeenEvent, 
    118118            "last seen event for DerivTestingEvent" 
    119119        assert_equal :handleTestingEvent, @entity.lastHandler, 
    120120            "last handler for DerivTestingEvent" 
    121121 
    122         assert_nothing_raised { @entity.handleEvents(ddte) } 
    123         assert_same ddte, @entity.lastSeenEvent, 
     122        assert_nothing_raised { @entity.handleEvents(@derivDerivTestingEvent) } 
     123        assert_same @derivDerivTestingEvent, @entity.lastSeenEvent, 
    124124            "last seen event for DerivDerivTestingEvent" 
    125125        assert_equal :handleTestingEvent, @entity.lastHandler, 
     
    128128 
    129129 
     130    def test_event_handler_should_be_able_to_handle_single_event_result 
     131        rval = nil 
     132 
     133        def @entity.handleTestingEvent( ev ) 
     134            return ResultEvent::new 
     135        end 
     136 
     137        assert_nothing_raised { rval = @entity.handleEvents(@testingEvent) } 
     138        assert_instance_of Array, rval 
     139        assert_equal 1, rval.length 
     140        assert_instance_of ResultEvent, rval[0] 
     141 
     142        assert_nothing_raised { rval = @entity.handleEvent(@testingEvent) } 
     143        assert_instance_of Array, rval 
     144        assert_equal 1, rval.length 
     145        assert_instance_of ResultEvent, rval[0] 
     146    end 
     147 
    130148end 
    131149 
  • trunk/tests/verb.tests.rb

    r217 r251  
    44# $Id$ 
    55# 
    6 # Copyright (c) 2004, 2005 The FaerieMUD Consortium. 
     6# Copyright (c) 2004-2006 The FaerieMUD Consortium. 
    77#  
    88 
     
    4343 
    4444    ### Instance test 
    45     def test_00_Instance 
    46         printTestHeader "FaerieMUD::Verb: Class/instantiation" 
     45    def test_verb_class_should_be_defined_and_a_singleton 
    4746        rval = nil 
    4847 
     
    6059 
    6160 
    62     ### Event-generation interface 
    63     def test_50_invoke 
    64         printTestHeader "FaerieMUD::Verb: Event-generation interface: invoke" 
     61    # Event interface: Things which employ verbs expect to be able to fire the 
     62    # verb and get back one or more appropriate events. 
     63    def test_verbs_should_be_able_to_be_invoked 
    6564        rval = nil 
    6665 
     
    8079 
    8180 
    82     ### CommandParser interface 
    83     def test_60_words 
    84         printTestHeader "FaerieMUD::Verb: CommandParser interface: words" 
     81    # CommandParser interface: Verbs should be able to provide a list of 
     82    # commands they expect to be invoked for. 
     83    def test_verbs_should_be_able_to_provide_a_list_of_autogenerated_command_words 
    8584        rval = nil 
    8685        verb = TestVerb::instance 
     
    9594    end 
    9695 
     96    # Subclasses of Verbs should be singletons, too. 
     97    def test_subclasses_should_be_singletons 
     98        rval = nil 
     99 
     100        assert_raises( NoMethodError ) { TestVerb.new } 
     101        assert_nothing_raised { rval = TestVerb.instance } 
     102 
     103        assert_instance_of TestVerb, rval 
     104    end 
    97105 
    98106end 
  • trunk/utils.rb

    r250 r251  
    33#   $Id: utils.rb,v 1.20 2003/11/23 04:37:57 stillflame Exp $ 
    44# 
    5 #   Copyright (c) 2001-2005, The FaerieMUD Consortium. 
     5#   Copyright (c) 2001-2006, The FaerieMUD Consortium. 
    66# 
    77#   This is free software. You may use, modify, and/or redistribute this 
     
    2626    end 
    2727 
    28     begin 
    29         require 'yaml' 
    30         $yaml = true 
    31     rescue LoadError => e 
    32         $stderr.puts "No YAML; try() will use PrettyPrint instead." 
    33         $yaml = false 
    34     end 
    3528} 
    3629 
     
    642635            end 
    643636 
    644             if $yaml 
    645                 result = rval.to_yaml 
    646             else 
    647                 PP.pp( rval, result ) 
    648             end 
     637            PP.pp( rval, result ) 
    649638 
    650639        rescue Exception => err