!---------------------------------------------------------------------------- ! ! NPC_ENGINE DEMO STORY ! ! ! Copyright (c) 1999, 2000 Volker Lanz. ! ! ! With material from: ! ! INTRUDER ! Interactive Fiction: A Burglary ! Copyright 1998, 1999 by Volker Lanz. ! Release 59 Interpreter 6 Version F Serial Number 990210 ! ! Also see the Deadline Inform version found on ftp.gmd.de/if-archive for ! a more complex game using the NPC Engine. ! !---------------------------------------------------------------------------- !---------------------------------------------------------------------------- ! C O N S T A N T S !---------------------------------------------------------------------------- Constant Story "NPC ENGINE DEMO STORY"; Constant Headline "^using rooms from Intruder r59s990210 ^with apologies to Graham Nelson, Marc, Mike and Dave (who?) ^Copyright (c) 1999, 2000 by Volker Lanz. May be distributed and copied freely.^"; Constant DEBUG; ! Comment out the following line if you want to use the old style path ! finding; using Subway move type in this demo game doesn't really make ! sense, since it is way too small to benefit from it, so this is merely ! for demonstrational purposes. Constant SUBWAY_MOVE_TYPE; Release 17; Statusline time; !---------------------------------------------------------------------------- ! I N C L U D E S !---------------------------------------------------------------------------- Include "Parser.h"; Include "VerbLib.h"; Include "NPC_ENGINE.h"; !---------------------------------------------------------------------------- ! R E P L A C E S !---------------------------------------------------------------------------- Replace BeforeParsing; !------------------------------------------------------------------------------ ! B E F O R E P A R S I N G !------------------------------------------------------------------------------ [ BeforeParsing flag i p1 p2 p3; for(i = 4: i <= buffer->1 + 1: i++) if (buffer->i == '.') { p3 = buffer->(i-1); p2 = buffer->(i-2); if (i > 4) p1 = buffer->(i-3); else p1 = 0; if ((p1 == 'm' && p2 == 'r' && p3 == 's') || (p2 == 'm' && p3 == 'r') || (p2 == 'm' && p3 == 's')) { buffer->i = ' '; flag = 1; } } else if (buffer->i == '!' or '?' or '"') { buffer->i = ' '; flag = 1; } if (flag) @tokenise buffer parse; ]; !---------------------------------------------------------------------------- ! C L A S S E S !---------------------------------------------------------------------------- Class Door_Class with npc_open [npc; if (self hasnt locked) { npc.npc_door_passed = self; give self open; StartTimer(self, 2+random(2)); rtrue; } rfalse; ], time_left, time_out [; if (self hasnt open) rfalse; give self ~open; if (TestScope(self)) print_ret (The) self, " suddenly closes as if moved by an invisible hand."; ], has scenery door openable; Class NPC_Class class NPC_Engine with before [d; if (action ~= ##Hello or ##NPC_WaitFor && self notin location) { d = NPC_CheckVisible(ScopeCeiling(self)); print_ret (The) self, " ", (isorare) self, " too far away to ", (LeaveToDir) d, "."; } Hello: self.npc_stopped = 3; d = NPC_CheckVisible(ScopeCeiling(self)); print (The) self; if (ScopeCeiling(self) == location) " ", (isorare) self, " facing you."; ", off towards ", (LeaveToDir) d, ", ", (isorare) self, " turning towards you."; Kiss: "Now, now! Don't let your fanatic worship get out of hand!"; ], life [; if (self notin location) print_ret (The) self, " can't seem to hear you."; self.npc_stopped = 2; Ask: "~", (CIorWe) self, " don't know much about that.~"; ], orders [; Hello: << Hello self >>; ], has proper; Class Ground_Floor class NPC_Room has light npc_goto; Class Outside class NPC_Room has light; !---------------------------------------------------------------------------- ! R O O M S !---------------------------------------------------------------------------- Ground_Floor Foyer "Foyer" with name 'foyer', description [; "This is the foyer of the summer house. It's quite unpretentiously furnished, with only a wardrobe and a small sofa next to it. The corridor continues westward, the front door, closed at the moment, is to the east of you. You can see the staircase to the north and another door, which is ", (OpenOrClosed) Children_Bedroom_Door, ", leads to the children's bedroom to the south."; ], npc_subway red_line blue_line, e_to "In this demo game, there is no front door.", w_to Ground_Hallway_1, s_to Children_Bedroom_Door, n_to Top_Of_Stairs; Door_Class Children_Bedroom_Door "bedroom door" with name 'bedroom' 'door', door_to [; if (self in Foyer) return Children_Bedroom; return Foyer; ], door_dir [; if (location == Foyer) ! This is bad style, nevertheless it works with the NPC Engine return s_to; return n_to; ], found_in Foyer Children_Bedroom, with_key Small_Key, has lockable; Ground_Floor Ground_Hallway_1 "Centre Hallway" with description "You are the middle of the hallway running from east to west. Open doorways lead to the dining room to the north and the living room to the south of you.", npc_subway blue_line pink_line, e_to Foyer, w_to Ground_Hallway_2, n_to Dining_Room, s_to Living_Room; Ground_Floor Ground_Hallway_2 "Hallway" with description "At the west end of the ground floor hallway, a door leads out to the terrace. This door is closed right now. An open passage to the north leads to the kitchen and another door, currently open, leads to the master bedroom to the south.", npc_subway blue_line green_line, e_to Ground_Hallway_1, n_to Kitchen, s_to Master_Bedroom, w_to Terrace; Ground_Floor Top_Of_Stairs "Top of Stairs" with description "You find yourself on top of a wooden staircase which leads down to the basement of the house. Above the staircase is a small closed window in the east wall. The foyer, not as spooky as the basement, is to the south.", npc_subway red_line, d_to "You can't enter the basement in this demo game.", s_to Foyer; Ground_Floor Children_Bedroom "Children's Bedroom" with name 'children^s' 'bedroom', description [; "Furnished in a simple but tasteful style, this room is a typical children's bedroom. There are two beds, one on each side, a big wardrobe, shelves piled with all sorts of things and numerous toys scattered on the floor. The bedroom door to the north is ", (OpenOrClosed) Children_Bedroom_Door, ". Another doorway to the west leads to the bathroom."; ], npc_subway red_line, n_to Children_Bedroom_Door, w_to Children_Bathroom; Ground_Floor Children_Bathroom "Children's Bathroom" with name 'children^s' 'bathroom', description "A rather small bathroom, usually used by the Kelly children (that is, unless there aren't any strangers rummaging about in it). There is both a shower and a bath tub on the north wall. Shelves filled with the usual stuff found in all bathrooms around the world are attached to the south wall. Above the shelves a small window can be seen, which is closed. On the east wall there is a sink with a large mirror above it. You can get back to the bedroom to the east.", npc_subway red_line, e_to Children_Bedroom; Ground_Floor Dining_Room "Dining Room" with name 'dining' 'room', description "This room is rather small, has a table seating six in the centre, and a window in the north wall lets in the faint moonlight. Some paintings on the east wall, apparently by local artists and all originals, give the room more of a cheerful atmosphere. Open doorways to the west and south lead out of here.", npc_subway green_line pink_line, s_to Ground_Hallway_1, w_to Kitchen; Ground_Floor Living_Room "Living Room" with name 'living' 'room', description "You have entered the living room. In its centre, a large coffee table with eight chairs around shows that guests are welcome here (this, however, may not necessarily apply to you). A leather sofa with a small side table also adds to the impression of a comfortable place. Above the sofa and a wooden cabinet, a collection of silver, golden and platinum records covers the wall, displaying the success of the house owner in quite an impressive manner. The most prominent feature of this room, however, resides beneath a large window in the south wall that looks onto the dark garden: An original Steinway grand piano. An open doorway to the north leads to the corridor.", npc_subway pink_line, n_to Ground_Hallway_1; Ground_Floor Kitchen "Kitchen" with name 'kitchen', description "The kitchen of the house has been furnished with an eye more for utility than beauty. It has all the usual tools and appliances: Refrigerator, microwave oven, shelves, cabinets with china, some drawers and more. There are two open doorways here: The one in the south wall leads to the corridor and the other, in the east, to the dining room. Next to the latter, a kitchen clock is affixed to the wall.", npc_subway green_line, e_to Dining_Room, s_to Ground_Hallway_2; Ground_Floor Master_Bedroom "Master Bedroom" with name 'master' 'bedroom', description "You are now in the master bedroom, a place where one can quite easily feel comfortable. It's tastefully furnished, with a large double size bed in the centre, small tables on each side. There are dressers, there is an expensively looking carpet on the floor, there is a large mirror on the east wall next to a door to the master bathroom, which is open. A window to the south would let the daylight in if it wasn't dark outside and a door, currently open, leads north to the corridor.", npc_subway green_line, n_to Ground_Hallway_2, e_to Master_Bathroom; Ground_Floor Master_Bathroom "Master Bathroom" with name 'master' 'bathroom', description "This beautifully ornated bathroom is decorated with all possible signs of taste and wealth. Its most prominent feature is probably the large bath-tub in the middle of the room. Further, there are two large sinks, a shower, various shelves and closets and a small window far above the ground in the south wall. You can get back to the bedroom through a doorway to the west.", npc_subway green_line, w_to Master_Bedroom; Outside South_Of_House "South of House" with description "Here you are at the south side of the house. A path leads to the terrace to the west and to the south of the front door to the east. You can see a few small and one large window. They are all closed and locked from the inside.", npc_subway blue_line, w_to South_Of_Terrace; Object -> Windows "window" with name 'small' 'large' 'window' 'windows', before [; Search: if (self in Living_Room) "You can only see the dark garden outside."; NPC_LookThroughWindow(self); "You can see the living room and the area beyond in the house."; ], door_to Living_Room, door_dir n_to, looks_to Living_Room Ground_Hallway_1 Dining_Room, found_in South_Of_House Living_Room, has scenery; Outside Terrace "Terrace" with description "During daytime, this terrace between house and beach is probably used for sunbathing. At the moment, though, this isn't possible due to lack of sunlight. Three steps lead up to a glass door into the house east of you. The door is currently open. You can go west to the beach or walk north or south to get around the house.", npc_subway blue_line, s_to South_Of_Terrace, e_to Ground_Hallway_2; Outside South_Of_Terrace "South of Terrace" with description "The stone path you're on bends around the house to the north and east here. The sun terrace is to the north and the south side of the house to the east. Dunes to the west block the view of the ocean.", npc_subway blue_line, n_to Terrace, e_to South_Of_House; !---------------------------------------------------------------------------- ! N P C s !---------------------------------------------------------------------------- NPC_Class Duffy "Sgt. Duffy" Dining_Room with name 'sgt' 'sergeant' 'duffy', orders [; Follow: if (noun == player) { if (self.npc_move_type == 5) "~I'm already following you!~"; NPC_FollowPlayer(self); "~Alright, I'll follow you!~"; } StayHere: NPC_StopFollowPlayer(self); "~Okay, no problem. I'll stay right where I am.~"; ]; NPC_Class Marc "Marc" Living_Room with name 'marc', react_after [; Unlock: if (self in Children_Bedroom && noun == Children_Bedroom_Door) { NPC_Path(self, Living_Room); if (self has general) { give self ~general; "~At last!~ Marc exclaims."; } } ], npc_arrived [r; switch(r) { Dining_Room: NPC_Schedule(self, Children_Bedroom, 3); Children_Bedroom: NPC_Schedule(self, Living_Room, 4); Living_Room: NPC_Schedule(self, Dining_Room, 3); default: "*** Oops: ", (name) self, " arrived somewhere he shouldn't."; } ], npc_path_blocked [src dest door; src = dest = door; NPC_Path(self, Living_Room); if (~~ TestScope(self)) rfalse; if (self in Children_Bedroom) { ! Indicating he tried to leave the bedroom give self general; NPC_Schedule(self, Living_Room, 5+random(5)); if (self in location) "Marc tries to open the bedroom door and finds it locked. He turns towards you. ~Would you mind unlocking this door?~"; "Through the doorway, you can see Marc trying to open the bedroom door. He finds it locked, turns around and shakes his head slowly."; } if (self in location) "~Hmmm~, you hear Marc mumble. ~Wonder who of those idiots locked this door?~ He grimaces and looks around, until he spots you. With a sigh, he turns away from you."; "Down the hall you can see Marc trying to open the door to the children's bedroom. When he finds it locked, he shakes his head, then turns around."; ]; NPC_Class Dave "Dave" Top_Of_Stairs with name 'dave' 'david', npc_arrived [r; switch(r) { Dining_Room: NPC_Schedule(self, Children_Bathroom, 3+random(7)); Children_Bathroom: NPC_Schedule(self, Ground_Hallway_2, 3+random(7)); Ground_Hallway_2: NPC_Schedule(self, Top_Of_Stairs, 3+random(7)); Top_Of_Stairs: NPC_Schedule(self, Dining_Room, 3+random(7)); default: "*** Oops: ", (name) self, " arrived somewhere he shouldn't."; } ]; NPC_Class Mike "Mike" Master_Bedroom with name 'mike', npc_arrived [r; switch(r) { Children_Bedroom: NPC_Schedule(self, Kitchen, 5+random(5)); Kitchen: NPC_Schedule(self, Living_Room, 5+random(5)); Living_Room: NPC_Schedule(self, Master_Bedroom, 5+random(5)); Master_Bedroom: NPC_Schedule(self, Children_Bedroom, 5+random(5)); default: "*** Oops: ", (name) self, " arrived somewhere he shouldn't."; } ]; !---------------------------------------------------------------------------- ! O T H E R O B J E C T S !---------------------------------------------------------------------------- Object Small_Key "small brass key" with description "This key fits the lock of the children's bedroom door.", name 'small' 'brass' 'key'; !---------------------------------------------------------------------------- ! V E R B S !---------------------------------------------------------------------------- [ HelloSub; if (~~noun) "Good day."; "You can't say hello to ", (a) noun, "."; ]; [ StayHereSub; "As long as you want to!"; ]; !---------------------------------------------------------------------------- ! R O U T I N E S !---------------------------------------------------------------------------- [ OpenOrClosed d; if (d has open) print "open"; else print "closed"; ]; !---------------------------------------------------------------------------- ! I N I T I A L I S E !---------------------------------------------------------------------------- [ Initialise x; ! Calling NPC_Initialise() to set up the NPC Engine NPC_Initialise(); SetTime(60*23+15, 1); location = Dining_Room; ! Starting first movements x = npc_first_npc; while(x) { x.npc_arrived(ScopeCeiling(x)); x = x.npc_next; } ! Give the player a key for the children's bedroom door move Small_Key to player; "^^Days of searching, days of thirsty hacking through the briars of the Inform manual, but at last your patience was rewarded. A discovery - living creatures!^"; ]; !---------------------------------------------------------------------------- ! F I N A L I N C L U D E S !---------------------------------------------------------------------------- Include "Grammar"; Include "npc_wait.h"; !---------------------------------------------------------------------------- ! V E R B D E F I N I T I O N S !---------------------------------------------------------------------------- Verb 'hello' 'hi' 'hey' * -> Hello * noun -> Hello; Verb 'stay' * -> StayHere * 'here' -> StayHere; Extend 'go' * 'to' scope=NPC_Goto_Scope -> NPC_Goto; !---------------------------------------------------------------------------- ! E N D O F F I L E !---------------------------------------------------------------------------- end;