! infunit.inf - test the NpcAct framework NpcAct.h ! Version 1.0 (19-Sep-2001) ! ! by Matt Albrecht - groboclown@users.sourceforge.net ! ! (If you need to edit this file, note that indentations are 4 spaces ! and tabs are not used.) ! ! This has been donated to the Public Domain. Use, abuse, and don't blame me. ! ! Try the game out. Switches d2v5; !For defines Constant DEBUG; Constant NPCACT_TRACE_PLAYER 0; Constant NPCACT_TRACE_LOGIC 0; Constant NPCACT_CHECK_ERRORS; Constant Story "TestNPC"; Release 1; Constant Headline "^Test the NPC Actions^ Kopywrong (k) 2001 by Matt Albrecht.^^"; Message "Including parser and verblib"; Include "Parser"; Include "Verblib"; Include "NpcAct"; ![ NpcAct_NewRoom ; !]; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! Initialisation block !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! [ Initialise ; location = FirstRoom; classutl_InitialiseObjects(); "^^^^ Interact with the NPCs! ^"; ]; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! A monitor to be installed on the Imp to properly report ! characters moving about. NpcAct_Monitor GoMonitor NpcAct_Imp with npcact_Before [ _actionList _action _source; !print "[Go Monitor! Before]^"; _action = _actionList.npcact_CurrentAction(); if (_action.npcact_IsCanceled()) { ! already canceled - don't display anything rfalse; } _source = _action.npcact_source; !print "[Go Monitor! - go = ",##Go, !", verb = ",_action.npcact_verb, !", player in scope = ",_action.npcact_PlayerInScope(), !", source = ~",(name)_source,"~]^"; if (_action.npcact_verb == ##Go && _action.npcact_PlayerInScope() && _source ~= player) { !print "[Go Monitor! - Printing Message]^"; if (_source provides npcact_GoAwayMessage) { switch (metaclass( _source.npcact_GoAwayMessage )) { Object: !print "[Go Monitor! - showing go away object]^"; print (The)_source," leaves to ", (print_dir)_source.npcact_GoAwayMessage, ".^"; String: !print "[Go Monitor! - printing go away string]^"; print (string)_source.npcact_GoAwayMessage,"^"; Routine: !print "[Go Monitor! - running go away message]^"; _source.npcact_GoAwayMessage( _action.npcact_noun ); default: !print "[Go Monitor! - unknown go away message: ",_source.npcact_GoAwayMessage,"]^"; } } else { print (The)_source," leaves to ", (print_dir)_action.npcact_noun, ".^"; } } ], npcact_After [ _actionList _action _source; !print "[Go Monitor! After]^"; _action = _actionList.npcact_CurrentAction(); _source = _action.npcact_source; if (_action.npcact_verb == ##Go && _action.npcact_PlayerInScope() && _source ~= player) { !print "[Go Monitor! - Printing Message]^"; if (_source provides npcact_ArriveMessage) { switch (metaclass( _source.npcact_ArriveMessage )) { Object: print (The)_source," arrives from "; print_dir( _source.npcact_ArriveMessage ); print ".^"; String: print (string)_source.npcact_ArriveMessage,"^"; Routine: _source.npcact_ArriveMessage( _action.npcact_noun ); } } else { print (The)_source," arrives from ", (print_dir)_action.npcact_noun, ".^"; } } ], ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Class Topic has general; Topic ReportOnFlowerPot "reported manipulation of flower pot"; Topic Wanda1 "I really don't like that television."; Topic Wanda2 "It's too bad I can't do anything but say preprogrammed sentences."; Topic Wanda3 "I wish I could talk to someone else."; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Executes a routine if the action executes & the player is ! in scope. The routine is passed the parameters: action source, ! topic. NpcAct_Action SayTopic "say topic action" with ! this_noun is the topic npcact_verb ##Answer, npcact_Setup [ topic _sayRoutine; if (topic == nothing) { "** Did not specify a say topic. **^"; } ! if (~~(topic ofclass Topic)) ! { ! "** Did not pass in a topic, but rather ",(name)topic,".^"; ! } self.npcact_noun = topic; self.npcact_data = _sayRoutine; ], npcact_Execute [ _routine; if (self.npcact_PlayerInScope()) { _routine = self.npcact_data; _routine( self.npcact_source, self.npcact_noun ); } ], ; ! Characters that use this action must have the action be of this type, since it ! defines new variables. ! The npcact_Construct method must be invoked with the underlying action's ! template. The npcact_Setup method must be invoked for the underlying action, ! then the npcact_SetupSay must be invoked. Class ActionAndSayTopic class NpcAct_Action with npcact_Construct [ _template _npc; ! clean ourself up self.npcact__ActionExecute = nothing; self.npcact__ActionCanceledResponse = nothing; self.npcact__topic = nothing; self.npcact__okroutine = nothing; self.npcact__cancelroutine = nothing; ! call the original constructor self.NpcAct_Action::npcact_Construct( _template, _npc ); ! re-set ourself up self.npcact__ActionExecute = self.npcact_Execute; self.npcact__ActionCanceledResponse = self.npcact_CanceledResponse; self.npcact_Execute = self.npcact_SayExecute; self.npcact_CanceledResponse = self.npcact_SayCanceledResponse; ], ! Sets up the spe npcact_SetupSay [ _topic _sayRoutine _canceledSayRoutine; if (topic == nothing) { "** Did not specify a say topic. **^"; } ! if (~~(topic ofclass Topic)) ! { ! "** Did not pass in a topic, but rather ",(name)topic,".^"; ! } self.npcact__topic = _topic; self.npcact__okroutine = _sayRoutine; self.npcact__cancelroutine = _canceledSayRoutine; ], npcact_SayExecute [ _routine; ! Execute the action first if (self.npcact__ActionExecute ~= nothing && metaclass( self.npcact__ActionExecute ) == Routine) { self.npcact__ActionExecute(); } ! Execute the say if (self.npcact_PlayerInScope()) { _routine = self.npcact__okroutine; _routine( self.npcact_source, self.npcact__topic ); } ], npcact_SayCanceledResponse [ _canceller _routine; ! Execute the action first if (self.npcact__ActionCanceledResponse ~= nothing && metaclass( self.npcact__ActionCanceledResponse ) == Routine) { self.npcact__ActionCanceledResponse( _canceller ); } ! Execute the say if (self.npcact_PlayerInScope()) { _routine = self.npcact__cancelroutine; _routine( self.npcact_source, self.npcact__topic ); } ], npcact__ActionExecute nothing, npcact__ActionCanceledResponse nothing, npcact__topic nothing, npcact__okroutine nothing, npcact__cancelroutine nothing, ; NpcAct_Action GetObject "get object action" with ! this_noun is the topic npcact_verb ##Take, npcact_Setup [ obj; if (obj == nothing) { "** Did not specify a get target. **^"; } ! if (~~(topic ofclass Topic)) ! { ! "** Did not pass in a topic, but rather ",(name)topic,".^"; ! } self.npcact_noun = obj; ], npcact_Execute [ obj; obj = self.npcact_noun; ! Not right - only works when player is present! if (ObjectIsUntouchable( obj, true )) { "",(the)self.npcact_noun," can't get ",(the)obj," because something is in the way."; } if (obj has static or scenery) { "",(the)self.npcact_noun," can't get ",(the)obj," because it is ungettable."; } move obj to self.npcact_source; if (self.npcact_PlayerInScope()) { "",(the)self.npcact_source," took ", (the)self.npcact_noun,"."; } ], npcact_CanceledResponse [ _canceller; if (self.npcact_PlayerInScope()) { "",(The)_canceller," prevented ",(the)self.npcact_source, " from taking ",(the)self.npcact_noun,"."; } ], ; NpcAct_Action DropObject "drop object action" with ! this_noun is the topic npcact_verb ##Drop, npcact_Setup [ obj; if (obj == nothing) { "** Did not specify a get target. **^"; } ! if (~~(topic ofclass Topic)) ! { ! "** Did not pass in a topic, but rather ",(name)topic,".^"; ! } self.npcact_noun = obj; ], npcact_Execute [ obj; obj = self.npcact_noun; if (obj notin self.npcact_source) { "",(The)self.npcact_source," is not holding ", (the)self.npcact_noun,"."; } move obj to parent( self.npcact_source ); if (self.npcact_PlayerInScope()) { "",(The)self.npcact_source," dropped ", (the)self.npcact_noun,"."; } ], npcact_CanceledResponse [ _canceller; if (self.npcact_PlayerInScope()) { "",(The)_canceller," prevented ",(the)self.npcact_source, " from dropping ",(the)self.npcact_noun,"."; } ], ; NpcAct_Action GoDirection "go in a direction" with ! this_noun is the topic npcact_verb ##Go, npcact_Setup [ nextRoom; if (nextRoom == nothing) { "** Did not specify a direction. **^"; } if (nextRoom ofclass CompassDirection) { nextRoom = nextRoom.door_dir; } self.npcact_noun = nextRoom; ], npcact_Execute [ _room _dir; ! For proper printing of character movement, a GoMonitor ! is installed in the player Imp. _room = parent( self.npcact_source ); _dir = _room.(self.npcact_noun); while (_dir ~= nothing && metaclass(_dir) == Routine) { _dir = _room._dir(); } if (_dir == nothing || metaclass(_dir) ~= Object) { return; } move self.npcact_source to _dir; ], ; [ print_dir val; switch (val) { n_to, n_obj: print "the north"; return; ne_to, ne_obj: print "the north-east"; return; e_to, e_obj: print "the east"; return; se_to, se_obj: print "the south-east"; return; s_to, s_obj: print "the south"; return; sw_to, sw_obj: print "the south-west"; return; w_to, w_obj: print "the west"; return; nw_to, nw_obj: print "the north-west"; return; u_to, u_obj: print "above you"; return; d_to, d_obj: print "below you"; return; in_to, in_obj: print "the inside"; return; out_to, out_obj: print "the outside"; return; } ! else switch (metaclass(val)) { Object: print_ret (name)val; Routine: val(); String: print_ret (string)val; } ]; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Rooms !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Object FirstRoom "The First Room" with description "East to the next room. Here, you may interact with an NPC.", e_to SecondRoom, has light; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Object SecondRoom "The Second Room" with description "West to the previous room, east to the next room. Here, you may watch an NPC interact with a monitor. ", w_to FirstRoom, e_to ThirdRoom, has light; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Object ThirdRoom "The Third Room" with description "West to the previous room, east to the next room. Here, you may watch two NPCs interact with each other. ", w_to SecondRoom, e_to FourthRoom, has light ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Object FourthRoom "The Fourth Room" with description "West to the previous room, east to the next room. North and south lead to travelable NPC rooms (a simple maze). Here, you may watch an NPC move about on its own. ", w_to ThirdRoom, e_to FifthRoom, n_to Wander1Room, s_to Wander4Room, has light general ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Object FifthRoom "The Fifth Room" with description "West to the previous room. There are signs of heavy construction in this room, but apparently you will soon be able to watch three NPCs interact here. ", w_to FourthRoom, has light ; Class WanderRoom with description [ _dir _next; objectloop (_dir in compass) { if (self provides _dir.door_dir) { _next = self.(_dir.door_dir); if (_next ~= null) { print "To ",(print_dir)_dir," is ", (name)_next,". "; } } } print "This area has a wandering NPC.^^"; ! Cheat print "[Help: ~",(name)Sammy,"~ is in ~",(name)parent(Sammy),"~.]^"; rtrue; ], has light general ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander1Room "Wander Maze 1" with s_to FourthRoom, n_to Wander2Room, w_to Wander5Room, e_to Wander5Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander2Room "Wander Maze 2" with s_to Wander1Room, n_to Wander3Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander3Room "Wander Maze 3" with s_to Wander2Room, n_to Wander4Room, w_to Wander7Room, e_to Wander7Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander4Room "Wander Maze 4" with s_to Wander3Room, n_to FourthRoom, w_to Wander6Room, e_to Wander6Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander5Room "Wander Maze 5" with s_to Wander6Room, n_to Wander7Room, w_to Wander1Room, e_to Wander1Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander6Room "Wander Maze 6" with s_to Wander7Room, n_to Wander5Room, w_to Wander4Room, e_to Wander4Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WanderRoom Wander7Room "Wander Maze 7" with s_to Wander5Room, n_to Wander6Room, w_to Wander3Room, e_to Wander3Room, ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Objects !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Object FlowerPot "flower pot" FirstRoom with name 'flower' 'pot', description "A simple flower arrangement in a decorative pot.", has ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Change the TV so it actually registers actions, not ! just displaying text. NpcAct_Monitor TV "television" SecondRoom with name 'television' 'tele' 'tv', description [; print "A television which may be turned off and on (on == interact w/ character). On, it will interrupt the character's speech."; if (self has on) { " ",(The)self," is on, screaming with noise."; } " ",(The)self," appears to be off."; ], npcact_Before [ _actionList ! parameters _action; ! locals _action = _actionList.npcact_CurrentAction(); switch( _action.npcact_verb ) { ##Answer: if (self has on) { _actionList.npcact_Cancel(); } ##Switchon: if (self has on) { _actionList.npcact_Cancel(); } rtrue; ##Switchoff: if (self hasnt on) { _actionList.npcact_Cancel(); } rtrue; } rfalse; ], npcact_Canceled [ _actionList ! parameters _action; ! locals _action = _actionList.npcact_CurrentAction(); switch( _action.npcact_verb ) { ##Answer: if (_action.npcact_PlayerInScope()) { "You can tell that ",(the)_action.npcact_source, " is trying to speak, but the TV's deafening screech kills all sound around it."; } ##Switchon: if (_action.npcact_PlayerInScope()) { "The TV is already on."; } ##Switchoff: if (_action.npcact_PlayerInScope()) { "The TV is already off."; } } ], npcact_After [ _actionList ! parameters _action; ! locals _action = _actionList.npcact_CurrentAction(); switch( _action.npcact_verb ) { ##Switchon: give self on; if (_action.npcact_PlayerInScope()) { "The TV turns on, blasting the air around it with a deadening screech."; } ##Switchoff: give self ~on; if (_action.npcact_PlayerInScope()) { "The TV turns off, releaving everyone of its horrific noise."; } } ], has static ~on; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! NPCs !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NpcAct_Character Aaron "Aaron" FirstRoom with name 'aaron', npcact_Turn [ _actionList; if (parent( FlowerPot ) == self) { AaronAction.npcact_Construct( DropObject ); } else { AaronAction.npcact_Construct( GetObject ); } AaronAction.npcact_Setup( FlowerPot ); AaronAction.npcact_SetupSay( ReportOnFlowerPot, Aaron_okSay ); _actionList.npcact_Register( AaronAction ); ], has proper male; ActionAndSayTopic AaronAction "Aaron Action" Aaron; [ Aaron_okSay _source _topic; "",(The)Aaron," gleefully reports, ~Gee, that was fun!~"; ]; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NpcAct_Character Wanda "Wanda" SecondRoom with name 'wanda', npcact_Turn [ _actionList _topic; WandaAction.npcact_Construct( SayTopic ); switch (random( 3 )) { 1: _topic = Wanda1; 2: _topic = Wanda2; 3: _topic = Wanda3; } WandaAction.npcact_Setup( _topic, Wanda_Say ); _actionList.npcact_Register( WandaAction ); ], has proper female; NpcAct_Action WandaAction "Wanda Action" Wanda; [ Wanda_Say _source _topic; "",(The)_source," mutters, ~",(name)_topic,"~"; ]; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Two arguing spouses - uses an extention to the SayTopic / Topic ! stuff above to create a conversation graph. ! - doesn't have general if the topic is interruptable. Class ArgueTopic class Topic with tellTo nothing, responses nothing, ; [ ArgueSay _source _topic most; most = 8; if (_topic.tellTo == nothing) most = 5; switch (random( most )) { 1: print "In a fit of rage, ",(the)_source," yells, "; 2: print "Frustrated and anguished, ",(the)_source," sighs. "; 3: print (The)_source," bursts out with, "; 4: print (The)_source," says, "; 5: print (The)_source," screams, "; 6: print (The)_source," screams back at ",(the)_topic.tellTo,", "; 7: print (The)_source,", reeling back from the viscious assault, whimpers, "; 8: print "Angry at ",(the)_topic.tellTo,", ",(the)_source," replies, "; } "~",(name)_topic,"~"; ]; Class ArguingCharacter class NpcAct_CharacterMonitor with npcact_Turn [ _actionList _topic; !print "[Argue: ~",(name)self,"~ start turn.]^"; if (self.__discoverConstructAction() ~= nothing) { !print "[Argue: ~",(name)self,"~ turn: performing an action.]^"; _actionList.npcact_Register( self.__getAction() ); self.__lastTopic = nothing; self.__turnNumber = -1; } ], npcact_Before [ _actionList _action; _action = _actionList.npcact_CurrentAction(); if (_action.npcact_source == self or player) rfalse; switch (_action.npcact_verb) { ##Answer: self.__lastTopic = _action.npcact_noun; self.__turnNumber = turns; !print "[Argue: ~",(name)self,"~ last topic = ",(name)_action.npcact_noun,".]^"; if (self.__lastTopic hasnt general && self.npcact__action == nothing) { if (self.__discoverConstructAction() ~= nothing) { _actionList.npcact_Cancel(); _actionList.npcact_RegisterAfter( self.__getAction() ); } self.__lastTopic = nothing; self.__turnNumber = -1; } } rfalse; ], ! npcact_Canceled ! npcact_After __lastTopic nothing, firstTopic nothing, __turnNumber -1, __getAction [; return child( self ); ], __discoverConstructAction [ _topic _action _val; _topic = nothing; _action = self.__getAction(); if (self.__lastTopic == nothing) { if (self.firstTopic ~= nothing && self hasnt general) { !print "[Argue: ~",(name)self,"~ last topic = nothing, first topic isn't nothing, and haven't general.]^"; _topic = self.firstTopic; give self general; } } else if (self.__turnNumber > 0 && self.__turnNumber < turns) { _val = random( (self.__lastTopic.#responses / 2) ) - 1; !print "[Argue: ~",(name)self,"~ getting topic: # responses = ",(self.__lastTopic.#responses / 2),", index = ",_val,".]^"; _topic = self.__lastTopic.&responses-->_val; !print "[Argue: Got topic ",(name)_topic," from index ",_val," of ",(name)self.__lastTopic,".]^"; } if (_topic ~= nothing) { !print "[Argue: Constructing topic.]^"; _action.npcact_Construct( SayTopic ); _action.npcact_Setup( _topic, ArgueSay ); } return _topic; ], has proper; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArgueTopic Jimmy1 "Why did you do it?" with tellTo Kathy, responses Kathy2a Kathy2b Kathy4b; ArgueTopic Kathy2a "I hate you! That's why." with tellTo Jimmy, responses Jimmy3a Jimmy3b; ArgueTopic Kathy2b "You just haven't given me any attention lately." with tellTo Jimmy, responses Jimmy3b Jimmy3c; ArgueTopic Jimmy3a "Get a grip! This isn't funny." with tellTo Kathy, responses Kathy4a Kathy4b; ArgueTopic Jimmy3b "Darling, don't say such things." with tellTo Kathy, responses Kathy4a Kathy4b; ArgueTopic Jimmy3c "You aren't telling me what you need." with tellTo Kathy, responses Kathy4a Kathy4b; ArgueTopic Kathy4a "Why don't you just leave me alone?" with tellTo Jimmy, responses Jimmy5a Jimmy5a; ArgueTopic Kathy4b "I'm going to mother's." with tellTo Jimmy, responses Jimmy3a Jimmy3a; ArgueTopic Jimmy5a "I have needs, too. Why don't you care about me?" with tellTo Kathy, responses Kathy2a Kathy2a; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArguingCharacter Jimmy "Jimmy" ThirdRoom with name 'jimmy' 'jim', firstTopic Jimmy1, has proper male; NpcAct_Action JimmyAction Jimmy; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArguingCharacter Kathy "Kathy" ThirdRoom with name 'kathy' 'k//', has proper female; NpcAct_Action KathyAction Kathy; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NpcAct_CharacterMonitor Sammy "Sammy" FourthRoom with name 'sammy', npcact_Turn [ _actionList _dir _chance _total _i _x; if (self.npcact__action ~= nothing) return; !!!!!!!!!!!!!!!!!!!! ! Wander ! Find the total chance to find a direction _total = 0; objectloop (_x in Compass) { if (self.__isExit( _x )) { ++_total; } } if (_total > 0) { _chance = random( _total ); _i = 0; objectloop( _x in Compass ) { if (self.__isExit( _x )) { ++_i; if (_i == _chance) { ! found the exit! SammyAction.npcact_Construct( GoDirection ); SammyAction.npcact_Setup( _x ); _actionList.npcact_Register( SammyAction ); return; } } } } ! error? couldn't find a way out! SammyAction.npcact_Construct( SayTopic ); SammyAction.npcact_Setup( ReportOnFlowerPot, SammyConfused ); _actionList.npcact_Register( SammyAction ); ], npcact_Before [ _actionList ! parameters _action _currentRoom _dir; ! locals _action = _actionList.npcact_CurrentAction(); !print "[Action: ",(name)_action,", source = ",(name)_action.npcact_source,"]^"; if (_action.npcact_actor == self && _action.npcact_source ~= self) { ! prevent the order, as we're already doing something if (self.npcact__action ~= nothing) { !print "[Sammy: actor = self, but already acting. aborting before.]^"; rfalse; } switch (_action.npcact_verb) { ##Go: if (self.__isExit( _action.npcact_noun )) { SammyAction.npcact_Construct( GoDirection ); SammyAction.npcact_Setup( _action.npcact_noun ); } else { ! else direction is bad SammyAction.npcact_Construct( SayTopic ); SammyAction.npcact_Setup( ReportOnFlowerPot, SammyConfused ); } _actionList.npcact_RegisterAfter( SammyAction ); !print "[Sammy: actor = self, performing action.]^"; rtrue; } } ! else !print "[Sammy: actor = self, ignoring before.]^"; rfalse; ], __isExit [ _compDir _dir _currentRoom; _currentRoom = parent( self ); !print "[Sammy: compass dir = ",(name)_compDir,", door_to = ",_compDir.(door_dir), !", current room = ",(name)_currentRoom,".]^"; !print "[General: n_to = ",n_to,", door_to = ",door_dir,".]^"; if (_currentRoom provides (_compDir.door_dir)) { _dir = _currentRoom.(_compDir.door_dir); if (_dir ~= nothing && metaclass(_dir) ~= String) { if (metaclass(_dir) == Routine) { _dir = _currentRoom._dir(); } ! only move to a spot that has the general flag!! if (_dir ~= nothing && _dir has general) { rtrue; } } } rfalse; ], npcact_GoAwayMessage [ _dir; "",(The)self," skips away to ",(print_dir)_dir,".^"; ], npcact_ArriveMessage [ _dir; "",(The)self," bounces from ",(print_dir)_dir,", whistling a happy tune.^"; ], has proper female; ActionAndSayTopic SammyAction Sammy; [ SammyConfused _source _topic; "",(The)_source," sits down and begins to cry."; ]; !---------------------------------------------- ! Vague grammar opperations !---------------------------------------------- [ VagueAskSub x y z; ! locals x = nothing; y = nothing; z = 0; objectloop( x in location ) { if (x == Player) { continue; } if (x has animate or talkable) { if (y ~= nothing) { if (z == 0) { print "Who do you want to ask? ", (name)y; z = 1; } print " or ",(name)x; } else { y = x; } } } if (z > 0) { "?"; } else if (y == nothing) { "There's no one around to ask that."; } else { print "(ask ", (the)y, ")^"; <>; } ]; [ VagueConsultSub x y z; ! locals x = nothing; y = nothing; z = 0; objectloop( x in location ) { if (x == Player) { continue; } if (x has animate or talkable) { if (y ~= nothing) { if (z == 0) { print "Whhat do you want to consult? ", (name)y; z = 1; } print " or ",(name)x; } else { y = x; } } } if (z > 0) { "?"; } else if (y == nothing) { "There's nothing around to consult on that."; } else { print "(consult ", (the)y, ")^"; <>; } ]; !!---------------------------------------------------- !! Include Grammar !!---------------------------------------------------- Include "Grammar"; Verb 'what' * 'about'/'is' topic -> VagueAsk; Verb 'why' * topic -> VagueAsk * 'is' topic -> VagueAsk; Extend 'ask' first * 'about' topic -> VagueAsk; Extend 'consult' first * 'about' topic -> VagueConsult;