home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #7 / amigamamagazinepolishissue1998.iso / rozrywka / rpg / amigamud / src / scenario / machines.m < prev    next >
Text File  |  1997-07-03  |  18KB  |  681 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1997 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * machines.m - code to add two simple machines to the world.
  9.  *    NOTE: rooms referenced directly:
  10.  *        r_mallEntrance - 3 times for the entry-exit recorder
  11.  *        r_crossSW - starting point for Caretaker
  12.  *        r_pearField - used in packratStep to force pear picking
  13.  *        r_es2 - starting point for Packrat
  14.  *    We also reference directly: p_oPlayAction, p_oEraseAction
  15.  *    We also require DoGet and DoDrop from verbs.m
  16.  */
  17.  
  18. use t_streets
  19.  
  20. private tp_machines CreateTable()$
  21. use tp_machines
  22.  
  23. /*****************************************************************************\
  24. *                                          *
  25. *   NOTE: This entry-exit recorder should be commented out if the MUD is      *
  26. *    running on a floppy disk. Since it continually modifies its record    *
  27. *    when the automatic machines go by, it is continually creating          *
  28. *    database entries that must be written out, hence there will be          *
  29. *    continual disk I/O even if no-one is playing. A big database cache    *
  30. *    can minimize this effect, but will not stop it completely.          *
  31. *                                          *
  32. \*****************************************************************************/
  33.  
  34. /* first, stuff in the entry-exit recorder (not a true machine) */
  35.  
  36. define tp_machines o_recorder CreateThing(nil)$
  37. SetThingStatus(o_recorder, ts_readonly)$
  38. SetupObject(o_recorder, r_mallEntrance,
  39.     "machine,player,recorder;enter-exit.machine,player,recorder;enter,exit,"
  40.     "enter-exit.exit;enter",
  41.     "This is a very strange machine. It's purpose, as indicated by a small "
  42.     "instruction label, is to record the comings and goings of people. "
  43.     "It will respond to 'play' and 'erase' to play its current record "
  44.     "and to erase it, respectively.")$
  45. define tp_machines p_recorderRecord CreateStringProp()$
  46. o_recorder@p_recorderRecord := ""$
  47. o_recorder@p_Image := "Town/recorder"$
  48.  
  49. /*
  50.  * recorderEnter - the recorder's player enter action.
  51.  */
  52.  
  53. define tp_machines proc recorderEnter()status:
  54.     string s;
  55.  
  56.     s := o_recorder@p_recorderRecord;
  57.     if Length(s) >= 3500 then
  58.     /* we are obviously pretty busy, and getting close to the current
  59.        arbitrary string maximum of 4K, so just nuke the record. */
  60.     s := "";
  61.     else
  62.     s := s + "    " + Capitalize(CharacterNameG(Me())) + " arrived.\n";
  63.     fi;
  64.     o_recorder@p_recorderRecord := s;
  65.     continue
  66. corp;
  67.  
  68. /*
  69.  * recorderLeave - the recorder's player leave action.
  70.  */
  71.  
  72. define tp_machines proc recorderLeave()status:
  73.     string s;
  74.  
  75.     s := o_recorder@p_recorderRecord;
  76.     if Length(s) >= 3500 then
  77.      s := "";
  78.     else
  79.     s := s + "    " + Capitalize(CharacterNameG(Me())) + " left.\n";
  80.     fi;
  81.     o_recorder@p_recorderRecord := s;
  82.     continue
  83. corp;
  84.  
  85. /* prevent players from picking up the recorder */
  86.  
  87. define tp_machines proc recorderGet(thing th)status:
  88.     Print("Sorry, but the machine is bolted to the floor!\n");
  89.     if not Me()@p_pHidden then
  90.     OPrint(Capitalize(CharacterNameG(Me())) +
  91.            " tries to pick up the enter-exit machine.\n");
  92.     fi;
  93.     fail
  94. corp;
  95.  
  96. /* play/erase functions */
  97.  
  98. define tp_machines proc recorderPlay()status:
  99.     string s;
  100.  
  101.     s := o_recorder@p_recorderRecord;
  102.     if s = "" then
  103.     Print("The machine's record is empty.\n");
  104.     else
  105.     Print("The machine's record contains:\n" + s);
  106.     fi;
  107.     if not Me()@p_pHidden then
  108.     OPrint(Capitalize(CharacterNameG(Me())) +
  109.         " fiddles with the machine.\n");
  110.     fi;
  111.     succeed
  112. corp;
  113.  
  114. /* recorderErase is in tp_misc since it is needed by the Postman */
  115. define tp_misc proc recorderErase()status:
  116.     string s;
  117.  
  118.     s := Capitalize(CharacterNameG(Me()));
  119.     o_recorder@p_recorderRecord := "    " + s + " erased this record.\n";
  120.     Print("OK, the machine's record is erased.\n");
  121.     if not Me()@p_pHidden then
  122.     OPrint(s + " fiddles with the machine.\n");
  123.     fi;
  124.     succeed
  125. corp;
  126.  
  127. /* attach the functions to the room the recorder is in */
  128.  
  129. AddAnyEnterChecker(r_mallEntrance, recorderEnter, false)$
  130. AddAnyLeaveChecker(r_mallEntrance, recorderLeave, false)$
  131.  
  132. /* and to the recorder itself */
  133.  
  134. o_recorder@p_oGetChecker := recorderGet$
  135. o_recorder@p_oPlayChecker := recorderPlay$
  136. o_recorder@p_oEraseChecker := recorderErase$
  137.  
  138. /* Exercise for the reader: remove the limitation of the recorder not
  139.    being portable. Do it without leaving a lot of properties hanging around
  140.    that aren't being used. */
  141.  
  142.  
  143.  
  144. /* Now the true machines */
  145.  
  146.  
  147. define tp_machines p_mLastDir CreateIntProp()$
  148. define tp_machines p_mWantDelay CreateBoolProp()$
  149. define tp_machines p_mArrived CreateBoolProp()$
  150. define tp_machines p_mCommand CreateStringProp()$
  151. define tp_machines p_mWho CreateStringProp()$
  152. define tp_machines p_mStepCount CreateIntProp()$
  153. define tp_machines MAX_STEPS 100$
  154.  
  155.  
  156. /* First, Caretaker */
  157.  
  158. define tp_machines Caretaker CreateThing(nil)$
  159.  
  160. /* caretakerGreet - let the caretaker greet everyone in a room he enters. */
  161.  
  162. define tp_machines proc caretakerGreet(thing who)void:
  163.     string name;
  164.  
  165.     name := who@p_pName;
  166.     if name ~= "" then
  167.     /* Skip watcher agents, etc. */
  168.     name := FormatName(name);
  169.     if name ~= "Caretaker" then
  170.         DoSay("Good day " + name + "!");
  171.     fi;
  172.     fi;
  173. corp;
  174.  
  175. /* caretakerStep - the central action routine for the caretaker */
  176.  
  177. define tp_machines proc caretakerStep()void:
  178.     thing here, me, object, home;
  179.     list thing lt;
  180.     int dir, firstNum, count, n;
  181.     bool found, lost;
  182.  
  183.     me := Me();
  184.     if not ClientsActive() then
  185.     /* no clients (humans) are playing - do little */
  186.     count := me@p_mStepCount + 1;
  187.     if count = MAX_STEPS then
  188.         SetLocation(r_crossSW);
  189.         me@p_mStepCount := 0;
  190.     else
  191.         me@p_mStepCount := count;
  192.     fi;
  193.     After(60.0, caretakerStep);
  194.     else
  195.     me@p_mStepCount := 0;
  196.     if me@p_mArrived then
  197.         /* this phase - greet everyone */
  198.         me@p_mArrived := false;
  199.         ForEachAgent(Here(), caretakerGreet);
  200.         After(20.0, caretakerStep);
  201.     else
  202.         /* this phase - move */
  203.         me@p_mArrived := true;
  204.         firstNum := me@p_mLastDir;
  205.         if Random(3) ~= 0 then
  206.         dir := firstNum;
  207.         else
  208.         firstNum := DirBack(firstNum);
  209.         while
  210.             dir := Random(12);
  211.             dir = firstNum
  212.         do
  213.         od;
  214.         firstNum := dir;
  215.         fi;
  216.         found := false;
  217.         lost := false;
  218.         while not found do
  219.         if TryToMove(dir) then
  220.             found := true;
  221.         else
  222.             dir := (dir + 1) % 12;
  223.             if dir = firstNum then
  224.             lost := true;
  225.             found := true;
  226.             fi;
  227.         fi;
  228.         od;
  229.         if lost then
  230.         Log("Caretaker stuck, " + Here()@p_rName + "\n");
  231.         Say("", "I'm stuck! Heeeeelp!!");
  232.         SetLocation(r_crossSW);
  233.         After(60.0, caretakerStep);
  234.         else
  235.         me@p_mLastDir := dir;
  236.         MachineMove(dir);
  237.         here := Here();
  238.  
  239.         /* Go through the objects in the room we just entered. Pick
  240.            each normal object up. If the object is not where it
  241.            "belongs", then keep it, otherwise drop it right away. */
  242.         lt := here@p_rContents;
  243.         count := Count(lt);
  244.         n := 0;
  245.         while n < count do
  246.             object := lt[n];
  247.             if not object@p_oInvisible and not object@p_oNotGettable
  248.             then
  249.             /* DoGet removes an object from the list */
  250.             count := count - 1;
  251.             if DoGet(here, me, object) ~= continue then
  252.                 /* something happened - abort out */
  253.                 n := count;
  254.             else
  255.                 home := object@p_oHome;
  256.                 if home = here or home = nil then
  257.                 /* object belongs here - drop it right away */
  258.                 if DoDrop(here, me, object) ~= continue then
  259.                     /* something happened - abort out */
  260.                     n := count;
  261.                 fi;
  262.                 /* otherwise, object is put on the end of the
  263.                    contents list, and we do not need to look at
  264.                    it again. */
  265.                 fi;
  266.                 /* otherwise, he just keeps it for now */
  267.             fi;
  268.             else
  269.             n := n + 1;
  270.             fi;
  271.         od;
  272.  
  273.         /* Go through the list of stuff he is carrying. If anything
  274.            in that list "belongs" here, then drop it. */
  275.         lt := me@p_pCarrying;
  276.         count := Count(lt);
  277.         n := 0;
  278.         while n < count do
  279.             object := lt[n];
  280.             if object@p_oHome = here then
  281.             count := count - 1;
  282.             if DoDrop(here, me, object) ~= continue then
  283.                 n := count;
  284.             fi;
  285.             else
  286.             n := n + 1;
  287.             fi;
  288.         od;
  289.  
  290.         After(20.0, caretakerStep);
  291.         fi;
  292.     fi;
  293.     fi;
  294. corp;
  295.  
  296. /* have the caretaker do the command we want him to do */
  297.  
  298. define tp_machines proc caretakerCommand()void:
  299.     thing me;
  300.     string command;
  301.  
  302.     me := Me();
  303.     command := me@p_mCommand;
  304.     me -- p_mCommand;
  305.     ignore Parse(G, command);
  306. corp;
  307.  
  308. /* the caretaker's "understanding" of things told to him */
  309.  
  310. define tp_machines proc caretakerTold()void:
  311.     thing me;
  312.     string w, np;
  313.  
  314.     me := Me();
  315.     w := GetTail();
  316.     SetTail(w);
  317.     w := GetWord();
  318.     if w == "drop" or w == "put" or w == "p" then
  319.     /* someone is telling the caretaker to drop something */
  320.     w := GetTail();
  321.     np := GetNounPhrase(G, w, 0);
  322.     if np = "" or FindName(me@p_pCarrying, p_oName, np) ~= succeed then
  323.         /* he is not carrying something matching what they want him to
  324.            drop */
  325.         if MatchName("flashlight.light;flash", np) >= 0 then
  326.         /* there really isn't any such thing */
  327.         DoSay("No way! It's mine!");
  328.         else
  329.         OPrint("Caretaker shakes his head in confusion.\n");
  330.         fi;
  331.     else
  332.         /* He is carrying something that matches. Say 'Certainly' and
  333.            try to drop it after 1 second. */
  334.         DoSay("Certainly.");
  335.         me@p_mCommand := "drop " + w;
  336.         After(1.0, caretakerCommand);
  337.     fi;
  338.     elif w == "work" or w == "clean" or w == "sweep" then
  339.     DoSay("I will, if you'll let me get back to my work!");
  340.     else
  341.     /* Dropping things is the only thing he will do */
  342.     DoSay("Sorry, I've got my work to see to.");
  343.     fi;
  344. corp;
  345.  
  346. define tp_machines proc caretakerHear(string what)void:
  347.     string word;
  348.  
  349.     word := SetSay(what);
  350.     if word ~= "" and word ~= "Packrat" and word ~= "Caretaker" then
  351.     /* ignore things said by the packrat or by himself */
  352.     word := GetWord();
  353.     if word == "Caretaker" or word == "Caretaker," or word == "Caretaker:"
  354.     then
  355.         /* only act if the speech started with his name */
  356.         caretakerTold();
  357.     elif word == "hello" or word == "hi" then
  358.         /* minimal conversationalist! */
  359.         OPrint("Caretaker grunts an acknowledgement.\n");
  360.     fi;
  361.     fi;
  362. corp;
  363.  
  364. /* called by the system when someone whispers to him */
  365.  
  366. define tp_machines proc caretakerWhispered(string what)void:
  367.  
  368.     if SetWhisperMe(what) ~= "" then
  369.     caretakerTold();
  370.     fi;
  371. corp;
  372.  
  373. /* called as the first step of someone giving something to him */
  374.  
  375. define tp_machines proc caretakerPre()status:
  376.  
  377.     SPrint(TrueMe(), "Caretaker accepts the gift.\n");
  378.     continue
  379. corp;
  380.  
  381. /* used for several other possible actions */
  382.  
  383. define tp_machines proc caretakerNoNo()status:
  384.  
  385.     DoSay("Watch it!");
  386.     fail
  387. corp;
  388.  
  389. define tp_machines proc caretakerCreate()void:
  390.  
  391.     Caretaker@p_pStandard := true;
  392.     Caretaker@p_mLastDir := D_SOUTH;
  393.     Caretaker@p_mArrived := true;
  394.     Caretaker@p_mStepCount := 0;
  395.     SetupMachine(Caretaker);
  396.     Caretaker@p_pDesc :=
  397. "The caretaker is a simple soul. He wears faded overalls, a green check "
  398. "shirt, heavy work boots and a grimy cap, on backwards. His goal in life is "
  399. "to put things back where they belong. One of his most prized possessions is "
  400. "a small handheld flashlight, which he keeps securely hidden in an inside "
  401. "pocket until he needs it.";
  402.     Caretaker@p_oLight := true;
  403.     CreateMachine("Caretaker,car", Caretaker, r_crossSW, caretakerStep);
  404.     ignore SetMachineActive(Caretaker, caretakerStep);
  405.     ignore SetMachineSay(Caretaker, caretakerHear);
  406.     ignore SetMachineWhisperMe(Caretaker, caretakerWhispered);
  407.     GNewIcon(Caretaker, makeCaretakerIcon());
  408.     Caretaker@p_pGivePre := caretakerPre;
  409.     Caretaker@p_oTouchChecker := caretakerNoNo;
  410.     Caretaker@p_oSmellChecker := caretakerNoNo;
  411.     Caretaker@p_oPushChecker := caretakerNoNo;
  412.     Caretaker@p_oPullChecker := caretakerNoNo;
  413.     Caretaker@p_oTurnChecker := caretakerNoNo;
  414.     Caretaker@p_oLiftChecker := caretakerNoNo;
  415.     Caretaker@p_oLowerChecker := caretakerNoNo;
  416.     Caretaker@p_oEatChecker := caretakerNoNo;
  417.     Caretaker@p_Image := "Characters/Caretaker";
  418. corp;
  419. caretakerCreate()$
  420. ignore DeleteSymbol(tp_machines, "caretakerCreate")$
  421.  
  422.  
  423. /* Now Packrat */
  424.  
  425. define tp_machines Packrat CreateThing(nil)$
  426.  
  427. /* packratStep - the central action routine for the packrat */
  428.  
  429. define tp_machines proc packratStep()void:
  430.     thing here, me, object;
  431.     list thing lt;
  432.     int dir, firstNum, n;
  433.     bool found, lost;
  434.  
  435.     me := Me();
  436.     if not ClientsActive() then
  437.     n := me@p_mStepCount + 1;
  438.     if n = MAX_STEPS then
  439.         me@p_mStepCount := 0;
  440.         SetLocation(r_es2);
  441.     else
  442.         me@p_mStepCount := n;
  443.     fi;
  444.     After(60.0, packratStep);
  445.     else
  446.     if me@p_mWantDelay then
  447.         me@p_mWantDelay := false;
  448.         After(IntToFixed(10 + Random(20)), packratStep);
  449.         me@p_mArrived := true;
  450.     elif me@p_pPosition ~= 0 then
  451.         ignore Parse(G, "stand up");
  452.         After(IntToFixed(10 + Random(20)), packratStep);
  453.     elif me@p_mArrived then
  454.         me@p_mArrived := false;
  455.         if Here() = r_pearField then
  456.         if FindName(me@p_pCarrying, p_oName, "pear") ~= fail then
  457.             ignore Parse(G, "eat pear");
  458.         else
  459.             ignore Parse(G, "pick pear");
  460.             me@p_mArrived := true;
  461.         fi;
  462.         fi;
  463.         After(IntToFixed(10 + Random(20)), packratStep);
  464.     else
  465.         me@p_mArrived := true;
  466.         firstNum := me@p_mLastDir;
  467.         if Random(2) ~= 0 then
  468.         dir := firstNum;
  469.         else
  470.         firstNum := DirBack(firstNum);
  471.         while
  472.             dir := Random(12);
  473.             dir = firstNum
  474.         do
  475.         od;
  476.         firstNum := dir;
  477.         fi;
  478.         found := false;
  479.         lost := false;
  480.         while not found do
  481.         if TryToMove(dir) then
  482.             found := true;
  483.         else
  484.             dir := (dir + 1) % 12;
  485.             if dir = firstNum then
  486.             lost := true;
  487.             found := true;
  488.             fi;
  489.         fi;
  490.         od;
  491.         if lost then
  492.         Log("Packrat is stuck, " + Here()@p_rName + "\n");
  493.         Say("", "I'm stuck! Waaaahhhh!!");
  494.         SetLocation(r_es2);
  495.         After(60.0, packratStep);
  496.         else
  497.         me@p_mLastDir := dir;
  498.         MachineMove(dir);
  499.         here := Here();
  500.         lt := here@p_rContents;
  501.         n := Count(lt);
  502.         if n ~= 0 then
  503.             object := lt[Random(n)];
  504.             if not object@p_oInvisible and not object@p_oNotGettable
  505.             then
  506.             if DoGet(here, me, object) = continue then
  507.                 lt := me@p_pCarrying;
  508.                 n := Count(lt);
  509.                 if n = 4 then
  510.                 ignore DoDrop(here, me, lt[Random(3)]);
  511.                 fi;
  512.             fi;
  513.             fi;
  514.         else
  515.             lt := me@p_pCarrying;
  516.             n := Count(lt);
  517.             if n ~= 0 and Random(20) = 0 then
  518.             ignore DoDrop(here, me, lt[Random(n)]);
  519.             fi;
  520.         fi;
  521.         After(IntToFixed(10 + Random(20)), packratStep);
  522.         fi;
  523.     fi;
  524.     fi;
  525. corp;
  526.  
  527. /*
  528.  * This kind of delay is a wise thing to do, since it avoids many possible
  529.  *    cases of recursion that could be troublesome. Consider the possibility
  530.  *    of multiple packrat's in one room, and someone waves...
  531.  */
  532.  
  533. define tp_machines proc packratCommand()void:
  534.     thing me;
  535.     string command, who;
  536.  
  537.     me := Me();
  538.     who := me@p_mWho;
  539.     if who ~= "" then
  540.     SetMeString(who);
  541.     me -- p_mWho;
  542.     fi;
  543.     command := me@p_mCommand;
  544.     me -- p_mCommand;
  545.     SetTail(command);
  546.     if GetWord() == "pose" then
  547.     Pose("", GetTail());
  548.     else
  549.     if Parse(G, command) = 0 then
  550.         DoSay("Sorry luv, you've confused me.");
  551.     fi;
  552.     fi;
  553. corp;
  554.  
  555. define tp_machines proc packratTold()void:
  556.     thing me;
  557.     string command;
  558.     int direction;
  559.  
  560.     me := Me();
  561.     /* need to save the tail, since doing 'DoSay' can change it! */
  562.     command := GetTail();
  563.     me@p_mWantDelay := true;
  564.     DoSay("Right you are luv.");
  565.     direction := DirMatch(command);
  566.     if direction ~= -1 then
  567.     me@p_mLastDir := direction;
  568.     fi;
  569.     me@p_mCommand := command;
  570.     After(1.0, packratCommand);
  571. corp;
  572.  
  573. define tp_machines proc packratHear(string what)void:
  574.     string word;
  575.  
  576.     word := SetSay(what);
  577.     if word ~= "" and word ~= "Packrat" and word ~= "Caretaker" then
  578.     Me()@p_mWho := word;
  579.     word := GetWord();
  580.     if word == "Packrat" or word == "Packrat," or word == "Packrat:" then
  581.         packratTold();
  582.     elif word == "hello" or word == "hi" or word == "greetings" then
  583.         DoSay(word + " to you too, luv!");
  584.     elif word == "good" or word == "nice" then
  585.         word := GetWord();
  586.         DoSay("You have a good'n too luv!");
  587.     fi;
  588.     fi;
  589. corp;
  590.  
  591. define tp_machines proc packratWhispered(string what)void:
  592.     string who;
  593.  
  594.     who := SetWhisperMe(what);
  595.     if who ~= "" then
  596.     Me()@p_mWho := who;
  597.     packratTold();
  598.     fi;
  599. corp;
  600.  
  601. define tp_machines proc packratOverhear(string what)void:
  602.     string who, target;
  603.  
  604.     who := SetWhisperOther(what);
  605.     if who ~= "" then
  606.     target := GetWord();
  607.     if target ~= "" then
  608.         what := GetTail();
  609.         if what ~= "" then
  610.         DoSay("Luv, if you want " + target + " to " + what +
  611.             ", you'd better speak up!");
  612.         fi;
  613.     fi;
  614.     fi;
  615. corp;
  616.  
  617. define tp_machines proc packratSaw(string what)void:
  618.  
  619.     SetTail(what);
  620.     ignore GetWord();
  621.     what := GetTail();
  622.     Me()@p_mCommand := "pose " + what;
  623.     After(1.0, packratCommand);
  624. corp;
  625.  
  626. define tp_machines proc packratNoNo()status:
  627.  
  628.     DoSay("'ere now - don't get fresh wi' me!");
  629.     fail
  630. corp;
  631.  
  632. /* This is needed so that Packrat can thank you AFTER you have seen the
  633.    message about giving. */
  634.  
  635. define tp_machines proc packratThank()void:
  636.  
  637.     DoSay("ta, luv!");
  638. corp;
  639.  
  640. define tp_machines proc packratPost()status:
  641.  
  642.     After(1.0, packratThank);
  643.     continue
  644. corp;
  645.  
  646. define tp_machines proc packratCreate()void:
  647.  
  648.     Packrat@p_pStandard := true;
  649.     Packrat@p_mLastDir := D_SOUTH;
  650.     Packrat@p_mArrived := false;
  651.     Packrat@p_mStepCount := 0;
  652.     SetupMachine(Packrat);
  653.     Packrat@p_pDesc :=
  654. "The packrat is a small woman with a wizened face, stringy brown hair, and "
  655. "beady little eyes. She is wearing a very old blue dress and an indeterminate "
  656. "number of sweaters. A battered felt hat with a drab daisy perches "
  657. "precariously on her head.";
  658.     CreateMachine("Packrat,pac,pack", Packrat, r_es2, packratStep);
  659.     ignore SetMachineActive(Packrat, packratStep);
  660.     ignore SetMachineSay(Packrat, packratHear);
  661.     ignore SetMachineWhisperMe(Packrat, packratWhispered);
  662.     ignore SetMachineWhisperOther(Packrat, packratOverhear);
  663.     ignore SetMachinePose(Packrat, packratSaw);
  664.     GNewIcon(Packrat, makePackratIcon());
  665.     Packrat@p_pGivePost := packratPost;
  666.     Packrat@p_oTouchChecker := packratNoNo;
  667.     Packrat@p_oSmellChecker := packratNoNo;
  668.     Packrat@p_oPushChecker := packratNoNo;
  669.     Packrat@p_oPullChecker := packratNoNo;
  670.     Packrat@p_oTurnChecker := packratNoNo;
  671.     Packrat@p_oLiftChecker := packratNoNo;
  672.     Packrat@p_oLowerChecker := packratNoNo;
  673.     Packrat@p_oEatChecker := packratNoNo;
  674.     Packrat@p_Image := "Characters/Packrat";
  675. corp;
  676. packratCreate()$
  677. ignore DeleteSymbol(tp_machines, "packratCreate")$
  678.  
  679. unuse tp_machines
  680. unuse t_streets
  681.