home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 May / Amiga_Games_Extra_CD_5-96.bin / spiele / publicdomain / amsrc / proving / proving0.m < prev    next >
Text File  |  1996-02-19  |  50KB  |  1,435 lines

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