home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume12 / mdg / part03 / magic.c < prev    next >
C/C++ Source or Header  |  1991-03-04  |  17KB  |  940 lines

  1. /*
  2.     MDG Multiuser Dungeon Game -- magic.c magic handler
  3.     
  4.     MDG is Copyright 1990 John C. Gonnerman
  5.     This program is subject to the general MDG 
  6.     copyright statement (see enclosed file, Copyright).
  7. */
  8.  
  9.  
  10. static char *sccsvers = "@(#) magic.c\t(1.2)\tcreated 1/2/91";
  11.  
  12. #include <stdio.h>
  13.  
  14. #include "setup.h"
  15. #include "struct.h"
  16. #include "spells.h"
  17.  
  18. #define NOSPELL(x)    dmsg_add(x, "spell not available")
  19.  
  20. extern struct player_seg *pseg;
  21. extern struct map_seg *mseg;
  22.  
  23. extern struct monster_tbl *m_table;
  24. extern int n_monster;
  25.  
  26. extern char *spell_names[];
  27. extern int spell_dd[];
  28.  
  29. extern struct ast a_spell_table[];
  30.  
  31. char under[8];
  32. int n_sectors[4];
  33.  
  34.  
  35. cast_spell(indx, mptr)
  36. int indx;
  37. struct dmessage *mptr;
  38. {
  39.     int spell, who, what, dir, max_damage, rc;
  40.     char buf[35];
  41.     char *text;
  42.  
  43.     spell = mptr->subcmd;
  44.     what = who = dir = mptr->arg;
  45.     text = mptr->text;
  46.  
  47.     sprintf(buf, "cast %s...", spell_names[spell]);
  48.     dmsg_add(indx, buf);
  49.  
  50.     if(cast_it(spell, indx) == -1) {
  51.         pseg->p[indx].magicpts -= (pseg->p[indx].magicpts ? 1 : 0);
  52.         sprintf(buf, "%s failed", spell_names[spell]);
  53.         dmsg_add(indx, buf);
  54.         return;
  55.     }
  56.  
  57.     switch(spell + 'a') {
  58.     case 'a' : /* armor */
  59.         pseg->p[indx].ma_count += rnd(300);
  60.         pseg->p[indx].m_armor += rnd(5);
  61.         if(pseg->p[indx].m_armor > MAX_MARMOR)
  62.             pseg->p[indx].m_armor = MAX_MARMOR;
  63.         pseg->player_sem++;
  64.         tell_player(indx);
  65.         break;
  66.         
  67.     case 'b' : /* block */
  68.         pseg->p[indx].blocked += go2r(100);
  69.         dmsg_add(indx, "Seeks now blocked.");
  70.         break;
  71.         
  72.     case 'c' : /* cold */
  73.         dmsg_add(indx, "Whoosh!");
  74.         visible(indx);
  75.         max_damage = (pseg->p[indx].spells[spell] + 50) / 3;
  76.         cast_a_spell(&(pseg->p[indx].loc), AS_COLD, dir, 
  77.             go2r(max_damage));
  78.         break;
  79.  
  80.     case 'd' : /* detect */
  81.         detect(indx);
  82.         tell_player(indx);
  83.         break;
  84.  
  85.     case 'e' : /* escape */
  86.         if((rc = jump_to(indx, pseg->p[indx].home)) == -1)
  87.             dmsg_add(indx, "escape bounced");
  88.         else if(rc == -2)
  89.             dmsg_add(indx, "escape fizzled");
  90.         else
  91.             dmsg_add(indx, "escaped!");
  92.         break;
  93.  
  94.     case 'f' : /* fireball */
  95.         visible(indx);
  96.         dmsg_add(indx, "Boom!");
  97.         max_damage = (pseg->p[indx].spells[spell] + 50) / 3;
  98.         cast_a_spell(&(pseg->p[indx].loc), AS_FIREBALL, dir, 
  99.             go2r(max_damage));
  100.         break;
  101.  
  102.     case 'g' : /* glow */
  103.         glow(indx);
  104.         tell_player(indx);
  105.         break;
  106.  
  107.     case 'h' : /* heal */
  108.         heal(indx);
  109.         tell_player(indx);
  110.         break;
  111.  
  112.     case 'i' : /* invisible */
  113.         invisible(indx);
  114.         tell_player(indx);
  115.         break;
  116.  
  117.     case 'j' : /* jump back */
  118.         jump_back(indx);
  119.         break;
  120.  
  121.     case 'k' : /* knight */
  122.         knight(indx);
  123.         break;
  124.  
  125.     case 'l' : /* lightning */
  126.         visible(indx);
  127.         dmsg_add(indx, "Crackle!");
  128.         max_damage = (pseg->p[indx].spells[spell] + 50) / 3;
  129.         cast_a_spell(&(pseg->p[indx].loc), AS_LIGHTNING, dir, 
  130.             go2r(max_damage));
  131.         break;
  132.  
  133.     case 'm' : /* missile */
  134.         visible(indx);
  135.         dmsg_add(indx, "A fiery missile appears!");
  136.         max_damage = (pseg->p[indx].spells[spell] + 50) / 3;
  137.         ranged_spell(indx, dir, 'm' - 'a', go2r(10), max_damage);
  138.         break;
  139.  
  140.     case 'n' : /* n */
  141.         nightmare(indx, who);
  142.         break;
  143.  
  144.     case 'o' : /* obscure */
  145.         if(what >= 0) {
  146.             toggle_obscure(what);
  147.             dmsg_add(indx, "The object shimmers...");
  148.         } else if(what == -1) {
  149.             pseg->p[indx].gold_hidden = 
  150.                 (pseg->p[indx].gold_hidden ? 0 : 1);
  151.             dmsg_add(indx, "Your gold shimmers...");
  152.         } else
  153.             dmsg_add(indx, "obscure what?");
  154.         break;
  155.  
  156.     case 'p' : /* partners */
  157.         show_partners(indx);
  158.         break;
  159.  
  160.     case 'q' : /* quit */
  161.         quit_spell(indx);
  162.         break;
  163.  
  164.     case 'r' : /* death ray */
  165.         visible(indx);
  166.         dmsg_add(indx, "Bzzzzzt!");
  167.         max_damage = (pseg->p[indx].spells[spell] + 50) / 3;
  168.         cast_a_spell(&(pseg->p[indx].loc), AS_DEATHRAY, dir, 
  169.             go2r(max_damage));
  170.         break;
  171.  
  172.     case 's' : /* seek */
  173.         seek_s(indx, who);
  174.         break;
  175.  
  176.     case 't' : /* teleport */
  177.         teleport(indx);
  178.         break;
  179.  
  180.     case 'u' : /* user */
  181.         pseg->p[indx].user_spell += go2r(USER_DUR);
  182.         pseg->player_sem++;
  183.         break;
  184.  
  185.     case 'v' : /* verify */
  186.         verify_item(indx, what);
  187.         break;
  188.  
  189.     case 'w' : /* whisper */
  190.         whisper(indx, who, text);
  191.         break;
  192.  
  193.     case 'x' : /* spell x */
  194.         spell_x(indx);
  195.         break;
  196.  
  197.     case 'y' : /* yank */
  198.         yank(indx, who);
  199.         break;
  200.  
  201.     case 'z' : /* zap */
  202.         visible(indx);
  203.         dmsg_add(indx, "Zap!");
  204.         max_damage = (pseg->p[indx].spells[spell] + 50) / 3;
  205.         cast_a_spell(&(pseg->p[indx].loc), AS_ZAP, L_EAST, 
  206.             go2r(max_damage));
  207.         break;
  208.  
  209.     default :
  210.         break;
  211.     }
  212. }
  213.  
  214.  
  215. quit_spell(indx)
  216. int indx;
  217. {
  218.     int sector, x, y;
  219.  
  220.     sector = pseg->p[indx].loc.sector;
  221.  
  222.     if(sector < 0)
  223.         return;
  224.  
  225.     x = pseg->p[indx].loc.x;
  226.     y = pseg->p[indx].loc.y;
  227.  
  228.     mseg->m[sector].map[y][x] = pseg->p[indx].loc.under;
  229.     mseg->map_sem++;
  230.  
  231.     pseg->p[indx].loc.x = sector;
  232.     pseg->p[indx].loc.sector = LOC_HOME;
  233. }
  234.  
  235.  
  236. show_partners(p_indx)
  237. int p_indx;
  238. {
  239.     int i, len;
  240.     char o_buf[35];
  241.  
  242.     strcpy(o_buf, "Partners:");
  243.  
  244.     for(i = 0; i < MAX_PLAYERS; i++)
  245.         if(i != p_indx
  246.         && pseg->p[i].playernum >= 0
  247.         && pseg->p[i].partners[p_indx] == 1) {
  248.             len = strlen(o_buf);
  249.             o_buf[len] = ' ';
  250.             o_buf[len + 1] = i + '1';
  251.             o_buf[len + 2] = '\0';
  252.         }
  253.  
  254.     dmsg_add(p_indx, o_buf);
  255. }
  256.  
  257.  
  258. int cast_it(spell, indx)
  259. int spell, indx;
  260. {
  261.     if(pseg->p[indx].magicpts < (spell_dd[spell] + 1)
  262.     || rnd(90 + (10 * spell_dd[spell])) > pseg->p[indx].spells[spell])
  263.         return -1;
  264.  
  265.     improve_s(indx, spell);
  266.  
  267.     pseg->p[indx].magicpts -= (spell_dd[spell] + 1);
  268.     pseg->player_sem++;
  269.     tell_player(indx);
  270.  
  271.     return 0;
  272. }
  273.  
  274.  
  275. spell_x(p_indx)
  276. int p_indx;
  277. {
  278.     int max_damage, i, sector;
  279.  
  280.     sector = pseg->p[p_indx].loc.sector;
  281.  
  282.     for(i = 0; i < MAX_PLAYERS; i++)
  283.         if(pseg->p[i].loc.sector == sector)
  284.             dmsg_add(i, "KA-BOOM!!!");
  285.  
  286.     max_damage = 5 * pseg->p[p_indx].magicpts;
  287.  
  288.     if(max_damage < 1)
  289.         max_damage = 5;
  290.  
  291.     pseg->p[p_indx].magicpts = 0;
  292.  
  293.     for(i = 0; i < n_monster; i++)
  294.         if(m_table[i].loc.sector == sector)
  295.             mgethit(i, go2r(max_damage));
  296.  
  297.     for(i = 0; i < MAX_PLAYERS; i++)
  298.         if(pseg->p[i].loc.sector == sector
  299.         && i != p_indx
  300.         && pseg->p[p_indx].partners[i] == 0)
  301.             pgethit(i, rnd(max_damage));
  302.  
  303.     pseg->player_sem++;
  304.     mseg->map_sem++;
  305.  
  306.     notify(sector);
  307. }
  308.  
  309.  
  310. yank(p_indx, v_indx)
  311. int p_indx, v_indx;
  312. {
  313.     int dest_a, rc;
  314.     char buf[35];
  315.  
  316.     if(v_indx < 0 || v_indx >= MAX_PLAYERS)
  317.         return;
  318.  
  319.     dest_a = pseg->p[p_indx].loc.sector;
  320.  
  321.     if(pseg->p[v_indx].loc.sector < 0
  322.     || pseg->p[v_indx].playernum < 0
  323.     || pseg->p[v_indx].blocked > 0) {
  324.         sprintf(buf, "%c not found.", (char)('1' + v_indx));
  325.         dmsg_add(p_indx, buf);
  326.     } else if((rc = jump_to(v_indx, dest_a)) == -1)
  327.         dmsg_add(p_indx, "yank bounced");
  328.     else if(rc == -2)
  329.         dmsg_add(p_indx, "yank fizzled");
  330.     else {
  331.         sprintf(buf, "%c yanked!", (char)('1' + v_indx));
  332.         dmsg_add(p_indx, buf);
  333.         dmsg_add(v_indx, "you've been yanked!");
  334.     }
  335. }
  336.  
  337.  
  338. jump_back(indx)
  339. int indx;
  340. {
  341.     int dest_a, rc;
  342.  
  343.     dest_a = pseg->p[indx].prev_sect;
  344.  
  345.     if((rc = jump_to(indx, dest_a)) == -1)
  346.         dmsg_add(indx, "jump back bounced");
  347.     else if(rc == -2)
  348.         dmsg_add(indx, "jump back fizzled");
  349.     else
  350.         dmsg_add(indx, "returned");
  351. }
  352.  
  353.  
  354. teleport(indx)
  355. int indx;
  356. {
  357.     int dest_a, rc;
  358.  
  359.     dest_a = rnd(mseg->max_areas) - 1;
  360.  
  361.     if((rc = jump_to(indx, dest_a)) == -1)
  362.         dmsg_add(indx, "teleport bounced");
  363.     else if(rc == -2)
  364.         dmsg_add(indx, "teleport fizzled");
  365.     else
  366.         dmsg_add(indx, "teleported");
  367. }
  368.  
  369.  
  370. int jump_to(indx, sector)
  371. int indx, sector;
  372. {
  373.     int cnt, rc, symbol, link_dd;
  374.     int old_s, x, y, dest_x, dest_y;
  375.  
  376.     old_s = pseg->p[indx].loc.sector;
  377.     x = pseg->p[indx].loc.x;
  378.     y = pseg->p[indx].loc.y;
  379.  
  380.     link_dd = mseg->m[old_s].jump_inhibit + mseg->m[sector].jump_inhibit;
  381.  
  382.     if(rnd(10) < link_dd)
  383.         return -2;
  384.  
  385.     for(cnt = 0; cnt < TELE_TRYS; cnt++) {
  386.         mseg->m[old_s].map[y][x] = pseg->p[indx].loc.under;
  387.         mseg->map_sem++;
  388.  
  389.         dest_x = rnd(MAPCOLS) - 1;
  390.         dest_y = rnd(MAPROWS) - 1;
  391.  
  392.         rc = t_move_to(&(pseg->p[indx].loc), 
  393.             sector, dest_x, dest_y, indx);
  394.         
  395.         symbol = pseg->p[indx].invis ? indx + 11 : indx + 1;
  396.  
  397.         move_sym(&(pseg->p[indx].loc), symbol);
  398.         mseg->map_sem++;
  399.  
  400.         if(rc == 0) {
  401.             pseg->p[indx].prev_sect = old_s;
  402.             notify(sector);
  403.             notify(old_s);
  404.             return 0;
  405.         }
  406.     }
  407.  
  408.     return -1;
  409. }
  410.  
  411.  
  412. int send_monster(m_indx, sector)
  413. int m_indx, sector;
  414. {
  415.     int rc;
  416.  
  417.     lift_a_monster(m_indx);
  418.  
  419.     rc = move_to(&(m_table[m_indx].loc), sector, 
  420.         m_table[m_indx].loc.x, m_table[m_indx].loc.y, -1);
  421.  
  422.     move_sym(&(m_table[m_indx].loc), m_table[m_indx].m_sym);
  423.  
  424.     mseg->map_sem++;
  425.  
  426.     if(rc == 0) {
  427.         notify(sector);
  428.         return 0;
  429.     }
  430.  
  431.     return -1;
  432. }
  433.  
  434.  
  435. visible(p_indx)
  436. int p_indx;
  437. {
  438.     int sector, x, y;
  439.  
  440.     pseg->p[p_indx].invis = 0;
  441.  
  442.     sector = pseg->p[p_indx].loc.sector;
  443.     x = pseg->p[p_indx].loc.x;
  444.     y = pseg->p[p_indx].loc.y;
  445.  
  446.     if(sector < 0)
  447.         return;
  448.  
  449.     mseg->m[sector].map[y][x] = 1 + p_indx;
  450.     mseg->map_sem++;
  451. }
  452.  
  453.  
  454. invisible(p_indx)
  455. int p_indx;
  456. {
  457.     int sector, x, y;
  458.  
  459.     pseg->p[p_indx].invis += rnd(100);
  460.     dmsg_add(p_indx, "you disappear!");
  461.  
  462.     sector = pseg->p[p_indx].loc.sector;
  463.     x = pseg->p[p_indx].loc.x;
  464.     y = pseg->p[p_indx].loc.y;
  465.  
  466.     if(sector < 0)
  467.         return;
  468.  
  469.     mseg->m[sector].map[y][x] = 11 + p_indx;
  470.     mseg->map_sem++;
  471.  
  472.     notify(sector);
  473. }
  474.  
  475.  
  476. heal(p_indx)
  477. int p_indx;
  478. {
  479.     pseg->p[p_indx].hitpoints += rnd(10);
  480.  
  481.     if(pseg->p[p_indx].hitpoints > pseg->p[p_indx].max_hp)
  482.         pseg->p[p_indx].hitpoints = pseg->p[p_indx].max_hp;
  483.  
  484.     dmsg_add(p_indx, "you feel better");
  485. }
  486.  
  487.  
  488. glow(p_indx)
  489. int p_indx;
  490. {
  491.     pseg->p[p_indx].light += (6 * rnd(100));
  492.  
  493.     mseg->map_sem++;
  494.  
  495.     dmsg_add(p_indx, "it's brighter now");
  496. }
  497.  
  498.  
  499. detect(indx)
  500. int indx;
  501. {
  502.     pseg->p[indx].detect += go2r(DETECT_DUR);
  503.  
  504.     mseg->map_sem++;
  505.  
  506.     dmsg_add(indx, "your vision sharpens");
  507. }
  508.  
  509.  
  510. ranged_spell(p_indx, dir, spell, range, damage)
  511. int p_indx, dir, spell, range, damage;
  512. {
  513.     char buf[35];
  514.  
  515.     if(rspell_start(p_indx, 21, range, damage, dir) == -1) {
  516.         sprintf(buf, "%s failed", spell_names[spell]);
  517.         dmsg_add(p_indx, buf);
  518.     } 
  519. }
  520.  
  521.  
  522. int rspell_start(indx, symbol, range, damage, dir)
  523. int indx, symbol, range, damage, dir;
  524. {
  525.     return start_ranged(symbol, 5, damage, 
  526.         pseg->p[indx].loc.sector, pseg->p[indx].loc.x, 
  527.         pseg->p[indx].loc.y, dir);
  528. }
  529.  
  530.  
  531. int t_move_to(locptr, dest_a, dest_x, dest_y, p_indx)
  532. struct location *locptr;
  533. int dest_a, dest_x, dest_y, p_indx;
  534. {
  535.     char at_loc;
  536.  
  537.     if(dest_a < 0)
  538.         return -1;
  539.  
  540.     at_loc = mseg->m[dest_a].map[dest_y][dest_x];
  541.  
  542.     switch(at_loc) {
  543.     case '0' : /* 0-9 are traps */
  544.     case '1' :
  545.     case '2' :
  546.     case '3' :
  547.     case '4' :
  548.     case '5' :
  549.     case '6' :
  550.     case '7' :
  551.     case '8' :
  552.     case '9' :
  553.         do_trap(p_indx, at_loc);
  554.         locptr->sector = dest_a;
  555.         locptr->x = dest_x;
  556.         locptr->y = dest_y;
  557.         locptr->under = at_loc;
  558.         mseg->map_sem++;
  559.         return 0;
  560.  
  561.     case '.' :
  562.     case ' ' :
  563.     case '`' : /* shallow water */
  564.     case '+' : /* secret door */
  565.     case '<' : /* down */
  566.     case '>' : /* up */
  567.         locptr->sector = dest_a;
  568.         locptr->x = dest_x;
  569.         locptr->y = dest_y;
  570.         locptr->under = at_loc;
  571.         mseg->map_sem++;
  572.         return 0;
  573.  
  574.     default :
  575.         return (int)at_loc;
  576.     }
  577. }
  578.  
  579.  
  580. clear_n_sectors()
  581. {
  582.     int i;
  583.  
  584.     for(i = 0; i < 4; i++)
  585.         n_sectors[i] = LOC_NONESUCH;
  586. }
  587.  
  588.  
  589. add_n_sector(sector)
  590. int sector;
  591. {
  592.     int i;
  593.  
  594.     for(i = 0; i < 4; i++)
  595.         if(n_sectors[i] == LOC_NONESUCH) {
  596.             n_sectors[i] = sector;
  597.             return;
  598.         }
  599. }
  600.  
  601.  
  602. notify_n_sectors()
  603. {
  604.     int i;
  605.  
  606.     for(i = 0; i < 4; i++)
  607.         if(n_sectors[i] != LOC_NONESUCH) 
  608.             notify(n_sectors[i]);
  609. }
  610.  
  611.  
  612. cast_a_spell(loc, a_spell, dir, effect)
  613. struct location *loc;
  614. int a_spell, dir, effect;
  615. {
  616.     int i, limit;
  617.     char at_spot;
  618.     struct location t_loc;
  619.  
  620.     switch(dir) {
  621.     case L_NORTH :
  622.     case L_SOUTH :
  623.     case L_EAST :
  624.     case L_WEST :
  625.     case L_NEAST :
  626.     case L_NWEST :
  627.     case L_SEAST :
  628.     case L_SWEST :
  629.         break;
  630.     default :
  631.         return;
  632.     }
  633.     
  634.     clear_n_sectors();
  635.     limit = 99;
  636.  
  637.     for(i = 0; i < 8; i++) {
  638.         t_loc.sector = loc->sector;
  639.         t_loc.x = loc->x;
  640.         t_loc.y = loc->y;
  641.  
  642.         loc_a_spell(&t_loc, a_spell, i, dir);
  643.  
  644.         if(correct_loc(&t_loc) != -1) {
  645.             at_spot = mseg->m[t_loc.sector].map[t_loc.y][t_loc.x];
  646.  
  647.             if(a_spell_table[a_spell].advance[i] <= limit
  648.             && at_spot != '#') {
  649.                 add_n_sector(t_loc.sector);
  650.                 under[i] = at_spot;
  651.                 mseg->m[t_loc.sector].map[t_loc.y][t_loc.x] = 
  652.                     '*';
  653.             } else if(at_spot == '#'
  654.             && a_spell_table[a_spell].advance[i] < limit
  655.             && a_spell_table[a_spell].flag == ASF_LIMITED) {
  656.                 limit = a_spell_table[a_spell].advance[i];
  657.             }
  658.         }
  659.     }
  660.  
  661.     mseg->map_sem++;
  662.     notify_n_sectors();
  663.  
  664.     busy_wait(600000L);
  665.  
  666.     clear_n_sectors();
  667.  
  668.     for(i = 0; i < 8; i++) {
  669.         t_loc.sector = loc->sector;
  670.         t_loc.x = loc->x;
  671.         t_loc.y = loc->y;
  672.  
  673.         loc_a_spell(&t_loc, a_spell, i, dir);
  674.  
  675.         if(a_spell_table[a_spell].advance[i] <= limit
  676.         && correct_loc(&t_loc) != -1 
  677.         && mseg->m[t_loc.sector].map[t_loc.y][t_loc.x] == '*') {
  678.             add_n_sector(t_loc.sector);
  679.             mseg->m[t_loc.sector].map[t_loc.y][t_loc.x] = under[i];
  680.         }
  681.     }
  682.  
  683.     mseg->map_sem++;
  684.     notify_n_sectors();
  685.  
  686.     for(i = 0; i < 8; i++) {
  687.         t_loc.sector = loc->sector;
  688.         t_loc.x = loc->x;
  689.         t_loc.y = loc->y;
  690.  
  691.         loc_a_spell(&t_loc, a_spell, i, dir);
  692.  
  693.         if(correct_loc(&t_loc) != -1
  694.         && a_spell_table[a_spell].advance[i] <= limit)
  695.             zap_spot(t_loc.sector, t_loc.x, t_loc.y, effect);
  696.     }
  697. }
  698.  
  699.  
  700. zap_spot(sector, x, y, effect)
  701. int sector, x, y, effect;
  702. {
  703.     int i;
  704.  
  705.     if(is_player(mseg->m[sector].map[y][x])) {
  706.         for(i = 0; i < MAX_PLAYERS; i++)
  707.             if(pseg->p[i].loc.sector == sector 
  708.             && pseg->p[i].loc.x == x 
  709.             && pseg->p[i].loc.y == y)
  710.                 pgetzapped(i, effect);
  711.     } else {
  712.         for(i = 0; i < n_monster; i++)
  713.             if(m_table[i].loc.sector == sector 
  714.             && m_table[i].loc.x == x 
  715.             && m_table[i].loc.y == y)
  716.                 mgethit(i, effect);
  717.     }
  718. }
  719.  
  720.  
  721. loc_a_spell(loc, spell, pos, dir)
  722. struct location *loc;
  723. int spell, pos, dir;
  724. {
  725.     int off, adv;
  726.  
  727.     off = a_spell_table[spell].offset[pos];
  728.     adv = a_spell_table[spell].advance[pos];
  729.  
  730.     switch(dir) {
  731.     case L_NORTH :
  732.         loc->y -= adv;
  733.         loc->x += off;
  734.         break;
  735.     case L_SOUTH :
  736.         loc->y += adv;
  737.         loc->x -= off;
  738.         break;
  739.     case L_EAST :
  740.         loc->x += adv;
  741.         loc->y += off;
  742.         break;
  743.     case L_WEST :
  744.         loc->x -= adv;
  745.         loc->y -= off;
  746.         break;
  747.     case L_NEAST :
  748.         loc->y += (-1 * adv) + off - (off > 0);
  749.         loc->x += off + adv + (off < 0);
  750.         break;
  751.     case L_NWEST :
  752.         loc->y += (-1 * adv) + (-1 * off) - (off < 0);
  753.         loc->x += off + (-1 * adv) - (off > 0);
  754.         break;
  755.     case L_SEAST :
  756.         loc->y += adv + off + (off < 0);
  757.         loc->x += (-1 * off) + adv + (off > 0);
  758.         break;
  759.     case L_SWEST :
  760.         loc->y += adv + (-1 * off) + (off > 0);
  761.         loc->x += (-1 * off) + (-1 * adv) - (off < 0);
  762.         break;
  763.     }
  764. }
  765.  
  766.  
  767. int correct_loc(loc)
  768. struct location *loc;
  769. {
  770.     if(loc->y < 0 && loc->x >= MAPCOLS)
  771.         return -1;
  772.     if(loc->y < 0 && loc->x < 0)
  773.         return -1;
  774.     if(loc->y >= MAPROWS && loc->x < 0)
  775.         return -1;
  776.     if(loc->y >= MAPROWS && loc->x >= MAPCOLS)
  777.         return -1;
  778.  
  779.     if(loc->x >= MAPCOLS) {
  780.         loc->x -= MAPCOLS;
  781.         loc->sector = mseg->m[loc->sector].links[L_EAST];
  782.     }
  783.  
  784.     if(loc->x < 0) {
  785.         loc->x += MAPCOLS;
  786.         loc->sector = mseg->m[loc->sector].links[L_WEST];
  787.     }
  788.  
  789.     if(loc->y >= MAPROWS) {
  790.         loc->y -= MAPROWS;
  791.         loc->sector = mseg->m[loc->sector].links[L_SOUTH];
  792.     }
  793.  
  794.     if(loc->y < 0) {
  795.         loc->y += MAPROWS;
  796.         loc->sector = mseg->m[loc->sector].links[L_NORTH];
  797.     }
  798.  
  799.     if(loc->sector < 0)
  800.         return -1;
  801.  
  802.     return 0;
  803. }
  804.  
  805.  
  806. busy_wait(delay)
  807. long delay;
  808. {
  809.     for(; delay; delay--);
  810. }
  811.  
  812.  
  813. seek_s(p_indx, v_indx)
  814. int p_indx, v_indx;
  815. {
  816.     char buf[35];
  817.     int rc;
  818.  
  819.     if(v_indx < 0 || v_indx >= MAX_PLAYERS)
  820.         return;
  821.  
  822.     if(pseg->p[v_indx].loc.sector < 0
  823.     || pseg->p[v_indx].playernum < 0
  824.     || pseg->p[v_indx].blocked > 0) {
  825.         sprintf(buf, "%c not found.", (char)('1' + v_indx));
  826.         dmsg_add(p_indx, buf);
  827.     } else if((rc = jump_to(p_indx, pseg->p[v_indx].loc.sector)) == -1)
  828.         dmsg_add(p_indx, "seek bounced.");
  829.     else if(rc == -2)
  830.         dmsg_add(p_indx, "seek fizzled.");
  831.     else {
  832.         sprintf(buf, "%c found!", (char)('1' + v_indx));
  833.         dmsg_add(p_indx, buf);
  834.     }
  835. }
  836.  
  837.  
  838. toggle_obscure(item_indx)
  839. int item_indx;
  840. {
  841.     if(item_indx < 0
  842.     || item_indx >= pseg->item_count
  843.     || pseg->itm[item_indx].loc.sector > -1)
  844.         return;
  845.  
  846.     if(pseg->itm[item_indx].type == pseg->itm[item_indx].symbol)
  847.         pseg->itm[item_indx].symbol = HIDDEN;
  848.     else
  849.         pseg->itm[item_indx].symbol = pseg->itm[item_indx].type;
  850.  
  851.     pseg->item_sem++;
  852. }
  853.  
  854.  
  855. verify_item(indx, what)
  856. int indx, what;
  857. {
  858.     char buf[35];
  859.  
  860.     if(what < 0 || what >= pseg->item_count)
  861.         return;
  862.  
  863.     if(pseg->itm[what].curse == 0)
  864.         sprintf(buf, "%s is OK", pseg->itm[what].name);
  865.     else
  866.         sprintf(buf, "%s is CURSED", pseg->itm[what].name);
  867.  
  868.     dmsg_add(indx, buf);
  869. }
  870.  
  871.  
  872. knight(p_indx)
  873. int p_indx;
  874. {
  875.     dmsg_add(p_indx, "You feel more confident.");
  876.     pseg->p[p_indx].knight += rnd(KNIGHT_DUR);
  877. }
  878.  
  879.  
  880. nightmare(p_indx, v_indx)
  881. int p_indx, v_indx;
  882. {
  883.     char buf[35];
  884.     int choice;
  885.  
  886.     if(v_indx < 0 || v_indx >= MAX_PLAYERS)
  887.         return;
  888.  
  889.     if(pseg->p[v_indx].loc.sector < 0
  890.     || pseg->p[v_indx].playernum < 0
  891.     || pseg->p[v_indx].blocked > 0) {
  892.         sprintf(buf, "%c not found.", (char)('1' + v_indx));
  893.         dmsg_add(p_indx, buf);
  894.         return;
  895.     }
  896.  
  897.     if((choice = nearestm(p_indx)) == -1) {
  898.         dmsg_add(p_indx, "No monster.");
  899.         return;
  900.     }
  901.  
  902.     if(send_monster(choice, pseg->p[v_indx].loc.sector) == -1) {
  903.         dmsg_add(p_indx, "Can't send monster.");
  904.         return;
  905.     }
  906.  
  907.     dmsg_add(p_indx, "Monster sent...");
  908.     dmsg_add(v_indx, "A Nightmare!!!");
  909. }
  910.  
  911.  
  912. int nearestm(p_indx)
  913. int p_indx;
  914. {
  915.     int result, dist, n_dist, i;
  916.     int dest_a, m_a, m_x, m_y;
  917.  
  918.     result = -1;
  919.     dist = 100;
  920.  
  921.     dest_a = pseg->p[p_indx].loc.sector;
  922.  
  923.     for(i = 0; i < n_monster; i++) {
  924.         m_a = m_table[i].loc.sector;
  925.         m_x = m_table[i].loc.x;
  926.         m_y = m_table[i].loc.y;
  927.  
  928.         if(m_a == dest_a
  929.         && (n_dist = distance(p_indx, m_x, m_y)) < dist) {
  930.             dist = n_dist;
  931.             result = i;
  932.         }
  933.     }
  934.  
  935.     return result;
  936. }
  937.  
  938.  
  939. /* end of file. */
  940.