home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #7 / amigamamagazinepolishissue1998.iso / rozrywka / rpg / amigamud / src / basics / graphics.m < prev    next >
Text File  |  1997-05-28  |  44KB  |  1,659 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1997 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * graphics.m - some stuff to do simple graphics.
  9.  */
  10.  
  11. private tp_graphics CreateTable()$
  12. use tp_graphics
  13.  
  14. define t_graphics p_rName1 CreateStringProp()$
  15. define t_graphics p_rName2 CreateStringProp()$
  16. define t_graphics p_rBackGroundPen CreateIntProp()$
  17. define t_graphics p_rForeGroundPen CreateIntProp()$
  18. define t_graphics p_rEdgePen CreateIntProp()$
  19. define t_graphics p_rDoorPen CreateIntProp()$
  20. define t_graphics p_rCursorX CreateFixedProp()$
  21. define t_graphics p_rCursorY CreateFixedProp()$
  22. define t_graphics p_rDrawAction CreateActionProp()$
  23. define t_graphics p_pStandardButtonsNow CreateBoolProp()$
  24.  
  25. define tp_graphics p_rAutoGraphics CreateBoolProp()$
  26. define tp_graphics p_rAutoDrawAction CreateActionProp()$
  27. define tp_graphics p_pXBase CreateIntProp()$
  28. define tp_graphics p_pYBase CreateIntProp()$
  29.  
  30. /* first, some names for the standard colours */
  31.  
  32. define t_graphics C_BLACK        0$
  33. define t_graphics C_DARK_GREY        1$
  34. define t_graphics C_MEDIUM_GREY     2$
  35. define t_graphics C_LIGHT_GREY        3$
  36. define t_graphics C_WHITE        4$
  37. define t_graphics C_BRICK_RED        5$
  38. define t_graphics C_RED         6$
  39. define t_graphics C_RED_ORANGE        7$
  40. define t_graphics C_ORANGE        8$
  41. define t_graphics C_GOLD        9$
  42. define t_graphics C_CADMIUM_YELLOW 10$
  43. define t_graphics C_LEMON_YELLOW   11$
  44. define t_graphics C_LIME_GREEN       12$
  45. define t_graphics C_GREEN       13$
  46. define t_graphics C_LIGHT_GREEN    14$
  47. define t_graphics C_DARK_GREEN       15$
  48. define t_graphics C_FOREST_GREEN   16$
  49. define t_graphics C_BLUE_GREEN       17$
  50. define t_graphics C_AQUA       18$
  51. define t_graphics C_LIGHT_AQUA       19$
  52. define t_graphics C_SKY_BLUE       20$
  53. define t_graphics C_LIGHT_BLUE       21$
  54. define t_graphics C_BLUE       22$
  55. define t_graphics C_DARK_BLUE       23$
  56. define t_graphics C_VIOLET       24$
  57. define t_graphics C_PURPLE       25$
  58. define t_graphics C_FLESH       26$
  59. define t_graphics C_PINK       27$
  60. define t_graphics C_TAN        28$
  61. define t_graphics C_BROWN       29$
  62. define t_graphics C_MEDIUM_BROWN   30$
  63. define t_graphics C_DARK_BROWN       31$
  64.  
  65. /*
  66.  * ColourMatch - a routine to map name to number at run-time
  67.  */
  68.  
  69. define t_graphics proc public ColourMatch(string name)int:
  70.  
  71.     if name == "grey" then
  72.     C_MEDIUM_GREY
  73.     elif name == "red" then
  74.     C_RED
  75.     elif name == "green" then
  76.     C_GREEN
  77.     elif name == "blue" then
  78.     C_BLUE
  79.     else
  80.     MatchName(
  81.         "black.grey;dark.grey;medium.grey;light.white.red;brick.red."
  82.         "red-orange.orange.gold.yellow;cadmium.yellow;lemon.green;lime."
  83.         "green.green;light.green;dark.green;forest.blue-green.aqua."
  84.         "aqua;light.blue;sky.blue;light.blue.blue;dark.violet.purple."
  85.         "flesh.pink.tan.brown.brown;medium.brown;dark", name)
  86.     fi
  87. corp;
  88.  
  89. /*
  90.  * ColourName - map from colour number to colour name
  91.  */
  92.  
  93. define t_graphics proc public ColourName(int colour)string:
  94.  
  95.     case colour
  96.     incase C_BLACK:        "black"
  97.     incase C_DARK_GREY:     "dark grey"
  98.     incase C_MEDIUM_GREY:    "medium grey"
  99.     incase C_LIGHT_GREY:    "light grey"
  100.     incase C_WHITE:        "white"
  101.     incase C_BRICK_RED:     "brick red"
  102.     incase C_RED:        "red"
  103.     incase C_RED_ORANGE:    "red-orange"
  104.     incase C_ORANGE:        "orange"
  105.     incase C_GOLD:        "gold"
  106.     incase C_CADMIUM_YELLOW:    "cadmium yellow"
  107.     incase C_LEMON_YELLOW:    "lemon yellow"
  108.     incase C_LIME_GREEN:    "lime green"
  109.     incase C_GREEN:        "green"
  110.     incase C_LIGHT_GREEN:    "light green"
  111.     incase C_DARK_GREEN:    "dark green"
  112.     incase C_FOREST_GREEN:    "forest green"
  113.     incase C_BLUE_GREEN:    "blue green"
  114.     incase C_AQUA:        "aqua"
  115.     incase C_LIGHT_AQUA:    "light aqua"
  116.     incase C_SKY_BLUE:        "sky blue"
  117.     incase C_LIGHT_BLUE:    "light blue"
  118.     incase C_BLUE:        "blue"
  119.     incase C_DARK_BLUE:     "dark blue"
  120.     incase C_VIOLET:        "violet"
  121.     incase C_PURPLE:        "purple"
  122.     incase C_FLESH:        "flesh"
  123.     incase C_PINK:        "pink"
  124.     incase C_TAN:        "tan"
  125.     incase C_BROWN:        "brown"
  126.     incase C_MEDIUM_BROWN:    "medium brown"
  127.     incase C_DARK_BROWN:    "dark brown"
  128.     default:            "<BAD-COLOUR>"
  129.     esac
  130. corp;
  131.  
  132. /*
  133.  * ShowKnownColours - print the colour names that we understand.
  134.  */
  135.  
  136. define t_graphics proc public ShowKnownColours()void:
  137.     int i;
  138.  
  139.     Print("Known colours are: ");
  140.     for i from C_BLACK upto C_MEDIUM_BROWN do
  141.     Print(ColourName(i));
  142.     Print(", ");
  143.     od;
  144.     Print(ColourName(C_DARK_BROWN));
  145.     Print("\n");
  146. corp;
  147.  
  148. /* tools for providing unique map group and effect id values */
  149.  
  150. /* some standard MapGroup values */
  151.  
  152. define t_graphics UNKNOWN_MAP_GROUP    -1$
  153. define t_graphics NO_MAP_GROUP        0$
  154. define t_graphics AUTO_MAP_GROUP    1$
  155.  
  156. define tp_graphics GraphicsThing CreateThing(nil)$
  157. define tp_graphics p_NextMapGroup CreateIntProp()$
  158. define tp_graphics p_NextEffectId CreateIntProp()$
  159. GraphicsThing@p_NextMapGroup := AUTO_MAP_GROUP + 1$
  160. GraphicsThing@p_NextEffectId := 1$
  161.  
  162. define t_graphics proc public NextMapGroup()int:
  163.     int g;
  164.  
  165.     g := GraphicsThing@p_NextMapGroup;
  166.     GraphicsThing@p_NextMapGroup := g + 1;
  167.     g
  168. corp;
  169.  
  170. define t_graphics proc public NextEffectId()int:
  171.     int id;
  172.  
  173.     id := GraphicsThing@p_NextEffectId;
  174.     GraphicsThing@p_NextEffectId := id + 1;
  175.     id
  176. corp;
  177.  
  178. /* next, some general titling stuff */
  179.  
  180. define tp_graphics ROOM_NAME_BOX_ID NextEffectId()$
  181. define tp_graphics NAME_BOX_COLS 18$
  182.  
  183. define t_graphics proc public DrawRoomNameBox()void:
  184.     int i, cols;
  185.  
  186.     if not KnowsEffect(nil, ROOM_NAME_BOX_ID) then
  187.     cols := GCols(nil) / 2;
  188.     DefineEffect(nil, ROOM_NAME_BOX_ID);
  189.     GAMovePixels(nil, cols + (cols - NAME_BOX_COLS * 8 - 12) / 2, 0);
  190.     for i from 0 upto 3 do
  191.         GSetPen(nil, i + 1);
  192.         GRectanglePixels(nil, NAME_BOX_COLS * 8 + 12 - 2 * i, 29 - 2 * i,
  193.                  false);
  194.         GRMovePixels(nil, 1, 1);
  195.     od;
  196.     EndEffect();
  197.     fi;
  198.     CallEffect(nil, ROOM_NAME_BOX_ID);
  199. corp;
  200.  
  201. define t_graphics proc public DrawRoomName(string s1, s2)void:
  202.     int len, cols, col;
  203.  
  204.     cols := GCols(nil) / 2;
  205.     col := cols + (cols - NAME_BOX_COLS * 8 - 12) / 2;
  206.     GSetPen(nil, C_BLACK);
  207.     GAMovePixels(nil, col + 6, 6);
  208.     GRectanglePixels(nil, NAME_BOX_COLS * 8, 17, true);
  209.     GSetPen(nil, C_GOLD);
  210.     len := Length(s2);
  211.     if len ~= 0 then
  212.     if len > NAME_BOX_COLS then
  213.         len := NAME_BOX_COLS;
  214.         s2 := SubString(s2, 0, NAME_BOX_COLS);
  215.     fi;
  216.     GAMovePixels(nil, col + 6 + (NAME_BOX_COLS - len) * 4, 21);
  217.     GText(nil, s2);
  218.     len := Length(s1);
  219.     if len > NAME_BOX_COLS then
  220.         len := NAME_BOX_COLS;
  221.         s1 := SubString(s1, 0, NAME_BOX_COLS);
  222.     fi;
  223.     GAMovePixels(nil, col + 6 + (NAME_BOX_COLS - len) * 4, 12);
  224.     GText(nil, s1);
  225.     else
  226.     len := Length(s1);
  227.     if len > NAME_BOX_COLS then
  228.         len := NAME_BOX_COLS;
  229.         s1 := SubString(s1, 0, NAME_BOX_COLS);
  230.     fi;
  231.     GAMovePixels(nil, col + 6 + (NAME_BOX_COLS - len) * 4, 17);
  232.     GText(nil, s1);
  233.     fi;
  234. corp;
  235.  
  236. define tp_graphics HORIZONTAL_DOOR_ID NextEffectId()$
  237. define tp_graphics VERTICAL_DOOR_ID NextEffectId()$
  238. define tp_graphics NORTHWEST_DOOR_ID NextEffectId()$
  239. define tp_graphics NORTHEAST_DOOR_ID NextEffectId()$
  240.  
  241. define t_graphics proc public HorizontalDoor()void:
  242.  
  243.     if not KnowsEffect(nil, HORIZONTAL_DOOR_ID) then
  244.     DefineEffect(nil, HORIZONTAL_DOOR_ID);
  245.     GRMove(nil, 0.0, -0.01);
  246.     GRDraw(nil, 0.0, 0.021);
  247.     GRMove(nil, 0.0, -0.01);
  248.     GRDraw(nil, 0.03125, 0.0);
  249.     GRMove(nil, 0.0, -0.01);
  250.     GRDraw(nil, 0.0, 0.021);
  251.     EndEffect();
  252.     fi;
  253.     CallEffect(nil, HORIZONTAL_DOOR_ID);
  254. corp;
  255.  
  256. define t_graphics proc public VerticalDoor()void:
  257.  
  258.     if not KnowsEffect(nil, VERTICAL_DOOR_ID) then
  259.     DefineEffect(nil, VERTICAL_DOOR_ID);
  260.     GRMove(nil, -0.003, 0.0);
  261.     GRDraw(nil, 0.007, 0.0);
  262.     GRMove(nil, -0.003, 0.0);
  263.     GRDraw(nil, 0.0, 0.081);
  264.     GRMove(nil, -0.003, 0.0);
  265.     GRDraw(nil, 0.007, 0.0);
  266.     EndEffect();
  267.     fi;
  268.     CallEffect(nil, VERTICAL_DOOR_ID);
  269. corp;
  270.  
  271. define t_graphics proc public NorthWestDoor()void:
  272.  
  273.     if not KnowsEffect(nil, NORTHWEST_DOOR_ID) then
  274.     DefineEffect(nil, NORTHWEST_DOOR_ID);
  275.     GRMove(nil, -0.003, -0.012);
  276.     GRDraw(nil, 0.007, 0.021);
  277.     GRMove(nil, -0.003, -0.012);
  278.     GRDraw(nil, -0.013, 0.041);
  279.     GRMove(nil, -0.003, -0.012);
  280.     GRDraw(nil, 0.007, 0.021);
  281.     EndEffect();
  282.     fi;
  283.     CallEffect(nil, NORTHWEST_DOOR_ID);
  284. corp;
  285.  
  286. define t_graphics proc public NorthEastDoor()void:
  287.  
  288.     if not KnowsEffect(nil, NORTHEAST_DOOR_ID) then
  289.     DefineEffect(nil, NORTHEAST_DOOR_ID);
  290.     GRMove(nil, 0.003, -0.012);
  291.     GRDraw(nil, -0.007, 0.021);
  292.     GRMove(nil, 0.003, -0.012);
  293.     GRDraw(nil, 0.013, 0.042);
  294.     GRMove(nil, 0.003, -0.012);
  295.     GRDraw(nil, -0.007, 0.021);
  296.     EndEffect();
  297.     fi;
  298.     CallEffect(nil, NORTHEAST_DOOR_ID);
  299. corp;
  300.  
  301. /* a proc to yield the standard cursor for a character */
  302.  
  303. define t_graphics proc public MakeCursor()list int:
  304.     list int li;
  305.  
  306.     li := CreateIntArray(8);
  307.     li[0] := 0b01111100000000001100011000000000;
  308.     li[1] := 0b10101010000000001000001000000000;
  309.     li[2] := 0b10111010000000001100011000000000;
  310.     li[3] := 0b01111100000000000000000000000000;
  311.     li[4] := 0b00000000000000000000000000000000;
  312.     li[5] := 0b00000000000000000000000000000000;
  313.     li[6] := 0b00000000000000000000000000000000;
  314.     li[7] := 0b00000000000000000000000000000000;
  315.     li
  316. corp;
  317.  
  318. /* proc that can be attached to things, and which zaps all buttons. */
  319. /* We need this since we cannot attach builtins to things. */
  320.  
  321. define t_graphics proc EraseAllButtons()void:
  322.  
  323.     ClearButtons();
  324. corp;
  325.  
  326. /* create the standard set of movement buttons and region */
  327.  
  328. define t_graphics NW_BUTTON    1$
  329. define t_graphics N_BUTTON    2$
  330. define t_graphics NE_BUTTON    3$
  331. define t_graphics W_BUTTON    4$
  332. define t_graphics L_BUTTON    5$
  333. define t_graphics E_BUTTON    6$
  334. define t_graphics SW_BUTTON    7$
  335. define t_graphics S_BUTTON    8$
  336. define t_graphics SE_BUTTON    9$
  337. define t_graphics D_BUTTON    10$
  338. define t_graphics U_BUTTON    11$
  339. define t_graphics I_BUTTON    12$
  340. define t_graphics O_BUTTON    13$
  341. define t_graphics MOVE_REGION    1000$    /* want it large, so others override */
  342.  
  343. define tp_graphics ADD_DIRECTION_BUTTONS_ID NextEffectId()$
  344. define tp_graphics ERASE_DIRECTION_BUTTONS_ID NextEffectId()$
  345.  
  346. define t_graphics proc public AddDirectionButtons()void:
  347.     int xBase, yBase;
  348.  
  349.     xBase := GCols(nil) * 3 / 4;
  350.     yBase := GRows(nil) / 2;
  351.     if not KnowsEffect(nil, ADD_DIRECTION_BUTTONS_ID) then
  352.     DefineEffect(nil, ADD_DIRECTION_BUTTONS_ID);
  353.     AddButtonPixels(xBase - 34, yBase - 19, NW_BUTTON, "NW");
  354.     AddButtonPixels(xBase -  9, yBase - 19,  N_BUTTON, "N" );
  355.     AddButtonPixels(xBase +  8, yBase - 19, NE_BUTTON, "NE");
  356.     AddButtonPixels(xBase - 30, yBase -  2,  W_BUTTON, "W" );
  357.     AddButtonPixels(xBase + 12, yBase -  2,  E_BUTTON, "E" );
  358.     AddButtonPixels(xBase - 34, yBase + 15, SW_BUTTON, "SW");
  359.     AddButtonPixels(xBase -  9, yBase + 15,  S_BUTTON, "S" );
  360.     AddButtonPixels(xBase +  8, yBase + 15, SE_BUTTON, "SE");
  361.     AddButtonPixels(xBase + 33, yBase - 11,  U_BUTTON, "U" );
  362.     AddButtonPixels(xBase + 33, yBase +  7,  D_BUTTON, "D" );
  363.     AddButtonPixels(xBase - 51, yBase - 11,  I_BUTTON, "I" );
  364.     AddButtonPixels(xBase - 51, yBase +  7,  O_BUTTON, "O" );
  365.     EndEffect();
  366.     fi;
  367.     CallEffect(nil, ADD_DIRECTION_BUTTONS_ID);
  368. corp;
  369.  
  370. define t_graphics proc public EraseDirectionButtons()void:
  371.  
  372.     if not KnowsEffect(nil, ERASE_DIRECTION_BUTTONS_ID) then
  373.     DefineEffect(nil, ERASE_DIRECTION_BUTTONS_ID);
  374.     EraseButton(NW_BUTTON);
  375.     EraseButton(N_BUTTON);
  376.     EraseButton(NE_BUTTON);
  377.     EraseButton(W_BUTTON);
  378.     EraseButton(E_BUTTON);
  379.     EraseButton(SW_BUTTON);
  380.     EraseButton(S_BUTTON);
  381.     EraseButton(SE_BUTTON);
  382.     EraseButton(U_BUTTON);
  383.     EraseButton(D_BUTTON);
  384.     EraseButton(I_BUTTON);
  385.     EraseButton(O_BUTTON);
  386.     EndEffect();
  387.     fi;
  388.     CallEffect(nil, ERASE_DIRECTION_BUTTONS_ID);
  389. corp;
  390.  
  391. define t_graphics proc public AddStandardButtons()void:
  392.  
  393.     AddDirectionButtons();
  394.     AddButtonPixels(GCols(nil) * 3 / 4 - 9, GRows(nil) / 2 - 2, L_BUTTON, "L");
  395.     Me()@p_pStandardButtonsNow := true;
  396. corp;
  397.  
  398. define t_graphics proc public AddStandardRegions()void:
  399.  
  400.     AddRegion(0.0, 0.0, 0.5, 1.0, MOVE_REGION);
  401. corp;
  402.  
  403. define t_graphics proc public EraseStandardButtons()void:
  404.  
  405.     EraseDirectionButtons();
  406.     EraseButton(L_BUTTON);
  407. corp;
  408.  
  409. define t_graphics proc public EraseStandardRegions()void:
  410.  
  411.     EraseRegion(MOVE_REGION);
  412. corp;
  413.  
  414. /* a standard button handler for the above buttons */
  415.  
  416. define t_graphics proc public StandardButtonHandler(int whichButton)void:
  417.  
  418.     case whichButton
  419.     incase NW_BUTTON:
  420.     InsertCommand("northwest");
  421.     incase N_BUTTON:
  422.     InsertCommand("north");
  423.     incase NE_BUTTON:
  424.     InsertCommand("northeast");
  425.     incase W_BUTTON:
  426.     InsertCommand("west");
  427.     incase L_BUTTON:
  428.     InsertCommand("look");
  429.     incase E_BUTTON:
  430.     InsertCommand("east");
  431.     incase SW_BUTTON:
  432.     InsertCommand("southwest");
  433.     incase S_BUTTON:
  434.     InsertCommand("south");
  435.     incase SE_BUTTON:
  436.     InsertCommand("southeast");
  437.     incase U_BUTTON:
  438.     InsertCommand("up");
  439.     incase D_BUTTON:
  440.     InsertCommand("down");
  441.     incase I_BUTTON:
  442.     InsertCommand("in");
  443.     incase O_BUTTON:
  444.     InsertCommand("out");
  445.     default:
  446.     Print("Unknown button ");
  447.     IPrint(whichButton);
  448.     Print(" hit!\n");
  449.     esac;
  450. corp;
  451.  
  452. /* a standard region hit handler for the above region */
  453.  
  454. define t_graphics proc public StandardMouseDownHandler(int region, x, y)void:
  455.     thing here;
  456.     fixed fracX, fracY;
  457.     int rows, cols, cursorX, cursorY, deltaX, deltaY;
  458.  
  459.     if region = MOVE_REGION then
  460.     here := Here();
  461.     fracX := here@p_rCursorX;
  462.     fracY := here@p_rCursorY;
  463.     if fracX = 0.0 and fracY = 0.0 and here@p_rAutoGraphics then
  464.         /* pick the middle of the mapping region */
  465.         fracX := 0.25;
  466.         fracY := 0.5;
  467.     fi;
  468.     rows := GRows(nil);
  469.     cols := GCols(nil);
  470.     cursorX := FixedToInt(fracX * IntToFixed(cols));
  471.     cursorY := FixedToInt(fracY * IntToFixed(rows));
  472.     if cursorX < x then
  473.         deltaX := x - cursorX;
  474.     else
  475.         deltaX := cursorX - x;
  476.     fi;
  477.     if cursorY < y then
  478.         deltaY := y - cursorY;
  479.     else
  480.         deltaY := cursorY - y;
  481.     fi;
  482.     if deltaY * 10 <= deltaX * 4 then
  483.         if x < cursorX then
  484.         InsertCommand("west");
  485.         else
  486.         InsertCommand("east");
  487.         fi;
  488.     elif deltaX * 10 <= deltaY * 4 then
  489.         if y < cursorY then
  490.         InsertCommand("north");
  491.         else
  492.         InsertCommand("south");
  493.         fi;
  494.     else
  495.         if x < cursorX then
  496.         if y < cursorY then
  497.             InsertCommand("northwest");
  498.         else
  499.             InsertCommand("southwest");
  500.         fi;
  501.         else
  502.         if y < cursorY then
  503.             InsertCommand("northeast");
  504.         else
  505.             InsertCommand("southeast");
  506.         fi;
  507.         fi;
  508.     fi;
  509.     else
  510.     Print("Unknown region ");
  511.     IPrint(region);
  512.     Print(" hit!\n");
  513.     fi;
  514. corp;
  515.  
  516. /* set up the standard graphics stuff. */
  517.  
  518. define t_graphics p_pStandardGraphicsDone CreateBoolProp()$
  519.  
  520. define t_graphics proc public InitStandardGraphics()void:
  521.     thing me;
  522.  
  523.     me := Me();
  524.     GClear(nil);
  525.     DrawRoomNameBox();
  526.     AddStandardButtons();
  527.     AddStandardRegions();
  528.     SetCursorPen(me@p_pCursorColour);
  529.     SetCursorPattern(me@p_pCursor);
  530.     GSetIconPen(nil, me@p_pIconColour);
  531.     me@p_pStandardGraphicsDone := true;
  532. corp;
  533.  
  534. /* Simply display the currently set image file. Using this routine keeps
  535.    all of the magic "GShowImage" parameters all in one place. */
  536.  
  537. define t_graphics proc public ShowCurrentImage()void:
  538.  
  539.     GShowImage(nil, "", 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.5, 1.0);
  540. corp;
  541.  
  542. define t_graphics proc public ShowImage(string name)void:
  543.  
  544.     GSetImage(nil, name);
  545.     IfFound(nil);
  546.     RemoveCursor();
  547.     GResetIcons(nil);
  548.     ShowCurrentImage();
  549.     Fi(nil);
  550.     Me()@p_MapGroup := NO_MAP_GROUP;
  551. corp;
  552.  
  553. define t_graphics proc public ShowImageAndRefresh(string name)void:
  554.  
  555.     GSetImage(nil, name);
  556.     IfFound(nil);
  557.     RemoveCursor();
  558.     GResetIcons(nil);
  559.     ShowCurrentImage();
  560.     GRedrawIcons(nil);
  561.     PlaceCursor(0.253 - 3.0 / IntToFixed(GCols(nil)),
  562.             0.499  - 3.0 / IntToFixed(GRows(nil)));
  563.     Fi(nil);
  564.     Me()@p_MapGroup := NO_MAP_GROUP;
  565. corp;
  566.  
  567. define tp_graphics CLEAR_GRAPHICS_ID NextEffectId()$
  568.  
  569. define t_graphics proc public ClearGraphics()void:
  570.  
  571.     if not KnowsEffect(nil, CLEAR_GRAPHICS_ID) then
  572.     DefineEffect(nil, CLEAR_GRAPHICS_ID);
  573.     GSetPen(nil, C_BLACK);
  574.     GAMove(nil, 0.0, 0.0);
  575.     GRectangle(nil, 0.5, 1.0, true);
  576.     EndEffect();
  577.     fi;
  578.     CallEffect(nil, CLEAR_GRAPHICS_ID);
  579. corp;
  580.  
  581. /* these are used when entering and exiting a room using this scheme. */
  582.  
  583. define t_graphics proc public EnterRoomDraw()void:
  584.     thing me, here;
  585.     int g, len, pos;
  586.     fixed xAdj, yAdj;
  587.     string name;
  588.     action a;
  589.  
  590.     xAdj := 3.0 / IntToFixed(GCols(nil));
  591.     yAdj := 3.0 / IntToFixed(GRows(nil));
  592.     me := Me();
  593.     here := Here();
  594.     g := me@p_MapGroup;
  595.     if here@p_rAutoGraphics and here@p_rDrawAction = nil then
  596.     if g ~= AUTO_MAP_GROUP then
  597.         if not me@p_pStandardGraphicsDone then
  598.         InitStandardGraphics();
  599.         else
  600.         ClearGraphics();
  601.         fi;
  602.         me@p_MapGroup := AUTO_MAP_GROUP;
  603.     fi;
  604.     a := here@p_rAutoDrawAction;
  605.     if here@p_Image ~= "" then
  606.         /* Use key 0 - this is a temporary effect only. */
  607.         DefineEffect(nil, 0);
  608.         GSetImage(nil, here@p_Image);
  609.         IfFound(nil);
  610.         ShowCurrentImage();
  611.         Else(nil);
  612.         if a ~= nil then
  613.             call(a, void)();
  614.         fi;
  615.         Fi(nil);
  616.         EndEffect();
  617.         CallEffect(nil, 0);
  618.     else
  619.         if a ~= nil then
  620.         call(a, void)();
  621.         fi;
  622.     fi;
  623.     if here@p_rName1 ~= "" then
  624.         DrawRoomName(here@p_rName1, here@p_rName2);
  625.     else
  626.         a := here@p_rNameAction;
  627.         if a ~= nil then
  628.         name := call(a, string)();
  629.         else
  630.         name := here@p_rName;
  631.         fi;
  632.         len := Length(name);
  633.         pos := len - 1;
  634.         while pos ~= 0 and SubString(name, pos, 1) ~= " " do
  635.         pos := pos - 1;
  636.         od;
  637.         if SubString(name, pos, 1) = " " then
  638.         pos := pos + 1;
  639.         fi;
  640.         DrawRoomName(Capitalize(SubString(name, pos, len - pos)), "");
  641.     fi;
  642.     PlaceCursor(0.253 - xAdj, 0.499 - yAdj);
  643.     else
  644.     if g = NO_MAP_GROUP then
  645.         /* The place the character was previously at did not use room
  646.            graphics, so start it up */
  647.         if not me@p_pStandardGraphicsDone then
  648.         InitStandardGraphics();
  649.         else
  650.         ClearGraphics();
  651.         fi;
  652.     fi;
  653.     if g ~= here@p_MapGroup then
  654.         /* The current room (the character has just entered it, or is doing
  655.            a 'look'), uses room graphics, and the map group for the room
  656.            is different from that which was last shown to the player.
  657.            Remember the new group in the player, clear the room graphics
  658.            area, and call the room's display function. */
  659.         me@p_MapGroup := here@p_MapGroup;
  660.         ClearGraphics();
  661.         a := here@p_rDrawAction;
  662.         if a ~= nil then
  663.         call(a, void)();
  664.         fi;
  665.     fi;
  666.     DrawRoomName(here@p_rName1, here@p_rName2);
  667.     if here@p_rCursorX ~= 0.0 or here@p_rCursorY ~= 0.0 then
  668.         /* Location specifies center of cursor. Adjust for the standard
  669.            7x7 cursor pattern. */
  670.         PlaceCursor(here@p_rCursorX - xAdj, here@p_rCursorY - yAdj);
  671.     fi;
  672.     fi;
  673. corp;
  674.  
  675. define t_graphics proc public LeaveRoomDraw(thing dest)void:
  676.  
  677.     RemoveCursor();
  678.     if dest = nil or dest@p_rEnterRoomDraw = nil then
  679.     /* No room graphics in destination - clear the display area, etc. */
  680.     ClearGraphics();
  681.     DrawRoomName("", "");
  682.     Me()@p_MapGroup := NO_MAP_GROUP;
  683.     fi;
  684. corp;
  685.  
  686. /*
  687.  * RoomGraphics - set up a room for standard form custom graphics.
  688.  */
  689.  
  690. define t_graphics proc public RoomGraphics(thing room; string name1, name2;
  691.     int group; fixed x, y; action drawAction)void:
  692.  
  693.     room -- p_rAutoGraphics;
  694.     if name1 ~= "" then
  695.     room@p_rName1 := name1;
  696.     fi;
  697.     if name2 ~= "" then
  698.     room@p_rName2 := name2;
  699.     fi;
  700.     room@p_MapGroup := group;
  701.     if x ~= 0.0 then
  702.     room@p_rCursorX := x;
  703.     fi;
  704.     if y ~= 0.0 then
  705.     room@p_rCursorY := y;
  706.     fi;
  707.     if drawAction ~= nil then
  708.     room@p_rDrawAction := drawAction;
  709.     fi;
  710.     room@p_rEnterRoomDraw := EnterRoomDraw;
  711.     room@p_rLeaveRoomDraw := LeaveRoomDraw;
  712. corp;
  713.  
  714. /* the following few are 'utility' so they can be used in build code */
  715.  
  716. /*
  717.  * AutoGraphics - set up a room to use auto graphics.
  718.  */
  719.  
  720. define t_graphics proc public utility AutoGraphics(thing room;
  721.     action drawAction)void:
  722.  
  723.     room@p_rAutoGraphics := true;
  724.     room@p_rEnterRoomDraw := EnterRoomDraw;
  725.     room@p_rLeaveRoomDraw := LeaveRoomDraw;
  726.     room@p_rAutoDrawAction := drawAction;
  727. corp;
  728.  
  729. /*
  730.  * AutoRedraw - redraw the room for the current user.
  731.  */
  732.  
  733. define t_graphics proc public utility AutoRedraw()void:
  734.     action a;
  735.  
  736.     if Here()@p_rDrawAction = nil then
  737.     a := Here()@p_rAutoDrawAction;
  738.     if a ~= nil then
  739.         GUndrawIcons(nil);
  740.         RemoveCursor();
  741.         call(a, void)();
  742.         GRedrawIcons(nil);
  743.         PlaceCursor(0.253 - 3.0 / IntToFixed(GCols(nil)),
  744.             0.499  - 3.0 / IntToFixed(GRows(nil)));
  745.     fi;
  746.     fi;
  747. corp;
  748.  
  749. /*
  750.  * AutoPens - set the pens for auto graphics.
  751.  */
  752.  
  753. define t_graphics proc public utility AutoPens(thing room;
  754.     int back, fore, edge, door)void:
  755.  
  756.     if back ~= 0 then
  757.     room@p_rBackGroundPen := back;
  758.     else
  759.     room -- p_rBackGroundPen;
  760.     fi;
  761.     if fore ~= 0 then
  762.     room@p_rForeGroundPen := fore;
  763.     else
  764.     room -- p_rForeGroundPen;
  765.     fi;
  766.     if edge ~= 0 then
  767.     room@p_rEdgePen := edge;
  768.     else
  769.     room -- p_rEdgePen;
  770.     fi;
  771.     if door ~= 0 then
  772.     room@p_rDoorPen := door;
  773.     else
  774.     room -- p_rDoorPen;
  775.     fi;
  776. corp;
  777.  
  778. /*
  779.  * RoomName - set the graphics name of the room.
  780.  */
  781.  
  782. define t_graphics proc public utility RoomName(thing room;
  783.     string name1, name2)void:
  784.  
  785.     room@p_rName1 := name1;
  786.     if name2 ~= "" then
  787.     room@p_rName2 := name2;
  788.     else
  789.     room -- p_rName2;
  790.     fi;
  791. corp;
  792.  
  793. /*
  794.  * TextBox - draw, as the complete graphics for a room, a pretty box
  795.  *    containing 1, 2, or 3 lines of text. Heavy assumption of using
  796.  *    an 8 x 8 fixed font.
  797.  */
  798.  
  799. define t_graphics proc TextBox(string s1, s2, s3)void:
  800.     int rows, cols, maxChars, xOffset, yOffset, len1, len2, len3,
  801.     width, height, i;
  802.  
  803.     rows := GRows(nil);
  804.     cols := GCols(nil) / 2;
  805.     maxChars := (cols - 10) / 8;
  806.     len1 := Length(s1);
  807.     if len1 > maxChars then
  808.     len1 := maxChars;
  809.     fi;
  810.     len2 := Length(s2);
  811.     if len2 > maxChars then
  812.     len2 := maxChars;
  813.     fi;
  814.     len3 := Length(s3);
  815.     if len3 > maxChars then
  816.     len3 := maxChars;
  817.     fi;
  818.     maxChars := len1;
  819.     if len2 > maxChars then
  820.     maxChars := len2;
  821.     fi;
  822.     if len3 > maxChars then
  823.     maxChars := len3;
  824.     fi;
  825.     xOffset := (cols - 10 - maxChars * 8) / 2;
  826.     width := 10 + maxChars * 8;
  827.     if s3 = "" then
  828.     if s2 = "" then
  829.         yOffset := (rows - 10 - 1 * 8) / 2;
  830.         height := 10 + 1 * 8;
  831.     else
  832.         yOffset := (rows - 10 - 2 * 8) / 2;
  833.         height := 11 + 2 * 8;
  834.     fi;
  835.     else
  836.     yOffset := (rows - 10 - 3 * 8) / 2;
  837.     height := 12 + 3 * 8;
  838.     fi;
  839.     GAMovePixels(nil, xOffset, yOffset);
  840.     for i from 0 upto 3 do
  841.     GSetPen(nil, i + 1);
  842.     GRectanglePixels(nil, width, height, false);
  843.     GRMovePixels(nil, 1, 1);
  844.     width := width - 2;
  845.     height := height - 2;
  846.     od;
  847.     xOffset := xOffset + 5;
  848.     GSetPen(nil, C_GOLD);
  849.     GAMovePixels(nil, xOffset + (maxChars - len1) * 4, yOffset + 11);
  850.     GText(nil, s1);
  851.     if s2 ~= "" then
  852.     GAMovePixels(nil, xOffset + (maxChars - len2) * 4, yOffset + 20);
  853.     GText(nil, s2);
  854.     if s3 ~= "" then
  855.         GAMovePixels(nil, xOffset + (maxChars - len3) * 4, yOffset + 29);
  856.         GText(nil, s3);
  857.     fi;
  858.     fi;
  859. corp;
  860.  
  861.  
  862. define tp_graphics GOLD_UP_ARROW_ID NextEffectId()$
  863. define tp_graphics GOLD_DOWN_ARROW_ID NextEffectId()$
  864.  
  865. /*
  866.  * DrawUpArrow - draw the up arrow.
  867.  */
  868.  
  869. define t_graphics proc public DrawUpArrow(int pen)void:
  870.  
  871.     if pen = C_GOLD then
  872.     if not KnowsEffect(nil, GOLD_UP_ARROW_ID) then
  873.         DefineEffect(nil, GOLD_UP_ARROW_ID);
  874.         GSetPen(nil, C_GOLD);
  875.         GAMove(nil, 0.26874, 0.45);
  876.         GRDraw(nil, 0.01563, -0.05);
  877.         GRDraw(nil, 0.01563, 0.05);
  878.         GRMove(nil, -0.01563, -0.05);
  879.         GRDraw(nil, 0.0, 0.2);
  880.         EndEffect();
  881.     fi;
  882.     CallEffect(nil, GOLD_UP_ARROW_ID);
  883.     else
  884.     GSetPen(nil, pen);
  885.     GAMove(nil, 0.26874, 0.45);
  886.     GRDraw(nil, 0.01563, -0.05);
  887.     GRDraw(nil, 0.01563, 0.05);
  888.     GRMove(nil, -0.01563, -0.05);
  889.     GRDraw(nil, 0.0, 0.20);
  890.     fi;
  891. corp;
  892.  
  893. /*
  894.  * DrawDownArrow - draw the down arrow.
  895.  */
  896.  
  897. define t_graphics proc public DrawDownArrow(int pen)void:
  898.  
  899.     if pen = C_GOLD then
  900.     if not KnowsEffect(nil, GOLD_DOWN_ARROW_ID) then
  901.         DefineEffect(nil, GOLD_DOWN_ARROW_ID);
  902.         GSetPen(nil, C_GOLD);
  903.         GAMove(nil, 0.2, 0.55);
  904.         GRDraw(nil, 0.01563, 0.05);
  905.         GRDraw(nil, 0.01563, -0.05);
  906.         GRMove(nil, -0.01563, 0.05);
  907.         GRDraw(nil, 0.0, -0.2);
  908.         EndEffect();
  909.     fi;
  910.     CallEffect(nil, GOLD_DOWN_ARROW_ID);
  911.     else
  912.     GSetPen(nil, pen);
  913.     GAMove(nil, 0.2, 0.55);
  914.     GRDraw(nil, 0.01563, 0.05);
  915.     GRDraw(nil, 0.01563, -0.05);
  916.     GRMove(nil, -0.01563, 0.05);
  917.     GRDraw(nil, 0.0, -0.2);
  918.     fi;
  919. corp;
  920.  
  921. /*
  922.  * DrawUpDown - draw up/down arrows for any of the auto graphics.
  923.  */
  924.  
  925. define t_graphics proc public DrawUpDown(thing here; list int exits)void:
  926.     int pen;
  927.  
  928.     pen := here@p_rEdgePen;
  929.     if pen = 0 or pen = here@p_rBackGroundPen or pen = here@p_rForeGroundPen
  930.     then
  931.     pen := C_GOLD;
  932.     fi;
  933.     if FindElement(exits, D_UP) ~= -1 then
  934.     DrawUpArrow(pen);
  935.     fi;
  936.     if FindElement(exits, D_DOWN) ~= -1 then
  937.     DrawDownArrow(pen);
  938.     fi;
  939. corp;
  940.  
  941. /*
  942.  * AutoRoads - autodraw a roads view.
  943.  */
  944.  
  945. define t_graphics proc public AutoRoads()void:
  946.     thing here;
  947.     int background, foreground;
  948.     list int exits;
  949.  
  950.     here := Here();
  951.     background := here@p_rBackGroundPen;
  952.     foreground := here@p_rForeGroundPen;
  953.     if background = 0 and foreground = 0 then
  954.     background := C_DARK_GREEN;
  955.     foreground := C_TAN;
  956.     fi;
  957.     exits := here@p_rExits;
  958.     GSetPen(nil, background);
  959.     GAMove(nil, 0.0, 0.0);
  960.     GRectangle(nil, 0.5, 1.0, true);
  961.     GSetPen(nil, foreground);
  962.     GAMove(nil, 0.25, 0.5);
  963.     GEllipse(nil, 0.04688, 0.12, true);
  964.     if exits ~= nil then
  965.     if FindElement(exits, D_NORTH) ~= -1 then
  966.         GAMove(nil, 0.20313, 0.0);
  967.         GRectangle(nil, 0.09375, 0.5, true);
  968.     fi;
  969.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  970.         GPolygonStart(nil);
  971.         GAMove(nil, 0.499, 0.0);
  972.         GADraw(nil, 0.499, 0.16);
  973.         GADraw(nil, 0.28, 0.595);
  974.         GADraw(nil, 0.22, 0.425);
  975.         GADraw(nil, 0.43, 0.0);
  976.         GPolygonEnd(nil);
  977.     fi;
  978.     if FindElement(exits, D_EAST) ~= -1 then
  979.         GAMove(nil, 0.25, 0.39);
  980.         GRectangle(nil, 0.25, 0.24, true);
  981.     fi;
  982.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  983.         GPolygonStart(nil);
  984.         GAMove(nil, 0.499, 0.999);
  985.         GADraw(nil, 0.499, 0.83);
  986.         GADraw(nil, 0.276, 0.405);
  987.         GADraw(nil, 0.226, 0.6);
  988.         GADraw(nil, 0.43, 0.999);
  989.         GPolygonEnd(nil);
  990.     fi;
  991.     if FindElement(exits, D_SOUTH) ~= -1 then
  992.         GAMove(nil, 0.20313, 0.5);
  993.         GRectangle(nil, 0.09375, 0.499, true);
  994.     fi;
  995.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  996.         GPolygonStart(nil);
  997.         GAMove(nil, 0.0, 0.999);
  998.         GADraw(nil, 0.067, 0.999);
  999.         GADraw(nil, 0.285, 0.58);
  1000.         GADraw(nil, 0.232, 0.405);
  1001.         GADraw(nil, 0.0, 0.83);
  1002.         GPolygonEnd(nil);
  1003.     fi;
  1004.     if FindElement(exits, D_WEST) ~= -1 then
  1005.         GAMove(nil, 0.0, 0.39);
  1006.         GRectangle(nil, 0.25, 0.24, true);
  1007.     fi;
  1008.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1009.         GPolygonStart(nil);
  1010.         GAMove(nil, 0.0, 0.0);
  1011.         GADraw(nil, 0.075, 0.0);
  1012.         GADraw(nil, 0.276, 0.405);
  1013.         GADraw(nil, 0.226, 0.6);
  1014.         GADraw(nil, 0.0, 0.16);
  1015.         GPolygonEnd(nil);
  1016.     fi;
  1017.     DrawUpDown(here, exits);
  1018.     fi;
  1019. corp;
  1020.  
  1021. /*
  1022.  * AutoPaths - autodraw a paths view.
  1023.  */
  1024.  
  1025. define t_graphics proc public AutoPaths()void:
  1026.     thing here;
  1027.     int background, foreground;
  1028.     list int exits;
  1029.  
  1030.     here := Here();
  1031.     background := here@p_rBackGroundPen;
  1032.     foreground := here@p_rForeGroundPen;
  1033.     if background = 0 and foreground = 0 then
  1034.     background := C_FOREST_GREEN;
  1035.     foreground := C_TAN;
  1036.     fi;
  1037.     exits := here@p_rExits;
  1038.     GSetPen(nil, background);
  1039.     GAMove(nil, 0.0, 0.0);
  1040.     GRectangle(nil, 0.5, 1.0, true);
  1041.     GSetPen(nil, foreground);
  1042.     GAMove(nil, 0.252, 0.499);
  1043.     GEllipse(nil, 0.01563, 0.05, true);
  1044.     if exits ~= nil then
  1045.     if FindElement(exits, D_NORTH) ~= -1 then
  1046.         GAMove(nil, 0.2376, 0.0);
  1047.         GRectangle(nil, 0.029, 0.5, true);
  1048.     fi;
  1049.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1050.         GPolygonStart(nil);
  1051.         GAMove(nil, 0.499, 0.0);
  1052.         GADraw(nil, 0.499, 0.05);
  1053.         GADraw(nil, 0.257, 0.536);
  1054.         GADraw(nil, 0.24, 0.475);
  1055.         GADraw(nil, 0.475, 0.0);
  1056.         GPolygonEnd(nil);
  1057.     fi;
  1058.     if FindElement(exits, D_EAST) ~= -1 then
  1059.         GAMove(nil, 0.25, 0.455);
  1060.         GRectangle(nil, 0.25, 0.095, true);
  1061.     fi;
  1062.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1063.         GPolygonStart(nil);
  1064.         GAMove(nil, 0.499, 0.999);
  1065.         GADraw(nil, 0.499, 0.94);
  1066.         GADraw(nil, 0.26, 0.465);
  1067.         GADraw(nil, 0.24, 0.52);
  1068.         GADraw(nil, 0.475, 0.999);
  1069.         GPolygonEnd(nil);
  1070.     fi;
  1071.     if FindElement(exits, D_SOUTH) ~= -1 then
  1072.         GAMove(nil, 0.2376, 0.5);
  1073.         GRectangle(nil, 0.029, 0.5, true);
  1074.     fi;
  1075.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1076.         GPolygonStart(nil);
  1077.         GAMove(nil, 0.0, 0.999);
  1078.         GADraw(nil, 0.022, 0.999);
  1079.         GADraw(nil, 0.261, 0.53);
  1080.         GADraw(nil, 0.244, 0.465);
  1081.         GADraw(nil, 0.0, 0.94);
  1082.         GPolygonEnd(nil);
  1083.     fi;
  1084.     if FindElement(exits, D_WEST) ~= -1 then
  1085.         GAMove(nil, 0.0, 0.455);
  1086.         GRectangle(nil, 0.252, 0.095, true);
  1087.     fi;
  1088.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1089.         GPolygonStart(nil);
  1090.         GAMove(nil, 0.0, 0.0);
  1091.         GADraw(nil, 0.022, 0.0);
  1092.         GADraw(nil, 0.26, 0.465);
  1093.         GADraw(nil, 0.24, 0.525);
  1094.         GADraw(nil, 0.0, 0.05);
  1095.         GPolygonEnd(nil);
  1096.     fi;
  1097.     DrawUpDown(here, exits);
  1098.     fi;
  1099. corp;
  1100.  
  1101. /*
  1102.  * AutoTunnels - autodraw a tunnels view.
  1103.  */
  1104.  
  1105. define t_graphics proc public AutoTunnels()void:
  1106.     thing here;
  1107.     int background, foreground;
  1108.     list int exits;
  1109.  
  1110.     here := Here();
  1111.     background := here@p_rBackGroundPen;
  1112.     foreground := here@p_rForeGroundPen;
  1113.     if background = 0 and foreground = 0 then
  1114.     background := C_DARK_GREY;
  1115.     foreground := C_LIGHT_GREY;
  1116.     fi;
  1117.     exits := here@p_rExits;
  1118.     GSetPen(nil, background);
  1119.     GAMove(nil, 0.0, 0.0);
  1120.     GRectangle(nil, 0.5, 1.0, true);
  1121.     GSetPen(nil, foreground);
  1122.     GAMove(nil, 0.25, 0.497);
  1123.     GEllipse(nil, 0.04375, 0.08, true);
  1124.     if exits ~= nil then
  1125.     if FindElement(exits, D_NORTH) ~= -1 then
  1126.         GAMove(nil, 0.207, 0.0);
  1127.         GRectangle(nil, 0.087, 0.5, true);
  1128.     fi;
  1129.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1130.         GPolygonStart(nil);
  1131.         GAMove(nil, 0.499, 0.0);
  1132.         GADraw(nil, 0.499, 0.13);
  1133.         GADraw(nil, 0.267, 0.575);
  1134.         GADraw(nil, 0.22, 0.454);
  1135.         GADraw(nil, 0.445, 0.0);
  1136.         GPolygonEnd(nil);
  1137.     fi;
  1138.     if FindElement(exits, D_EAST) ~= -1 then
  1139.         GAMove(nil, 0.25, 0.425);
  1140.         GRectangle(nil, 0.25, 0.155, true);
  1141.     fi;
  1142.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1143.         GPolygonStart(nil);
  1144.         GAMove(nil, 0.499, 0.999);
  1145.         GADraw(nil, 0.499, 0.86);
  1146.         GADraw(nil, 0.276, 0.44);
  1147.         GADraw(nil, 0.226, 0.56);
  1148.         GADraw(nil, 0.445, 0.999);
  1149.         GPolygonEnd(nil);
  1150.     fi;
  1151.     if FindElement(exits, D_SOUTH) ~= -1 then
  1152.         GAMove(nil, 0.207, 0.5);
  1153.         GRectangle(nil, 0.087, 0.5, true);
  1154.     fi;
  1155.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1156.         GPolygonStart(nil);
  1157.         GAMove(nil, 0.0, 0.999);
  1158.         GADraw(nil, 0.043, 0.999);
  1159.         GADraw(nil, 0.276, 0.56);
  1160.         GADraw(nil, 0.227, 0.435);
  1161.         GADraw(nil, 0.0, 0.86);
  1162.         GPolygonEnd(nil);
  1163.     fi;
  1164.     if FindElement(exits, D_WEST) ~= -1 then
  1165.         GAMove(nil, 0.0, 0.425);
  1166.         GRectangle(nil, 0.25, 0.155, true);
  1167.     fi;
  1168.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1169.         GPolygonStart(nil);
  1170.         GAMove(nil, 0.0, 0.0);
  1171.         GADraw(nil, 0.043, 0.0);
  1172.         GADraw(nil, 0.276, 0.435);
  1173.         GADraw(nil, 0.228, 0.56);
  1174.         GADraw(nil, 0.0, 0.13);
  1175.         GPolygonEnd(nil);
  1176.     fi;
  1177.     DrawUpDown(here, exits);
  1178.     fi;
  1179. corp;
  1180.  
  1181. define tp_graphics GREYS_TUNNEL_CHAMBER_ID NextEffectId()$
  1182.  
  1183. define tp_graphics proc chamberStrokes(int background, foreground)void:
  1184.  
  1185.     GSetPen(nil, background);
  1186.     GAMove(nil, 0.0, 0.0);
  1187.     GRectangle(nil, 0.5, 1.0, true);
  1188.     GSetPen(nil, foreground);
  1189.     GPolygonStart(nil);
  1190.     GAMove(nil, 0.125, 0.2);
  1191.     GADraw(nil, 0.373, 0.2);
  1192.     GADraw(nil, 0.435, 0.35);
  1193.     GADraw(nil, 0.435, 0.65);
  1194.     GADraw(nil, 0.373, 0.8);
  1195.     GADraw(nil, 0.125, 0.8);
  1196.     GADraw(nil, 0.062,0.65);
  1197.     GADraw(nil, 0.062, 0.35);
  1198.     GPolygonEnd(nil);
  1199. corp;
  1200.  
  1201. /*
  1202.  * DrawTunnelChamber - draw the non-exit part of a tunnel chamber.
  1203.  */
  1204.  
  1205. define t_graphics proc public DrawTunnelChamber(int background,foreground)void:
  1206.  
  1207.     if background = C_DARK_GREY and foreground = C_LIGHT_GREY then
  1208.     if not KnowsEffect(nil, GREYS_TUNNEL_CHAMBER_ID) then
  1209.         DefineEffect(nil, GREYS_TUNNEL_CHAMBER_ID);
  1210.         chamberStrokes(C_DARK_GREY, C_LIGHT_GREY);
  1211.         EndEffect();
  1212.     fi;
  1213.     CallEffect(nil, GREYS_TUNNEL_CHAMBER_ID);
  1214.     else
  1215.     chamberStrokes(background, foreground);
  1216.     fi;
  1217. corp;
  1218.  
  1219. /*
  1220.  * AutoTunnelChamber - autodraw a large tunnel chamber.
  1221.  */
  1222.  
  1223. define t_graphics proc public AutoTunnelChamber()void:
  1224.     thing here;
  1225.     int background, foreground;
  1226.     list int exits;
  1227.  
  1228.     here := Here();
  1229.     background := here@p_rBackGroundPen;
  1230.     foreground := here@p_rForeGroundPen;
  1231.     if background = 0 and foreground = 0 then
  1232.     background := C_DARK_GREY;
  1233.     foreground := C_LIGHT_GREY;
  1234.     fi;
  1235.     DrawTunnelChamber(background, foreground);
  1236.     exits := here@p_rExits;
  1237.     if exits ~= nil then
  1238.     if FindElement(exits, D_NORTH) ~= -1 then
  1239.         GAMove(nil, 0.20313, 0.0);
  1240.         GRectangle(nil, 0.09063, 0.2, true);
  1241.     fi;
  1242.     if FindElement(exits, D_SOUTH) ~= -1 then
  1243.         GAMove(nil, 0.20313, 0.79);
  1244.         GRectangle(nil, 0.09063, 0.299, true);
  1245.     fi;
  1246.     if FindElement(exits, D_EAST) ~= -1 then
  1247.         GAMove(nil, 0.4373, 0.42);
  1248.         GRectangle(nil, 0.0645, 0.15, true);
  1249.     fi;
  1250.     if FindElement(exits, D_WEST) ~= -1 then
  1251.         GAMove(nil, 0.0, 0.42);
  1252.         GRectangle(nil, 0.0625, 0.15, true);
  1253.     fi;
  1254.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1255.         GPolygonStart(nil);
  1256.         GAMove(nil, 0.374, 0.2);
  1257.         GADraw(nil, 0.435, 0.0);
  1258.         GADraw(nil, 0.499, 0.0);
  1259.         GADraw(nil, 0.499, 0.15);
  1260.         GADraw(nil, 0.436, 0.35);
  1261.         GPolygonEnd(nil);
  1262.     fi;
  1263.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1264.         GPolygonStart(nil);
  1265.         GAMove(nil, 0.374, 0.8);
  1266.         GADraw(nil, 0.436, 0.999);
  1267.         GADraw(nil, 0.499, 0.999);
  1268.         GADraw(nil, 0.499, 0.84);
  1269.         GADraw(nil, 0.436, 0.64);
  1270.         GPolygonEnd(nil);
  1271.     fi;
  1272.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1273.         GPolygonStart(nil);
  1274.         GAMove(nil, 0.125, 0.2);
  1275.         GADraw(nil, 0.065, 0.0);
  1276.         GADraw(nil, 0.0, 0.0);
  1277.         GADraw(nil, 0.0, 0.15);
  1278.         GADraw(nil, 0.063, 0.35);
  1279.         GPolygonEnd(nil);
  1280.     fi;
  1281.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1282.         GPolygonStart(nil);
  1283.         GAMove(nil, 0.125, 0.8);
  1284.         GADraw(nil, 0.063, 0.999);
  1285.         GADraw(nil, 0.0, 0.999);
  1286.         GADraw(nil, 0.0, 0.84);
  1287.         GADraw(nil, 0.063, 0.64);
  1288.         GPolygonEnd(nil);
  1289.     fi;
  1290.     DrawUpDown(here, exits);
  1291.     fi;
  1292. corp;
  1293.  
  1294. /*
  1295.  * AutoOpenSpace - autodraw an open space with edges.
  1296.  */
  1297.  
  1298. define t_graphics proc public AutoOpenSpace()void:
  1299.     thing here;
  1300.     int background, foreground;
  1301.     list int exits;
  1302.  
  1303.     here := Here();
  1304.     background := here@p_rBackGroundPen;
  1305.     foreground := here@p_rForeGroundPen;
  1306.     if background = 0 and foreground = 0 then
  1307.     foreground := C_DARK_GREEN;
  1308.     background := C_DARK_BROWN;
  1309.     fi;
  1310.     exits := here@p_rExits;
  1311.     GSetPen(nil, foreground);
  1312.     GAMove(nil, 0.0, 0.0);
  1313.     GRectangle(nil, 0.5, 1.0, true);
  1314.     GSetPen(nil, background);
  1315.     if exits ~= nil then
  1316.     if FindElement(exits, D_NORTH) = -1 then
  1317.         GAMove(nil, 0.125, 0.0);
  1318.         GRectangle(nil, 0.25, 0.19, true);
  1319.     fi;
  1320.     if FindElement(exits, D_NORTHEAST) = -1 then
  1321.         GPolygonStart(nil);
  1322.         GAMove(nil, 0.373, 0.0);
  1323.         GADraw(nil, 0.499, 0.0);
  1324.         GADraw(nil, 0.499, 0.295);
  1325.         GADraw(nil, 0.439, 0.295);
  1326.         GADraw(nil, 0.439, 0.19);
  1327.         GADraw(nil, 0.373, 0.19);
  1328.         GPolygonEnd(nil);
  1329.     fi;
  1330.     if FindElement(exits, D_EAST) = -1 then
  1331.         GAMove(nil, 0.438, 0.3);
  1332.         GRectangle(nil, 0.062, 0.39, true);
  1333.     fi;
  1334.     if FindElement(exits, D_SOUTHEAST) = -1 then
  1335.         GPolygonStart(nil);
  1336.         GAMove(nil, 0.499, 0.69);
  1337.         GADraw(nil, 0.499, 0.999);
  1338.         GADraw(nil, 0.376, 0.999);
  1339.         GADraw(nil, 0.376, 0.8);
  1340.         GADraw(nil, 0.439, 0.8);
  1341.         GADraw(nil, 0.439, 0.69);
  1342.         GPolygonEnd(nil);
  1343.     fi;
  1344.     if FindElement(exits, D_SOUTH) = -1 then
  1345.         GAMove(nil, 0.125, 0.8);
  1346.         GRectangle(nil, 0.25, 0.21, true);
  1347.     fi;
  1348.     if FindElement(exits, D_SOUTHWEST) = -1 then
  1349.         GPolygonStart(nil);
  1350.         GAMove(nil, 0.0, 0.69);
  1351.         GADraw(nil, 0.0, 0.999);
  1352.         GADraw(nil, 0.125, 0.999);
  1353.         GADraw(nil, 0.125, 0.8);
  1354.         GADraw(nil, 0.059, 0.8);
  1355.         GADraw(nil, 0.059, 0.69);
  1356.         GPolygonEnd(nil);
  1357.     fi;
  1358.     if FindElement(exits, D_WEST) = -1 then
  1359.         GAMove(nil, 0.0, 0.3);
  1360.         GRectangle(nil, 0.05938, 0.39, true);
  1361.     fi;
  1362.     if FindElement(exits, D_NORTHWEST) = -1 then
  1363.         GPolygonStart(nil);
  1364.         GAMove(nil, 0.0, 0.295);
  1365.         GADraw(nil, 0.0, 0.0);
  1366.         GADraw(nil, 0.125, 0.0);
  1367.         GADraw(nil, 0.125, 0.19);
  1368.         GADraw(nil, 0.059, 0.19);
  1369.         GADraw(nil, 0.059, 0.295);
  1370.         GPolygonEnd(nil);
  1371.     fi;
  1372.     DrawUpDown(here, exits);
  1373.     fi;
  1374. corp;
  1375.  
  1376. /*
  1377.  * AutoOpenRoom - autodraw a room with corridors.
  1378.  */
  1379.  
  1380. define t_graphics proc public AutoOpenRoom()void:
  1381.     thing here;
  1382.     int background, foreground, edge;
  1383.     list int exits;
  1384.  
  1385.     here := Here();
  1386.     background := here@p_rBackGroundPen;
  1387.     foreground := here@p_rForeGroundPen;
  1388.     edge := here@p_rEdgePen;
  1389.     if background = 0 and foreground = 0 and edge = 0 then
  1390.     foreground := C_BLACK;
  1391.     background := C_MEDIUM_GREY;
  1392.     edge := C_TAN;
  1393.     fi;
  1394.     exits := here@p_rExits;
  1395.     GSetPen(nil, background);
  1396.     GAMove(nil, 0.0, 0.0);
  1397.     GRectangle(nil, 0.5, 1.0, true);
  1398.     GSetPen(nil, foreground);
  1399.     GAMove(nil, 0.059, 0.2);
  1400.     GRectangle(nil, 0.38, 0.616, true);
  1401.     GSetPen(nil, edge);
  1402.     GAMove(nil, 0.059, 0.2);
  1403.     GRectangle(nil, 0.38, 0.616, false);
  1404.     if exits ~= nil then
  1405.     if FindElement(exits, D_NORTH) ~= -1 then
  1406.         GSetPen(nil, foreground);
  1407.         GAMove(nil, 0.206, 0.0);
  1408.         GRectangle(nil, 0.084, 0.2, true);
  1409.         GSetPen(nil, edge);
  1410.         GAMove(nil, 0.206, 0.0);
  1411.         GADraw(nil, 0.206, 0.2);
  1412.         GAMove(nil, 0.289, 0.0);
  1413.         GADraw(nil, 0.289, 0.2);
  1414.     fi;
  1415.     if FindElement(exits, D_SOUTH) ~= -1 then
  1416.         GSetPen(nil, foreground);
  1417.         GAMove(nil, 0.206, 0.805);
  1418.         GRectangle(nil, 0.084, 0.205, true);
  1419.         GSetPen(nil, edge);
  1420.         GAMove(nil, 0.206, 0.806);
  1421.         GADraw(nil, 0.206, 0.999);
  1422.         GAMove(nil, 0.289, 0.806);
  1423.         GADraw(nil, 0.289, 0.999);
  1424.     fi;
  1425.     if FindElement(exits, D_EAST) ~= -1 then
  1426.         GSetPen(nil, foreground);
  1427.         GAMove(nil, 0.435, 0.4);
  1428.         GRectangle(nil, 0.065, 0.2, true);
  1429.         GSetPen(nil, edge);
  1430.         GAMove(nil, 0.436, 0.4);
  1431.         GADraw(nil, 0.499, 0.4);
  1432.         GAMove(nil, 0.436, 0.6);
  1433.         GADraw(nil, 0.499, 0.6);
  1434.     fi;
  1435.     if FindElement(exits, D_WEST) ~= -1 then
  1436.         GSetPen(nil, foreground);
  1437.         GAMove(nil, 0.0, 0.4);
  1438.         GRectangle(nil, 0.059, 0.2, true);
  1439.         GSetPen(nil, edge);
  1440.         GAMove(nil, 0.0, 0.4);
  1441.         GADraw(nil, 0.059, 0.4);
  1442.         GAMove(nil, 0.0, 0.6);
  1443.         GADraw(nil, 0.059, 0.6);
  1444.     fi;
  1445.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1446.         GSetPen(nil, foreground);
  1447.         GAMove(nil, 0.39, 0.0);
  1448.         GRectangle(nil, 0.111, 0.27, true);
  1449.         GSetPen(nil, edge);
  1450.         GAMove(nil, 0.39, 0.0);
  1451.         GADraw(nil, 0.39, 0.2);
  1452.         GAMove(nil, 0.437, 0.275);
  1453.         GADraw(nil, 0.499, 0.275);
  1454.     fi;
  1455.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1456.         GSetPen(nil, foreground);
  1457.         GAMove(nil, 0.0, 0.0);
  1458.         GRectangle(nil, 0.118, 0.27, true);
  1459.         GSetPen(nil, edge);
  1460.         GAMove(nil, 0.118, 0.0);
  1461.         GADraw(nil, 0.118, 0.2);
  1462.         GAMove(nil, 0.0, 0.275);
  1463.         GADraw(nil, 0.059, 0.275);
  1464.     fi;
  1465.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1466.         GSetPen(nil, foreground);
  1467.         GAMove(nil, 0.39, 0.74);
  1468.         GRectangle(nil, 0.111, 0.27, true);
  1469.         GSetPen(nil, edge);
  1470.         GAMove(nil, 0.39, 0.806);
  1471.         GADraw(nil, 0.39, 0.999);
  1472.         GAMove(nil, 0.437, 0.735);
  1473.         GADraw(nil, 0.499, 0.735);
  1474.     fi;
  1475.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1476.         GSetPen(nil, foreground);
  1477.         GAMove(nil, 0.0, 0.74);
  1478.         GRectangle(nil, 0.118, 0.27, true);
  1479.         GSetPen(nil, edge);
  1480.         GAMove(nil, 0.118, 0.806);
  1481.         GADraw(nil, 0.118, 0.999);
  1482.         GAMove(nil, 0.0, 0.735);
  1483.         GADraw(nil, 0.059, 0.735);
  1484.     fi;
  1485.     DrawUpDown(here, exits);
  1486.     fi;
  1487. corp;
  1488.  
  1489. /*
  1490.  * AutoHalls - a simple horizontal/vertical hallway set.
  1491.  */
  1492.  
  1493. define t_graphics proc public AutoHalls()void:
  1494.     thing here;
  1495.     list int exits;
  1496.     int background, foreground, edge;
  1497.  
  1498.     here := Here();
  1499.     background := here@p_rBackGroundPen;
  1500.     foreground := here@p_rForeGroundPen;
  1501.     edge := here@p_rEdgePen;
  1502.     if background = 0 and foreground = 0 and edge = 0 then
  1503.     foreground := C_BLACK;
  1504.     background := C_MEDIUM_GREY;
  1505.     edge := C_TAN;
  1506.     fi;
  1507.     exits := here@p_rExits;
  1508.     GSetPen(nil, background);
  1509.     GAMove(nil, 0.0, 0.0);
  1510.     GRectangle(nil, 0.5, 1.0, true);
  1511.     GSetPen(nil, foreground);
  1512.     GAMove(nil, 0.21, 0.41);
  1513.     GRectangle(nil, 0.084, 0.195, true);
  1514.     GSetPen(nil, edge);
  1515.     GAMove(nil, 0.21, 0.41);
  1516.     GRectangle(nil, 0.084, 0.197, false);
  1517.     if exits ~= nil then
  1518.     if FindElement(exits, D_NORTH) ~= -1 then
  1519.         GSetPen(nil, foreground);
  1520.         GAMove(nil, 0.21, 0.0);
  1521.         GRectangle(nil, 0.0837, 0.41, true);
  1522.         GSetPen(nil, edge);
  1523.         GAMove(nil, 0.21, 0.0);
  1524.         GADraw(nil, 0.21, 0.41);
  1525.         GAMove(nil, 0.293, 0.0);
  1526.         GADraw(nil, 0.293, 0.41);
  1527.     fi;
  1528.     if FindElement(exits, D_SOUTH) ~= -1 then
  1529.         GSetPen(nil, foreground);
  1530.         GAMove(nil, 0.21, 0.59);
  1531.         GRectangle(nil, 0.0837, 0.42, true);
  1532.         GSetPen(nil, edge);
  1533.         GAMove(nil, 0.21, 0.59);
  1534.         GADraw(nil, 0.21, 0.999);
  1535.         GAMove(nil, 0.293, 0.59);
  1536.         GADraw(nil, 0.293, 0.999);
  1537.     fi;
  1538.     if FindElement(exits, D_EAST) ~= -1 then
  1539.         GSetPen(nil, foreground);
  1540.         GAMove(nil, 0.293, 0.41);
  1541.         GRectangle(nil, 0.208, 0.195, true);
  1542.         GSetPen(nil, edge);
  1543.         GAMove(nil, 0.293, 0.41);
  1544.         GADraw(nil, 0.499, 0.41);
  1545.         GAMove(nil, 0.293, 0.596);
  1546.         GADraw(nil, 0.499, 0.596);
  1547.     fi;
  1548.     if FindElement(exits, D_WEST) ~= -1 then
  1549.         GSetPen(nil, foreground);
  1550.         GAMove(nil, 0.0, 0.41);
  1551.         GRectangle(nil, 0.211, 0.195, true);
  1552.         GSetPen(nil, edge);
  1553.         GAMove(nil, 0.0, 0.41);
  1554.         GADraw(nil, 0.21, 0.41);
  1555.         GAMove(nil, 0.0, 0.596);
  1556.         GADraw(nil, 0.21, 0.596);
  1557.     fi;
  1558.     DrawUpDown(here, exits);
  1559.     fi;
  1560. corp;
  1561.  
  1562. /*
  1563.  * AutoClosedRoom - autodraw a room with doors.
  1564.  */
  1565.  
  1566. define t_graphics proc public AutoClosedRoom()void:
  1567.     thing here;
  1568.     int background, foreground, edge, door;
  1569.     list int exits;
  1570.  
  1571.     here := Here();
  1572.     background := here@p_rBackGroundPen;
  1573.     foreground := here@p_rForeGroundPen;
  1574.     edge := here@p_rEdgePen;
  1575.     door := here@p_rDoorPen;
  1576.     if background = 0 and foreground = 0 and edge = 0 and door = 0 then
  1577.     background := C_MEDIUM_GREY;
  1578.     foreground := C_BLACK;
  1579.     edge := C_TAN;
  1580.     door := C_BROWN;
  1581.     fi;
  1582.     exits := here@p_rExits;
  1583.     GSetPen(nil, background);
  1584.     GAMove(nil, 0.0, 0.0);
  1585.     GRectangle(nil, 0.5, 1.0, true);
  1586.     GSetPen(nil, foreground);
  1587.     GAMove(nil, 0.059, 0.2);
  1588.     GRectangle(nil, 0.38, 0.606, true);
  1589.     GSetPen(nil, edge);
  1590.     GAMove(nil, 0.059, 0.2);
  1591.     GRectangle(nil, 0.38, 0.606, false);
  1592.     GSetPen(nil, door);
  1593.     if exits ~= nil then
  1594.     if FindElement(exits, D_NORTH) ~= -1 then
  1595.         GAMove(nil, 0.235, 0.2);
  1596.         HorizontalDoor();
  1597.     fi;
  1598.     if FindElement(exits, D_SOUTH) ~= -1 then
  1599.         GAMove(nil, 0.235, 0.8);
  1600.         HorizontalDoor();
  1601.     fi;
  1602.     if FindElement(exits, D_EAST) ~= -1 then
  1603.         GAMove(nil, 0.436, 0.46);
  1604.         VerticalDoor();
  1605.     fi;
  1606.     if FindElement(exits, D_WEST) ~= -1 then
  1607.         GAMove(nil, 0.059, 0.46);
  1608.         VerticalDoor();
  1609.     fi;
  1610.     if FindElement(exits, D_NORTHEAST) ~= -1 then
  1611.         GSetPen(nil, background);
  1612.         GPolygonStart(nil);
  1613.         GAMove(nil, 0.42, 0.19);
  1614.         GADraw(nil, 0.436, 0.19);
  1615.         GADraw(nil, 0.436, 0.24);
  1616.         GPolygonEnd(nil);
  1617.         GSetPen(nil, door);
  1618.         GAMove(nil, 0.422, 0.2);
  1619.         NorthEastDoor();
  1620.     fi;
  1621.     if FindElement(exits, D_NORTHWEST) ~= -1 then
  1622.         GSetPen(nil, background);
  1623.         GPolygonStart(nil);
  1624.         GAMove(nil, 0.0735, 0.19);
  1625.         GADraw(nil, 0.059, 0.19);
  1626.         GADraw(nil, 0.059, 0.24);
  1627.         GPolygonEnd(nil);
  1628.         GSetPen(nil, door);
  1629.         GAMove(nil, 0.072, 0.2);
  1630.         NorthWestDoor();
  1631.     fi;
  1632.     if FindElement(exits, D_SOUTHEAST) ~= -1 then
  1633.         GSetPen(nil, background);
  1634.         GPolygonStart(nil);
  1635.         GAMove(nil, 0.42, 0.81);
  1636.         GADraw(nil, 0.436, 0.81);
  1637.         GADraw(nil, 0.436, 0.76);
  1638.         GPolygonEnd(nil);
  1639.         GSetPen(nil, door);
  1640.         GAMove(nil, 0.435, 0.76);
  1641.         NorthWestDoor();
  1642.     fi;
  1643.     if FindElement(exits, D_SOUTHWEST) ~= -1 then
  1644.         GSetPen(nil, background);
  1645.         GPolygonStart(nil);
  1646.         GAMove(nil, 0.0735, 0.81);
  1647.         GADraw(nil, 0.059, 0.81);
  1648.         GADraw(nil, 0.059, 0.76);
  1649.         GPolygonEnd(nil);
  1650.         GSetPen(nil, door);
  1651.         GAMove(nil, 0.059, 0.76);
  1652.         NorthEastDoor();
  1653.     fi;
  1654.     DrawUpDown(here, exits);
  1655.     fi;
  1656. corp;
  1657.  
  1658. unuse tp_graphics
  1659.