!------------------------------------------------------------------ ! Compass Spin ! Brian D. Smith ! ---------------------------------------------------------------------- ! This little program is the result of my work at porting the game ! "Battlestar" to Inform. For those of you who don't know, Battlestar uses ! the directions "ahead", "behind", "left", and "right" for most game ! movement. Movement in compass directions is impossible without a compass, ! which turns up later on in the game. Room descriptions also use this ahead, ! behind, etc. description style, and, obviously these change as the player ! moves about. ! ! After some experimentation, I have a workable method of doing this, ! although it could probably be neater. ! ! I freely give this code to whoever wants it, and ask only that you use it ! in a good game for the entertainment of us all. ! ! -- BDS 22/11/97 ! ---------------------------------------------------------------------- Switches dsv5; Constant Story "Compass Spin"; Constant Headline "^An Experiment in Low Strings and Relative Directions^ By Brian D. Smith^"; Constant Object_Score 5; Constant Max_score 10; Include "Parser"; Include "Verblib"; Global Facing = n_to; ! Start off facing north, for no real reason. ! Define some low strings for direction names. Lowstring Ahead_str "ahead"; ! The original Battlestar alternates between using "behind you" and "back", ! so I have included, and used both. Lowstring Behind_str "behind you"; Lowstring Back_str "back"; Lowstring Left_str "left"; Lowstring Right_str "right"; Lowstring n_str "north"; Lowstring e_str "east"; Lowstring s_str "south"; Lowstring w_str "west"; ! The pattern of string assignments: ! @01: north ! @02: south ! @03: east ! @04: west ! @05 through @08 are identical to @01 through @04, with the exception that ! the behind player direction becomes "back", rather than "behind you". This ! has been done to prevent some very silly sounding text such as: ! "In the window back you can see...", or ! "There are no exits except the way you came in. Better go behind you." ! Set the strings to give cardinal directions when the player has a compass. [ CompassDirs; string 1 n_str; ! north string 2 s_str; ! south string 3 e_str; ! east string 4 w_str; ! west string 5 n_str; ! north string 6 s_str; ! south string 7 e_str; ! east string 8 w_str; ! west ]; ! When the player faces north, these are the settings. [ Face_North; string 1 Ahead_str; ! north string 2 Behind_str; ! south string 3 Right_str; ! east string 4 Left_str; ! west string 5 Ahead_str; ! north string 6 Back_str; ! south string 7 Right_str; ! east string 8 Left_str; ! west ]; [ Face_East; string 1 Left_str; ! north string 2 Right_str; ! south string 3 Ahead_str; ! east string 4 Behind_str; ! west string 5 Left_str; ! north string 6 Right_str; ! south string 7 Ahead_str; ! east string 8 Back_str; ! west ]; [ Face_South; string 1 Behind_str; ! north string 2 Ahead_str; ! south string 3 Left_str; ! east string 4 Right_str; ! west string 5 Back_str; ! north string 6 Ahead_str; ! south string 7 Left_str; ! east string 8 Right_str; ! west ]; [ Face_West; string 1 Right_str; ! north string 2 Left_str; ! south string 3 Behind_str; ! east string 4 Ahead_str; ! west string 5 Right_str; ! north string 6 Left_str; ! south string 7 Back_str; ! east string 8 Ahead_str; ! west ]; ! Set the direction strings, depending on which way the player is facing. [ SetDirStrs; switch( Facing ) { n_to: Face_North(); e_to: Face_East(); s_to: Face_South(); w_to: Face_West(); } ]; [ SetRelDir aobj robj bobj lobj; Facing = aobj; a_obj.door_dir = aobj; b_obj.door_dir = bobj; l_obj.door_dir = lobj; r_obj.door_dir = robj; ]; [ GetDir dir; if ( dir==0 ) dir=n_to; ! Default the player direction to north. switch( dir ) { ! Look at the direction n_to, u_to, d_to: SetRelDir( n_to, e_to, s_to, w_to ); e_to: SetRelDir( e_to, s_to, w_to, n_to ); s_to: SetRelDir( s_to, w_to, n_to, e_to ); w_to: SetRelDir( w_to, n_to, e_to, s_to ); } if ( MyCompass notin player ) SetDirStrs(); ]; ! Here's what happens when the player enters a new room: ! 1: Facing is set to the direction the player is facing by a call to GetDir. ! 2: If the player is not carrying a compass, set the escape strings properly. ! 3: Other tasks, like scoring, take place. [ NewRoom; if ( noun in compass ) GetDir( noun.door_dir ); ]; ! Put the relative direction objects in the compass. CompassDirection A_obj "ahead" compass with name 'wall' 'a//' 'ahead', door_dir 0; CompassDirection B_Obj "back" compass with name 'b//' 'back' 'wall' 'behind', door_dir 0; CompassDirection L_Obj "left" compass with name 'left' 'wall', door_dir 0; CompassDirection R_Obj "right" compass with name 'r//' 'right' 'wall', door_dir 0; ! This game removes the normal cardinal directions from play, restoring them ! only when the player has a compass. This is not necessary. [ Initialise; location = Room1; remove n_obj; remove ne_obj; remove e_obj; remove se_obj; remove s_obj; remove sw_obj; remove w_obj; remove nw_obj; give player light; ! Saves typing new_line; new_line; LMode2Sub(); ! Verbose GetDir( n_to ); SetDirStrs(); "^^^Oh, my head! Where am I? Oh blast! I dropped my compass, and I have no sense of direction without it...^^^ To face a different direction, type ~face dir~, eg, ~face left~.^^^"; ]; Object Fragment "code fragments" with name 'fragment' 'fragments' 'code' 'codes' 'program' 'programs', initial "The ground is littered with code fragments.", description "They are all parts of a game called Battlestar.", found_in Room1 Room2 Room3 Room4 Room5 Room6 Room7, before [ ; Take: "They sift through your fingers."; ], has pluralname static; Object Room1 "Room #1" with n_to Room2, e_to Room3, w_to Room4, description "You are in room #1. Room #2 is @01, Room #3 is @03, and Room #4 is @04.", ; Object Room2 "Room #2" with s_to Room1, e_to Room5, description "This is Room #2. Room #1 is @02. There is another room @03.", ; Object Room3 "Room #3" with w_to Room1, n_to Room5, description "You are now in Room #3. Your starting room is @04, and @01 is Room #5."; Object Room4 "Room #4" with description [; if ( nw_obj in compass ) "You see two exits from this room, one to the northwest, the other @07."; "It's a dead end. You can only go @07."; ], e_to Room1, nw_to Room9; ! The exit to Room9 can be safely defined, since the player can't ! go that way until after gaining the compass. Object Room5 "Room #5" with d_to Room6, u_to Room7, w_to Room2, s_to Room3, description "You are in a small landing on a flight of spiral stairs. You can go up and down from here. Rooms open @04 and @02."; Object Room6 "Room #6" with u_to Room5, s_to Room8, description "You are at the bottom of a flight of stairs. There is a small closet @02."; ! Room #7 shows the problems with relative vs. real directions. Visit this ! room, and face different directions in it. Then return with the compass, ! and read the description. Object Room7 "Room #7" with name 'windows' 'ocean' 'mountain' 'mountains' 'sun' 'valley' 'window', d_to Room5, e_to Chute, description "This is the top of a great tower. Large windows allow a panoramic view of the surroundings. Great mountains lie off in the distance @01, the windows @03 show a verdant valley, the windows @02 show a heaving ocean, and in the windows @04 the sun sets majestically. You can go back down the stairs."; Object -> Stone "small stone" with name 'stone' 'small' 'rock' 'jagged' 'sharp' 'pebble', initial "A piece of the stone floor has come loose, and lies at your feet.", description "It's a jagged piece of stone, about half an inch long.", ; Object -> Chute "long chute" has static door open container, with name "chute" "slide" "long" "metal", initial "There is also a long, metal slide @07.", description "Long, dark, and cold, the chute descends in a long slide.", after [; Receive: move noun to Room8; print_ret (The) noun, " slides away down the chute."; ], door_dir e_to, door_to [; print "Wheeeeeeeeeeeeeeeeeeeeeeeeeeeeeee!!!!^^ You slide down the chute completely out of control, until you land with a thump at the bottom."; GetDir( random( n_to, e_to, s_to, w_to ) ); return Room8; ], ; Object Room8 "Way Out" with n_to Room6, s_to "Your way is blocked by a program crash. Go @05.", description "This is the way into the rest of the game. Unfortunately, it has been blocked by a recent program crash. You can only go @05."; Object -> MyCompass "compass" with name "compass" "my", initial "Hey! Here's my compass.", description "This is my adventure compass. Without it, I'm totally lost.", after [; Take: CompassDirs(); move n_obj to compass; move e_obj to compass; move s_obj to compass; move w_obj to compass; move ne_obj to compass; move se_obj to compass; move sw_obj to compass; move nw_obj to compass; "Now I know which direction is which."; Insert, Drop: SetDirStrs(); remove n_obj; remove e_obj; remove s_obj; remove w_obj; remove ne_obj; remove se_obj; remove sw_obj; remove nw_obj; print "I'm facing north, or is that east... No, no, it was s-- Blast, I've lost my sense of direction again."; if ( second ~= nothing ) { print " "; rfalse; } new_line; rtrue; ], has scored; Object -> Fragment2 "code fragment" with name 'code' 'program' 'fragment', initial "A fragment from the crashed program is here.", description "This seems to be part of the game's internal map structure. More specifically, it is of this tower, and shows a second exit from Room #4, to the northwest."; Object Room9 "Real Exit" with description [; deadflag=2; score = score + 5; "You enter the new room, which you couldn't get in to without a compass. A sense of great achievement fills your being, as your screen flashes the simple words..."; ]; Include "Grammar"; [ GoLeftSub; <>; ]; Extend only 'l//' first * -> GoLeft; [ FaceSub; if ( noun notin compass ) "Face what?"; GetDir( noun.door_dir ); print "You turn to ", (the) noun, ".^"; <>; ]; Verb 'face' * noun=ADirection -> Face * 'toward'/'to' noun=ADirection -> Face; Extend 'turn' first * noun=ADirection -> Face * 'to'/'toward' noun=ADirection -> Face; End;