home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #7 / amigamamagazinepolishissue1998.iso / rozrywka / rpg / amigamud / src / proving / surface.m < prev    next >
Text File  |  1997-07-05  |  54KB  |  1,530 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1997 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * surface.m - surface level of the proving grounds.
  9.  */
  10.  
  11. use t_streets
  12.  
  13. /*
  14.  * monsterDrink - used for the drinking troll and the drinking goblin.
  15.  *    Half the time they will try to drink, other half will do normal stuff.
  16.  */
  17.  
  18. define tp_proving proc monsterDrink()bool:
  19.  
  20.     if FindName(Here()@p_rContents, p_oName, "water") = succeed and
  21.     Random(2) = 0
  22.     then
  23.     ignore Parse(G, "drink water");
  24.     else
  25.     DoMonsterMove(Me());
  26.     fi;
  27.     MonsterReschedule(Me());
  28.     true
  29. corp;
  30.  
  31. define tp_proving tp_surface CreateTable()$
  32. use tp_surface
  33.  
  34. define tp_surface proc monsterSet1(thing room)void:
  35.  
  36.     InitMonsterModels(room, 300);
  37.     AddPossibleMonster(room, m_rat, 25);
  38.     AddPossibleMonster(room, m_snake, 25);
  39.     AddPossibleMonster(room, m_dog, 25);
  40.     AddPossibleMonster(room, m_gremlin, 25);
  41. corp;
  42.  
  43. define tp_surface proc monsterSetP(thing room)void:
  44.  
  45.     InitMonsterModels(room, 325);
  46.     AddPossibleMonster(room, m_rat, 20);
  47.     AddPossibleMonster(room, m_snake, 35);
  48.     AddPossibleMonster(room, m_dog, 20);
  49.     AddPossibleMonster(room, m_gremlin, 20);
  50.     AddPossibleMonster(room, m_deer, 25);
  51. corp;
  52.  
  53. define tp_surface m_birds CreateMonsterModel("birds,bir;pair,of.pair",
  54.     "The birds sing nicely, but they are nothing special to look at.",
  55.     MonsterInit, RandomMove,
  56.     0, 20, 0, 0, 0, 0)$
  57. GNewIcon(m_birds, makeBirdIcon())$
  58. define tp_surface proc birdsHit(thing theBirds)void:
  59.     Print("The birds flutter out of reach.\n");
  60.     OPrint(Capitalize(CharacterNameG(Me())) +
  61.     " takes a swipe at the birds, but they flutter out of reach.\n");
  62. corp;
  63. m_birds@p_mFightAction := birdsHit$
  64. /* Birds will sing once, then leave. Note that we do this a bit special,
  65.    not using the p_mSound property, since we want the birds to leave as
  66.    soon as they sing. */
  67. define tp_surface BIRDS_SING_ID NextSoundEffectId()$
  68. define tp_surface proc birdsSingOnce(thing client)void:
  69.     if SOn(client) then
  70.     SPlaySound(client, "birds", 1, BIRDS_SING_ID);
  71.     IfFound(client);
  72.     Else(client);
  73.         FailText(client, "The birds sing.");
  74.     Fi(client);
  75.     else
  76.     SPrint(client, "The birds sing.\n");
  77.     fi;
  78. corp;
  79. define tp_surface proc birdsSing()bool:
  80.     ForEachAgent(Here(), birdsSingOnce);
  81.     Me()@p_mMovesUntilVanish := 0;
  82.     MonsterReschedule(Me());
  83.     true
  84. corp;
  85. m_birds@p_mSpecialAction := birdsSing$
  86. m_birds@p_Image := "Characters/birds"$
  87.  
  88. define tp_surface m_drinkingTroll CreateThing(m_troll)$
  89. m_drinkingTroll@p_mSpecialAction := monsterDrink$
  90. m_drinkingTroll@p_Image := "Characters/drinkingTroll"$
  91.  
  92. define tp_surface proc monsterSet2(thing room)void:
  93.  
  94.     InitMonsterModels(room, 400);
  95.     AddPossibleMonster(room, m_wolf, 25);
  96.     AddPossibleMonster(room, m_blackBear, 25);
  97.     AddPossibleMonster(room, m_deer, 25);
  98.     AddPossibleMonster(room, m_moose, 25);
  99.     AddPossibleMonster(room, m_drinkingTroll, 25);
  100.     AddPossibleMonster(room, m_birds, 25);
  101. corp;
  102.  
  103. define tp_surface r_warning CreateThing(r_outdoors)$
  104. SetupRoom(r_warning, "on an east-west path", "")$
  105. Connect(r_path2, r_warning, D_WEST)$
  106. AutoGraphics(r_warning, AutoPaths)$
  107. ExtendDesc(r_path2, "A sign reading 'To the Proving Grounds' points along "
  108.     "a path heading west.")$
  109. Sign(r_path2, "sign;simple,painted,wooden",
  110.     "The sign is a simple painted wooden sign on a post.",
  111.     "To the Proving Grounds")$
  112. Scenery(r_path2, "post.path.pathway")$
  113. define tp_proving proc warning()status:
  114.     if not Me()@p_pInited then
  115.     Print(
  116. "\nWARNING: The area to the west of here is a combat zone. If you chose to "
  117. "enter that area, you may be subject to immediate attack. Entering the area "
  118. "will enable combat for your character. Once enabled, combat cannot be "
  119. "disabled.\n\n");
  120.     fi;
  121.     continue
  122. corp;
  123. AddWestChecker(r_path2, warning, false)$
  124.  
  125. /* Some generic rooms for this level of the proving grounds. */
  126.  
  127. define tp_surface r_provingRoad CreateThing(r_road)$
  128. SetThingStatus(r_provingRoad, ts_readonly)$
  129. AutoGraphics(r_provingRoad, AutoRoads)$
  130. AutoPens(r_provingRoad, C_FOREST_GREEN, C_TAN, 0, 0)$
  131. monsterSet1(r_provingRoad)$
  132.  
  133. define tp_surface r_provingField CreateThing(r_field)$
  134. SetThingStatus(r_provingField, ts_readonly)$
  135. monsterSet1(r_provingField)$
  136.  
  137. define tp_surface r_provingForest CreateThing(r_forest)$
  138. SetThingStatus(r_provingForest, ts_readonly)$
  139. monsterSet2(r_provingForest)$
  140. Scenery(r_forest, "path.trail")$
  141.  
  142. define tp_surface r_entrance CreateThing(r_provingRoad)$
  143. SetupRoom(r_entrance, "at the proving grounds entrance",
  144.     "A small, grimy tent is to the north, and a somewhat cleaner tent is "
  145.     "to the south. The path from the east turns into a cobbled road at "
  146.     "this point and continues to the west.")$
  147. Connect(r_warning, r_entrance, D_WEST)$
  148. r_warning@p_rNoMachines := true$
  149. Scenery(r_entrance,
  150.     "tent;small,grimy,somewhat,clean,cleaner.path,pathway,road;cobbled")$
  151. define tp_surface proc enterProvingGrounds()status:
  152.     if not Me()@p_pInited then
  153.     Print(
  154.         "Welcome to the proving grounds! You are hereby warned that "
  155.         "this area is not safe to just wander around in. It contains "
  156.         "monsters, etc. which will attempt to harm you. You should find "
  157.         "suitable weapons and armour to help protect yourself. You can "
  158.         "see your current statistics with the 'status' command.\n");
  159.     InitFighter(Me());
  160.     fi;
  161.     continue
  162. corp;
  163. AddWestChecker(r_warning, enterProvingGrounds, false)$
  164. AddEastChecker(r_entrance, LeaveFighting, false)$
  165. define tp_surface PR_ENTRANCE_ID NextEffectId()$
  166. define tp_surface proc drawEntrance()void:
  167.  
  168.     if not KnowsEffect(nil, PR_ENTRANCE_ID) then
  169.     DefineEffect(nil, PR_ENTRANCE_ID);
  170.     GSetImage(nil, "Proving/entrance");
  171.     IfFound(nil);
  172.         ShowCurrentImage();
  173.     Else(nil);
  174.         GSetPen(nil, C_FOREST_GREEN);
  175.         GAMove(nil, 0.0, 0.0);
  176.         GRectangle(nil, 0.5, 1.0, true);
  177.         GSetPen(nil, C_TAN);
  178.         GAMove(nil, 0.0, 0.38);
  179.         GRectangle(nil, 0.4, 0.24, true);
  180.         GAMove(nil, 0.37, 0.46);
  181.         GRectangle(nil, 0.131, 0.09, true);
  182.         GSetPen(nil, C_DARK_BLUE);
  183.         GAMove(nil, 0.06, 0.0);
  184.         GRectangle(nil, 0.37, 0.33, true);
  185.         GSetPen(nil, C_LEMON_YELLOW);
  186.         GAMove(nil, 0.06, 0.67);
  187.         GRectangle(nil, 0.37, 0.34, true);
  188.         GSetPen(nil, C_BRICK_RED);
  189.         GAMove(nil, 0.237, 0.33);
  190.         HorizontalDoor();
  191.         GAMove(nil, 0.237, 0.67);
  192.         HorizontalDoor();
  193.     Fi(nil);
  194.     EndEffect();
  195.     fi;
  196.     CallEffect(nil, PR_ENTRANCE_ID);
  197. corp;
  198. AutoGraphics(r_entrance, drawEntrance)$
  199.  
  200. /* Add an armoury to buy basic goods at */
  201.  
  202. define tp_surface r_armoury CreateThing(r_indoors)$
  203. SetupRoom(r_armoury, "in an armoury",
  204.     "This small establishment is run by a nasty-looking individual who "
  205.     "appears to be his own best customer. He is a short, but very heavyset "
  206.     "man with a dirty beard and greasy hair. He wears armoured boots, heavy "
  207.     "chain gauntlets, plate mail and an iron helm. The handle of a huge "
  208.     "sword can be seen behind his head, and a couple of handy daggers are "
  209.     "tucked into a loose belt. Perhaps he doesn't trust his clientele.")$
  210. Connect(r_entrance, r_armoury, D_NORTH)$
  211. UniConnect(r_armoury, r_entrance, D_EXIT)$
  212. AutoGraphics(r_armoury, AutoOpenRoom)$
  213. r_armoury@p_rNoMachines := true$
  214. r_armoury@p_Image := "Proving/armoury"$
  215. Scenery(r_armoury,
  216.     "tent;small,grimy.armoury."
  217.     "man,individual,shopkeeper,storekeeper,armourer;"
  218.     "nasty-looking,nasty,looking,short,but,very,heavyset."
  219.     "beard,hair;dirty,greasy."
  220.     "boot;armoured."
  221.     "gauntlet,glove;heavy,chain."
  222.     "helm,helmet;iron."
  223.     "sword;huge."
  224.     "head."
  225.     "weapon;weaponry."
  226.     "handle;huge,sword."
  227.     "dagger;handy."
  228.     "belt;loose")$
  229. MakeStore(r_armoury)$
  230. WeaponSell(r_armoury, "dagger",
  231.     "The dagger is nothing special - just a large, heavy knife. The blade "
  232.     "is fairly sharp, and should last.",
  233.     10, 0, 0, 0, 0, 0, 6, 6)@p_Image := "Proving/dagger"$
  234. define tp_proving o_stiletto WeaponSell(r_armoury,
  235.     "stiletto,stilleto,stileto,stilletto;fine",
  236.     "The stiletto is like a long dagger with a very narrow blade. It is "
  237.     "ideal for sticking into small places, like between ribs.",
  238.     15, 0, 0, 0, 0, 0, 8, 7)$
  239. o_stiletto@p_Image := "Proving/stiletto"$
  240. define tp_proving o_shortSword WeaponSell(r_armoury, "sword;short.shortsword",
  241.     "The short sword is halfway between a dagger and a true sword. It is "
  242.     "just under two feet long, and has a small straight guardpiece separating "
  243.     "the double-edged blade from the cord-wrapped hilt.",
  244.     50, 0, 0, 0, 0, 0, 7, 9)$
  245. o_shortSword@p_Image := "Proving/shortSword"$
  246. define tp_proving o_longSword WeaponSell(r_armoury, "sword;long.longsword",
  247.     "The long sword is nearly three feet long and both edges are sharpened. "
  248.     "The tip is also quite sharp, but not as sharp as those on smaller "
  249.     "weapons. The guardpiece between the blade and the hilt is about four "
  250.     "inches long, providing fair protection to the hand. There is a small "
  251.     "metal pommel on the end of the leather-wrapped grip.",
  252.     200, 0, 0, -1, 0, 0, 8, 11)$
  253. o_longSword@p_Image := "Proving/longSword"$
  254. define tp_proving o_twoHandedSword WeaponSell(r_armoury,
  255.     "sword;two-handed.sword;two,handed,2-handed,2handed,twohanded",
  256.     "The two-handed sword is a large, heavy weapon. It is about four feet "
  257.     "long and has a six-inch hand-guard which curves out over the blade, "
  258.     "serving to catch and hold other weapons sliding along the blade. The "
  259.     "hilt is nearly a foot long, and there is a large pommel on the end of "
  260.     "it. The grip area is wrapped in wide leather strips, providing a good "
  261.     "grip.",
  262.     400, 0, 0, -2, 0, 0, 8, 16)$
  263. o_twoHandedSword@p_Image := "Proving/twoHandedSword"$
  264. WeaponSell(r_armoury, "axe,ax;war.waraxe,warax",
  265.     "The war axe is much like a chopping axe, except that the blade is much "
  266.     "wider - it only has to chop flesh, not wood. There is a decorative "
  267.     "tassle on the end of the handle.",
  268.     150, 0, 0, -1, 0, 0, 6, 11)@p_Image := "Proving/warAxe"$
  269. WeaponSell(r_armoury, "poleaxe,poleax.axe,ax;pole",
  270.     "The poleaxe is an odd-looking but highly effective weapon. It has an "
  271.     "iron head which is a wide axe-blade on one side and a long spike on the "
  272.     "other. Thus it can be used for chopping actions and for spiking through "
  273.     "things. The head is on the end of a long shaft, which has a further "
  274.     "spike on its end.",
  275.     125, 0, 0, 0, 0, 0, 9, 8)@p_Image := "Proving/poleaxe"$
  276. define tp_proving o_leatherArmour WeaponSell(r_armoury, "armour;leather",
  277.     "Leather armour provides reasonable protection against small weapons, "
  278.     "but it is little help against larger ones.",
  279.     100, 0, 0, 0, -2, 0, 0, 0)$
  280. o_leatherArmour@p_Image := "Proving/leatherArmour"$
  281. WeaponSell(r_armoury, "armour;studded",
  282.     "The studded armour is made of boiled leather with many bronze studs "
  283.     "attached to it. The studs server to deflect and catch weapons that are "
  284.     "swung against the armour. The boiled leather is considerable tougher "
  285.     "than normal leather, and hence provides more protection.",
  286.     350, 0, 0, 0, -3, 0, 0, 0)@p_Image := "Proving/studdedArmour"$
  287. WeaponSell(r_armoury, "mail;chain.chainmail,chain-mail",
  288.     "Chain mail consists of a shirtlike contrivance made from small iron "
  289.     "links, much as a chain is made from links. Being metal, it provides "
  290.     "good protection against many weapons. A strong thrust can still break "
  291.     "the links, however.",
  292.     700, 0, 0, 0, -4, 0, 0, 0)@p_Image := "Proving/chainMail"$
  293. /* Do not call it 'plate' - that conflicts with the floor plate. */
  294. WeaponSell(r_armoury, "mail;plate.platemail,plate-mail",
  295.     "Plate armour is the ultimate in non-magical personal protection. Many "
  296.     "formed metal plates are attached to a leather framework and worn like "
  297.     "a heavy coat. The plates overlap near joints, so that gaps do not "
  298.     "appear when moving.",
  299.     2000, 0, 0, 0, -5, 0, 0, 0)@p_Image := "Proving/plateMail"$
  300. define tp_proving o_woodenShield WeaponSell(r_armoury,
  301.     "shield;wooden.shield;wood",
  302.     "The wooden shield is made from many strips of wood glued together to "
  303.     "form a rough circle. It is about one inch thick, and has a leather "
  304.     "strap on the back for holding it.",
  305.     75, 0, 0, 0, 0, -2, 0, 0)$
  306. o_woodenShield@p_Image := "Proving/woodenShield"$
  307. WeaponSell(r_armoury, "shield;bronze",
  308.     "The bronze shield is no heavier than a wooden shield, but provides "
  309.     "much better protection against piercing attacks. It also has a spike "
  310.     "in the middle of its face which can be used to force weapons aside.",
  311.     200, 0, 0, 0, 0, -3, 0, 0)@p_Image := "Proving/bronzeShield"$
  312. WeaponSell(r_armoury, "shield;iron",
  313.     "The iron shield is pretty much the same as a bronze shield, except that "
  314.     "it is much heavier, and is strong enough to resist nearly all puncture "
  315.     "attacks.",
  316.     500, 0, 0, 0, 0, -4, 0, 0)@p_Image := "Proving/ironShield"$
  317. WeaponSell(r_armoury, "sword;flashing",
  318.     "This sword is a bit out of the ordinary. It has quite pretty scrollwork "
  319.     "on the blade, mostly in the form of lightning bolts; and the pommel "
  320.     "contains a large red gem.",
  321.     1000000, 0, 0, 5, 0, 0, 7, 11)@p_Image := "Proving/flashingSword"$
  322. WeaponSell(r_armoury, "Thor;Hammer,of.hammer",
  323.     "The Hammer of Thor appears to be a special weapon. It smashes instead "
  324.     "of slashes, but that is likely to be just as effective. It appears to "
  325.     "be quite heavy and unwieldy, but you seem to have no trouble with it.",
  326.     1000000, 0, 3, 0, 0, 0, 10, 15)@p_Image := "Proving/HammerOfThor"$
  327. WeaponSell(r_armoury, "shield;enchanted",
  328.     "There is something magical about the enchanted shield. It is almost as "
  329.     "if some force within it wants to protect you.",
  330.     1000000, 25, 0, 0, 0, -5, 0, 0)@p_Image := "Proving/enchantedShield"$
  331.  
  332. /* add a healer for fixing up players */
  333.  
  334. define tp_surface r_healer CreateThing(r_indoors)$
  335. SetupRoom(r_healer, "in a healer's shop",
  336.     "The proprietor is a friendly-looking man wearing loose brown robes and "
  337.     "sandals. Shelves on one wall contain rows of neatly-labelled pottery "
  338.     "jars, and the back of this fairly large tent is filled with curtained "
  339.     "off areas containing simple cots. You can purchase healing here.")$
  340. Connect(r_entrance, r_healer, D_SOUTH)$
  341. UniConnect(r_healer, r_entrance, D_EXIT)$
  342. AutoGraphics(r_healer, AutoOpenRoom)$
  343. RoomName(r_healer, "Healer's", "Shop")$
  344. r_healer@p_rNoMachines := true$
  345. r_healer@p_Image := "Proving/healer"$
  346. Scenery(r_healer,
  347.     "tent;fairly,large."
  348.     "area;curtained,off."
  349.     "proprietor,man,healer;friendly-looking,friendly,looking."
  350.     "robe;loose,brown."
  351.     "sandal."
  352.     "healing."
  353.     "shelves,shelf,wall."
  354.     "jar,pottery;pottery,neatly-labelled,neatly,labelled."
  355.     "curtains."
  356.     "cot,simple")$
  357. HealSell(r_healer, "heal;minor.minor", 10, 6)$
  358. HealSell(r_healer, "heal;small.small", 20, 15)$
  359. HealSell(r_healer, "heal;medium.medium", 50, 40)$
  360. HealSell(r_healer, "heal;large.large", 150, 140)$
  361. HealSell(r_healer, "heal;great.great.heal;major", 500, 500)$
  362. r_healer@p_rBuyAction := HealingBuy$
  363.  
  364. /* and some more locations to play around in */
  365.  
  366. define tp_surface r_road1 CreateThing(r_provingRoad)$
  367. SetupRoom(r_road1, "on an east-west cobbled road",
  368.     "Small alleys head north and south. There is a manhole in the middle of "
  369.     "the road.")$
  370. Connect(r_entrance, r_road1, D_WEST)$
  371. define tp_proving o_manholeCover CreateThing(nil)$
  372. SetupObject(o_manholeCover, r_road1,
  373.     "cover,lid;manhole.manhole.hole;man", "")$
  374. o_manholeCover@p_oInvisible := true$
  375. o_manholeCover@p_oNotGettable := true$
  376. o_manholeCover@p_Image := "Proving/manholeCover"$
  377. define tp_surface PR_CROSSROADS_ID NextEffectId()$
  378. define tp_surface proc crossRoadsDraw()void:
  379.  
  380.     if not KnowsEffect(nil, PR_CROSSROADS_ID) then
  381.     DefineEffect(nil, PR_CROSSROADS_ID);
  382.     GSetImage(nil, "Proving/crossRoads");
  383.     IfFound(nil);
  384.         ShowCurrentImage();
  385.     Else(nil);
  386.         AutoRoads();
  387.         GSetPen(nil, C_MEDIUM_GREY);
  388.         GAMove(nil, 0.252, 0.499);
  389.         GEllipse(nil, 0.016, 0.04, true);
  390.     Fi(nil);
  391.     EndEffect();
  392.     fi;
  393.     CallEffect(nil, PR_CROSSROADS_ID);
  394. corp;
  395. AutoGraphics(r_road1, crossRoadsDraw)$
  396.  
  397. define tp_surface r_road2 CreateThing(r_provingRoad)$
  398. SetupRoomP(r_road2, "at the west end of the proving grounds road",
  399.     "A small trail continues to the west. A simple wooden building is to the "
  400.     "north.")$
  401. Connect(r_road1, r_road2, D_WEST)$
  402. Scenery(r_road2, "trail.path")$
  403. define tp_surface PR_ROAD2_ID NextEffectId()$
  404. define tp_surface proc road2Draw()void:
  405.  
  406.     if not KnowsEffect(nil, PR_ROAD2_ID) then
  407.     DefineEffect(nil, PR_ROAD2_ID);
  408.     GSetImage(nil, "Proving/road2");
  409.     IfFound(nil);
  410.         ShowCurrentImage();
  411.     Else(nil);
  412.         GSetPen(nil, C_FOREST_GREEN);
  413.         GAMove(nil, 0.0, 0.0);
  414.         GRectangle(nil, 0.5, 1.0, true);
  415.         GSetPen(nil, C_TAN);
  416.         GAMove(nil, 0.25, 0.5);
  417.         GEllipse(nil, 0.04688, 0.12, true);
  418.         GAMove(nil, 0.0, 0.455);
  419.         GRectangle(nil, 0.252, 0.095, true);
  420.         GAMove(nil, 0.25, 0.39);
  421.         GRectangle(nil, 0.25, 0.24, true);
  422.         GSetPen(nil, C_MEDIUM_BROWN);
  423.         GAMove(nil, 0.0625, 0.0);
  424.         GRectangle(nil, 0.37, 0.33, true);
  425.         GSetPen(nil, C_BRICK_RED);
  426.         GAMove(nil, 0.234, 0.33);
  427.         HorizontalDoor();
  428.     Fi(nil);
  429.     EndEffect();
  430.     fi;
  431.     CallEffect(nil, PR_ROAD2_ID);
  432. corp;
  433. AutoGraphics(r_road2, road2Draw)$
  434.  
  435. define tp_surface r_provingStore CreateThing(r_indoors)$
  436. SetupRoom(r_provingStore, "in a store",
  437.     "This simple store isn't much to look at, but you can shop here for a "
  438.     "variety of useful goods.")$
  439. Connect(r_road2, r_provingStore, D_NORTH)$
  440. UniConnect(r_provingStore, r_road2, D_EXIT)$
  441. AutoGraphics(r_provingStore, AutoOpenRoom)$
  442. r_provingStore@p_rNoMachines := true$
  443. r_provingStore@p_Image := "Proving/store"$
  444. Scenery(r_provingStore, "store;simple.goods;variety,of,useful")$
  445. MakeStore(r_provingStore)$
  446. WeaponSell(r_provingStore, "wrappings;fur",
  447.     "The fur wrappings can provide minimal protection from attacks with small "
  448.     "weapons, teeth and claws. They also provide an ideal nesting place for "
  449.     "many varieties of insect pests.",
  450.     25, 0, 0, 0, -1, 0, 0, 0)@p_Image := "Proving/furWrappings"$
  451. WeaponSell(r_provingStore, "shield;hide",
  452.     "The hide shield is just a piece of tough animal hide fastened over a "
  453.     "light wooden frame. It provides some shielding from light weapons, and "
  454.     "can be used to deflect attacks.",
  455.     40, 0, 0, 0, 0, -1, 0, 0)@p_Image := "Proving/hideShield"$
  456. define tp_surface o_flint AddForSale(r_provingStore,
  457.     "lighter;flint.flint",
  458.     "The flint lighter is simply a small piece of flint with an iron striker "
  459.     "tied to it. The combination can be used to light things.",
  460.     10, nil)$
  461. o_flint@p_Image := "Proving/flint"$
  462.  
  463. define tp_proving o_oilLamp AddForSale(r_provingStore, "lamp;oil",
  464.     "The oil lamp is made of tin. It is a small round container with a "
  465.     "wick on the top. The lamp can be filled with oil through a cap.",
  466.     100, nil)$
  467. o_oilLamp@p_oState := 5 * 60$    /* good for 5 hours of light */
  468. define tp_surface proc oilLampTick(thing lamp)void:
  469.     int newState;
  470.  
  471.     newState := lamp@p_oState - 1;
  472.     lamp@p_oState := newState;
  473.     if newState = 0 then
  474.     PassiveUnLightObject(lamp);
  475.     else
  476.     if newState < 10 then
  477.         if lamp@p_oCarryer ~= nil then
  478.         SPrint(lamp@p_oCarryer, "Your oil lamp flickers - "
  479.             "it is nearly out of oil!\n");
  480.         fi;
  481.     fi;
  482.     DoAfter(60, lamp, oilLampTick);
  483.     fi;
  484. corp;
  485. define tp_surface proc oilLampOn()status:
  486.     thing lamp;
  487.  
  488.     lamp := It();
  489.     if not FindChildOnList(Me()@p_pCarrying, o_flint) then
  490.     Print("You have no lighter to light the lamp with.\n");
  491.     fail
  492.     elif lamp@p_oState = 0 then
  493.     Print("The lamp is empty - you cannot light it.\n");
  494.     fail
  495.     elif lamp@p_oLight then
  496.     Print("The lamp is already lit.\n");
  497.     fail
  498.     else
  499.     ignore ActiveLightObject();
  500.     if lamp@p_oState = 1 then
  501.         Print("The lamp is virtually empty - it will not last long.\n");
  502.     elif lamp@p_oState <= 10 then
  503.         Print("The lamp is nearly empty - it will not last long.\n");
  504.     fi;
  505.     DoAfter(60, lamp, oilLampTick);
  506.     succeed
  507.     fi
  508. corp;
  509. o_oilLamp@p_oLightChecker := oilLampOn$
  510. define tp_surface proc oilLampOff()status:
  511.     status st;
  512.  
  513.     st := ActiveUnLightObject();
  514.     if st = succeed then
  515.     ignore CancelDoAfter(It(), oilLampTick);
  516.     succeed
  517.     else
  518.     st
  519.     fi
  520. corp;
  521. o_oilLamp@p_oExtinguishChecker := oilLampOff$
  522. define tp_surface proc oilLampPutIn(thing lamp, container)status:
  523.     if lamp@p_oLight then
  524.     Print("You'd better extinguish the lamp before putting it into the " +
  525.         FormatName(container@p_oName) + ".\n");
  526.     fail
  527.     else
  528.     continue
  529.     fi
  530. corp;
  531. o_oilLamp@p_oPutMeInChecker := oilLampPutIn$
  532. define tp_surface proc oilLampLookIn(thing lamp)string:
  533.     int timeLeft;
  534.  
  535.     timeLeft := lamp@p_oState;
  536.     if timeLeft = 0 then
  537.     "The lamp is currently empty."
  538.     elif timeLeft < 15 then
  539.     "The lamp is nearly empty."
  540.     else
  541.     "The lamp currently has enough fuel for about " +
  542.     if timeLeft >= 105 then
  543.         IntToString((timeLeft + 15) / 60) + " hours."
  544.     elif timeLeft >= 55 then
  545.         "an hour."
  546.     else
  547.         IntToString(timeLeft / 15 * 15) + " minutes."
  548.     fi
  549.     fi
  550. corp;
  551. o_oilLamp@p_oLookInAction := oilLampLookIn$
  552. define tp_surface proc oilLampEmptyChecker(thing lamp)status:
  553.     lamp@p_oState := 0;
  554.     continue
  555. corp;
  556. o_oilLamp@p_oEmptyChecker := oilLampEmptyChecker$
  557. o_oilLamp@p_Image := "Proving/oilLamp"$
  558.  
  559. define tp_surface proc refillBuy()status:
  560.     thing me, lamp;
  561.  
  562.     me := Me();
  563.     if FindName(me@p_pCarrying, p_oName, "lamp;oil") = fail then
  564.     lamp := nil;
  565.     else
  566.     lamp := FindResult();
  567.     if Parent(lamp) ~= o_oilLamp then
  568.         lamp := nil;
  569.     fi;
  570.     fi;
  571.     if lamp = nil then
  572.     Print("You have no oil lamp to refill.\n");
  573.     /* Cancel the entire purchase. */
  574.     fail
  575.     else
  576.     if lamp@p_oState = o_oilLamp@p_oState then
  577.         /* It's already full! */
  578.         Print("The shop owner smiles slyly and says "
  579.         "\"There you are - all filled up!\"\n");
  580.     else
  581.         Print("Your lamp is now refilled.\n");
  582.     fi;
  583.     lamp -- p_oState;
  584.     if not me@p_pHidden then
  585.         OPrint(Capitalize(CharacterNameG(me)) + " makes a purchase.\n");
  586.     fi;
  587.     /* Cancel message, adding to inventory; destroy the copy. */
  588.     succeed
  589.     fi
  590. corp;
  591. define tp_proving o_refill AddForSale(r_provingStore, "refill;oil,lamp",
  592.     "", 25, refillBuy)$
  593.  
  594. define tp_surface o_oilCan AddForSale(r_provingStore,
  595.     "oil;can,of.oilcan.oil-can.can;oil",
  596.     "The can of oil is a small tin container with a pouring spout.",
  597.     100, nil)$
  598. o_oilCan@p_oState := 5$
  599. define tp_surface proc oilCanDrop(thing can)status:
  600.     if can@p_oState = 0 then
  601.     if LightAt(Here()) then
  602.         if can@p_oCarryer = Me() then
  603.         Print("You discard the empty oil can. It vanishes in a puff "
  604.             "of neatness.\n");
  605.         fi;
  606.         OPrint(Capitalize(CharacterNameG(Me())) +
  607.         " discards an empty oil can.\n");
  608.     fi;
  609.     ClearThing(can);
  610.     DelElement(Me()@p_pCarrying, can);
  611.     succeed
  612.     else
  613.     continue
  614.     fi
  615. corp;
  616. o_oilCan@p_oDropChecker := oilCanDrop$
  617. define tp_surface proc oilLampFillWith(thing lamp, source)status:
  618.     int oilLeft;
  619.  
  620.     if Parent(source) = o_oilCan then
  621.     oilLeft := source@p_oState;
  622.     if oilLeft = 0 then
  623.         Print("The oil can is empty.\n");
  624.         succeed
  625.     else
  626.         lamp -- p_oState;    /* inherit full time from parent */
  627.         oilLeft := oilLeft - 1;
  628.         source@p_oState := oilLeft;
  629.         if oilLeft = 0 then
  630.         Print("You fill the lamp, but the oil can is now empty.\n");
  631.         succeed
  632.         else
  633.         continue
  634.         fi
  635.     fi
  636.     else
  637.     fail
  638.     fi
  639. corp;
  640. o_oilLamp@p_oFillMeWithChecker := oilLampFillWith$
  641. define tp_surface proc oilCanLookIn(thing oilCan)string:
  642.     int oilLeft;
  643.  
  644.     oilLeft := oilCan@p_oState;
  645.     if oilLeft = 0 then
  646.     "The oil can is empty."
  647.     elif oilLeft = 1 then
  648.     "The oil can has enough oil for one more lamp refill."
  649.     else
  650.     "The oil can has enough oil in it for about " + IntToString(oilLeft) +
  651.     " refills of an oil lamp."
  652.     fi
  653. corp;
  654. o_oilCan@p_oLookInAction := oilCanLookIn$
  655. define tp_surface proc oilCanEmptyChecker(thing oilCan)status:
  656.     oilCan@p_oState := 0;
  657.     continue
  658. corp;
  659. o_oilCan@p_oEmptyChecker := oilCanEmptyChecker$
  660. o_oilCan@p_Image := "Proving/oilcan"$
  661.  
  662. /* This next one is also needed in proving2.m, in the goblin city store. */
  663. define tp_proving o_torch AddForSale(r_provingStore, "torch;reed", "",
  664.     5, nil)$
  665. define tp_surface proc torchDesc()string:
  666.     int timeLeft;
  667.  
  668.     timeLeft := It()@p_oState;
  669.     if timeLeft = 0 then
  670.     "The torch is completely burned out."
  671.     else
  672.     "The reed torch is a simple bundle of dried reeds tied together, its "
  673.     "top coated with pitch. " +
  674.     if It()@p_oLight then
  675.         "It will continue to burn brightly for about "
  676.     else
  677.         "Although not now lit, it will burn brightly for about "
  678.     fi +
  679.     if timeLeft = 1 then
  680.         "one more minute."
  681.     else
  682.         IntToString(timeLeft) + " minutes."
  683.     fi
  684.     fi
  685. corp;
  686. o_torch@p_oDescAction := torchDesc$
  687. o_torch@p_oState := 10$
  688. define tp_surface proc torchTick(thing torch)void:
  689.     int newState;
  690.  
  691.     newState := torch@p_oState - 1;
  692.     torch@p_oState := newState;
  693.     if newState = 0 then
  694.     PassiveUnLightObject(torch);
  695.     else
  696.     if newState < 3 then
  697.         if torch@p_oCarryer ~= nil then
  698.         SPrint(torch@p_oCarryer, "Your torch splutters - "
  699.             "it is nearly burned out!\n");
  700.         fi;
  701.     fi;
  702.     DoAfter(60, torch, torchTick);
  703.     fi;
  704. corp;
  705. define tp_surface proc torchOn()status:
  706.     thing torch;
  707.  
  708.     torch := It();
  709.     if FindName(Me()@p_pCarrying, p_oName, "lighter;flint") = fail or
  710.     Parent(FindResult()) ~= o_flint
  711.     then
  712.     Print("You have no lighter to light the torch with.\n");
  713.     fail
  714.     elif torch@p_oState = 0 then
  715.     Print("The torch is burned out - you cannot light it.\n");
  716.     fail
  717.     elif torch@p_oLight then
  718.     Print("The torch is already lit.\n");
  719.     fail
  720.     else
  721.     ignore ActiveLightObject();
  722.     if torch@p_oState = 1 then
  723.         Print("The torch is virtually gone - it will not last long.\n");
  724.     elif torch@p_oState <= 3 then
  725.         Print("The torch is nearly gone - it will not last long.\n");
  726.     fi;
  727.     DoAfter(60, torch, torchTick);
  728.     succeed
  729.     fi
  730. corp;
  731. o_torch@p_oLightChecker := torchOn$
  732. define tp_surface proc torchOff()status:
  733.     status st;
  734.  
  735.     st := ActiveUnLightObject();
  736.     if st = succeed then
  737.     ignore CancelDoAfter(It(), torchTick);
  738.     succeed
  739.     else
  740.     st
  741.     fi
  742. corp;
  743. o_torch@p_oExtinguishChecker := torchOff$
  744. define tp_surface proc torchDrop(thing torch)status:
  745.     if torch@p_oState = 0 then
  746.     if LightAt(Here()) then
  747.         if torch@p_oCarryer = Me() then
  748.         Print("You discard the burned-out torch. It vanishes in a "
  749.             "puff of neatness.\n");
  750.         fi;
  751.         OPrint(Capitalize(CharacterNameG(Me())) +
  752.         " discards a burned out torch.\n");
  753.     fi;
  754.     ClearThing(torch);
  755.     DelElement(Me()@p_pCarrying, torch);
  756.     succeed
  757.     else
  758.     continue
  759.     fi
  760. corp;
  761. o_torch@p_oDropChecker := torchDrop$
  762. define tp_surface proc torchPutIn(thing torch, container)status:
  763.     if torch@p_oLight then
  764.     Print("You'd better extinguish the torch before putting it into the " +
  765.         FormatName(container@p_oName) + ".\n");
  766.     fail
  767.     else
  768.     continue
  769.     fi
  770. corp;
  771. o_torch@p_oPutMeInChecker := torchPutIn$
  772.  
  773. define tp_proving o_sack AddForSale(r_provingStore, "sack;canvas",
  774.     "The canvas sack is strong and reliable, but not very large.", 10, nil)$
  775. o_sack@p_oContents := CreateThingList()$
  776. o_sack@p_oCapacity := 5$
  777. o_sack@p_Image := "Proving/sack"$
  778.  
  779. define tp_surface r_alley1 CreateThing(r_provingRoad)$
  780. SetupRoom(r_alley1, "in a north-south alley",
  781.     "Piles of rusted metal, moldy leather and rotted wood litter the side "
  782.     "of the armoury tent, which is even dirtier on this side than on the "
  783.     "front. Across the alley from it is the remains of another tent, which "
  784.     "burned down long ago.")$
  785. Connect(r_road1, r_alley1, D_NORTH)$
  786. Scenery(r_alley1,
  787.     "metal;piles,of,rusted."
  788.     "leather;moldy."
  789.     "wood;rotted."
  790.     "litter."
  791.     "tent;dirty,armoury."
  792.     "tent,remains;burned,tent.")$
  793. r_alley1@p_Image := "Proving/alley1"$
  794.  
  795. define tp_proving r_alley2 CreateThing(r_provingRoad)$
  796. SetupRoomP(r_alley2, "at the north end of an alley",
  797.     "The alley ends here, although you can duck around the armoury "
  798.     "to the east, and a path heads north to a pasture. "
  799.     "There is a large drainage grate in the ground.")$
  800. Connect(r_alley1, r_alley2, D_NORTH)$
  801. UniConnect(r_alley2, r_entrance, D_EAST)$
  802. Scenery(r_alley2, "path.armoury.pasture")$
  803. define tp_surface PR_ALLEY2_ID NextEffectId()$
  804. define tp_surface proc alley2Draw()void:
  805.  
  806.     if not KnowsEffect(nil, PR_ALLEY2_ID) then
  807.     DefineEffect(nil, PR_ALLEY2_ID);
  808.     GSetImage(nil, "Proving/alley2");
  809.     IfFound(nil);
  810.         ShowCurrentImage();
  811.     Else(nil);
  812.         GSetPen(nil, C_FOREST_GREEN);
  813.         GAMove(nil, 0.0, 0.0);
  814.         GRectangle(nil, 0.5, 1.0, true);
  815.         GSetPen(nil, C_TAN);
  816.         GAMove(nil, 0.25, 0.5);
  817.         GEllipse(nil, 0.04688, 0.12, true);
  818.         GAMove(nil, 0.20313, 0.5);
  819.         GRectangle(nil, 0.09375, 0.499, true);
  820.         GAMove(nil, 0.2376, 0.0);
  821.         GRectangle(nil, 0.029, 0.5, true);
  822.         GAMove(nil, 0.25, 0.455);
  823.         GRectangle(nil, 0.25, 0.095, true);
  824.     Fi(nil);
  825.     EndEffect();
  826.     fi;
  827.     CallEffect(nil, PR_ALLEY2_ID);
  828. corp;
  829. AutoGraphics(r_alley2, alley2Draw)$
  830.  
  831. define tp_surface r_gateSouth CreateThing(r_provingField)$
  832. SetupRoom(r_gateSouth, "just outside the pasture",
  833.     "Immediately to your north is a gate into the pasture. The gate is wide "
  834.     "open, but the fence running east-west is quite sturdy.")$
  835. Connect(r_alley2, r_gateSouth, D_NORTH)$
  836. AutoGraphics(r_gateSouth, AutoPaths)$
  837. AutoPens(r_gateSouth, C_FOREST_GREEN, C_TAN, 0, 0)$
  838. RoomName(r_gateSouth, "Outside", "Pasture")$
  839. Scenery(r_gateSouth, "gate.fence.path")$
  840. r_gateSouth@p_Image := "Proving/gateSouth"$
  841.  
  842. define tp_surface r_pasture CreateThing(r_field)$
  843. AutoGraphics(r_pasture, AutoOpenSpace)$
  844. SetThingStatus(r_pasture, ts_readonly)$
  845. monsterSetP(r_pasture)$
  846.  
  847. define tp_surface r_gateNorth CreateThing(r_pasture)$
  848. SetupRoom(r_gateNorth, "just inside the pasture",
  849.     "The gate in the fence is to your south, and the pasture is all around "
  850.     "you.")$
  851. Connect(r_gateSouth, r_gateNorth, D_NORTH)$
  852. Scenery(r_gateNorth, "gate.fence")$
  853. r_gateNorth@p_Image := "Proving/gateNorth"$
  854.  
  855. define tp_surface r_pasture1 CreateThing(r_pasture)$
  856. SetupRoom(r_pasture1, "in the pasture", "The fence is to the south.")$
  857. Connect(r_gateNorth, r_pasture1, D_EAST)$
  858. Scenery(r_pasture1, "fence")$
  859.  
  860. define tp_surface r_pasture2 CreateThing(r_pasture)$
  861. SetupRoom(r_pasture2, "in the south-east corner of the pasture",
  862.     "The fence prevents you from going further east or further south.")$
  863. Connect(r_pasture1, r_pasture2, D_EAST)$
  864. Scenery(r_pasture2, "fence")$
  865.  
  866. define tp_surface r_pasture3 CreateThing(r_pasture)$
  867. SetupRoom(r_pasture3, "in the pasture", "The fence is to the east.")$
  868. Connect(r_pasture2, r_pasture3, D_NORTH)$
  869. Connect(r_pasture1, r_pasture3, D_NORTHEAST)$
  870. Scenery(r_pasture3, "fence")$
  871.  
  872. define tp_surface r_pasture4 CreateThing(r_pasture)$
  873. SetupRoom(r_pasture4, "in the pasture", "There is a bog to the north.")$
  874. Connect(r_pasture3, r_pasture4, D_WEST)$
  875. Connect(r_pasture1, r_pasture4, D_NORTH)$
  876. Connect(r_gateNorth, r_pasture4, D_NORTHEAST)$
  877. Connect(r_pasture2, r_pasture4, D_NORTHWEST)$
  878. Scenery(r_pasture4, "bog")$
  879.  
  880. define tp_surface o_cowpie CreateThing(nil)$
  881. SetupObject(o_cowpie, r_pasture4, "pie;cow.cow-pie.dung",
  882.     "The cow pie looks to be a few days old - it is dry on the surface, but "
  883.     "you can see moisture further in. Closer investigation is not warranted.")$
  884. define tp_surface proc getCowPie(thing th)status:
  885.     Print("YUCK!!! You'd need a sooper dooper pooper scooper to pick up the "
  886.       "cow pie!\n");
  887.     succeed
  888. corp;
  889. o_cowpie@p_oGetChecker := getCowPie$
  890. o_cowpie@p_oSmellString := "WHEW! It's not as old as it looks!"$
  891. o_cowpie@p_Image := "Proving/cowpie"$
  892.  
  893. define tp_surface r_pasture5 CreateThing(r_pasture)$
  894. SetupRoom(r_pasture5, "in the pasture", "There is a bog to the north.")$
  895. Connect(r_pasture4, r_pasture5, D_WEST)$
  896. Connect(r_gateNorth, r_pasture5, D_NORTH)$
  897. Connect(r_pasture1, r_pasture5, D_NORTHWEST)$
  898. Scenery(r_pasture5, "bog")$
  899.  
  900. define tp_surface r_pasture6 CreateThing(r_pasture)$
  901. SetupRoom(r_pasture6, "in the pasture", "There is a bog to the north.")$
  902. Connect(r_pasture5, r_pasture6, D_WEST)$
  903. Connect(r_gateNorth, r_pasture6, D_NORTHWEST)$
  904. Scenery(r_pasture6, "bog")$
  905.  
  906. define tp_surface r_pasture7 CreateThing(r_pasture)$
  907. SetupRoom(r_pasture7, "in the pasture", "The fence is to the south.")$
  908. Connect(r_pasture6, r_pasture7, D_SOUTH)$
  909. Connect(r_gateNorth, r_pasture7, D_WEST)$
  910. Connect(r_pasture5, r_pasture7, D_SOUTHWEST)$
  911. Scenery(r_pasture7, "fence")$
  912.  
  913. define tp_surface r_pasture8 CreateThing(r_pasture)$
  914. SetupRoomP(r_pasture8, "in the south-west corner of the pasture",
  915.     "Fences keep your from going further south or west.")$
  916. Connect(r_pasture7, r_pasture8, D_WEST)$
  917. Connect(r_pasture6, r_pasture8, D_SOUTHWEST)$
  918. Scenery(r_pasture8, "fence$hedge")$
  919.  
  920. define tp_surface r_pasture9 CreateThing(r_pasture)$
  921. SetupRoomP(r_pasture9, "in the pasture by the fence", "")$
  922. Connect(r_pasture8, r_pasture9, D_NORTH)$
  923. Connect(r_pasture6, r_pasture9, D_WEST)$
  924. Connect(r_pasture7, r_pasture9, D_NORTHWEST)$
  925. Scenery(r_pasture9, "hedge")$
  926.  
  927. define tp_surface r_pasture10 CreateThing(r_pasture)$
  928. SetupRoomP(r_pasture10, "in the pasture",
  929.     "A narrow spit of solid ground heads out into the bog to the east.")$
  930. Connect(r_pasture9, r_pasture10, D_NORTH)$
  931. Scenery(r_pasture10, "hedge.bog.ground;narrow,spit,of,solid")$
  932.  
  933. define tp_surface r_pasture11 CreateThing(r_pasture)$
  934. SetupRoomP(r_pasture11, "on a spit of land in the bog",
  935.     "Safe ground leads to the west.")$
  936. Connect(r_pasture10, r_pasture11, D_EAST)$
  937. Scenery(r_pasture11, "bog")$
  938.  
  939. define tp_surface r_pasture12 CreateThing(r_pasture)$
  940. SetupRoom(r_pasture12, "in the pasture",
  941.     "The fence is to the east and the bog is to the west.")$
  942. Connect(r_pasture3, r_pasture12, D_NORTH)$
  943. Scenery(r_pasture12, "fence.bog")$
  944.  
  945. define tp_surface r_pasture13 CreateThing(r_pasture)$
  946. SetupRoom(r_pasture13, "in the pasture",
  947.     "The fence is to the east and the bog is to the west.")$
  948. Connect(r_pasture12, r_pasture13, D_NORTH)$
  949. Scenery(r_pasture13, "fence.bog")$
  950.  
  951. define tp_surface r_pasture14 CreateThing(r_pasture)$
  952. SetupRoom(r_pasture14, "in the north-east corner of the pasture",
  953.     "Fences prevent further progress north or east.")$
  954. Connect(r_pasture13, r_pasture14, D_NORTH)$
  955. Scenery(r_pasture14, "fence.bog")$
  956.  
  957. define tp_surface r_pasture15 CreateThing(r_pasture)$
  958. SetupRoom(r_pasture15, "in the pasture",
  959.     "The fence is to the north and the bog is to the south.")$
  960. Connect(r_pasture14, r_pasture15, D_WEST)$
  961. Scenery(r_pasture15, "fence.bog")$
  962.  
  963. define tp_surface r_pasture16 CreateThing(r_pasture)$
  964. SetupRoom(r_pasture16, "in the pasture", "The fence is to the north.")$
  965. Connect(r_pasture15, r_pasture16, D_WEST)$
  966. Scenery(r_pasture16, "fence")$
  967.  
  968. define tp_surface r_pasture17 CreateThing(r_pasture)$
  969. SetupRoomP(r_pasture17, "in the pasture",
  970.     "The fence is to the north and the bog is both west and south.")$
  971. Connect(r_pasture16, r_pasture17, D_WEST)$
  972. Scenery(r_pasture17, "fence.bog")$
  973.  
  974. /* For the next little while is the apple tree, which can do healing. */
  975.  
  976. define tp_surface p_pAppleEatCount CreateIntProp()$
  977. define tp_surface p_pAppleEatTime CreateIntProp()$
  978.  
  979. define tp_surface r_pasture18 CreateThing(r_pasture)$
  980. SetupRoom(r_pasture18, "in the pasture",
  981.     "The bog is everywhere except north. There is a fine apple tree here, "
  982.     "loaded with juicy red apples.")$
  983. Connect(r_pasture16, r_pasture18, D_SOUTH)$
  984. Scenery(r_pasture18, "bog")$
  985. r_pasture18@p_Image := "Proving/pasture18"$
  986.  
  987. define tp_surface o_appleTree CreateThing(nil)$
  988. SetupObject(o_appleTree, r_pasture18, "tree;fine,apple",
  989.     "The tree is only medium sized, but holds an impressive quantity of "
  990.     "apples, many of which are in easy reach.")$
  991. o_appleTree@p_oInvisible := true$
  992. o_appleTree@p_oSmellString := "The apple tree smells somewhat woody."$
  993. o_appleTree@p_Image := "Proving/appleTree"$
  994.  
  995. define tp_surface o_appleOnTree CreateThing(nil)$
  996. SetupObject(o_appleOnTree, r_pasture18, "apple;juicy,red",
  997.     "The apples on the tree look quite delicious.")$
  998. o_appleOnTree@p_oInvisible := true$
  999. o_appleOnTree@p_oEatString := "You should pick an apple from the tree first."$
  1000. o_appleOnTree@p_oSmellString := o_appleOnTree@p_oEatString$
  1001. o_appleOnTree@p_oTouchString := o_appleOnTree@p_oEatString$
  1002.  
  1003. define tp_surface proc appleDrop(thing apple)status:
  1004.     thing carryer, here;
  1005.  
  1006.     carryer := apple@p_oCarryer;
  1007.     ClearThing(apple);
  1008.     SPrint(carryer, "The apple drops and is pulped!\n");
  1009.     here := Here();
  1010.     if CanSee(here, carryer) and not carryer@p_pHidden then
  1011.     ABPrint(here, carryer, carryer,
  1012.         Capitalize(CharacterNameG(carryer)) +
  1013.         " drops an apple which is pulped.\n");
  1014.     else
  1015.     ABPrint(here, carryer, carryer, "You hear a smack! sound.\n");
  1016.     fi;
  1017.     DelElement(carryer@p_pCarrying, apple);
  1018.     /* we have just destroyed the apple and already dropped it, we do NOT
  1019.        want to continue with normal drop processing */
  1020.     succeed
  1021. corp;
  1022.  
  1023. define tp_surface proc appleEat()status:
  1024.     thing th, me;
  1025.     int now, current, max;
  1026.  
  1027.     th := It();
  1028.     me := Me();
  1029.     if th@p_oCreator = me then
  1030.     now := Time();
  1031.     if now - me@p_pAppleEatTime > 60 * 60 then
  1032.         me@p_pAppleEatCount := 0;
  1033.     fi;
  1034.     if me@p_pAppleEatCount >= 3 then
  1035.         Print("You'd better not eat any more apples for a while. Too many "
  1036.         "of them will make you sick!\n");
  1037.         fail
  1038.     else
  1039.         Print("You eat the apple. It was really good.\n");
  1040.         current := me@p_pHitNow;
  1041.         max := me@p_pHitMax;
  1042.         if current ~= max then
  1043.         current := current + Random(5) + 5;
  1044.         if current > max then
  1045.             current := max;
  1046.         fi;
  1047.         me@p_pHitNow := current;
  1048.         fi;
  1049.         if CanSee(Here(), me) and not me@p_pHidden then
  1050.         OPrint(Capitalize(CharacterNameG(me)) + " eats an apple.\n");
  1051.         else
  1052.         OPrint("You hear some crunching noises.\n");
  1053.         fi;
  1054.         ClearThing(th);
  1055.         DelElement(me@p_pCarrying, th);
  1056.         if me@p_pAppleEatCount = 0 then
  1057.         me@p_pAppleEatCount := 1;
  1058.         me@p_pAppleEatTime := now;
  1059.         else
  1060.         me@p_pAppleEatCount := me@p_pAppleEatCount + 1;
  1061.         fi;
  1062.         succeed
  1063.     fi
  1064.     else
  1065.     Print("That's not your apple!\n");
  1066.     succeed
  1067.     fi
  1068. corp;
  1069.  
  1070. define tp_surface proc appleGive(thing target)status:
  1071.     thing me, apple;
  1072.  
  1073.     me := Me();
  1074.     apple := It();
  1075.     if apple@p_oCreator = me then
  1076.     Print("You fumble when trying to give away the apple, and drop it!\n");
  1077.     if CanSee(Here(), me) and not me@p_pHidden then
  1078.         OPrint(Capitalize(CharacterNameG(me)) +
  1079.         " drops an apple which is pulped.\n");
  1080.     else
  1081.         OPrint("You hear a smack! sound.\n");
  1082.     fi;
  1083.     ClearThing(apple);
  1084.     DelElement(me@p_pCarrying, apple);
  1085.     else
  1086.     Print("That's not your apple!\n");
  1087.     fi;
  1088.     /* the give never works */
  1089.     fail
  1090. corp;
  1091.  
  1092. define tp_surface o_appleInHand CreateThing(nil)$
  1093. o_appleInHand@p_oName := "apple;juicy,red"$
  1094. o_appleInHand@p_oDesc := "The apple looks quite delicious!"$
  1095. o_appleInHand@p_oEatChecker := appleEat$
  1096. o_appleInHand@p_oDropChecker := appleDrop$
  1097. o_appleInHand@p_oGiveChecker := appleGive$
  1098. o_appleInHand@p_oSmellString := "The apple smells like an apple."$
  1099. o_appleInHand@p_oTouchString := "Surprise! The apple feels like an apple."$
  1100. o_appleInHand@p_Image := "Proving/apple"$
  1101. SetThingStatus(o_appleInHand, ts_wizard)$
  1102.  
  1103. define tp_surface proc appleGet(thing th)status:
  1104.     thing me;
  1105.  
  1106.     me := Me();
  1107.     if FindName(me@p_pCarrying, p_oName, "apple;juicy,red") ~= fail then
  1108.     Print("Don't be greedy! You already have an apple.\n");
  1109.     else
  1110.     /* will be owned by the real player */
  1111.     th := CreateThing(o_appleInHand);
  1112.     th@p_oCreator := me;
  1113.     SetThingStatus(th, ts_public);
  1114.     if CarryItem(th) then
  1115.         Print("You pick an apple from the tree.\n");
  1116.         /* assume it is not dark */
  1117.         if not me@p_pHidden then
  1118.         OPrint(Capitalize(CharacterNameG(me)) +
  1119.                " picks an apple from the tree.\n");
  1120.         fi;
  1121.     else
  1122.         ClearThing(th);
  1123.     fi;
  1124.     fi;
  1125.     /* do not want to continue with normal get processing */
  1126.     succeed
  1127. corp;
  1128.  
  1129. o_appleOnTree@p_oGetChecker := appleGet$
  1130.  
  1131. define tp_surface proc appleTreeGet(thing th)status:
  1132.     Print("The tree is far too large for you to carry, and in any event, "
  1133.         "it is securely rooted to the ground.\n");
  1134.     if Me()@p_pHidden then
  1135.     OPrint("The tree shakes slightly.\n");
  1136.     else
  1137.     OPrint(Capitalize(CharacterNameG(Me())) +
  1138.            " seems to be embracing the tree.\n");
  1139.     fi;
  1140.     succeed
  1141. corp;
  1142.  
  1143. o_appleTree@p_oGetChecker := appleTreeGet$
  1144.  
  1145. /* Note that we do NOT prevent people from getting several apples and putting
  1146. them in containers. */
  1147.  
  1148. /* End of apple tree stuff */
  1149.  
  1150. define tp_surface r_alley3 CreateThing(r_provingRoad)$
  1151. SetupRoom(r_alley3, "in an alley",
  1152.     "The alley runs north-south between the healer's tent and a vacant spot.")$
  1153. Connect(r_road1, r_alley3, D_SOUTH)$
  1154. Scenery(r_alley3, "tent;healer's,healer.spot;vacant")$
  1155. r_alley3@p_Image := "Proving/alley3"$
  1156.  
  1157. define tp_proving r_alley4 CreateThing(r_provingRoad)$
  1158. SetupRoom(r_alley4, "at the south end of an alley",
  1159.     "You can go behind the healer's tent to the east, and a trail continues "
  1160.     "south. A vacant spot is west. There is a large drainage grate in the "
  1161.     "ground.")$
  1162. Connect(r_alley3, r_alley4, D_SOUTH)$
  1163. Scenery(r_alley4, "tent;healer's,healer.spot;vacant.path.trail")$
  1164. define tp_surface PR_ALLEY4_ID NextEffectId()$
  1165. define tp_surface proc alley4Draw()void:
  1166.  
  1167.     if not KnowsEffect(nil, PR_ALLEY4_ID) then
  1168.     DefineEffect(nil, PR_ALLEY4_ID);
  1169.     GSetImage(nil, "Proving/alley4");
  1170.     IfFound(nil);
  1171.         ShowCurrentImage();
  1172.     Else(nil);
  1173.         GSetPen(nil, C_FOREST_GREEN);
  1174.         GAMove(nil, 0.0, 0.0);
  1175.         GRectangle(nil, 0.5, 1.0, true);
  1176.         GSetPen(nil, C_TAN);
  1177.         GAMove(nil, 0.25, 0.5);
  1178.         GEllipse(nil, 0.04688, 0.12, true);
  1179.         GAMove(nil, 0.20313, 0.0);
  1180.         GRectangle(nil, 0.09375, 0.5, true);
  1181.         GAMove(nil, 0.25, 0.455);
  1182.         GRectangle(nil, 0.25, 0.095, true);
  1183.         GAMove(nil, 0.2376, 0.5);
  1184.         GRectangle(nil, 0.029, 0.5, true);
  1185.     Fi(nil);
  1186.     EndEffect();
  1187.     fi;
  1188.     CallEffect(nil, PR_ALLEY4_ID);
  1189. corp;
  1190. AutoGraphics(r_alley4, alley4Draw)$
  1191.  
  1192. define tp_surface r_behindHealer CreateThing(r_provingRoad)$
  1193. SetupRoom(r_behindHealer, "behind the healer's tent",
  1194.     "Even back here the tent is quite clean, and the garbage, consisting of "
  1195.     "empty clay jugs, small skeletons and assorted unrecognizeable objects, "
  1196.     "is piled neatly in several wooden bins. "
  1197.     "The alley is west and you can slip around the tent to the east.")$
  1198. Connect(r_alley4, r_behindHealer, D_EAST)$
  1199. UniConnect(r_behindHealer, r_entrance, D_EAST)$
  1200. RoomName(r_behindHealer, "Behind", "Healer's")$
  1201. Scenery(r_behindHealer,
  1202.     "path."
  1203.     "tent;clean,healer's,healer."
  1204.     "garbage."
  1205.     "jug;empty,clay."
  1206.     "skeleton;small."
  1207.     "object;assorted,unrecognizeable."
  1208.     "bin;wooden,wood")$
  1209. AutoGraphics(r_behindHealer, AutoPaths)$
  1210. AutoPens(r_behindHealer, C_FOREST_GREEN, C_TAN, 0, 0)$
  1211. r_behindHealer@p_Image := "Proving/behindHealer"$
  1212.  
  1213. define tp_surface r_fTrail0 CreateThing(r_provingField)$
  1214. SetupRoomP(r_fTrail0, "at a north and west bend in the trail", "")$
  1215. Connect(r_alley4, r_fTrail0, D_SOUTH)$
  1216. Scenery(r_fTrail0, "path.trail")$
  1217. AutoGraphics(r_fTrail0, AutoPaths)$
  1218.  
  1219. define tp_surface r_fTrail1 CreateThing(r_provingField)$
  1220. SetupRoomP(r_fTrail1, "on an east-west trail",
  1221.     "You can see forest to the west.")$
  1222. Connect(r_fTrail0, r_fTrail1, D_WEST)$
  1223. Scenery(r_fTrail1, "path.trail.forest.tree.bush.bushes")$
  1224. AutoGraphics(r_fTrail1, AutoPaths)$
  1225.  
  1226. define tp_surface r_forest1 CreateThing(r_provingForest)$
  1227. SetupRoomP(r_forest1, "in a forest",
  1228.     "You can see open space to the east, and paths in several directions.")$
  1229. Connect(r_fTrail1, r_forest1, D_WEST)$
  1230.  
  1231. define tp_surface r_forest2 CreateThing(r_provingForest)$
  1232. SetupRoomP(r_forest2, "in a forest",
  1233.     "You can skirt around a hill to the northwest and go straight south.")$
  1234. Connect(r_forest1, r_forest2, D_NORTH)$
  1235. Scenery(r_forest2, "hill")$
  1236. define tp_surface PR_FOREST2_ID NextEffectId()$
  1237. define tp_surface proc forest2Draw()void:
  1238.  
  1239.     if not KnowsEffect(nil, PR_FOREST2_ID) then
  1240.     DefineEffect(nil, PR_FOREST2_ID);
  1241.     GSetImage(nil, "Proving/forest2");
  1242.     IfFound(nil);
  1243.         ShowCurrentImage();
  1244.     Else(nil);
  1245.         AutoPaths();
  1246.         GSetPen(nil, C_MEDIUM_BROWN);
  1247.         GPolygonStart(nil);
  1248.         GAMove(nil, 0.078, 0.0);
  1249.         GADraw(nil, 0.22, 0.3);
  1250.         GADraw(nil, 0.28, 0.3);
  1251.         GADraw(nil, 0.42, 0.0);
  1252.         GPolygonEnd(nil);
  1253.     Fi(nil);
  1254.     EndEffect();
  1255.     fi;
  1256.     CallEffect(nil, PR_FOREST2_ID);
  1257. corp;
  1258. AutoGraphics(r_forest2, forest2Draw)$
  1259.  
  1260. define tp_surface r_forest3 CreateThing(r_provingForest)$
  1261. SetupRoomP(r_forest3, "in a forest beside a stream",
  1262.     "The stream blocks further progress to the west, but you can go "
  1263.     "northeast and north.")$
  1264. Connect(r_forest1, r_forest3, D_SOUTHWEST)$
  1265. RoomName(r_forest3, "Forest", "")$
  1266.  
  1267. define tp_surface o_stream CreateThing(nil)$
  1268. SetupObject(o_stream, r_forest3, "water.stream.creek.brook", "")$
  1269. o_stream@p_oInvisible := true$
  1270. o_stream@p_oNotGettable := true$
  1271. define tp_surface proc streamDrink()status:
  1272.     thing me;
  1273.     int current, max;
  1274.  
  1275.     me := Me();
  1276.     if not me@p_pHidden then
  1277.     OPrint(Capitalize(CharacterNameG(me)) +
  1278.         " takes a drink from the stream.\n");
  1279.     else
  1280.     OPrint("You hear a slurping sound.\n");
  1281.     fi;
  1282.     Print("Ahh! That was very refreshing!\n");
  1283.     current := me@p_pHitNow;
  1284.     max := me@p_pHitMax;
  1285.     if current ~= max then
  1286.     current := current + Random(3) + 2;
  1287.     if current > max then
  1288.         current := max;
  1289.     fi;
  1290.     me@p_pHitNow := current;
  1291.     fi;
  1292.     succeed
  1293. corp;
  1294. o_stream@p_oEatChecker := streamDrink$
  1295. o_stream@p_Image := "Proving/stream"$
  1296. o_stream@p_oListenString := "You can hear the stream splashing along."$
  1297. define tp_surface o_drink CreateThing(nil)$
  1298. SetupObject(o_drink, r_forest3, "drink.swallow", "")$
  1299. o_drink@p_oInvisible := true$
  1300. define tp_surface proc takeDrink(thing drink)status:
  1301.     streamDrink()
  1302. corp;
  1303. o_drink@p_oGetChecker := takeDrink$
  1304. define tp_surface proc streamDraw()void:
  1305.     AutoPaths();
  1306.     GSetPen(nil, C_BLUE);
  1307.     GAMove(nil, 0.125, 0.0);
  1308.     GRectangle(nil, 0.0625, 1.0, true);
  1309. corp;
  1310. AutoGraphics(r_forest3, streamDraw)$
  1311.  
  1312. define tp_surface STREAM_SOUND_ID NextSoundEffectId()$
  1313. define tp_proving p_StreamSoundVolume CreateIntProp()$
  1314. define tp_surface proc doStartStreamSound()void:
  1315.     int volume;
  1316.  
  1317.     volume := Here()@p_StreamSoundVolume;
  1318.     if volume ~= 0 then
  1319.     if SOn(nil) then
  1320.         SVolume(nil, volume);
  1321.         SPlaySound(nil, "stream", 0, STREAM_SOUND_ID);
  1322.         SVolume(nil, 10000);
  1323.         Me()@p_StreamSoundVolume := volume;
  1324.     fi;
  1325.     fi;
  1326. corp;
  1327. /* These two are also needed for the upper sewer level. */
  1328. define tp_proving proc startStreamSound()status:
  1329.     thing me;
  1330.  
  1331.     me := Me();
  1332.     if Character(me@p_pName) ~= nil then
  1333.     if Here()@p_StreamSoundVolume ~= me@p_StreamSoundVolume then
  1334.         if SOn(nil) and me@p_StreamSoundVolume ~= 0 then
  1335.         AbortEffect(nil, EFFECT_SOUND, STREAM_SOUND_ID);
  1336.         fi;
  1337.         if me@p_StreamSoundVolume = 0 and
  1338.         FindElement(me@p_pEnterActions, doStartStreamSound) = -1
  1339.         then
  1340.         AddTail(me@p_pEnterActions, doStartStreamSound);
  1341.         fi;
  1342.         doStartStreamSound();
  1343.     fi;
  1344.     fi;
  1345.     continue
  1346. corp;
  1347. define tp_proving proc stopStreamSound()status:
  1348.     thing me;
  1349.  
  1350.     me := Me();
  1351.     if Character(me@p_pName) ~= nil then
  1352.     if SOn(nil) then
  1353.         AbortEffect(nil, EFFECT_SOUND, STREAM_SOUND_ID);
  1354.     fi;
  1355.     me -- p_StreamSoundVolume;
  1356.     DelElement(me@p_pEnterActions, doStartStreamSound);
  1357.     fi;
  1358.     continue
  1359. corp;
  1360. AddAnyEnterChecker(r_forest1, stopStreamSound, false)$
  1361. r_forest3@p_StreamSoundVolume := 5000$
  1362. AddAnyEnterChecker(r_forest3, startStreamSound, false)$
  1363.  
  1364. define tp_surface r_forest4 CreateThing(r_provingForest)$
  1365. SetupRoomP(r_forest4, "in a forest beside a stream",
  1366.     "The stream blocks further progress to the west, but you can go "
  1367.     "north, south, and east.")$
  1368. Connect(r_forest1, r_forest4, D_WEST)$
  1369. Connect(r_forest3, r_forest4, D_NORTH)$
  1370. AddTail(r_forest4@p_rContents, o_stream)$
  1371. AddTail(r_forest4@p_rContents, o_drink)$
  1372. AutoGraphics(r_forest4, streamDraw)$
  1373. RoomName(r_forest4, "Forest", "")$
  1374. r_forest4@p_StreamSoundVolume := 5000$
  1375. AddAnyEnterChecker(r_forest4, startStreamSound, false)$
  1376.  
  1377. define tp_proving r_forestByStream CreateThing(r_provingForest)$
  1378. SetupRoomP(r_forestByStream, "down by the stream in the forest",
  1379.     "There is a large sewer draining into the stream here. The trickle of "
  1380.     "water coming from it manages to not pollute the stream. An iron grating "
  1381.     "covers the entrance to the sewer. You can climb up the bank to the "
  1382.     "trail.")$
  1383. Connect(r_forest4, r_forestByStream, D_DOWN)$
  1384. AddTail(r_forestByStream@p_rContents, o_stream)$
  1385. AddTail(r_forestByStream@p_rContents, o_drink)$
  1386. AutoGraphics(r_forestByStream, streamDraw)$
  1387. RoomName(r_forestByStream, "Down By", "Stream")$
  1388. Scenery(r_forestByStream,
  1389.     "trickle.bank.stonework.stone.work;stone.mouth;tunnel.tunnel."
  1390.     "sewer;large")$
  1391. r_forestByStream@p_StreamSoundVolume := 10000$
  1392. AddAnyEnterChecker(r_forestByStream, startStreamSound, false)$
  1393. define tp_proving o_barGrating CreateThing(nil)$
  1394. SetupObject(o_barGrating, r_forestByStream,
  1395.     "grating,grate;iron,bar.bar;iron.iron",
  1396.     "The grating is solidly built, and is firmly mounted into stonework "
  1397.     "around the tunnel mouth. It appears to be held closed by some "
  1398.     "kind of latch mechanism.")$
  1399. o_barGrating@p_oInvisible := true$
  1400. o_barGrating@p_oNotLockable := true$
  1401. define tp_proving proc barGratingGet(thing it)status:
  1402.     Print("The grating is held quite firmly in the stonework - you cannot "
  1403.     "break it free.\n");
  1404.     OPrint(Capitalize(CharacterNameG(Me())) + " rattles the grating.\n");
  1405.     fail
  1406. corp;
  1407. o_barGrating@p_oGetChecker := barGratingGet$
  1408. o_barGrating@p_oOpenString :=
  1409.     "The grating is held closed by the latch mechanism."$
  1410. o_barGrating@p_Image := "Proving/barGrating"$
  1411. define tp_proving o_gratingLatch CreateThing(nil)$
  1412. SetupObject(o_gratingLatch, r_forestByStream, "mechanism;latch.latch",
  1413.     "The mechanism is quite simple. It can be released by pulling on it, "
  1414.     "but it appears that it will latch again as soon as it is released.")$
  1415. o_gratingLatch@p_oInvisible := true$
  1416. o_gratingLatch@p_oNotLockable := true$
  1417. define tp_proving proc gratingLatchGet(thing it)status:
  1418.     Print("The latch mechanism is part of the grating - "
  1419.     "you cannot remove it.\n");
  1420.     OPrint(Capitalize(CharacterNameG(Me())) + " fiddles with the grating.\n");
  1421.     fail
  1422. corp;
  1423. o_gratingLatch@p_oGetChecker := gratingLatchGet$
  1424. o_gratingLatch@p_Image := "Proving/gratingLatch"$
  1425.  
  1426. define tp_surface r_forest5 CreateThing(r_provingForest)$
  1427. SetupRoomP(r_forest5, "in a forest beside a stream",
  1428.     "The stream blocks further progress to the west, but you can go "
  1429.     "north, south and southeast.")$
  1430. Connect(r_forest1, r_forest5, D_NORTHWEST)$
  1431. Connect(r_forest4, r_forest5, D_NORTH)$
  1432. AddTail(r_forest5@p_rContents, o_stream)$
  1433. AddTail(r_forest5@p_rContents, o_drink)$
  1434. AutoGraphics(r_forest5, streamDraw)$
  1435. RoomName(r_forest5, "Forest", "")$
  1436. r_forest5@p_StreamSoundVolume := 5000$
  1437. AddAnyEnterChecker(r_forest5, startStreamSound, false)$
  1438.  
  1439. define tp_surface r_forest6 CreateThing(r_provingForest)$
  1440. SetupRoomP(r_forest6, "in a forest between a stream and a hill",
  1441.     "The stream blocks further progress to the west, and the hill presents "
  1442.     "a barrier to the east. You can go northeast, south and southeast.")$
  1443. Connect(r_forest2, r_forest6, D_NORTHWEST)$
  1444. Connect(r_forest5, r_forest6, D_NORTH)$
  1445. AddTail(r_forest6@p_rContents, o_stream)$
  1446. AddTail(r_forest6@p_rContents, o_drink)$
  1447. Scenery(r_forest6, "hill.barrier")$
  1448. define tp_surface PR_FOREST6_ID NextEffectId()$
  1449. define tp_surface proc forest6Draw()void:
  1450.  
  1451.     if not KnowsEffect(nil, PR_FOREST6_ID) then
  1452.     DefineEffect(nil, PR_FOREST6_ID);
  1453.     GSetImage(nil, "Proving/forest6");
  1454.     IfFound(nil);
  1455.         ShowCurrentImage();
  1456.     Else(nil);
  1457.         streamDraw();
  1458.         GSetPen(nil, C_MEDIUM_BROWN);
  1459.         GPolygonStart(nil);
  1460.         GAMove(nil, 0.499, 0.15);
  1461.         GADraw(nil, 0.35, 0.42);
  1462.         GADraw(nil, 0.35, 0.58);
  1463.         GADraw(nil, 0.499, 0.84);
  1464.         GPolygonEnd(nil);
  1465.     Fi(nil);
  1466.     EndEffect();
  1467.     fi;
  1468.     CallEffect(nil, PR_FOREST6_ID);
  1469. corp;
  1470. AutoGraphics(r_forest6, forest6Draw)$
  1471. RoomName(r_forest6, "Forest", "")$
  1472. r_forest6@p_StreamSoundVolume := 5000$
  1473. AddAnyEnterChecker(r_forest6, startStreamSound, false)$
  1474. AddSouthEastChecker(r_forest6, stopStreamSound, false)$
  1475.  
  1476. define tp_surface r_forest7 CreateThing(r_provingForest)$
  1477. SetupRoomP(r_forest7, "in a forest, north of a small hill",
  1478.     "You can go deeper into the forest to the southwest, or get out of the "
  1479.     "woods to the southeast.")$
  1480. Connect(r_forest6, r_forest7, D_NORTHEAST)$
  1481. Scenery(r_forest7, "hill;small.wood")$
  1482. define tp_surface PR_FOREST7_ID NextEffectId()$
  1483. define tp_surface proc forest7Draw()void:
  1484.  
  1485.     if not KnowsEffect(nil, PR_FOREST7_ID) then
  1486.     DefineEffect(nil, PR_FOREST7_ID);
  1487.     GSetImage(nil, "Proving/forest7");
  1488.     IfFound(nil);
  1489.         ShowCurrentImage();
  1490.     Else(nil);
  1491.         AutoPaths();
  1492.         GSetPen(nil, C_MEDIUM_BROWN);
  1493.         GPolygonStart(nil);
  1494.         GAMove(nil, 0.078, 1.0);
  1495.         GADraw(nil, 0.22, 0.7);
  1496.         GADraw(nil, 0.28, 0.7);
  1497.         GADraw(nil, 0.42, 1.0);
  1498.         GPolygonEnd(nil);
  1499.     Fi(nil);
  1500.     EndEffect();
  1501.     fi;
  1502.     CallEffect(nil, PR_FOREST7_ID);
  1503. corp;
  1504. AutoGraphics(r_forest7, forest7Draw)$
  1505. RoomName(r_forest7, "Forest", "")$
  1506. AddNorthEastChecker(r_forest6, stopStreamSound, false)$
  1507.  
  1508. define tp_surface r_fTrail2 CreateThing(r_provingField)$
  1509. SetupRoomP(r_fTrail2, "on a trail",
  1510.     "The trail bends here, heading east to a cobbled road, and northwest "
  1511.     "towards a forest.")$
  1512. Connect(r_forest7, r_fTrail2, D_SOUTHEAST)$
  1513. Connect(r_road2, r_fTrail2, D_WEST)$
  1514. Scenery(r_fTrail2, "forest.tree.bush.bushes.path.trail.road;cobbled")$
  1515. AutoGraphics(r_fTrail2, AutoPaths)$
  1516.  
  1517. define tp_surface r_fTrailHidden CreateThing(r_provingForest)$
  1518. SetupRoomP(r_fTrailHidden, "in the forest",
  1519.     "There are trees all around you.")$
  1520. HConnect(r_fTrail2, r_fTrailHidden, D_SOUTH)$
  1521. HConnect(r_fTrail1, r_fTrailHidden, D_NORTH)$
  1522. /* Want to replace the scenery to remove the trail/path. */
  1523. r_fTrailHidden@p_rScenery := "ground.sky.forest.tree"$
  1524. Scenery(r_fTrailHidden, "forest.tree")$
  1525. AutoGraphics(r_fTrailHidden, AutoPaths)$
  1526.  
  1527. unuse tp_surface
  1528.  
  1529. unuse t_streets
  1530.