home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #7 / amigamamagazinepolishissue1998.iso / rozrywka / rpg / amigamud / src / basics / quests.m < prev    next >
Text File  |  1997-06-06  |  18KB  |  634 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1997 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * quests.m - define the quest setup for the starter scenario.
  9.  */
  10.  
  11. private tp_quests CreateTable()$
  12. use tp_quests
  13.  
  14. /* define some Quest stuff here so that we can refer to it from everywhere */
  15.  
  16. define tp_quests p_pQuestDoneList CreateThingListProp()$
  17. define tp_quests Questor CreateThing(nil)$
  18. define tp_quests p_rQuestUser CreateThingProp()$
  19. define tp_quests p_sQuestName CreateStringProp()$
  20. define tp_quests p_sQuestDesc CreateActionProp()$
  21. define tp_quests p_sQuestChecker CreateActionProp()$
  22. define tp_quests p_sQuestHint CreateActionProp()$
  23. define tp_quests p_sQuestType CreateIntProp()$
  24. define tp_quests QUEST_DIRECT    0$
  25. define tp_quests QUEST_GIVE    1$
  26. define tp_quests QUEST_TELL    2$
  27. define tp_quests p_sQuestList CreateThingListProp()$
  28.  
  29. Questor@p_sQuestList := CreateThingList()$
  30.  
  31. define t_quests proc QuestDirect(string name; action desc, checker, hint)void:
  32.     thing quest;
  33.  
  34.     if desc = nil or checker = nil or hint = nil then
  35.     Print("*** Invalid action given to QuestDirect.\n");
  36.     else
  37.     quest := CreateThing(nil);
  38.     quest@p_sQuestName := name;
  39.     quest@p_sQuestDesc := desc;
  40.     quest@p_sQuestChecker := checker;
  41.     quest@p_sQuestHint := hint;
  42.     quest@p_sQuestType := QUEST_DIRECT;
  43.     AddTail(Questor@p_sQuestList, quest);
  44.     fi;
  45. corp;
  46.  
  47. define t_quests proc QuestGive(string name; action desc, checker, hint)void:
  48.     thing quest;
  49.  
  50.     if desc = nil or checker = nil or hint = nil then
  51.     Print("*** Invalid action given to QuestGive.\n");
  52.     else
  53.     quest := CreateThing(nil);
  54.     quest@p_sQuestName := name;
  55.     quest@p_sQuestDesc := desc;
  56.     quest@p_sQuestChecker := checker;
  57.     quest@p_sQuestHint := hint;
  58.     quest@p_sQuestType := QUEST_GIVE;
  59.     AddTail(Questor@p_sQuestList, quest);
  60.     fi;
  61. corp;
  62.  
  63. define t_quests proc public GiveToQuestor(string what)void:
  64.     thing me;
  65.  
  66.     me := TrueMe();
  67.     SPrint(me, "You give the " + what + " to Questor.\n");
  68.     /* No-one should be able to see this message, but in case SysAdmin
  69.        *poofs* into the Questor's Office to watch, or some other wizard
  70.        similarly gets in, we'll do it "right". */
  71.     ABPrint(AgentLocation(me), me, nil,
  72.         Capitalize(CharacterNameS(me)) + AAn(" gives", what) +
  73.         " to Questor.\n");
  74. corp;
  75.  
  76. define t_quests proc QuestTell(string name; action desc, checker, hint)void:
  77.     thing quest;
  78.  
  79.     if desc = nil or checker = nil or hint = nil then
  80.     Print("*** Invalid action given to QuestTell.\n");
  81.     else
  82.     quest := CreateThing(nil);
  83.     quest@p_sQuestName := name;
  84.     quest@p_sQuestDesc := desc;
  85.     quest@p_sQuestChecker := checker;
  86.     quest@p_sQuestHint := hint;
  87.     quest@p_sQuestType := QUEST_TELL;
  88.     AddTail(Questor@p_sQuestList, quest);
  89.     fi;
  90. corp;
  91.  
  92. define tp_quests proc completeQuest(thing player, quest)bool:
  93.     list thing lt;
  94.  
  95.     lt := player@p_pQuestDoneList;
  96.     if lt = nil then
  97.     lt := CreateThingList();
  98.     player@p_pQuestDoneList := lt;
  99.     fi;
  100.     if FindElement(lt, quest) ~= -1 then
  101.     SPrint(player, "You have already completed the " +
  102.         quest@p_sQuestName + " quest!\n");
  103.     false
  104.     else
  105.     AddTail(lt, quest);
  106.     APrint("\n" + Capitalize(CharacterNameS(player)) +
  107.         " has completed a quest!!\n\n");
  108.     true
  109.     fi
  110. corp;
  111.  
  112. define t_quests proc public DoQuest(action checker)void:
  113.     list thing quests, lt;
  114.     thing me, quest;
  115.     int i;
  116.  
  117.     me := Me();
  118.     quests := Questor@p_sQuestList;
  119.     for i from 0 upto Count(quests) - 1 do
  120.     quest := quests[i];
  121.     if quest@p_sQuestChecker = checker then
  122.         ignore completeQuest(me, quest);
  123.     fi;
  124.     od;
  125. corp;
  126.  
  127. define t_quests proc public DoneQuest(action checker)bool:
  128.     list thing lt;
  129.     int i;
  130.     bool found;
  131.  
  132.     found := false;
  133.     lt := Me()@p_pQuestDoneList;
  134.     if lt ~= nil then
  135.     for i from 0 upto Count(lt) - 1 do
  136.         if lt[i]@p_sQuestChecker = checker then
  137.         found := true;
  138.         fi;
  139.     od;
  140.     fi;
  141.     found
  142. corp;
  143.  
  144. define t_quests proc ShowQuests(thing who; bool wantDetail)bool:
  145.     list thing lt;
  146.     int count, i, oldIndent;
  147.  
  148.     lt := who@p_pQuestDoneList;
  149.     if lt = nil then
  150.     false
  151.     else
  152.     count := Count(lt);
  153.     if count = 0 then
  154.         false
  155.     else
  156.         Print(Capitalize(CharacterNameS(who)));
  157.         if wantDetail then
  158.         oldIndent := GetIndent();
  159.         SetIndent(oldIndent + 2);
  160.         Print(" has completed the following quests:");
  161.         for i from 0 upto count - 1 do
  162.             Print(" " + lt[i]@p_sQuestName);
  163.         od;
  164.         SetIndent(oldIndent);
  165.         Print("\n");
  166.         else
  167.         Print(" has completed ");
  168.         if count = 1 then
  169.             Print("one quest.\n");
  170.         else
  171.             IPrint(count);
  172.             Print(" quests.\n");
  173.         fi;
  174.         fi;
  175.         true
  176.     fi
  177.     fi
  178. corp;
  179.  
  180. define tp_quests QUESTROOM_ID NextEffectId()$
  181. define tp_quests proc drawQuestRoom()void:
  182.  
  183.     if not KnowsEffect(nil, QUESTROOM_ID) then
  184.     DefineEffect(nil, QUESTROOM_ID);
  185.     GSetImage(nil, "Town/questRoom");
  186.     IfFound(nil);
  187.         ShowCurrentImage();
  188.     Else(nil);
  189.         TextBox("Complete your", "quests here", "");
  190.     Fi(nil);
  191.     EndEffect();
  192.     fi;
  193.     CallEffect(nil, QUESTROOM_ID);
  194. corp;
  195.  
  196. define tp_quests r_questRoom CreateThing(nil)$
  197. SetupRoom(r_questRoom, "in Questor's office",
  198.     "The office is old-fashioned, but quite opulent in its way. The walls "
  199.     "are lined with shelves and racks containing all sorts of trophies. "
  200.     "There are fine collections of Bushman spears, Watusi shields, "
  201.     "Aborigine horns, Iroquois pipes, samurai swords, Malay masks, "
  202.     "modern skateboards, Meershaum pipes, etc. One large case contains "
  203.     "a zoo of live-looking animals, many of which you cannot classify. "
  204.     "A shelf contains jars, each filled with smaller, very dead-looking "
  205.     "animals. Many appear to have faces and hands. Questor's desk is a "
  206.     "large construction of red-swirled marble. It is quite neat and tidy, "
  207.     "with a couple of piles of papers, a fine onyx pen-stand and a trio "
  208.     "of Fabergé eggs. Behind the desk is a matching marble chair with "
  209.     "purple velvet cushions and a pair of huge gems as handrests. Arching "
  210.     "over Questor's head (for he is sitting in the chair watching you as "
  211.     "you stare around) is a cobra with flaring hood, carved from pure "
  212.     "white marble. The cobra's eyes are deep red and it seems to be watching "
  213.     "you.")$
  214. r_questRoom@p_rNoMachines := true$
  215. Scenery(r_questRoom,
  216.     "wall,shelf,shelves,rack,trophy,trophies,collection,case;fine,large."
  217.     "spear;Bushman."
  218.     "shield;Watusi."
  219.     "horn;Aborigine."
  220.     "pipe;Iroquois."
  221.     "sword;samurai."
  222.     "mask;Malay."
  223.     "skateboard,board;skate,modern."
  224.     "pipe;Meerschaum."
  225.     "zoo."
  226.     "animal;live-looking,live,looking,dead-looking,dead."
  227.     "jar."
  228.     "face,hand."
  229.     "desk;large,red-swirled,red,swirled,marble."
  230.     "paper,pile;piles,of."
  231.     "pen-stand,stand;pen,fine,onyx."
  232.     "egg;Faberge,Fabergé,trio,of."
  233.     "chair;matching,marble."
  234.     "cushion;purple,velvet."
  235.     "gem,handrest,rest;hand,pair,of,huge,gem."
  236.     "beard,mustache,eyebrow,brow;eye,long,flowing,massive,white."
  237.     "cloak,satin;long,flowing,jet-black,jet,black,satin."
  238.     "pendant;extremely,large,ugly."
  239.     "q,'q';letter."
  240.     "chain,link;chain,of,iron.")$
  241. RoomGraphics(r_questRoom, "Questor's", "Office", NextMapGroup(), 0.0, 0.0,
  242.          drawQuestRoom)$
  243. FakeObject(CreateThing(nil), r_questRoom,
  244.     "cobra,hood,snake;with,flaring,hood,pure,white,marble",
  245.     "Other than being made of white marble and having deep red eyes that "
  246.     "seem to be staring at you, there is nothing special about the cobra.")$
  247. FakeObject(CreateThing(nil), r_questRoom, "eye;Questor's,Questor",
  248.     "Questor's eyes are not something you want to stare at.")$
  249. FakeObject(CreateThing(nil), r_questRoom,
  250.     "eye;cobra's,snake's,cobra,snake,deep,red",
  251.     "The stone cobra's eyes seem to be watching you.")$
  252. FakeObject(CreateThing(nil), r_questRoom, "office",
  253.     "Just use 'look' to look at the office.")$
  254.  
  255. /*
  256.  * Just in case some wise-guy wizard tries to force him out.
  257.  */
  258.  
  259. define tp_quests proc questorExit()status:
  260.  
  261.     if Me() = Questor then
  262.     fail
  263.     else
  264.     continue
  265.     fi
  266. corp;
  267. AddAnyLeaveChecker(r_questRoom, questorExit, false)$
  268.  
  269. define tp_quests proc resetQuestor()void:
  270.     list thing lt;
  271.     int i;
  272.     thing th;
  273.  
  274.     lt := Questor@p_pCarrying;
  275.     i := Count(lt);
  276.     while i ~= 0 do
  277.     i := i - 1;
  278.     th := lt[i];
  279.     ZapObject(th);
  280.     DelElement(lt, th);
  281.     od;
  282.     Questor -- p_rQuestUser;
  283. corp;
  284.  
  285. define tp_quests proc questActiveAction()void:
  286.  
  287.     Print("\n* You were moved out of Questor's office on a server "
  288.       "restart. *\n\n");
  289.     DelElement(Me()@p_pEnterActions, questActiveAction);
  290. corp;
  291.  
  292. define tp_quests proc questRestart(thing th)void:
  293.     thing who;
  294.  
  295.     who := Questor@p_rQuestUser;
  296.     if who ~= nil then
  297.     SetCharacterLocation(ThingCharacter(who), r_questRoom@p_rExit);
  298.     AddTail(who@p_pEnterActions, questActiveAction);
  299.     resetQuestor();
  300.     fi;
  301. corp;
  302.  
  303. RegisterActiveAction(Questor, questRestart)$
  304.  
  305. define tp_quests proc questIdle()void:
  306.  
  307.     DelElement(Me()@p_pExitActions, questIdle);
  308.     resetQuestor();
  309.     SetLocation(r_questRoom@p_rExit);
  310. corp;
  311.  
  312. define tp_quests proc questEnter()status:
  313.     thing who, me;
  314.  
  315.     who := Questor@p_rQuestUser;
  316.     if who = nil then
  317.     me := Me();
  318.     if CharacterNameS(me) ~= "Packrat" then
  319.         Questor@p_rQuestUser := me;
  320.         Print(
  321.         "The huge door opens easily, and you enter Questor's office.\n"
  322.         "NOTE: no-one else can enter the office while you are in it - "
  323.         "please keep your stay as short as possible. Thank-you.\n");
  324.         AddHead(me@p_pExitActions, questIdle);
  325.     fi;
  326.     continue
  327.     else
  328.     Print("The huge door will not open - you cannot enter. Questor is "
  329.         "currently in conference with " + CharacterNameS(who) + ".\n");
  330.     fail
  331.     fi
  332. corp;
  333.  
  334. define tp_quests proc questExit()status:
  335.  
  336.     DelElement(Me()@p_pExitActions, questIdle);
  337.     resetQuestor();
  338.     Print("You open the huge door and go outside. "
  339.     "Questor can now deal with other players.\n");
  340.     continue
  341. corp;
  342.  
  343. define tp_quests proc showQuests()string:
  344.     list thing lt;
  345.     int count, i, oldIndent;
  346.     thing quest;
  347.     string result;
  348.  
  349.     lt := Questor@p_sQuestList;
  350.     count := Count(lt);
  351.     if count = 0 then
  352.     result := "There are no quests yet.";
  353.     else
  354.     result := "The current quests are:";
  355.     oldIndent := GetIndent();
  356.     for i from 0 upto count - 1 do
  357.         quest := lt[i];
  358.         result := result + "\n  " + quest@p_sQuestName + " quest: " +
  359.         call(quest@p_sQuestDesc, string)();
  360.     od;
  361.     result := result + "\nIf you need a hint on a quest, just ask.";
  362.     fi;
  363.     result
  364. corp;
  365.  
  366. define tp_quests proc questHint(string what)bool:
  367.     list thing lt;
  368.     thing quest;
  369.     int count, i;
  370.     bool found;
  371.  
  372.     if what = "" then
  373.     Print("Use 'hint <quest-name>' to get a hint for a given quest.\n");
  374.     false
  375.     else
  376.     lt := Questor@p_sQuestList;
  377.     count := Count(lt);
  378.     if count = 0 then
  379.         Print("There are no quests yet!\n");
  380.         false
  381.     else
  382.         if SubString(what, 0, 6) = "quest;" then
  383.         what := SubString(what, 6, Length(what) - 6);
  384.         fi;
  385.         found := false;
  386.         for i from 0 upto count - 1 do
  387.         quest := lt[i];
  388.         if quest@p_sQuestName == what then
  389.             Print(call(quest@p_sQuestHint, string)() + "\n");
  390.             found := true;
  391.         fi;
  392.         od;
  393.         if not found then
  394.         Print("There is no '" + what + "' quest.\n");
  395.         false
  396.         else
  397.         true
  398.         fi
  399.     fi
  400.     fi
  401. corp;
  402.  
  403. define tp_quests proc questorStep()void:
  404. corp;
  405.  
  406. define tp_quests proc questorSay(string what)void:
  407.     list thing lt;
  408.     thing quest, player;
  409.     int count, i;
  410.     bool found, toPackrat, first;
  411.     string who, word, specialWord;
  412.  
  413.     player := Questor@p_rQuestUser;
  414.     /* so that the checker procs can find the player in question */
  415.     SetIt(player);
  416.     who := SetSay(what);
  417.     found := false;
  418.     toPackrat := false;
  419.     first := true;
  420.     specialWord := "";
  421.     while
  422.     word := GetWord();
  423.     word ~= "" and not found
  424.     do
  425.     if first then
  426.         if word == "Packrat" then
  427.         toPackrat := true;
  428.         fi;
  429.         first := false;
  430.     fi;
  431.     lt := Questor@p_sQuestList;
  432.     count := Count(lt);
  433.     i := 0;
  434.     while i ~= count and not found do
  435.         quest := lt[i];
  436.         if quest@p_sQuestType = QUEST_TELL and
  437.         call(quest@p_sQuestChecker, bool)(word)
  438.         then
  439.         found := true;
  440.         i := count;
  441.         if completeQuest(player, quest) then
  442.             SPrint(player,
  443.             "Questor smiles warmly and says: Congratulations " +
  444.             who + ", you have completed the " +
  445.             quest@p_sQuestName + " quest!\n");
  446.         fi;
  447.         else
  448.         if word == "quest" or word == "quests" or
  449.             word == "info" or word == "information" or
  450.             word == "help" or word == "hint" or word == "hints"
  451.         then
  452.             specialWord := word;
  453.         fi;
  454.         i := i + 1;
  455.         fi;
  456.     od;
  457.     od;
  458.     if not found then
  459.     if specialWord ~= "" then
  460.         if specialWord == "hint" or specialWord == "hints" then
  461.         DoSay("Go outside and ask - don't bother me!");
  462.         else
  463.         DoSay("To find out about quests, read the sign outside!");
  464.         fi;
  465.     elif who ~= "Packrat" and not toPackrat then
  466.         DoSay("Quit gabbing and get on with your business!");
  467.     fi;
  468.     fi;
  469. corp;
  470.  
  471. define tp_quests proc questorWhisperMe(string what)void:
  472.  
  473.     if SetWhisperMe(what) ~= "" then
  474.     DoSay("Don't try to get familiar with me!");
  475.     fi;
  476. corp;
  477.  
  478. define tp_quests proc questorOverhear(string what)void:
  479.  
  480.     DoSay("Whispering is impolite!");
  481. corp;
  482.  
  483. define tp_quests proc questorSaw(string what)void:
  484.  
  485.     DoSay("Stop messing around!");
  486. corp;
  487.  
  488. define tp_quests proc questorNoNo()status:
  489.  
  490.     Print("Questor glares at you, and so does the cobra!\n");
  491.     fail
  492. corp;
  493.  
  494. define tp_quests proc questorCreate()void:
  495.  
  496.     Questor@p_pStandard := true;
  497.     SetupMachine(Questor);
  498.     Questor@p_pDesc :=
  499.     "Questor is a tall, skinny man with a long, flowing white beard and "
  500.     "an equally long and flowing mustache. His massive white eyebrows "
  501.     "don't flow quite as much. He wears a long, flowing (naturally) cloak "
  502.     "of jet-black satin with no decorations. His head is bare (and a "
  503.     "little bit bald on top), but on his chest is an extremely large "
  504.     "and ugly pendant in the shape of the letter 'Q'. It is supported on "
  505.     "a massive chain of iron links. Wearing this may account for his "
  506.     "perpetual look of annoyance. All of these things you notice only "
  507.     "briefly, before you look at his eyes, which are bright grey, and "
  508.     "seem to penetrate to your very core.";
  509.     CreateMachine("Questor", Questor, r_questRoom, questorStep);
  510.     ignore SetMachineActive(Questor, questorStep);
  511.     ignore SetMachineSay(Questor, questorSay);
  512.     ignore SetMachineWhisperMe(Questor, questorWhisperMe);
  513.     ignore SetMachineWhisperOther(Questor, questorOverhear);
  514.     ignore SetMachinePose(Questor, questorSaw);
  515.     GNewIcon(Questor, makeQuestorIcon());
  516.     Questor@p_oTouchChecker := questorNoNo;
  517.     Questor@p_oSmellChecker := questorNoNo;
  518.     Questor@p_oPushChecker := questorNoNo;
  519.     Questor@p_oPullChecker := questorNoNo;
  520.     Questor@p_oTurnChecker := questorNoNo;
  521.     Questor@p_oLiftChecker := questorNoNo;
  522.     Questor@p_oLowerChecker := questorNoNo;
  523.     Questor@p_oEatChecker := questorNoNo;
  524.     Questor@p_Image := "Characters/Questor";
  525. corp;
  526. questorCreate();
  527. ignore DeleteSymbol(tp_quests, "questorCreate")$
  528.  
  529. define tp_quests proc questorPre()status:
  530.     list thing lt;
  531.     thing me, item, quest;
  532.     int count, i;
  533.     status st;
  534.     bool found;
  535.  
  536.     me := TrueMe();
  537.     item := It();
  538.     lt := Questor@p_sQuestList;
  539.     count := Count(lt);
  540.     found := false;
  541.     i := 0;
  542.     while i ~= count do
  543.     quest := lt[i];
  544.     if quest@p_sQuestType = QUEST_GIVE then
  545.         st := call(quest@p_sQuestChecker, status)();
  546.         if st ~= continue then
  547.         found := true;
  548.         i := count;
  549.         if st = succeed then
  550.             if completeQuest(me, quest) then
  551.             SPrint(me,
  552.                 "Questor smiles warmly and says: Congratulations "+
  553.                   me@p_pName +  ", you have completed the " +
  554.                   quest@p_sQuestName + " quest!\n");
  555.             fi;
  556.         fi;
  557.         ZapObject(item);
  558.         DelElement(me@p_pCarrying, item);
  559.         else
  560.         i := i + 1;
  561.         fi;
  562.     else
  563.         i := i + 1;
  564.     fi;
  565.     od;
  566.     if found then succeed else continue fi
  567. corp;
  568.  
  569. Questor@p_pGivePre := questorPre$
  570.  
  571. define tp_quests questSign CreateThing(nil)$
  572.  
  573. /*
  574.  * SetupQuestorOffice - set things up so that the given direction from the
  575.  *    given location leads to Questor's office.
  576.  */
  577.  
  578. define t_quests proc SetupQuestorOffice(thing where; int dir)void:
  579.  
  580.     Connect(where, r_questRoom, dir);
  581.     Connect(where, r_questRoom, D_ENTER);
  582.     AddDirChecker(where, dir, questEnter, false);
  583.     AddDirChecker(r_questRoom, DirBack(dir), questExit, false);
  584.     AddEnterChecker(where, questEnter, false);
  585.     AddExitChecker(r_questRoom, questExit, false);
  586.     ExtendDesc(where,
  587.     "The building here appears to be constructed from solid granite "
  588.     "blocks and is quite featureless. The door is a large one of foot-"
  589.     "thick oak beams strengthed with iron straps. There are no windows. "
  590.     "In the center of the door is the letter 'Q', pounded out of thick "
  591.     "iron. Beside the door, a discreet sign labelled \"Quests\" has a "
  592.     "list of some kind.");
  593.     Scenery(where,
  594.     "block,granite;solid,granite."
  595.     "building;featureless."
  596.     "door,beam;foot-thick,foot,thick,oak."
  597.     "strap;iron."
  598.     "q,'q',letter;letter,thick,pounded,iron");
  599.     FakeObject(questSign, where,
  600.     "sign;discreet.sign,list,quest;discreet,quest,quests", "");
  601.     questSign@p_oReadAction := showQuests;
  602.     where@p_rHintAction := questHint;
  603. corp;
  604.  
  605. /* setup the 'quests' verb */
  606.  
  607. define tp_quests proc v_quests()bool:
  608.     string name;
  609.     thing who;
  610.  
  611.     name := GetWord();
  612.     if name = "" then
  613.     if not ShowQuests(Me(), true) then
  614.         Print("You have not yet completed any quests.\n");
  615.     fi;
  616.     true
  617.     else
  618.     who := FindAgent(name);
  619.     if who ~= nil then
  620.         if not ShowQuests(who, IsWizard()) then
  621.         Print(name + " has not yet completed any quests.\n");
  622.         fi;
  623.         true
  624.     else
  625.         Print("There is no " + name + " here.\n");
  626.         false
  627.     fi
  628.     fi
  629. corp;
  630.  
  631. VerbTail(G, "quests", v_quests)$
  632.  
  633. unuse tp_quests
  634.