home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 May / Amiga_Games_Extra_CD_5-96.bin / spiele / publicdomain / amsrc / proving / proving6.m < prev   
Text File  |  1996-02-19  |  25KB  |  961 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1996 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * proving6.m - the 3D maze area
  9.  */
  10.  
  11. private tp_proving6 CreateTable().
  12. use tp_proving6
  13.  
  14. define tp_proving6 p_pHasShovel CreateBoolProp().
  15. define tp_proving6 p_pMazeX CreateIntProp().
  16. define tp_proving6 p_pMazeY CreateIntProp().
  17. define tp_proving6 p_pMazeZ CreateIntProp().
  18. define tp_proving6 MAZE_MAX_X 15.
  19. define tp_proving6 MAZE_MAX_Y 9.
  20. define tp_proving6 MAZE_MAX_Z 9.
  21. define tp_proving6 MAZE_ENTER_X 8.
  22. define tp_proving6 MAZE_ENTER_Y 9.
  23. define tp_proving6 MAZE_ENTER_Z 5.
  24. define tp_proving6 MAZE_GOAL_X    11.
  25. define tp_proving6 MAZE_GOAL_Y    3.
  26. define tp_proving6 MAZE_GOAL_Z    5.
  27. define tp_proving6 p_rLayerList CreateThingListProp().
  28. define tp_proving6 p_rLayer CreateIntListProp().
  29. define tp_proving6 MAZE_OPEN    0b00.
  30. define tp_proving6 MAZE_NORMAL    0b01.
  31. define tp_proving6 MAZE_BLOCK    0b10.
  32. define tp_proving6 p_oCurrentUser CreateThingProp().
  33.  
  34. define tp_proving6 r_shovelChamber CreateThing(r_provingCave).
  35. SetupRoomDP(r_shovelChamber, "in a small chamber", "").
  36. AutoGraphics(r_shovelChamber, AutoOpenRoom).
  37. Connect(r_doorsExit, r_shovelChamber, D_NORTH).
  38. r_shovelChamber@p_rNoGenerateMonsters := true.
  39. r_shovelChamber@p_Image := "Proving/shovelRoom".
  40.  
  41. define tp_proving6 o_trollShovel CreateThing(nil).
  42. SetupObject(o_trollShovel, r_shovelChamber,
  43.     "Shovel;Troll,King's.shovel;troll's,troll,king's,king",
  44.     "The shovel is the same size and shape as a normal garden shovel, but it "
  45.     "seems to be made of silver or some other shiny, whitish metal. There is "
  46.     "a faint greenish glow surrounding it.").
  47.  
  48. define tp_proving6 r_trollMaze CreateThing(nil).
  49. SetupRoomD(r_trollMaze, "", "").
  50. HConnect(r_shovelChamber, r_trollMaze, D_NORTH).
  51. Scenery(r_trollMaze, "chasm.rock.cavity").
  52. r_trollMaze@p_rHintString := "Explore carefully - there is a route!".
  53.  
  54. define tp_proving6 proc mazeDropCheck(thing what)status:
  55.     Print("You can't drop things here.\n");
  56.     fail
  57. corp;
  58. AddRoomDropChecker(r_trollMaze, mazeDropCheck, false).
  59.  
  60. define tp_proving6 o_drawBridge CreateThing(nil).
  61. FakeObject(o_drawBridge, r_trollMaze,
  62.     "bridge;wooden,draw.drawbridge;wooden.draw-bridge;wooden", "").
  63. o_drawBridge@p_oState := 0.
  64. define tp_proving6 proc drawBridgeDesc()string:
  65.     thing me;
  66.  
  67.     me := Me();
  68.     if me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 3 and
  69.     me@p_pMazeX = MAZE_GOAL_X
  70.     then
  71.     "The drawbridge is quite old, but still in good condition. "
  72.     "It is currently " +
  73.     if o_drawBridge@p_oState = 0 then
  74.         "drawn up on the far side of the chasm."
  75.     else
  76.         "lowered into position across the chasm."
  77.     fi
  78.     else
  79.     "There is no drawbridge here."
  80.     fi
  81. corp;
  82. o_drawBridge@p_oDescAction := drawBridgeDesc.
  83.  
  84. define tp_proving6 proc mazeNotify()void:
  85.  
  86.     Print("\n* You were in the troll maze when the database was last backed "
  87.     "up. You have been moved out of the maze. *\n\n");
  88.     DelElement(Me()@p_pEnterActions, mazeNotify);
  89. corp;
  90.  
  91. /* forward declaration */
  92. define tp_proving6 proc mazeIdle()void: corp;
  93.  
  94. define tp_proving6 proc mazeActive(thing shovel)void:
  95.     thing who;
  96.  
  97.     who := o_trollShovel@p_oCurrentUser;
  98.     if who ~= nil then
  99.     Log("mazeActive moving " + who@p_pName + " out of the troll maze.\n");
  100.     who -- p_pHasShovel;
  101.     AddTail(r_shovelChamber@p_rContents, o_trollShovel);
  102.     o_trollShovel -- p_oCurrentUser;
  103.     o_drawBridge@p_oState := 0;
  104.     SetCharacterLocation(ThingCharacter(who), r_shovelChamber);
  105.     AddTail(who@p_pEnterActions, mazeNotify);
  106.     DelElement(who@p_pExitActions, mazeIdle);
  107.     fi;
  108. corp;
  109.  
  110. replace mazeIdle()void:
  111.     thing me;
  112.  
  113.     me := Me();
  114.     me -- p_pHasShovel;
  115.     DelElement(me@p_pExitActions, mazeIdle);
  116.     SetLocation(r_shovelChamber);
  117.     ABPrint(r_shovelChamber, nil, nil, "Clunk!\n");
  118.     AddTail(r_shovelChamber@p_rContents, o_trollShovel);
  119.     o_trollShovel -- p_oCurrentUser;
  120.     o_drawBridge@p_oState := 0;
  121.     ignore RemoveActiveAction(o_trollShovel, mazeActive);
  122. corp;
  123.  
  124. define tp_proving6 proc touchShovel()status:
  125.     thing me;
  126.     action a;
  127.  
  128.     me := Me();
  129.     Print("As you touch the shovel, you feel a sharp shock, as of electricity."
  130.     " The shock momentarily clouds your mind, but even so you look with "
  131.     "bewilderment as the shovel seems to melt into your hand. When you "
  132.     "recover your senses, the shovel is gone, and you feel a strong "
  133.     "desire to dig. There is a nagging feeling of something tugging at "
  134.     "your mind, from somewhere to the northeast.\n");
  135.     OPrint("As " + me@p_pName + " touches the shovel, it seems to cloud or "
  136.     "blur, and then it is gone.\n");
  137.     me@p_pHasShovel := true;
  138.     DelElement(r_shovelChamber@p_rContents, o_trollShovel);
  139.     AddTail(me@p_pExitActions, mazeIdle);
  140.     RegisterActiveAction(o_trollShovel, mazeActive);
  141.     o_trollShovel@p_oCurrentUser := me;
  142.     succeed
  143. corp;
  144. o_trollShovel@p_oTouchChecker := touchShovel.
  145. define tp_proving6 proc getShovel(thing shovel)status:
  146.     touchShovel()
  147. corp;
  148. o_trollShovel@p_oGetChecker := getShovel.
  149. o_trollShovel@p_Image := "Proving/trollShovel".
  150.  
  151. define tp_proving6 proc leaveShovel()status:
  152.     thing me;
  153.  
  154.     me := Me();
  155.     if me@p_pHasShovel then
  156.     me -- p_pHasShovel;
  157.     Print("As you leave this chamber, you experience a momentary feeling "
  158.         "of loss.\n");
  159.     ABPrint(r_shovelChamber, nil, nil, "Clunk!\n");
  160.     AddTail(r_shovelChamber@p_rContents, o_trollShovel);
  161.     DelElement(me@p_pExitActions, mazeIdle);
  162.     o_trollShovel -- p_oCurrentUser;
  163.     o_drawBridge@p_oState := 0;
  164.     ignore RemoveActiveAction(o_trollShovel, mazeActive);
  165.     fi;
  166.     continue
  167. corp;
  168. AddSouthChecker(r_shovelChamber, leaveShovel, false).
  169.  
  170. HUniConnect(r_shovelChamber, r_shovelChamber, D_NORTHWEST).
  171. HUniConnect(r_shovelChamber, r_shovelChamber, D_WEST).
  172. HUniConnect(r_shovelChamber, r_shovelChamber, D_SOUTHWEST).
  173. HUniConnect(r_shovelChamber, r_shovelChamber, D_NORTHEAST).
  174. HUniConnect(r_shovelChamber, r_shovelChamber, D_EAST).
  175. HUniConnect(r_shovelChamber, r_shovelChamber, D_SOUTHEAST).
  176. define tp_proving6 proc shovelNoGo()status:
  177.     if Me()@p_pHasShovel then
  178.     Print("The stone is much too hard for you to walk through!\n");
  179.     else
  180.     Print("You can't go in that direction.\n");
  181.     fi;
  182.     fail
  183. corp;
  184. AddNorthWestChecker(r_shovelChamber, shovelNoGo, false).
  185. AddWestChecker(r_shovelChamber, shovelNoGo, false).
  186. AddSouthWestChecker(r_shovelChamber, shovelNoGo, false).
  187. AddNorthEastChecker(r_shovelChamber, shovelNoGo, false).
  188. AddEastChecker(r_shovelChamber, shovelNoGo, false).
  189. AddSouthEastChecker(r_shovelChamber, shovelNoGo, false).
  190.  
  191. HUniConnect(r_shovelChamber, r_shovelChamber, D_UP).
  192. define tp_proving6 proc shovelUp()status:
  193.     if Me()@p_pHasShovel then
  194.     Print("The ceiling is too high - you cannot go up that way.\n");
  195.     else
  196.     Print("You can't go in that direction.\n");
  197.     fi;
  198.     fail
  199. corp;
  200. AddUpChecker(r_shovelChamber, shovelUp, false).
  201. HUniConnect(r_shovelChamber, r_shovelChamber, D_DOWN).
  202. define tp_proving6 proc shovelDown()status:
  203.     if Me()@p_pHasShovel then
  204.     Print("The stone of the floor is quite hard - you cannot go down that "
  205.         "way.\n");
  206.     else
  207.     Print("You can't go in that direction.\n");
  208.     fi;
  209.     fail
  210. corp;
  211. AddDownChecker(r_shovelChamber, shovelDown, false).
  212.  
  213. define tp_proving6 proc doShovelDig()void:
  214.     if Me()@p_pHasShovel then
  215.     Print("The stone of the floor is quite hard - you cannot go down that "
  216.         "way.\n");
  217.     else
  218.     Print("Digging through solid rock is quite difficult.\n");
  219.     fi;
  220. corp;
  221. AddSpecialCommand(r_shovelChamber, "dig,excavate,shovel", doShovelDig).
  222.  
  223. define tp_proving6 o_bridgeSign CreateThing(nil).
  224. FakeObject(o_bridgeSign, r_trollMaze, "sign", "").
  225. define tp_proving6 proc bridgeSignDesc()string:
  226.     thing me;
  227.  
  228.     me := Me();
  229.     if me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 3 and
  230.     me@p_pMazeX = MAZE_GOAL_X
  231.     then
  232.     "You see nothing special about the sign. It reads:\n\n"
  233.     "\tSPEAK THE BOTTOM WORD\n"
  234.     else
  235.     "There is no sign here."
  236.     fi
  237. corp;
  238. o_bridgeSign@p_oDescAction := bridgeSignDesc.
  239. define tp_proving6 proc bridgeSignRead()string:
  240.     thing me;
  241.  
  242.     me := Me();
  243.     if me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 3 and
  244.     me@p_pMazeX = MAZE_GOAL_X
  245.     then
  246.     "The sign reads:\n\n\tSPEAK THE BOTTOM WORD\n"
  247.     else
  248.     "There is no sign here."
  249.     fi
  250. corp;
  251. o_bridgeSign@p_oReadAction := bridgeSignRead.
  252.  
  253. define tp_proving6 proc trollMazeListen(string s)status:
  254.     thing me;
  255.  
  256.     me := Me();
  257.     if me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 3 and
  258.     me@p_pMazeX = MAZE_GOAL_X
  259.     then
  260.     SetTail(s);
  261.     while
  262.         s := GetWord();
  263.         s ~= ""
  264.     do
  265.         if s == "LURT" and o_drawBridge@p_oState = 0 then
  266.         o_drawBridge@p_oState := 1;
  267.         Print("With a rumble and a bang, the drawbridge lowers into "
  268.             "place across the chasm.\n");
  269.         GSetPen(nil, C_BROWN);
  270.         GAMove(nil, MAZE_GOAL_X * 10 + 1, MAZE_GOAL_Y * 10 + 19);
  271.         GRectangle(nil, 7, 11, true);
  272.         fi;
  273.     od;
  274.     fi;
  275.     continue
  276. corp;
  277. AddRoomSayChecker(r_trollMaze, trollMazeListen, false).
  278.  
  279. define tp_proving6 proc questHeartDesc()string:
  280.     "Find the heart of the trolls."
  281. corp;
  282. define tp_proving6 proc questHeartCheck()void:
  283. corp;
  284. define tp_proving6 proc questHeartHint()string:
  285.     "It lies deep in the rock."
  286. corp;
  287. QuestDirect("Heart", questHeartDesc, questHeartCheck, questHeartHint).
  288.  
  289. define tp_proving6 proc maze(int z, y, x)int:
  290.     if z < 0 or z > MAZE_MAX_Z or
  291.     y < 0 or y > MAZE_MAX_Y or
  292.     x < 0 or x > MAZE_MAX_X
  293.     then
  294.     MAZE_BLOCK
  295.     else
  296.     (r_trollMaze@p_rLayerList[z]@p_rLayer[y] >>
  297.         ((MAZE_MAX_X - x) * 2)) & 0b11
  298.     fi
  299. corp;
  300.  
  301. define tp_proving6 p_rSpaceCount CreateIntProp().
  302. define tp_proving6 p_rSpaceVector CreateIntListProp().
  303. r_trollMaze@p_rSpaceCount := 0.
  304. r_trollMaze@p_rSpaceVector := CreateIntArray(6).
  305. define tp_proving6 proc markSpace(int dir)void:
  306.     int count;
  307.  
  308.     count := r_trollMaze@p_rSpaceCount;
  309.     r_trollMaze@p_rSpaceVector[count] := dir;
  310.     r_trollMaze@p_rSpaceCount := count + 1;
  311. corp;
  312. define tp_proving6 proc dumpSpaces()bool:
  313.     list int spaces;
  314.     int count, i;
  315.  
  316.     count := r_trollMaze@p_rSpaceCount;
  317.     spaces := r_trollMaze@p_rSpaceVector;
  318.     if count ~= 0 then
  319.     if count = 1 then
  320.         Print("There is open space ");
  321.     else
  322.         Print("There are open spaces ");
  323.     fi;
  324.     for i from 0 upto count - 1 do
  325.         if i ~= 0 then
  326.         if i = count - 1 then
  327.             Print(" and ");
  328.         else
  329.             Print(", ");
  330.         fi;
  331.         fi;
  332.         Print(
  333.         case spaces[i]
  334.         incase D_NORTH:
  335.             "to the north"
  336.         incase D_SOUTH:
  337.             "to the south"
  338.         incase D_EAST:
  339.             "to the east"
  340.         incase D_WEST:
  341.             "to the west"
  342.         incase D_UP:
  343.             "above you"
  344.         incase D_DOWN:
  345.             "below you"
  346.         default:
  347.             "?"
  348.         esac);
  349.     od;
  350.     Print(".");
  351.     r_trollMaze@p_rSpaceCount := 0;
  352.     true
  353.     else
  354.     false
  355.     fi
  356. corp;
  357.  
  358. define tp_proving6 proc drawFloor(int x, y, z)void:
  359.     int kind;
  360.  
  361.     kind := maze(z - 1, y, x);
  362.     if kind = MAZE_NORMAL then
  363.     GSetPen(nil, C_GOLD);
  364.     elif kind = MAZE_BLOCK then
  365.     GSetPen(nil, C_LIGHT_GREY);
  366.     else
  367.     GSetPen(nil, C_DARK_GREY);
  368.     fi;
  369.     GAMove(nil, x * 10, y * 10);
  370.     GRectangle(nil, 9, 9, true);
  371. corp;
  372.  
  373. define tp_proving6 proc drawBlock(int x, y, kind)void:
  374.  
  375.     if kind = MAZE_NORMAL then
  376.     GSetPen(nil, C_ORANGE);
  377.     else
  378.     GSetPen(nil, C_MEDIUM_GREY);
  379.     fi;
  380.     GAMove(nil, x * 10, y * 10);
  381.     GRectangle(nil, 9, 9, true);
  382. corp;
  383.  
  384. define tp_proving6 proc showMaze()void:
  385.     thing me;
  386.     int x, y, z, dx, dy, dz, x0, y0, kind;
  387.     bool needNewLine;
  388.  
  389.     me := Me();
  390.     if me@p_oLight or FindFlagOnList(me@p_pCarrying, p_oLight) then
  391.     x := me@p_pMazeX;
  392.     y := me@p_pMazeY;
  393.     z := me@p_pMazeZ;
  394.     dx := x - MAZE_GOAL_X;
  395.     dy := y - MAZE_GOAL_Y;
  396.     dz := z - MAZE_GOAL_Z;
  397.     if dz = 0 and dy = 0 and dx = 0 then
  398.         Print("You are in the heart of the trolls.\n");
  399.     elif dz = 0 and dy = 2 and dx = 0 then
  400.         Print("You are on a drawbridge.\n");
  401.     elif maze(z, y, x) = MAZE_NORMAL then
  402.         Print("You are in solid rock.\n");
  403.     else
  404.         Print("You are in a cavity in the rock.\n");
  405.     fi;
  406.     if maze(z + 1, y, x) = MAZE_OPEN then
  407.         markSpace(D_UP);
  408.     fi;
  409.     if maze(z - 1, y, x) = MAZE_OPEN then
  410.         markSpace(D_DOWN);
  411.     fi;
  412.     if maze(z, y - 1, x) = MAZE_OPEN then
  413.         markSpace(D_NORTH);
  414.     fi;
  415.     if maze(z, y + 1, x) = MAZE_OPEN then
  416.         markSpace(D_SOUTH);
  417.     fi;
  418.     if maze(z, y, x - 1) = MAZE_OPEN then
  419.         markSpace(D_WEST);
  420.     fi;
  421.     if maze(z, y, x + 1) = MAZE_OPEN then
  422.         markSpace(D_EAST);
  423.     fi;
  424.     needNewLine := dumpSpaces();
  425.     if z = MAZE_GOAL_Z and y = MAZE_GOAL_Y + 3 and x = MAZE_GOAL_X then
  426.         if o_drawBridge@p_oState = 0 then
  427.         Print(" There is a drawbridge drawn up on the other side of "
  428.             "the chasm, and there is a small sign on this side.");
  429.         else
  430.         Print(" There is a drawbridge across the chasm, and there "
  431.             "is a small sign on this side.");
  432.         fi;
  433.     fi;
  434.     if needNewLine then
  435.         Print("\n");
  436.     fi;
  437.     if dx ~= 0 or dy ~= 0 or dz ~= 0 then
  438.         if dx > -2 and dx < 2 then
  439.         dx := 0;
  440.         fi;
  441.         if dy > -2 and dy < 2 then
  442.         dy := 0;
  443.         fi;
  444.         if dz > -2 and dz < 2 then
  445.         dz := 0;
  446.         fi;
  447.         if dx = 0 and dy = 0 and dz = 0 then
  448.         Print("Whatever has been leading you around is very close.\n");
  449.         else
  450.         Print("The tugging is coming from ");
  451.         if dz ~= 0 then
  452.             if dz < 0 then
  453.             Print("above");
  454.             elif dz > 0 then
  455.             Print("below");
  456.             fi;
  457.             if dx ~= 0 or dy ~= 0 then
  458.             Print(" and from ");
  459.             fi;
  460.         fi;
  461.         if dx ~= 0 or dy ~= 0 then
  462.             Print("the ");
  463.             if dx < 0 then
  464.             if dy < 0 then
  465.                 Print("southeast");
  466.             elif dy = 0 then
  467.                 Print("east");
  468.             else
  469.                 Print("northeast");
  470.             fi;
  471.             elif dx = 0 then
  472.             if dy < 0 then
  473.                 Print("south");
  474.             elif dy > 0 then
  475.                 Print("north");
  476.             fi;
  477.             else
  478.             if dy < 0 then
  479.                 Print("southwest");
  480.             elif dy = 0 then
  481.                 Print("west");
  482.             else
  483.                 Print("northwest");
  484.             fi;
  485.             fi;
  486.         fi;
  487.         Print(".\n");
  488.         fi;
  489.     fi;
  490.     if GOn(nil) then
  491.         GSetPen(nil, C_BLACK);
  492.         GAMove(nil, 0, 0);
  493.         GRectangle(nil, 159, 99, true);
  494.         kind := maze(z, y, x);
  495.         if kind = MAZE_OPEN then
  496.         drawFloor(x, y, z);
  497.         else
  498.         drawBlock(x, y, kind);
  499.         fi;
  500.         if y > 0 then
  501.         kind := maze(z, y - 1, x);
  502.         if kind = MAZE_OPEN then
  503.             drawFloor(x, y - 1, z);
  504.             if y > 1 then
  505.             kind := maze(z, y - 2, x);
  506.             if kind = MAZE_OPEN then
  507.                 drawFloor(x, y - 2, z);
  508.             else
  509.                 drawBlock(x, y - 2, kind);
  510.             fi;
  511.             fi;
  512.         else
  513.             drawBlock(x, y - 1, kind);
  514.         fi;
  515.         if x < MAZE_MAX_X then
  516.             kind := maze(z, y - 1, x + 1);
  517.             if kind = MAZE_OPEN then
  518.             drawFloor(x + 1, y - 1, z);
  519.             else
  520.             drawBlock(x + 1, y - 1, kind);
  521.             fi;
  522.         fi;
  523.         fi;
  524.         if x < MAZE_MAX_X then
  525.         kind := maze(z, y, x + 1);
  526.         if kind = MAZE_OPEN then
  527.             drawFloor(x + 1, y, z);
  528.             if x < MAZE_MAX_X - 1 then
  529.             kind := maze(z, y, x + 2);
  530.             if kind = MAZE_OPEN then
  531.                 drawFloor(x + 2, y, z);
  532.             else
  533.                 drawBlock(x + 2, y, kind);
  534.             fi;
  535.             fi;
  536.         else
  537.             drawBlock(x + 1, y, kind);
  538.         fi;
  539.         if y < MAZE_MAX_Y then
  540.             kind := maze(z, y + 1, x + 1);
  541.             if kind = MAZE_OPEN then
  542.             drawFloor(x + 1, y + 1, z);
  543.             else
  544.             drawBlock(x + 1, y + 1, kind);
  545.             fi;
  546.         fi;
  547.         fi;
  548.         if y < MAZE_MAX_Y then
  549.         kind := maze(z, y + 1, x);
  550.         if kind = MAZE_OPEN then
  551.             drawFloor(x, y + 1, z);
  552.             if y < MAZE_MAX_Y - 1 then
  553.             kind := maze(z, y + 2, x);
  554.             if kind = MAZE_OPEN then
  555.                 drawFloor(x, y + 2, z);
  556.             else
  557.                 drawBlock(x, y + 2, kind);
  558.             fi;
  559.             fi;
  560.         else
  561.             drawBlock(x, y + 1, kind);
  562.         fi;
  563.         if x > 0 then
  564.             kind := maze(z, y + 1, x - 1);
  565.             if kind = MAZE_OPEN then
  566.             drawFloor(x - 1, y + 1, z)
  567.             else
  568.             drawBlock(x - 1, y + 1, kind);
  569.             fi;
  570.         fi;
  571.         fi;
  572.         if x > 0 then
  573.         kind := maze(z, y, x - 1);
  574.         if kind = MAZE_OPEN then
  575.             drawFloor(x - 1, y, z);
  576.             if x > 1 then
  577.             kind := maze(z, y, x - 2);
  578.             if kind = MAZE_OPEN then
  579.                 drawFloor(x - 2, y, z);
  580.             else
  581.                 drawBlock(x - 2, y, kind);
  582.             fi;
  583.             fi;
  584.         else
  585.             drawBlock(x - 1, y, kind);
  586.         fi;
  587.         if y > 0 then
  588.             kind := maze(z, y - 1, x - 1);
  589.             if kind = MAZE_OPEN then
  590.             drawFloor(x - 1, y - 1, z);
  591.             else
  592.             drawBlock(x - 1, y - 1, kind);
  593.             fi;
  594.         fi;
  595.         fi;
  596.         if z = MAZE_GOAL_Z and
  597.         x >= MAZE_GOAL_X - 1 and x <= MAZE_GOAL_X + 1 and
  598.         y >= MAZE_GOAL_Y and y <= MAZE_GOAL_Y + 3
  599.         then
  600.         x0 := MAZE_GOAL_X * 10;
  601.         y0 := MAZE_GOAL_Y * 10;
  602.         GSetPen(nil, C_RED_ORANGE);
  603.         GAMove(nil, x0 + 11, y0 + 31);
  604.         GPixel(nil);
  605.         GSetPen(nil, C_BROWN);
  606.         GAMove(nil, x0 + 1, y0 + 19);
  607.         if o_drawBridge@p_oState = 0 then
  608.             GRectangle(nil, 7, 2, true);
  609.         else
  610.             GRectangle(nil, 7, 11, true);
  611.         fi;
  612.         fi;
  613.         PlaceCursor(x * 10 + 1, y * 10 + 1);
  614.     fi;
  615.     else
  616.     Print("It is dark.\n");
  617.     fi;
  618. corp;
  619.  
  620. define tp_proving6 proc mazeLookChecker()status:
  621.     showMaze();
  622.     succeed
  623. corp;
  624. AddRoomLookChecker(r_trollMaze, mazeLookChecker, false).
  625.  
  626. define tp_proving6 proc enterMaze()status:
  627.     thing me;
  628.  
  629.     me := Me();
  630.     if me@p_pHasShovel then
  631.     me@p_pMazeX := MAZE_ENTER_X;
  632.     me@p_pMazeY := MAZE_ENTER_Y;
  633.     me@p_pMazeZ := MAZE_ENTER_Z;
  634.     o_drawBridge@p_oState := 0;
  635.     Print("Amazingly enough, you are able to walk right into the wall. "
  636.         "The stone seems to be soft, and it parts before you and closes "
  637.         "behind you.\n");
  638.     SetLocation(r_trollMaze);
  639.     if LightAt(r_shovelChamber) then
  640.         if not me@p_pHidden then
  641.         OPrint(me@p_pName + " disappears.\n");
  642.         ForEachAgent(r_shovelChamber, UnShowIconOnce);
  643.         fi;
  644.     else
  645.         ForEachAgent(r_shovelChamber, UnShowRoomFromAgent);
  646.     fi;
  647.     SetLocation(r_trollMaze);
  648.     if GOn(nil) then
  649.         RemoveCursor();
  650.         GUndrawIcons(nil);
  651.         GResetIcons(nil);
  652.         DrawRoomName("Solid", "Rock");
  653.     else
  654.         Print("Warning! This puzzle area is MUCH easier if you have "
  655.         "a graphics display!\n\n");
  656.     fi;
  657.     succeed
  658.     else
  659.     Print("You can't go in that direction.\n");
  660.     fail
  661.     fi
  662. corp;
  663. AddNorthChecker(r_shovelChamber, enterMaze, false).
  664.  
  665. define tp_proving6 proc mazeMove(int xDelta, yDelta, zDelta)status:
  666.     thing me;
  667.     int x, y, z, oldKind, kind;
  668.  
  669.     me := Me();
  670.     x := me@p_pMazeX;
  671.     y := me@p_pMazeY;
  672.     z := me@p_pMazeZ;
  673.     oldKind := maze(z, y, x);
  674.     if oldKind = MAZE_OPEN and zDelta = 1 then
  675.     Print("The ceiling is too high - you cannot go up that way.\n");
  676.     else
  677.     x := x + xDelta;
  678.     y := y + yDelta;
  679.     z := z + zDelta;
  680.     kind := maze(z, y, x);
  681.     if kind = MAZE_BLOCK then
  682.         Print("That rock is too hard for you to dig into.\n");
  683.     else
  684.         if oldKind ~= MAZE_OPEN or kind ~= MAZE_OPEN then
  685.         Print("You dig ");
  686.         if zDelta = -1 then
  687.             Print("downwards ");
  688.         elif zDelta = 1 then
  689.             Print("upwards ");
  690.         fi;
  691.         if kind = MAZE_OPEN then
  692.             Print("into a cavity in the rock.\n");
  693.         else
  694.             Print("through the rock.\n");
  695.         fi;
  696.         fi;
  697.         if kind = MAZE_OPEN then
  698.         while maze(z - 1, y, x) = MAZE_OPEN do
  699.             Print("There is a cavity beneath you - you fall.\n");
  700.             z := z - 1;
  701.         od;
  702.         fi;
  703.         me@p_pMazeX := x;
  704.         me@p_pMazeY := y;
  705.         me@p_pMazeZ := z;
  706.         if GOn(nil) then
  707.         RemoveCursor();
  708.         fi;
  709.         showMaze();
  710.     fi;
  711.     fi;
  712.     fail
  713. corp;
  714.  
  715. define tp_proving6 proc mazeMoveNorth()status:
  716.     thing me;
  717.  
  718.     me := Me();
  719.     if me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 3 and
  720.     me@p_pMazeX = MAZE_GOAL_X and o_drawBridge@p_oState = 1
  721.     then
  722.     if GOn(nil) then
  723.         RemoveCursor();
  724.     fi;
  725.     me@p_pMazeY := MAZE_GOAL_Y + 2;
  726.     showMaze();
  727.     fail
  728.     else
  729.     if me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 1 and
  730.         me@p_pMazeX = MAZE_GOAL_X
  731.     then
  732.         Print("You enter the heart of the trolls - their most sacred "
  733.         "place. Congratulations on finding it!\n");
  734.         DoQuest(questHeartCheck);
  735.     fi;
  736.     mazeMove(0, -1, 0)
  737.     fi
  738. corp;
  739. define tp_proving6 proc mazeMoveEast()status:
  740.     mazeMove(1, 0, 0)
  741. corp;
  742. define tp_proving6 proc mazeMoveSouth()status:
  743.     thing me;
  744.  
  745.     me := Me();
  746.     if me@p_pMazeX = MAZE_ENTER_X and
  747.     me@p_pMazeY = MAZE_ENTER_Y and
  748.     me@p_pMazeZ = MAZE_ENTER_Z
  749.     then
  750.     continue
  751.     elif me@p_pMazeZ = MAZE_GOAL_Z and me@p_pMazeY = MAZE_GOAL_Y + 1 and
  752.     me@p_pMazeX = MAZE_GOAL_X
  753.     then
  754.     if GOn(nil) then
  755.         RemoveCursor();
  756.     fi;
  757.     me@p_pMazeY := MAZE_GOAL_Y + 2;
  758.     showMaze();
  759.     fail
  760.     else
  761.     mazeMove(0, 1, 0)
  762.     fi
  763. corp;
  764. define tp_proving6 proc mazeMoveWest()status:
  765.     mazeMove(-1, 0, 0)
  766. corp;
  767. define tp_proving6 proc mazeMoveUp()status:
  768.     mazeMove(0, 0, 1)
  769. corp;
  770. define tp_proving6 proc mazeMoveDown()status:
  771.     mazeMove(0, 0, -1)
  772. corp;
  773.  
  774. HUniConnect(r_trollMaze, r_trollMaze, D_NORTH).
  775. HUniConnect(r_trollMaze, r_trollMaze, D_EAST).
  776. HUniConnect(r_trollMaze, r_shovelChamber, D_SOUTH).
  777. HUniConnect(r_trollMaze, r_trollMaze, D_WEST).
  778. HUniConnect(r_trollMaze, r_trollMaze, D_DOWN).
  779. HUniConnect(r_trollMaze, r_trollMaze, D_UP).
  780. AddNorthChecker(r_trollMaze, mazeMoveNorth, false).
  781. AddEastChecker(r_trollMaze, mazeMoveEast, false).
  782. AddSouthChecker(r_trollMaze, mazeMoveSouth, false).
  783. AddWestChecker(r_trollMaze, mazeMoveWest, false).
  784. AddUpChecker(r_trollMaze, mazeMoveUp, false).
  785. AddDownChecker(r_trollMaze, mazeMoveDown, false).
  786.  
  787. define tp_proving6 proc shovelDig()void:
  788.     ignore mazeMove(0, 0, -1);
  789. corp;
  790. AddSpecialCommand(r_trollMaze, "dig,excavate,shovel", shovelDig).
  791.  
  792. r_trollMaze@p_rLayerList := CreateThingList().
  793.  
  794. define tp_proving6 proc makeRow(string r)int:
  795.     int row, i;
  796.     string ch;
  797.  
  798.     row := 0;
  799.     for i from 0 upto MAZE_MAX_X do
  800.     row := row << 2;
  801.     ch := SubString(r, i, 1);
  802.     if ch = "B" then
  803.         row := row | MAZE_BLOCK;
  804.     elif ch = "N" then
  805.         row := row | MAZE_NORMAL;
  806.     elif ch = "." then
  807.         row := row | MAZE_OPEN;
  808.     else
  809.         Print("Illegal character in maze row: '" + ch + "'.\n");
  810.     fi;
  811.     od;
  812.     row
  813. corp;
  814.  
  815. define tp_proving6 proc makeLayer(string y0,y1,y2,y3,y4,y5,y6,y7,y8,y9)void:
  816.     thing th;
  817.     list int li;
  818.  
  819.     li := CreateIntArray(10);
  820.     li[0] := makeRow(y0);
  821.     li[1] := makeRow(y1);
  822.     li[2] := makeRow(y2);
  823.     li[3] := makeRow(y3);
  824.     li[4] := makeRow(y4);
  825.     li[5] := makeRow(y5);
  826.     li[6] := makeRow(y6);
  827.     li[7] := makeRow(y7);
  828.     li[8] := makeRow(y8);
  829.     li[9] := makeRow(y9);
  830.     th := CreateThing(nil);
  831.     th@p_rLayer := li;
  832.     AddTail(r_trollMaze@p_rLayerList, th);
  833. corp;
  834.  
  835. /* must be given from the bottom up */
  836.  
  837. makeLayer(    /* 0 */
  838.     "NNNNNNNNNNNNNNNN",
  839.     "NNNNNNNNNNNNNNNN",
  840.     "BNNNBNBNBBNNBBBN",
  841.     "BNNNBNBNBNBNNBNN",
  842.     "BNNNBNBNBBNNNBNN",
  843.     "BNNNBNBNBNBNNBNN",
  844.     "BBBNNBBNBNBNNBNN",
  845.     "NNNNNNNNNNNNNNNN",
  846.     "NNNNNNNNNNNNNNNN",
  847.     "BBBNBBBNBBBNBBBN").
  848.  
  849. makeLayer(    /* 1 */
  850.     "BBBBBBBBBBBBBBBB",
  851.     "BBBBBBBBBBBBBBBB",
  852.     "BBBBBBBBBBBBBBBB",
  853.     "BBBBBNBBBNBBBBBB",
  854.     "BBBBBBBBBBBBBBBB",
  855.     "BBBBBBBBBBBBBBBB",
  856.     "BBBBBBBBBBBBBBBB",
  857.     "BBBBBBBBBBBBBBBB",
  858.     "BBBBBBBBBBNBBBBB",
  859.     "BBBBBBBBBBBBBBBB").
  860.  
  861. makeLayer(    /* 2 */
  862.     "BBBBNN..B..NN..N",
  863.     "...B....B...BBBN",
  864.     ".B.BBB..B...BBBN",
  865.     ".....NN.B...BBBN",
  866.     ".B.BBBBBBBBBBBBB",
  867.     "...BNNNBBBBBBBBB",
  868.     ".B.BNBNBBBBBBBBN",
  869.     "...BNBNBBB.....N",
  870.     ".B.BNBNB.B.BBBBB",
  871.     "...BNBN..BBBNNNB").
  872.  
  873. makeLayer(    /* 3 */
  874.     "BBBB.NN...NN....",
  875.     "BBBB........BBB.",
  876.     "BBBBBB......B...",
  877.     "BBBBBBN.B...B.BB",
  878.     "BBBBBBBBBBBBB.BB",
  879.     "BBBB.B.B.B....BN",
  880.     "BBBB.B.B.BBBBBBN",
  881.     "BBBB...B.B......",
  882.     "BBBB...B.B......",
  883.     "BBBB..NNNNNNNNBB").
  884.  
  885. makeLayer(    /* 4 */
  886.     ".NBB..NNNNN...BB",
  887.     "..NN........BBBB",
  888.     "BBBBB.....BBBBBB",
  889.     "BBB.NNN...BBBBBB",
  890.     "BBBBBBBBBBBBBBBN",
  891.     "N....BBB.B...BBN",
  892.     "BBBB.BBBBBBBBBB.",
  893.     "......BB.BBBBBB.",
  894.     ".NNNNNNBBB..BBBB",
  895.     "......NNN..NBBBB").
  896.  
  897. makeLayer(    /* 5 */
  898.     ".NNB............",
  899.     "...B............",
  900.     ".........BBBB.B.",
  901.     "NBBN....BBB.B.NN",
  902.     "NBBBBBBBBBB.BBNN",
  903.     "NBBB..B..B...BBB",
  904.     "BBBB..B......BBB",
  905.     "......BB.BBBBB.B",
  906.     "......NBBB.....B",
  907.     "......NNNN.NNNNN").
  908.  
  909. makeLayer(    /* 6 */
  910.     "..BB.......B.BBB",
  911.     "..BB.......B..BB",
  912.     "BBBB...B.NBBB.BB",
  913.     "BBBN...BBNBBB.BB",
  914.     "BBBBBBBBBNBBBBNB",
  915.     "BBBB..B.BBBBBBNB",
  916.     "BBBB..BBBBBBBBNB",
  917.     "BBBBBBBBBBBBBBBB",
  918.     "BBBB...BBB......",
  919.     "BBBB........BBBB").
  920.  
  921. makeLayer(    /* 7 */
  922.     "BBB..BBBBBBB....",
  923.     "BBB....BBBB...B.",
  924.     "BBNN...NNNN...B.",
  925.     "...N...NBBBB..B.",
  926.     "BBBBBBBBBNB..BN.",
  927.     "NNNN..B..NB.BBN.",
  928.     "N.....BBBBB.....",
  929.     "N.......B...BBB.",
  930.     "N...............",
  931.     "NNNN........BBBB").
  932.  
  933. makeLayer(    /* 8 */
  934.     "BB.....NNNNNN.BB",
  935.     "BBN....NBBBBB.B.",
  936.     ".......NNNNBB.B.",
  937.     "BBBBBB.NBBBBB.BB",
  938.     "BBBBBBBBBBBBBBB.",
  939.     "BBBB..BBBBBBBBB.",
  940.     "BBBB..BBBBBBBBB.",
  941.     "BBBB...BBBBBBBBB",
  942.     "BBBB...BBBB.BBBB",
  943.     "BBBB...BBBB.BBBB").
  944.  
  945. makeLayer(    /* 9 */
  946.     "B......NBBBB.B..",
  947.     "....BBBBBBBB....",
  948.     "........NBBB.B..",
  949.     "BBBBBB..B....B..",
  950.     "........BB.B.B..",
  951.     "NNNN..B.BB.B.B..",
  952.     "N..........B.B..",
  953.     "N.NN...BB.BB.B..",
  954.     "N..N....B.B..BB.",
  955.     "NNNN............").
  956.  
  957. ignore DeleteSymbol(tp_proving6, "makeLayer").
  958. ignore DeleteSymbol(tp_proving6, "makeRow").
  959.  
  960. unuse tp_proving6
  961.