home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume5 / omega2 / part08 / ocom3.c < prev    next >
C/C++ Source or Header  |  1988-07-25  |  27KB  |  1,050 lines

  1. /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988 */
  2. /* ocom3.c */
  3.  
  4. /* This file contains some more top level command functions
  5.    called from ocom1.c */
  6.  
  7. #include "oglob.h"
  8. #include "odate.h"
  9.  
  10. /* look at some spot */
  11. void examine()
  12. {
  13.   pol ol;
  14.   int x=Player.x,y=Player.y,drewmenu=FALSE;
  15.  
  16.   clearmsg();
  17.  
  18.   setgamestatus(SKIP_MONSTERS);
  19.   mprint("Examine --");
  20.   setspot(&x,&y);
  21.   if (inbounds(x,y)) {
  22.     clearmsg();
  23.     if (Current_Environment == E_COUNTRYSIDE) {
  24.       if (! Country[x][y].explored) 
  25.     print3("How should I know what that is?");
  26.       else {
  27.     mprint("That terrain is:");
  28.     mprint(countryid(Country[x][y].current_terrain_type));
  29.       }
  30.     } 
  31.     else if (! los_p(Player.x,Player.y,x,y))
  32.       print3("I refuse to examine something I can't see.");
  33.     else {
  34.       clearmsg();
  35.       if (Level->site[x][y].creature != NULL) 
  36.     mprint(mstatus_string(Level->site[x][y].creature));
  37.       else if ((Player.x == x) && (Player.y ==y)) 
  38.     describe_player();
  39.       if (loc_statusp(x,y,SECRET))
  40.     print2("An age-worn stone wall.");
  41.       else
  42.     switch (Level->site[x][y].locchar) {
  43.     case SPACE: print2("An infinite void."); break;
  44.     case PORTCULLIS: print2("A heavy steel portcullis"); break;
  45.     case ABYSS: print2("An entrance to the infinite abyss"); break;
  46.     case FLOOR:
  47.       if (Current_Dungeon == Current_Environment)
  48.         print2("A dirty stone floor.");
  49.       else print2("The ground.");
  50.       break;
  51.     case WALL:
  52.       if (Level->site[x][y].aux == 0)
  53.         print2("A totally impervious wall.");
  54.       else if (Level->site[x][y].aux < 10)
  55.         print2("A pitted concrete wall.");
  56.       else if (Level->site[x][y].aux < 30)
  57.         print2("An age-worn sandstone wall.");
  58.       else if (Level->site[x][y].aux < 50)
  59.         print2("A smooth basalt wall.");
  60.       else if (Level->site[x][y].aux < 70)
  61.         print2("A solid granite wall.");
  62.       else if (Level->site[x][y].aux < 90)
  63.         print2("A wall of steel.");
  64.       else if (Level->site[x][y].aux < 210) {
  65.         if (Current_Environment == E_CITY)
  66.           print2("A thick wall of Rampart bluestone");
  67.         else print2("A magically reinforced wall.");
  68.       }
  69.       else print2("An almost totally impervious wall.");
  70.       break;
  71.     case RUBBLE:print2("A dangerous-looking pile of rubble."); break;
  72.     case SAFE:print2("A steel safe inset into the floor."); break;
  73.     case CLOSED_DOOR:print2("A solid oaken door, now closed."); break;
  74.     case OPEN_DOOR:print2("A solid oaken door, now open."); break;
  75.     case STATUE:print2("A strange-looking statue."); break;
  76.     case UP:print2("A stairway leading up."); break;
  77.     case DOWN:print2("A stairway leading down...."); break;
  78.     case TRAP:print2(trapid(Level->site[x][y].p_locf)); break;
  79.     case HEDGE:
  80.       if (Level->site[x][y].p_locf == L_EARTH_STATION)
  81.         print2("A weird fibrillation of oozing tendrils.");
  82.       else print2("A brambly, thorny hedge."); 
  83.       break;
  84.     case LAVA:print2("A bubbling pool of lava."); break;
  85.     case LIFT:print2("A strange glowing disk."); break;
  86.     case ALTAR:print2("An (un?)holy altar."); break;
  87.     case CHAIR:print2("A chair."); break;
  88.     case WHIRLWIND:print2("A strange cyclonic electrical storm."); break;
  89.     case WATER: 
  90.       if (Level->site[x][y].p_locf == L_WATER)
  91.         print2("A deep pool of water.");
  92.       else if (Level->site[x][y].p_locf == L_CHAOS)
  93.         print2("A pool of primal chaos.");
  94.       else if (Level->site[x][y].p_locf == L_WATER_STATION)
  95.         print2("A bubbling pool of acid.");
  96.       else print2("An eerie pool of water.");
  97.       break;
  98.     case FIRE:print2("A curtain of fire."); break;
  99.     default:print2("Wow, I haven't the faintest idea!"); break;
  100.     }
  101.       if ((ol = Level->site[x][y].things) != NULL) {
  102.     if (ol->next == NULL)
  103.       print3(itemid(ol->thing));
  104.     else {
  105.       drewmenu = TRUE;
  106.       menuclear();
  107.       menuprint("Things on floor:\n");
  108.       while (ol != NULL) {
  109.         menuprint("\n");
  110.         menuprint(itemid(ol->thing));
  111.         ol = ol->next;
  112.       }
  113.     }
  114.       }
  115.       morewait();
  116.       sign_print(x,y,TRUE);
  117.     }
  118.   }
  119.   if (drewmenu) xredraw();
  120. }
  121.  
  122. void help()
  123. {
  124.   char c;
  125.   char filestr[80];
  126.   int n,filenum;
  127.   clearmsg();
  128.   print1("Please enter the letter indicating what topic you want help on.");
  129.   menuclear();
  130.   menuprint("a: Overview\n");
  131.   menuprint("b: Characters\n");
  132.   menuprint("c: Inventories\n");
  133.   menuprint("d: Movement\n");
  134.   menuprint("e: Combat\n");
  135.   menuprint("f: Bugs\n");
  136.   menuprint("g: Magic\n");
  137.   menuprint("h: The Countryside\n");
  138.   menuprint("i: The Screen Display\n");
  139.   menuprint("j: Saving and Restoring\n");
  140.   menuprint("k: Options Settings\n");
  141.   menuprint("l: Dungeon/City/Other Command List\n");
  142.   menuprint("m: Countryside Command List\n");
  143.   menuprint("n: Everything\n");
  144.   menuprint("ESCAPE: Forget the whole thing.");
  145.   do 
  146.     c = mcigetc();
  147.   while ((c < 'a') && (c > 'n') && (c != ESCAPE));
  148.   if (c == 'n') {
  149.     print1("Trying to copy all help files to ./omega.doc ");
  150.     nprint1("Confirm [yn]");
  151.     if (ynq1()=='y') {
  152.       print2("Copying");
  153.       nprint2(".");
  154.       strcpy(Str1,"cat ");
  155.       strcat(Str1,OMEGALIB);
  156.       strcat(Str1,"ohelp1.txt");
  157.       strcat(Str1," >> omega.doc");
  158.       system(Str1);
  159.       nprint2(".");
  160.       strcpy(Str1,"cat ");
  161.       strcat(Str1,OMEGALIB);
  162.       strcat(Str1,"ohelp2.txt");
  163.       strcat(Str1," >> omega.doc");
  164.       system(Str1);
  165.       nprint2(".");
  166.       strcpy(Str1,"cat ");
  167.       strcat(Str1,OMEGALIB);
  168.       strcat(Str1,"ohelp3.txt");
  169.       strcat(Str1," >> omega.doc");
  170.       system(Str1);
  171.       nprint2(".");
  172.       strcpy(Str1,"cat ");
  173.       strcat(Str1,OMEGALIB);
  174.       strcat(Str1,"ohelp4.txt");
  175.       strcat(Str1," >> omega.doc");
  176.       system(Str1);
  177.       nprint2(".");
  178.       strcpy(Str1,"cat ");
  179.       strcat(Str1,OMEGALIB);
  180.       strcat(Str1,"ohelp5.txt");
  181.       strcat(Str1," >> omega.doc");
  182.       system(Str1);
  183.       nprint2(".");
  184.       strcpy(Str1,"cat ");
  185.       strcat(Str1,OMEGALIB);
  186.       strcat(Str1,"ohelp6.txt");
  187.       strcat(Str1," >> omega.doc");
  188.       system(Str1);
  189.       nprint2(".");
  190.       strcpy(Str1,"cat ");
  191.       strcat(Str1,OMEGALIB);
  192.       strcat(Str1,"ohelp7.txt");
  193.       strcat(Str1," >> omega.doc");
  194.       system(Str1);
  195.       nprint2(".");
  196.       strcpy(Str1,"cat ");
  197.       strcat(Str1,OMEGALIB);
  198.       strcat(Str1,"ohelp8.txt");
  199.       strcat(Str1," >> omega.doc");
  200.       system(Str1);
  201.       nprint2(".");
  202.       strcpy(Str1,"cat ");
  203.       strcat(Str1,OMEGALIB);
  204.       strcat(Str1,"ohelp9.txt");
  205.       strcat(Str1," >> omega.doc");
  206.       system(Str1);
  207.       nprint2(".");
  208.       strcpy(Str1,"cat ");
  209.       strcat(Str1,OMEGALIB);
  210.       strcat(Str1,"ohelp10.txt");
  211.       strcat(Str1," >> omega.doc");
  212.       system(Str1);
  213.       nprint2(".");
  214.       strcpy(Str1,"cat ");
  215.       strcat(Str1,OMEGALIB);
  216.       strcat(Str1,"ohelp11.txt");
  217.       strcat(Str1," >> omega.doc");
  218.       system(Str1);
  219.       nprint2(".");
  220.       strcpy(Str1,"cat ");
  221.       strcat(Str1,OMEGALIB);
  222.       strcat(Str1,"ohelp12.txt");
  223.       strcat(Str1," >> omega.doc");
  224.       system(Str1);
  225.       nprint2(".");
  226.       strcpy(Str1,"cat ");
  227.       strcat(Str1,OMEGALIB);
  228.       strcat(Str1,"ohelp13.txt");
  229.       strcat(Str1," >> omega.doc");
  230.       system(Str1);
  231.       nprint2(" Done.");
  232.     }
  233.   }
  234.   else if (c != ESCAPE) {
  235.     strcpy(filestr,OMEGALIB);
  236.     strcat(filestr,"ohelp");
  237.     filenum = c+1-'a';
  238.     n = strlen(filestr);
  239.     if (filenum<10) {
  240.       filestr[n] = filenum+'0';
  241.       filestr[n+1] = 0;
  242.     }
  243.     else {
  244.       filestr[n] = '1';
  245.       filenum = c - 'j';
  246.       filestr[n+1] = filenum+'0';
  247.       filestr[n+2] = 0;
  248.     }
  249.     strcat(filestr,".txt");
  250.     print1("Display help file, or Copy help file to file in wd. [dc] ");
  251.     do 
  252.       c = mcigetc();
  253.     while ((c != 'd') && (c != 'c')&& (c!=ESCAPE));
  254.     if (c == 'd')
  255.       displayfile(filestr);
  256.     else if (c == 'c') copyfile(filestr);
  257.   }
  258.   xredraw();
  259. }
  260.  
  261. void version()
  262. {
  263.   setgamestatus(SKIP_MONSTERS);
  264.   print3(VERSIONSTRING);
  265.   nprint3(":");
  266.   nprint3(" Last Edited: ");
  267.   nprint3(LAST_OMEGA_EDIT_DATE);
  268. }
  269.  
  270. void fire()
  271. {
  272.   int index,x1,y1,x2,y2;
  273.   pob obj;
  274.   struct monster *m;
  275.  
  276.   clearmsg();
  277.  
  278.   print1("Fire/Throw --");
  279.   index = getitem(NULL);
  280.   if (index == ABORT)
  281.     setgamestatus(SKIP_MONSTERS);
  282.   else if (index == CASHVALUE) print3("Can't fire money at something!");
  283.   else if (cursed(Player.possessions[index]) && 
  284.        Player.possessions[index]->used)
  285.     print3("You can't seem to get rid of it!");
  286.   /* load a crossbow */
  287.   else if ((Player.possessions[O_WEAPON_HAND] != NULL) &&  
  288.        (Player.possessions[O_WEAPON_HAND]->id == WEAPONID+27) && 
  289.        (Player.possessions[O_WEAPON_HAND]->aux != LOADED) &&
  290.        (Player.possessions[index]->id == WEAPONID+29)) {
  291.          mprint("You crank back the crossbow and load a bolt.");
  292.          Player.possessions[O_WEAPON_HAND]->aux = LOADED;
  293.        }
  294.   else {
  295.     if (Player.possessions[index]->used) {
  296.       Player.possessions[index]->used = FALSE;
  297.       item_use(Player.possessions[index]);
  298.     }
  299.     obj = Player.possessions[index];
  300.     x1 = x2 = Player.x;
  301.     y1 = y2 = Player.y;
  302.     setspot(&x2,&y2);
  303.     if ((x2 == Player.x) && (y2 == Player.y)) 
  304.       mprint("You practice juggling for a moment or two.");
  305.     else {
  306.       do_object_los(obj->objchar,&x1,&y1,x2,y2);
  307.       if ((m=Level->site[x1][y1].creature) != NULL) {
  308.     if (obj->dmg == 0) {
  309.       if (m->treasure > 0) { /* the monster can have treasure/objects */
  310.         mprint("Your gift is caught!");
  311.         givemonster(m,obj);
  312.         conform_lost_objects(1,obj);
  313.       }
  314.       else {
  315.         mprint("Your thrown offering is ignored.");
  316.         p_drop_at(x1,y1,1,obj);
  317.         conform_lost_objects(1,obj);
  318.       }
  319.     }
  320.     else if (hitp(Player.hit,m->ac)) {/* ok already, hit the damn thing */
  321.       weapon_use(2*statmod(Player.str),obj,m);
  322.       dispose_lost_objects(1,obj);
  323.     }
  324.     else {
  325.       mprint("You miss it.");
  326.       p_drop_at(x1,y1,1,obj);
  327.       conform_lost_objects(1,obj);
  328.     }
  329.       }
  330.       else {
  331.     p_drop_at(x1,y1,1,obj);
  332.     conform_lost_objects(1,obj);
  333.       }
  334.     }
  335.   }
  336. }
  337.  
  338.  
  339.  
  340. int quit()
  341. {
  342.   clearmsg();
  343.   mprint("Quit: Are you sure? [yn] ");
  344.   if (ynq()=='y') {
  345.     if (Player.rank[ADEPT] == 0) display_quit();
  346.     else display_bigwin();
  347.     endgraf();
  348.     exit(0);
  349.   }
  350.   else resetgamestatus(SKIP_MONSTERS);
  351. }
  352.  
  353.  
  354.  
  355. /* rest in 10 second segments so if woken up by monster won't
  356. die automatically.... */
  357. void nap()
  358. {
  359.   static int naptime;
  360.   if (gamestatusp(FAST_MOVE)) {
  361.     if (naptime-- < 1) {
  362.       clearmsg();
  363.       mprint("Yawn. You wake up.");
  364.       resetgamestatus(FAST_MOVE);
  365.       drawvision(Player.x,Player.y);
  366.     }
  367.   }
  368.   else {
  369.     clearmsg();
  370.     mprint("Rest for how long? (in minutes) ");
  371.     naptime = parsenum();
  372.     if (naptime > 600) {
  373.       print3("You can only sleep up to 10 hours (600 minutes)");
  374.       naptime = 3600;
  375.     }
  376.     else naptime *= 6;
  377.     if (naptime > 1) {
  378.       clearmsg();
  379.       setgamestatus(FAST_MOVE);
  380.       mprint("Resting.... ");
  381.     }
  382.   }
  383. }
  384.  
  385.  
  386. void charid()
  387. {
  388.   char id;
  389.   int countryside=FALSE;
  390.   char cstr[80];
  391.  
  392.   clearmsg();
  393.   mprint("Character to identify: ");
  394.   id = mgetc();
  395.   if (Current_Environment == E_COUNTRYSIDE) {
  396.     countryside = TRUE;
  397.     strcpy(cstr,countryid(id));
  398.     if (strcmp(cstr,"I have no idea.")==0)
  399.       countryside = FALSE;
  400.     else mprint(cstr);
  401.   }
  402.   if (! countryside) {
  403.     if (((id >= 'a') && (id <= 'z')) || ((id >= 'A') && (id <= 'Z'))) 
  404.       mprint("A monster or NPC -- examine (x) to find out exactly.");
  405.     else switch(id) {
  406.     case SPACE:
  407.       mprint(" : An airless void (if seen) or unknown region (if unseen)");
  408.       break;
  409.     case WALL:
  410.       mprint(" : An (impenetrable?) wall");
  411.       break;
  412.     case OPEN_DOOR:
  413.       mprint(" : An open door");
  414.       break;
  415.     case CLOSED_DOOR:
  416.       mprint(" : A closed (possibly locked) door");
  417.       break;
  418.     case LAVA:
  419.       mprint(" : A pool of lava");
  420.       break;
  421.     case HEDGE:
  422.       mprint(" : A dense hedge");
  423.       break;
  424.     case WATER:
  425.       mprint(" : A deep body of water");
  426.       break;
  427.     case FIRE:
  428.       mprint(" : A curtain of fire");
  429.       break;
  430.     case TRAP:
  431.       mprint(" : An uncovered trap");
  432.       break;
  433.     case UP:
  434.       mprint(" : A stairway leading up");
  435.       break;
  436.     case DOWN:
  437.       mprint(" : A stairway leading down");
  438.       break;
  439.     case FLOOR:
  440.       mprint(" : The dungeon floor");
  441.       break;
  442.     case PORTCULLIS:
  443.       mprint(" : A heavy steel portcullis");
  444.       break;
  445.     case ABYSS:
  446.       mprint(" : An entrance to the infinite abyss");
  447.       break;
  448.     case PLAYER:
  449.       mprint(" : You, the player");
  450.       break;
  451.     case CORPSE:
  452.       mprint(" : The remains of some creature");
  453.       break;
  454.     case THING:
  455.       mprint(" : Some random miscellaneous object");
  456.       break;
  457.     case SAFE:
  458.       mprint(" : A steel safe inset into the floor"); 
  459.       break;
  460.     case RUBBLE:
  461.       mprint(" : A dangerous-looking pile of rubble");
  462.       break;
  463.     case STATUE:
  464.       mprint(" : A statue");
  465.       break;
  466.     case ALTAR:
  467.       mprint(" : A (un?)holy altar");
  468.       break;
  469.     case CASH:
  470.       mprint(" : Bills, specie, gems: cash");
  471.       break;
  472.     case PILE:
  473.       mprint(" : A pile of objects");
  474.       break;
  475.     case FOOD:
  476.       mprint(" : Something edible");
  477.       break;
  478.     case WEAPON:
  479.       mprint(" : Some kind of weapon");
  480.       break;
  481.     case MISSILEWEAPON:
  482.       mprint(" : Some kind of missile weapon");
  483.       break;
  484.     case SCROLL:
  485.       mprint(" : Something readable");
  486.       break;
  487.     case POTION:
  488.       mprint(" : Something drinkable");
  489.       break;
  490.     case ARMOR:
  491.       mprint(" : A suit of armor");
  492.       break;
  493.     case SHIELD:
  494.       mprint(" : A shield");
  495.       break;
  496.     case CLOAK:
  497.       mprint(" : A cloak");
  498.       break;
  499.     case BOOTS:
  500.       mprint(" : A pair of boots");
  501.       break;
  502.     case STICK:
  503.       mprint(" : A stick");
  504.       break;
  505.     case RING:
  506.       mprint(" : A ring");
  507.       break;
  508.     case ARTIFACT:
  509.       mprint(" : An artifact");
  510.       break;
  511.     case CHAIR:
  512.       mprint(" : A chair");
  513.       break;
  514.     case WHIRLWIND:
  515.       mprint(" : A whirlwind");
  516.       break;
  517.     default:
  518.       mprint("That character is unused.");
  519.       break;
  520.     }
  521.   }
  522. }
  523.  
  524.  
  525. void wizard()
  526. {
  527.   setgamestatus(SKIP_MONSTERS);
  528.   if (gamestatusp(CHEATED)) mprint("You're already in wizard mode!");
  529.   else {
  530.     clearmsg();
  531.     mprint("Really try to enter wizard mode? [yn] ");
  532.     if (ynq()=='y') {
  533.       if (strcmp(getlogin(),WIZARD)==0) {
  534.     setgamestatus(CHEATED);
  535.     mprint("Wizard mode set.");
  536.       }
  537.       else {
  538.     mprint("There is a shrieking sound, as of reality being distorted.");
  539.     strcpy(Str1,WIZARD);
  540.     strcat(Str1,", the Wizard of omega appears before you....");
  541.     mprint(Str1);
  542.     mprint("'Do not meddle in the affairs of Wizards --");
  543.     if (random_range(2)) mprint("it makes them soggy and hard to light.'");
  544.     else mprint("for they are subtle, and swift to anger!'");
  545.       }
  546.     }
  547.   }
  548. }
  549.  
  550. /* Jump, that is */
  551. void vault()
  552. {
  553.   int x=Player.x,y=Player.y,jumper=0;
  554.   
  555.   clearmsg();
  556.  
  557.   if (Player.possessions[O_BOOTS] != NULL)
  558.     if (Player.possessions[O_BOOTS]->usef = I_BOOTS_JUMPING)
  559.       jumper = 2;
  560.   if (Player.status[IMMOBILE] > 0) {
  561.     resetgamestatus(FAST_MOVE);
  562.     print3("You are unable to move");
  563.   }
  564.   else {
  565.     setgamestatus(SKIP_MONSTERS);
  566.     mprint("Jump where?");
  567.     setspot(&x,&y);
  568.     if (! los_p(x,y,Player.x,Player.y))
  569.       print3("The way is obstructed.");
  570.     else if (Player.itemweight > Player.maxweight) 
  571.       print3("You are too burdened to jump anywhere.");
  572.     else if (distance(x,y,Player.x,Player.y) > 
  573.          max(2,statmod(Player.agi)+2)+jumper)
  574.       print3("The jump is too far for you.");
  575.     else if (Level->site[x][y].creature != NULL)
  576.       print3("You can't jump on another creature.");
  577.     else if (! p_moveable(x,y))
  578.       print3("You can't jump there.");
  579.     else {
  580.       resetgamestatus(SKIP_MONSTERS);
  581.       Player.x = x;
  582.       Player.y = y;
  583.       if ((! jumper) && (random_range(30) > Player.agi)) {
  584.     mprint("Oops -- took a tumble.");
  585.     setgamestatus(SKIP_PLAYER);
  586.     p_damage((Player.itemweight/250),UNSTOPPABLE,"clumsiness");
  587.       }
  588.       p_movefunction(Level->site[Player.x][Player.y].p_locf);
  589.       if (Current_Environment != E_COUNTRYSIDE) 
  590.     if ((Level->site[Player.x][Player.y].things != NULL) &&
  591.         (optionp(PICKUP)))
  592.       pickup();
  593.     }
  594.   }
  595. }
  596.  
  597.  
  598. /* Sets sequence of combat maneuvers. */
  599. void tacoptions()
  600. {
  601.   int actionsleft,done,place;
  602.   float times;
  603.  
  604.   setgamestatus(SKIP_MONSTERS);
  605.  
  606.   done = FALSE;
  607.   actionsleft = maneuvers();
  608.   menuclear();
  609.   place = 0;
  610.   menuprint("Enter a combat maneuvers sequence.\n");
  611.   menuprint("? for help, ! for default, RETURN to save sequence\n");
  612.   do {
  613.     clearmsg1();
  614.     mprint("Maneuvers Left:");
  615.     mnumprint(actionsleft);
  616.     switch(mgetc()) {
  617.     case '?':
  618.       combat_help();
  619.       break;
  620.     case 'a': case 'A':
  621.       if (actionsleft < 1) print3("No more maneuvers!");
  622.       else {
  623.     if (Player.possessions[O_WEAPON_HAND] == NULL) {
  624.       Player.meleestr[place] = 'C';
  625.       menuprint("\nPunch:");
  626.     }
  627.     else if (Player.possessions[O_WEAPON_HAND]->type == THRUSTING) {
  628.       Player.meleestr[place] = 'T';
  629.       menuprint("\nThrust:");
  630.     }
  631.     else if (Player.possessions[O_WEAPON_HAND]->type == STRIKING) {
  632.       Player.meleestr[place] = 'C';
  633.       menuprint("\nStrike:");
  634.     }
  635.     else {
  636.       menuprint("\nCut:");
  637.       Player.meleestr[place] = 'C';
  638.     }
  639.     place++;
  640.     Player.meleestr[place]=getlocation();
  641.     place++;
  642.     actionsleft--;
  643.       }
  644.       break;
  645.     case 'b': case 'B':
  646.       if (actionsleft<1) print3("No more maneuvers!");
  647.       else {
  648.     Player.meleestr[place] = 'B';
  649.     if (Player.possessions[O_WEAPON_HAND] == NULL)
  650.       menuprint("\nDodge (from):");
  651.     else if (Player.possessions[O_WEAPON_HAND]->type == THRUSTING) 
  652.       menuprint("\nParry:");
  653.     else menuprint("\nBlock:");
  654.     place++;
  655.     Player.meleestr[place]= getlocation();
  656.     place++;
  657.     actionsleft--;
  658.       }
  659.       break;
  660.     case 'l': case 'L':
  661.       if (actionsleft<2) print3("Not enough maneuvers to lunge!");
  662.       else {
  663.     if (Player.possessions[O_WEAPON_HAND] != NULL) {
  664.       if (Player.possessions[O_WEAPON_HAND]->type != MISSILE) {
  665.         Player.meleestr[place] = 'L';
  666.         place++;
  667.         Player.meleestr[place]=getlocation();
  668.         place++;
  669.         actionsleft -= 2;
  670.         menuprint("\nLunge:");
  671.       }
  672.       else {
  673.         print3("Can't lunge with a missile weapon!");
  674.         morewait();
  675.       }
  676.     }
  677.     else {
  678.       print3("Can't lunge without a weapon!");
  679.       morewait();
  680.     }
  681.       }
  682.       break;
  683.     case 'r': case 'R':
  684.       if (actionsleft<2) print3("Not enough maneuvers to riposte!");
  685.       else {
  686.     if (Player.possessions[O_WEAPON_HAND] != NULL) {
  687.       if (Player.possessions[O_WEAPON_HAND]->type == THRUSTING) {
  688.         Player.meleestr[place] = 'R';
  689.         menuprint("\nRiposte ");
  690.         Player.meleestr[place]=getlocation();
  691.         actionsleft -= 2;
  692.       }
  693.       else {
  694.         print3("Can't riposte without a thrusting weapon!");
  695.         morewait();
  696.       }
  697.     }
  698.     else {
  699.       print3("Can't riposte without a thrusting weapon!");
  700.       morewait();
  701.     }
  702.       }
  703.       break;
  704.     case BACKSPACE:
  705.     case DELETE:
  706.       place = 0;
  707.       actionsleft=maneuvers();
  708.       break;
  709.     case RETURN:
  710.     case LINEFEED:
  711.     case ESCAPE:
  712.       done = TRUE;
  713.       break;
  714.     }
  715.   } while (! done);
  716.   xredraw();
  717.   Player.meleestr[place] = 0;
  718. }
  719.  
  720.  
  721.  
  722.  
  723. /* Do the Artful Dodger trick */
  724. void pickpocket()
  725. {
  726.   int dx,dy,index=0;
  727.   struct monster *m;
  728.  
  729.   clearmsg();
  730.  
  731.   mprint("Pickpocketing --");
  732.  
  733.   index = getdir();
  734.  
  735.   if (index == ABORT)
  736.     setgamestatus(SKIP_MONSTERS);
  737.   else {
  738.     dx = Dirs[0][index];
  739.     dy = Dirs[1][index];
  740.     
  741.     if ((! inbounds(Player.x+dx, Player.y+dy)) ||
  742.     (Level->site[Player.x+dx][Player.y+dy].creature == NULL)) {
  743.       print3("There's nothing there to steal from!!!");
  744.       setgamestatus(SKIP_MONSTERS);
  745.     }
  746.     else {
  747.       m = Level->site[Player.x+dx][Player.y+dy].creature;
  748.       if (m->id == ML0+3) {
  749.     mprint("Trying to steal from a guardsman, eh?");
  750.     mprint("Not a clever idea.");
  751.     if (Player.cash > 0) {
  752.       mprint("As a punitive fine, the guard takes all your money.");
  753.       Player.cash = 0;
  754.       dataprint();
  755.     }
  756.     else {
  757.       mprint("The guardsman places you under arrest.");
  758.       morewait();
  759.       send_to_jail();
  760.     }
  761.       }
  762.       else if (m->possessions == NULL) {
  763.     mprint("You couldn't find anything worth taking!");
  764.     mprint("But you managed to annoy it...");
  765.     m_status_set(m,HOSTILE);
  766.       }
  767.       else if (Player.dex*5+Player.rank[THIEVES]*20+random_range(100) >
  768.            random_range(100)+m->level*20) {
  769.     mprint("You successfully complete your crime!");
  770.     mprint("You stole:");
  771.     mprint(itemid(m->possessions->thing));
  772.     Player.alignment--;
  773.     gain_experience(m->level*m->level);
  774.     gain_item(m->possessions->thing);
  775.     m->possessions = m->possessions->next;
  776.       }
  777.     }
  778.   }
  779. }
  780.  
  781.  
  782.  
  783. void rename_player()
  784. {
  785.   setgamestatus(SKIP_MONSTERS);
  786.   clearmsg();
  787.   mprint("Rename Character:");
  788.   strcpy(Player.name,msgscanstring());
  789. }
  790.  
  791.  
  792. void abortshadowform()
  793. {
  794.   setgamestatus(SKIP_MONSTERS);
  795.   if (Player.status[SHADOWFORM] && (Player.status[SHADOWFORM]<1000)) {
  796.     mprint("You abort your spell of Shadow Form.");
  797.     Player.immunity[NORMAL_DAMAGE]--;
  798.     Player.immunity[ACID]--;
  799.     Player.immunity[THEFT]--;
  800.     Player.immunity[INFECTION]--;
  801.     mprint("You feel less shadowy now.");
  802.     Player.status[SHADOWFORM] = 0;
  803.   }
  804. }
  805.  
  806. void tunnel()
  807. {
  808.   int dir,ox,oy,aux;
  809.  
  810.   clearmsg();
  811.   mprint("Tunnel -- ");
  812.   dir = getdir();
  813.   if (dir == ABORT)
  814.     setgamestatus(SKIP_MONSTERS);
  815.   else {
  816.     ox = Player.x + Dirs[0][dir];
  817.     oy = Player.y + Dirs[1][dir];
  818.     if (loc_statusp(ox,oy,SECRET))
  819.       mprint("You have no success as yet.");
  820.     else if (Level->site[ox][oy].locchar != WALL) {
  821.       print3("You can't tunnel through that!");
  822.       setgamestatus(SKIP_MONSTERS);
  823.     }
  824.     else {
  825.       aux = Level->site[ox][oy].aux;
  826.       if (random_range(20)==1){
  827.     if (Player.possessions[O_WEAPON_HAND] == NULL) {
  828.       mprint("Ouch! broke a fingernail...");
  829.       p_damage(Player.str / 6,UNSTOPPABLE,"A broken fingernail");
  830.     }
  831.     else if ((Player.possessions[O_WEAPON_HAND]->type == THRUSTING) ||
  832.          ((Player.possessions[O_WEAPON_HAND]->type != STRIKING) &&
  833.           (Player.possessions[O_WEAPON_HAND]->fragility < 
  834.            random_range(20)))) {
  835.       mprint("Clang! Uh oh...");
  836.       damage_item(Player.possessions[O_WEAPON_HAND]);
  837.     }
  838.     else mprint("Your digging implement shows no sign of breaking.");
  839.       }
  840.       if (Player.possessions[O_WEAPON_HAND] == NULL) {
  841.     if ((aux > 0) && ((Player.str/3)+random_range(100) > aux)) {
  842.       mprint("You carve a tunnel through the stone!");
  843.       tunnelcheck();
  844.       Level->site[ox][oy].locchar = RUBBLE;
  845.       Level->site[ox][oy].p_locf = L_RUBBLE;
  846.     }
  847.     else mprint("No joy.");
  848.       }
  849.       else if (Player.possessions[O_WEAPON_HAND]->type == THRUSTING) {
  850.     if ((aux > 0) && 
  851.         (Player.possessions[O_WEAPON_HAND]->dmg*2+random_range(100) > 
  852.          aux)) {
  853.       mprint("You carve a tunnel through the stone!");
  854.       tunnelcheck();
  855.       Level->site[ox][oy].locchar = RUBBLE;
  856.       Level->site[ox][oy].p_locf = L_RUBBLE;
  857.     }
  858.     else mprint("No luck.");
  859.       }
  860.       else if ((aux > 0) && 
  861.            (Player.possessions[O_WEAPON_HAND]->dmg+random_range(100) 
  862.         > aux)) {
  863.     mprint("You carve a tunnel through the stone!");
  864.     tunnelcheck();
  865.     Level->site[ox][oy].locchar = RUBBLE;
  866.     Level->site[ox][oy].p_locf = L_RUBBLE;
  867.       }
  868.       else mprint("You have no success as yet.");
  869.     }
  870.   }
  871. }
  872.  
  873.  
  874.  
  875.  
  876. void hunt(terrain)
  877. char terrain;     
  878. {
  879.   int fertility=0;
  880.   switch(terrain) {
  881.   case SWAMP: 
  882.     mprint("You hesitate to hunt for food in the marshy wasteland.");
  883.     break;
  884.   case VOLCANO:
  885.   case CASTLE:
  886.   case TEMPLE:
  887.   case CAVES:
  888.   case STARPEAK:
  889.   case MAGIC_ISLE:
  890.   case DRAGONLAIR:
  891.     mprint("There is nothing alive here (or so it seems)");
  892.     break;
  893.   case VILLAGE:
  894.   case CITY:
  895.     mprint("You can find no food here; perhaps if you went inside....");
  896.     break;
  897.   case ROAD:
  898.     mprint("You feel it would be a better idea to hunt off the road.");
  899.     break;
  900.   case CHAOS_SEA:
  901.     mprint("Food in the Sea of Chaos? Go on!");
  902.     break;
  903.   case DESERT:
  904.     mprint("You wander off into the trackless desert in search of food...");
  905.     Time += 100;
  906.     hourly_check();  
  907.     fertility = 10;
  908.     break;
  909.   case JUNGLE:
  910.     mprint("You search the lush and verdant jungle for game....");
  911.     Time += 100;
  912.     hourly_check();
  913.     fertility = 80;
  914.     break;
  915.   case PLAINS:
  916.     mprint("You set off through the tall grass; the game is afoot.");
  917.     Time += 100;
  918.     hourly_check();
  919.     fertility = 50;
  920.     break;
  921.   case TUNDRA:
  922.     mprint("You blaze a trail through the frozen wasteland....");
  923.     Time += 100;
  924.     hourly_check();
  925.     fertility = 30;
  926.     break;
  927.   case FOREST:
  928.     mprint("You try to follow the many tracks through the forest loam....");
  929.     Time += 100;
  930.     hourly_check();
  931.     fertility = 70;
  932.     break;
  933.   case MOUNTAINS: case PASS:
  934.     mprint("You search the cliff walls looking for something to eat....");
  935.     Time += 100;
  936.     hourly_check();  
  937.     fertility = 30;
  938.     break;
  939.   case RIVER:
  940.     mprint("The halcyon river is your hopeful food source...");
  941.     Time += 100;
  942.     hourly_check();  
  943.     fertility = 80;
  944.     break;
  945.   }
  946.   if (((Date % 360 < 60) || (Date % 360 > 300)) && 
  947.       (terrain != DESERT) &&
  948.       (terrain != JUNGLE)) {
  949.     mprint("The cold weather impedes your hunt....");
  950.     fertility = fertility / 2;
  951.   }
  952.   if (fertility > random_range(100)) {
  953.     mprint("You have an encounter...");
  954.     change_environment(E_TACTICAL_MAP);
  955.   }
  956.   else mprint("Your hunt is fruitless.");
  957. }
  958.  
  959. void dismount_steed()
  960. {
  961.   pml ml;
  962.   if (! gamestatusp(MOUNTED))
  963.     print3("You're on foot already!");
  964.   else if (Current_Environment == E_COUNTRYSIDE) {
  965.     mprint("If you leave your steed here he will wander away!");
  966.     mprint("Do it anyway? [yn] ");
  967.     if (ynq()=='y') resetgamestatus(MOUNTED);
  968.   }
  969.   else {
  970.     resetgamestatus(MOUNTED);;
  971.     ml = ((pml) malloc(sizeof(mltype)));
  972.     ml->m = ((pmt) malloc(sizeof(montype)));
  973.     *(ml->m) = Monsters[HORSE];
  974.     ml->m->x = Player.x;
  975.     ml->m->y = Player.y;
  976.     ml->m->status = MOBILE+SWIMMING;
  977.     ml->next = Level->mlist;
  978.     Level->site[Player.x][Player.y].creature = ml->m;
  979.     Level->mlist = ml;
  980.   }
  981.   calc_melee();
  982. }
  983.  
  984.  
  985. void city_move()
  986. {
  987.   int site,x=Player.x,y=Player.y,toggle=FALSE;
  988.   clearmsg();
  989.   if (Current_Environment != E_CITY) {
  990.     print3("This command only works in the city!");
  991.     setgamestatus(SKIP_MONSTERS);
  992.   }
  993.   else if (Player.status[IMMOBILE] > 0) 
  994.     print3("You can't even move!");
  995.   else if (hostilemonstersnear()) {
  996.     setgamestatus(SKIP_MONSTERS);
  997.     print3("You can't move this way with hostile monsters around!");
  998.   }
  999.   else if (Level->site[Player.x][Player.y].aux == NOCITYMOVE)
  1000.     print3("You can't use the 'M' command from this location.");
  1001.   else {
  1002.     mprint("Move to which establishment [? for help, ESCAPE to quit] ");
  1003.     site = parsecitysite();
  1004.     if (site != ABORT) {
  1005.       mprint("You're on your way...");
  1006.       morewait();
  1007.       while ((x != CitySiteList[site][1]) || (y != CitySiteList[site][2])) {
  1008.     toggle = ! toggle;
  1009.     if (toggle) {
  1010.       Time++;
  1011.       if (Time % 10 == 0) tenminute_check();
  1012.       else minute_status_check();
  1013.     }
  1014.     x += sign(CitySiteList[site][1] - x);
  1015.     y += sign(CitySiteList[site][2] - y);
  1016.     screencheck(y);
  1017.     showcursor(x,y);
  1018.       }
  1019.       Player.x = x;
  1020.       Player.y = y;
  1021.       screencheck(Player.y);
  1022.       mprint("Made it!");
  1023.       morewait();
  1024.       p_movefunction(Level->site[x][y].p_locf);
  1025.     }
  1026.   }
  1027. }
  1028.  
  1029.  
  1030.  
  1031. void frobgamestatus()
  1032. {
  1033.   char response;
  1034.   long num;
  1035.   mprint("Set or Reset or Forget it [s,r,ESCAPE]:");
  1036.   do response = mcigetc();
  1037.   while ((response != 'r') && (response != 's') && (response != ESCAPE));
  1038.   if (response != ESCAPE) {
  1039.     mprint("Enter log2 of flag:");
  1040.     num = parsenum();
  1041.     if (num > -1) {
  1042.       num = pow2(num);
  1043.       if (response == 's') setgamestatus(num);
  1044.       else resetgamestatus(num);
  1045.       mprint("Done....");
  1046.     }
  1047.   }
  1048. }
  1049.       
  1050.