! ---------------------------------------------------------------------------- ! ! CheckOut.h ! original 1.0 May00 by Roger Firth (roger.firth@tesco.net) for Inform 6 ! ! ---------------------------------------------------------------------------- ! ! Installation: add the line: ! ! Include "CheckOut"; ! ! anywhere in your game AFTER the Include "Parser" statement. ! ! ---------------------------------------------------------------------------- ! ! Implements a debugging verb CHECKOUT which attempts to test all your rooms ! for asymmetric and one-way paths, on the basis that these /may/ represent ! errors in setting up the inter-room connections. ! ! Given two rooms Beach and Cliffs, the path between them is 'symmetric' if ! you can move (for example) NORTH from the Beach to get to the Cliffs, and ! then SOUTH from the Cliffs to return to the Beach. An 'asymmetric' path ! would be (for example) NORTH from the Beach to the Cliffs, while SOUTHEAST ! or WEST or DOWN (but not SOUTH) would take you back. Asymmetric paths are ! reported only where no symmetric path exists; if SOUTH, SOUTHEAST, WEST and ! DOWN all lead from the Cliffs to the Beach, no output is generated. ! ! A one-way path is (for example) NORTH from Beach to Cliffs, with no path ! returning to the Beach. ! ! All of this works by analysing the properties N_TO, NE_TO ... and DOOR_TO. ! Inform allows any of these to be a routine, but CheckOut has no way of ! determining what such a routine might return, and so treats it as though ! no exit was defined. Therefore, be prepared for some misleading reports. ! ! You can define a list of rooms to be skipped when analysing the paths; ! for example, a maze might deliberately contain many asymmetric paths which ! you don't wish to report on. Include a line like this immediately before ! you Include the file (don't forget the zero at the end of the list): ! ! Array SkipRoom --> room1 room2 ... roomN 0; ! ! ---------------------------------------------------------------------------- ! #ifdef DEBUG; message "Compiling CheckOut.h"; Constant ExitCount 12; Array ExitProp --> n_to ne_to e_to se_to u_to in_to s_to sw_to w_to nw_to d_to out_to; Array ExitName --> "North" "NorthEast" "East" "SouthEast" "Up" "In" "South" "SouthWest" "West" "NorthWest" "Down" "Out"; #ifndef SkipRoom; Array SkipRoom --> 1; #endif; [ CheckOutSub obj dest i k; objectloop(obj ofclass Object) { ! Loop through all Objects. if ((obj <= InformLibrary) || (obj == LibraryMessages) || ! Ignore system objects, (obj in 1) || ! those with a parent, (parent(obj)) || ! and those in SkipRoom, (OmitRoom(obj))) continue; ! leaving (mostly) rooms. for (i=0 : ii)) { 0: return 0; ! nowhere 1: return 0; ! routine 2: switch (ExitType(obj.(ExitProp-->i), door_to)) { 0: return 0; ! door to nowhere 1: return 0; ! door to routine 2: return 0; ! door to door! 3: return ((obj.(ExitProp-->i)).door_to); ! door to room } 3: return obj.(ExitProp-->i); ! room } ]; [ ExitType obj prop; if (obj == 0 || prop == 0) return 0; if (obj.#prop > 2 || obj.prop == NULL) return 0; switch(metaclass(obj.prop)) { nothing, Class, String: return 0; Routine: return 1; Object: if (obj.prop has door) return 2; else return 3; } ]; [ PrintExit obj i; print (name) obj, "->", (string) ExitName-->i, "->"; ]; [ OmitRoom obj i; i = 0; while (SkipRoom-->i) if (SkipRoom-->(i++) == obj) rtrue; rfalse; ]; Verb 'checkout' * -> CheckOut; #endif; ! ---------------------------------------------------------------------------- !