home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / ARSRC21.ZIP / AR256.CPP next >
C/C++ Source or Header  |  1995-06-02  |  44KB  |  1,860 lines

  1. // MAIN MODULE
  2.  
  3.  
  4.  
  5.  
  6. //  CURRENT BUG:    nearly done now!
  7. // swarm thinks it has killed you when it hasn't.
  8.  
  9. // whatmonster 0xff = wiz, whatside 0xff = nothing there
  10. #include <dos.h>
  11. #include<process.h>
  12. #include <graphics.h>
  13. #include <string.h>
  14. #include <conio.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <math.h>
  18.  
  19. #include "ar256h.cpp"
  20. #include "ar256def.h"
  21. enum tf {true,false};
  22.  
  23. #include "svga256.h"
  24. #define MONSTERS 27
  25.  
  26. char cheetR=73; //set to # of player who will be helped...
  27. char players,width,height,maxmon;
  28. int thisturn=0;
  29. int strength_history[4][50];
  30. int tree_history[4][50];
  31. int attack_history[5][50];//1 for mirkwoods
  32. int luck_history[5]; // 1 for mirkwoods
  33. //char equal_flag;
  34. unsigned char curpla,curmon,done=0,moves,noisy=0,isalive[4];
  35.  
  36. unsigned char pcol[4]={6,12,24,19};
  37. char pname[4][9];
  38. char pstartx[4];
  39. char pstarty[4];
  40. char pgraph[4];
  41. char moncounter[4]={0};
  42. char kills[4]={0};
  43. char balls=1;
  44. signed int alignment[4]={0};
  45. char pattern[8]={0x33,0xcc,0x33,0xcc,0x33,0xcc,0x33,0xcc};
  46. char spellprob[59]={
  47. 9,3,7,1,2,2,4,2,3,2,//0-9
  48. 2,5,3,5,3,5,3,2,3,5,//10-19
  49. 5,4,6,3,5,3,3,3,3,3,//20-29
  50. 6,2,2,2,2,2,2,3,2,2,//30-39
  51. 2,5,4,4,7,2,2,2,2,2,//40-49
  52. 5,3,3,3,2,2,2,2,3};   //50-59
  53. int UD_MONSTERS=0;
  54. int NOT_REGD=0; //this is set to 1 if it cant find stats.dat
  55. int SLIDE=1;    //set to 0 if noslide.
  56. unsigned char curx=30,cury=30;
  57. square sq[30][30];
  58. createitall(char);
  59. tweenturns();
  60. drawmap(char,char);
  61. char cursor=0;
  62. ending();
  63. endingtwo();
  64. drawtile(char,char,char,char);
  65. drawjustland(char,char,char,char);
  66.  
  67. readingfx();
  68. //readinrest();
  69. monster mondata[28]; //monster objects being used to store data
  70. monster mon[4][30];
  71. monster create(char,char,unsigned char,char,char,char);
  72. //recce();
  73. fire(char,char);
  74. showfire(int,int,int,int,int);
  75. char fight(monster,monster);
  76. spells(void);
  77. sento(unsigned char,unsigned char);
  78. flyto();
  79.  
  80.  
  81. castspell(int,int);                 //if 2nd arg then illusion
  82. void select(char *,char *,int);
  83. void getname(int,int,int);
  84. void getadj(char *,char *);
  85. decide(int,int);
  86. void foom(int,int); //show a shroom at map (int,int). calls drawtile.
  87. void moof(int,int); //show a pentagram. calls nowt.
  88. void penty(int size,int delay);    //shows a penty twice. use moveto() first
  89. void boof(int,int); //circles around int,int
  90. void swarm(int,int,int,int,int); //covers an area in dots :I
  91. void crawler(int,int,int,int); //line of fooms
  92. // graphics data
  93. unsigned char *terrt[8];
  94. unsigned char *shroom[8];  //globble pointers to gfx yo mofo
  95.  
  96. unsigned char *tile[26];
  97. unsigned char *ball[6];
  98. unsigned char *start;
  99. unsigned char *sparks;
  100.  
  101.  
  102. int range(long,long,long,long);
  103. int linesight(int,int,int,int);
  104. int rangesight(int,int,int,int,int);
  105. int check(int,int);
  106. int adjust(char *,char *);
  107.  
  108. int frontend(int);
  109. void besilly(int);
  110. void memerror();
  111. void title();
  112. int cycleballs();
  113. char mygetch();
  114. //void besillier(void);
  115.  
  116. int bigtile(int,int,unsigned char far *,char,char); //ptr is to 0x400 array
  117.  
  118. /*void bip(int);
  119. void risingbip(int);
  120. void downbip(int);
  121. void lowbip(int);
  122. void tripbip(int);
  123.  
  124. mark(int,int);
  125. niceellipse(int,int,int,int);*/
  126. void usemouse();
  127. void memerror(); // 4 little text msgs.
  128. void nospells();
  129. void noshots();
  130. void orbattacked(int,int);
  131. int drawsparks(int,int);
  132. //void norange();
  133.  
  134. //char *disc;
  135.  
  136. extern void bip(int);
  137. extern void lowbip(int);
  138. extern void tripbip(int);
  139. extern void downbip(int);
  140. extern void risingbip(int);
  141. extern void besilly(int);
  142. //#include "ar256sp.cpp"
  143. #include "ar256m.cpp"
  144. mouse m;
  145.  
  146. #include "ar256h3.cpp" //the function 'create' which contains data
  147.  
  148.  
  149. screenmsgs s;
  150.  
  151. extern int tweenturns();
  152. extern int frontend(int);
  153. extern void getname(int,int,int);
  154. extern int mark(int,int);
  155. extern int niceellipse(int,int,int,int);
  156. extern int bigtile(int,int,unsigned char far *,char,char);
  157. extern int ending();
  158. extern int ending2();
  159. extern int bossmsg();
  160. extern void getstrengths();
  161.  
  162. extern int drawjustland(char,char,char,char);
  163. extern int spritepath(int,int,int,int,unsigned char *);
  164. //extern int drawjustframe(int,int,unsigned char *);
  165. //extern int DetectVGA256();
  166. //extern void dimthegreys();
  167.  
  168. //#include "ar256h5.cpp" //frontend and tweenturns
  169.  
  170.  
  171. main(int argc,char *argv[])
  172.  
  173.     {
  174.     //besilly(0);
  175.     unsigned char shots,spelt,c;int i,j;char test[5];
  176.  
  177.     clrscr();
  178.     randomize();
  179.  
  180.     title();
  181.  
  182.  
  183.  
  184.  
  185.  
  186.     strcpy(pname[0],"Cherry");
  187.     strcpy(pname[1],"Iskander");
  188.     strcpy(pname[2],"Crowley");
  189.     strcpy(pname[3],"Virgil");
  190.  
  191.     j=0;
  192.  
  193.  
  194.     for(i=1;i<argc;++i)
  195.         {
  196.         if(argv[i][0]=='-')
  197.             {
  198.             if(!strcmp(argv[i],"-nocentre"))m.initbitmap(1);else m.initbitmap(0);
  199.             if(!strcmp(argv[i],"-noslide"))SLIDE=0;
  200.             }
  201.         else
  202.             {
  203.  
  204.             strcpy(pname[j],argv[i]);
  205.             if(!strcmp(argv[i],"*Ben*"))cheetR=j;
  206.             ++j;
  207.             }
  208.         }
  209.  
  210.  
  211.     m.unsetbounds();
  212.   
  213.  
  214.  
  215.  
  216.     readingfx();
  217.  
  218.  
  219.  
  220.  
  221.  
  222.     createitall(frontend(j)); //frontend returns 1 for equal spells
  223.  
  224.  
  225.  
  226.     s.logo();
  227.     s.boxes();
  228.  
  229.  
  230.  
  231. for(;;){
  232.  
  233.     // MAIN LOOP!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  234.     for (curpla=0;curpla<players;++curpla)
  235.         {
  236.  
  237.         if (isalive[curpla])
  238.         {
  239.  
  240.         s.boxes();
  241.         s.plecho(curpla);
  242.  
  243.         for (curmon=0;curmon<maxmon;++curmon)
  244.             {
  245.  
  246.             if ((mon[curpla][curmon].status)&&(mon[curpla][curmon].status<4))
  247.                 {
  248.                  //if monster moveable, look at monster and set move counter
  249.  
  250.                 curx=mon[curpla][curmon].x;cury=mon[curpla][curmon].y;
  251.                 drawmap(curx,cury);m.putat(240,240);
  252.                 s.mecho(curpla,curmon);
  253.                 moves=mon[curpla][curmon].mmoves;
  254.                 s.modecho(1);
  255.                 s.plecho(curpla);
  256.                 shots=mon[curpla][curmon].mshots;
  257.                 spelt=0;
  258.  
  259.                  while(moves)
  260.                     {
  261.                     //-------recce bit breaks on keypress but leaves keypress alone
  262.                     i=1;//if (i==1) then curx=current monster x
  263.                     cursor=0;
  264.  
  265.                     s.modecho(1);
  266.  
  267.                     for(;;)
  268.                         {
  269.                         cursor=0;
  270.                         while(m.wheremouse())
  271.                             {
  272.                             //m.adjustmouse(curx,cury);
  273.                             cycleballs();
  274.  
  275.  
  276.  
  277.                             if(kbhit())
  278.                                 {
  279.                                 if(i==0)
  280.                                     {
  281.                                     curx=mon[curpla][curmon].x,cury=mon[curpla][curmon].y;
  282.                                     drawmap(curx,cury);m.putat(240,240);
  283.                                     i=1;getch();
  284.                                     }
  285.                                 else
  286.                                     {
  287.  
  288.                                     break;//if already centered pass keypress along...
  289.                                     }
  290.                                 }
  291.                             }
  292.                             if(kbhit())break;
  293.                             i=0;
  294.                             curx=curx+(m.x/32)-7;cury=cury+(m.y/32)-7;
  295.                             drawmap(curx,cury);m.putat(240,240);
  296.                             s.recho(curx,cury);
  297.  
  298.                         }
  299.                     //---------end of recce bit
  300.                     c=getch();
  301.                     switch(c)
  302.                         {
  303.  
  304.                     case'8':{sento(curx,cury-1); break;}
  305.                     case'7':{sento(curx-1,cury-1);break;}
  306.                     case'2':{sento(curx,cury+1);  break;}
  307.                     case'9':{sento(curx+1,cury-1);break;}
  308.                     case'4':{sento(curx-1,cury); break;}
  309.                     case'1':{sento(curx-1,cury+1);break;}
  310.                     case'6':{sento(curx+1,cury);  break;}
  311.                     case'3':{sento(curx+1,cury+1);break;}
  312.  
  313.  
  314.  
  315.                     case'f':if(shots){s.modecho(4);shots=fire(shots,mon[curpla][curmon].fire);cursor=0;s.modecho(1);break;}
  316.                                     else{noshots();break;}
  317.                     case's':if((mon[curpla][curmon].spellnum)&&(!spelt))
  318.                         {
  319.  
  320.                         spells();
  321.                         s.plecho(curpla);s.modecho(1);s.mecho(curpla,curmon);
  322.                         ++spelt;
  323.                         break;
  324.                         }
  325.                         else{nospells();break;}
  326.  
  327.                     case' ':{bip(5);break;}
  328.                     case'Q':   // quit. this outer be a function
  329.                         {
  330.                         moof(curx,cury);setfillstyle(1,0);bar(0,0,640,480);settextstyle(0,0,1);
  331.                         outtextxy(240,190,"You agree to differ.");
  332.                         getch();closegraph();
  333.                         clrscr();m.unsetbounds();besilly(1);break;
  334.                         }
  335.                     case't':if(mon[curpla][curmon].fly)
  336.                                     {flyto();m.bitmapoff();m.bitmapon(0,pcol[curpla]);cursor=0;break;}
  337.                                     else{break;}
  338.  
  339.                     case'!':
  340.                         {
  341.                         closegraph();clrscr();bossmsg();m.unsetbounds();exit(0);
  342.                         break;
  343.                         }
  344.                     case'?':
  345.                         {
  346.                         s.help();drawmap(curx,cury);
  347.                         break;
  348.                         }
  349.  
  350.                     default:
  351.                   //s.bargraph(luck_history,"rolled his dice;","General luckiness of players:");
  352.  
  353.                                     break;
  354.  
  355.                     }//end of switch
  356.                     if(c==' ')break; //go on to next monster
  357.                     }//end of while
  358.  
  359.  
  360.                  s.modecho(3);lowbip(1);
  361.                  if(mygetch()=='!'){closegraph();bossmsg();exit(0);};
  362.                  s.boxes();    //this getch might take the char from case '!'
  363.  
  364.                  }// if monster is alive if
  365.  
  366.  
  367.                 }// monster loop
  368.             s.modecho(5);downbip(3);if(mygetch()=='!'){closegraph();bossmsg();exit(0);}
  369.             s.boxes();s.usespace();
  370.             }//if player is alive if
  371.          }// player loop
  372.          tweenturns();s.boxes();
  373.          }// for(;;)
  374.  
  375.  
  376.  
  377. return(0);
  378. }
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385. createitall(char equal_flag)
  386. {
  387.  
  388.  
  389. int i,j,x,y,treex,treey,r,k;
  390.  
  391. int given=1; char equalspells[28];
  392.  
  393.  
  394. for (i=0;i<width;++i) // set whatside to blanks
  395.     {
  396.     for (j=0;j<height;++j)
  397.         {
  398.         sq[i][j].whatside=0xff;sq[i][j].whose=0xff;
  399.         }
  400.     }
  401.  
  402.     for(i=0;i<10;++i)
  403.     {
  404.     x=random(width),y=random(height);
  405.     sq[x][y].land=5;sq[x][y].whose=0xff;  //place trees and mwoods
  406.     }
  407.     for(i=0;i<5;++i)
  408.     {
  409.     x=random(width),y=random(height);
  410.     sq[x][y].land=6;sq[x][y].whose=0xff;
  411.     }
  412.     i=0;
  413.  
  414.  
  415.     while(given<25)
  416.                 {
  417.                 r=random(59);
  418.                 if(random(8)+1>spellprob[r])
  419.                     {
  420.                     equalspells[given]=r; //make table of spells
  421.                     ++given;
  422.                     }
  423.                 }
  424.  
  425.  
  426.  
  427.     for (i=0;i<players;++i)
  428.     {
  429.     create(i,0,0xff,1,pstartx[i],pstarty[i]);
  430.  
  431.     //strength_history[i][0]=mon[i][0].power();
  432.  
  433.     if(equal_flag)
  434.         {
  435.         for(k=1;k<25;++k)                    //insert spells from table
  436.             {
  437.             mon[i][0].spells[k]=equalspells[k];
  438.             }
  439.         }
  440.     //make clumps of trees either in middl or at orbs
  441.     treex=pstartx[i];treey=pstarty[i];
  442.     if(random(3)){treex=width/2+random(7)-3;treey=height/2+random(7)-3;}
  443.     moncounter[i]=1;
  444.     for (j=0;j<15;++j)
  445.         {
  446.         x=random(10)-5,y=random(10)-5;
  447.         if((range(0,0,x,y)<6)&&
  448.             (x+treex>0)&&(y+treey>0)&&(x+treex<width)&&(y+treey<height)&&
  449.             (sq[x+treex][y+treey].land<10))
  450.             {
  451.             sq[x+treex][y+treey].land=1;
  452.             sq[x+treex][y+treey].whose=i;
  453.  
  454.  
  455.             }
  456.  
  457.         }
  458.     if(balls){
  459.     sq[pstartx[i]][pstarty[i]].land=10;
  460.     sq[pstartx[i]-1][pstarty[i]].land=11;
  461.     sq[pstartx[i]+1][pstarty[i]].land=12;
  462.     sq[pstartx[i]][pstarty[i]+1].land=13;
  463.     sq[pstartx[i]-1][pstarty[i]+1].land=14;
  464.     sq[pstartx[i]+1][pstarty[i]+1].land=15;
  465.     sq[pstartx[i]][pstarty[i]].whose=i;
  466.     sq[pstartx[i]-1][pstarty[i]].whose=i;
  467.     sq[pstartx[i]+1][pstarty[i]].whose=i;
  468.     sq[pstartx[i]][pstarty[i]+1].whose=i;
  469.     sq[pstartx[i]-1][pstarty[i]+1].whose=i;
  470.     sq[pstartx[i]+1][pstarty[i]+1].whose=i;}
  471.  
  472.     }
  473.  
  474.  
  475.  
  476.  
  477.  
  478.     getstrengths();
  479.     for(i=0;i<players;++i)
  480.         {
  481.         attack_history[i][0]=0;
  482.         }
  483.  
  484. return (0);
  485.  
  486.  
  487.  
  488.  
  489. }
  490.  
  491.  
  492. drawmap(char centrex,char centrey)
  493.     {
  494.     int i,j,recx,recy;
  495.  
  496.     m.bitmapoff();
  497.     for (i=0;i<15;++i)
  498.         {
  499.         for (j=0;j<15;++j)
  500.             {
  501.             //cur_tile_col=117+(i+j)/5;
  502.             drawtile(centrex-7+i,centrey-7+j,centrex,centrey);
  503.  
  504.             }
  505.  
  506.         }
  507.     setcolor(0x0f);
  508.     rectangle(32*7-1,32*7-1,32*8+1,32*8+1);//-1 looks a bit better...
  509.     rectangle(0,0,32*15,479);
  510.  
  511.     recx=((width-centrex)+7)*32;
  512.     recy=((height-centrey)+7)*32;
  513.  
  514.     if(recx>480)recx=480;
  515.  
  516.  
  517.     rectangle((7-centrex)*32,(7-centrey)*32,recx,recy);
  518.     m.setbounds(centrex,centrey);
  519.     //m.putat(240,240);
  520.     m.bitmapon(cursor,pcol[curpla]);
  521.  
  522.     return(0);
  523.  
  524.  
  525. }
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533. drawtile (char tilex,char tiley, char centrex,char centrey)
  534.     {
  535.     int i,nx,ny,px,py;char mtile; //nx,ny are toplefts pix
  536.  
  537.     nx=((signed char)tilex-centrex+7)*32;ny=((signed char)tiley-centrey+7)*32;
  538.  
  539.     if((tilex>=width)||(tiley>=height)||(tilex<0)||(tiley<0))//if off map dont draw. You'd think it'd wrap and be always false but it DOESNT.
  540.         {
  541.         setfillstyle(1,0xd3);
  542.         bar(nx,ny,nx+31,ny+31);
  543.         return(1);
  544.         }
  545.     setfillstyle(1,2);
  546.  
  547.     bar(nx,ny,nx+31,ny+31);
  548.  
  549.     if(sq[tilex][tiley].land)
  550.     {
  551.     if((sq[tilex][tiley].land==10)&&(sq[tilex][tiley].whatside!=0xff))
  552.         {
  553.         for (i=0;i<0x400;++i)   //draw ball+wiz
  554.             {
  555.             px=nx+(i % 32);py=ny+(i / 32);
  556.             if (start[i] != 0xff) putpixel(px,py,start[i]);
  557.             if (start[i] == 0xfe) putpixel(px,py,pcol[sq[tilex][tiley].whatside]);
  558.             if (start[i] == 247)  putpixel(px,py,247+sq[tilex][tiley].whose);
  559.             }
  560.         return(0);
  561.         }
  562.  
  563.     if(sq[tilex][tiley].land>9)
  564.         {
  565.         for (i=0;i<0x400;++i)   //draw ballz
  566.             {
  567.             px=nx+(i % 32);py=ny+(i / 32);
  568.             if (ball[sq[tilex][tiley].land-10][i] != 0xff) putpixel(px,py,ball[sq[tilex][tiley].land-10][i]);
  569.             if (ball[sq[tilex][tiley].land-10][i] == 247)  putpixel(px,py,247+sq[tilex][tiley].whose);
  570.             }
  571.  
  572.         }
  573.  
  574.     else
  575.         {
  576.         for (i=0;i<0x400;++i)   //draw trees craters etc etc
  577.             {
  578.             px=nx+(i % 32);py=ny+(i / 32);
  579.             if (terrt[sq[tilex][tiley].land-1][i] != 0xff) putpixel(px,py,terrt[sq[tilex][tiley].land-1][i]);
  580.             }
  581.         }
  582.     }
  583.  
  584.  
  585.  
  586.     if (sq[tilex][tiley].whatside!=0xff)
  587.         {
  588.         if (!(sq[tilex][tiley].whatside % 2))//if even player
  589.         {
  590.  
  591.         mtile=mon[sq[tilex][tiley].whatside][sq[tilex][tiley].whatmonster].graphic;
  592.         if (mon[sq[tilex][tiley].whatside][sq[tilex][tiley].whatmonster].status==0x11)
  593.             {
  594.             for (i=0;i<0x400;++i)                          //if corpse
  595.                 {
  596.                 px=nx+(i % 32);py=ny+(i / 32);
  597.                 if (!tile[mtile][i])putpixel(px,py,0x07);//print grey outline
  598.  
  599.                 }
  600.             return(0);
  601.             }
  602.         for (i=0;i<0x400;++i)     //if alive
  603.             {
  604.             px=nx+(i % 32);py=ny+(i / 32);
  605.             if (tile[mtile][i]<254) putpixel(px,py,tile[mtile][i]);
  606.             if (tile[mtile][i] == 254)putpixel(px,py,pcol[sq[tilex][tiley].whatside]);//print col of player
  607.             }
  608.         }
  609.         else
  610.         {   //if even player face left
  611.         mtile=mon[sq[tilex][tiley].whatside][sq[tilex][tiley].whatmonster].graphic;
  612.         if (mon[sq[tilex][tiley].whatside][sq[tilex][tiley].whatmonster].status==0x11)
  613.             {
  614.             for (i=0;i<0x400;++i)                          //if corpse
  615.                 {
  616.                 px=nx+(32-(i % 32));py=ny+(i / 32);
  617.                 if (!tile[mtile][i])putpixel(px,py,0x07);//print grey outline
  618.  
  619.                 }
  620.             return(0);
  621.             }
  622.         for (i=0;i<0x400;++i)
  623.             {
  624.             px=nx+(32-(i % 32));py=ny+(i / 32);
  625.             if (tile[mtile][i]<254) putpixel(px,py,tile[mtile][i]);
  626.             if (tile[mtile][i] == 254)putpixel(px,py,pcol[sq[tilex][tiley].whatside]);//print col of player
  627.             }
  628.         }
  629.  
  630.  
  631.         }
  632.  
  633.  
  634. return (0);
  635. }
  636.  
  637.  
  638. //FIGHT FNCTN FIGHT DOESNT CALL A DAMN THING EXCEPT FOR MSGS  ------------
  639.  
  640. char fight(monster attacker,monster defender)
  641.     {
  642.     char out,i;
  643.  
  644.     if (sq[defender.x][defender.y].land==10)defender.defend+=26;
  645.  
  646.     //if (sq[defender.x][defender.y].land==0x0f)defender.defend+=6;
  647.     if (defender.status==0x11) //if a corpse is attacked
  648.         {s.fecho(attacker,defender,2);moves=0;lowbip(4);return(0x11);}
  649.  
  650.  
  651.     if (
  652.          ((attacker.status!=3)&&(attacker.id<0x80))//if attacker neither undead nor illusory undead
  653.          &&((defender.status==3)||((defender.id>=0x80)&&(defender.id!=0xff)))
  654.          )
  655.         //if defender real or illusory undead
  656.         {s.fecho(attacker,defender,3);moves=0;lowbip(4);return(3);}
  657.  
  658.     if (decide(attacker.attack,defender.defend))
  659.         {
  660.         s.fecho(attacker,defender,0);
  661.         risingbip(5);
  662.         if (defender.status==1){out=0x11;} // live -> corpse
  663.         if ((defender.status==3)||(defender.status==2))
  664.             {
  665.             out=0x00;                                                        // illusion/undead -> nonexist
  666.             //sq[defender.x][defender.y].whatside=0xff;
  667.             //sq[defender.x][defender.y].whatmonster=0;
  668.  
  669.             }
  670.         ++kills[curpla];
  671.         }//attacker wins
  672.     else
  673.         {
  674.         s.fecho(attacker,defender,1);
  675.         lowbip(2);
  676.         out=defender.status;
  677.         }//defender wins
  678.     if(sq[defender.x][defender.y].land==10)
  679.         {
  680.         orbattacked(defender.x,defender.y);
  681.         }
  682.     else
  683.         {
  684.         for(i=0;i<10;++i)
  685.             {
  686.             mon[sq[defender.x][defender.y].whatside][sq[defender.x][defender.y].whatmonster].status
  687.             =0x11;drawtile(defender.x,defender.y,curx,cury);delay(i*15);
  688.             mon[sq[defender.x][defender.y].whatside][sq[defender.x][defender.y].whatmonster].status
  689.             =1;drawtile(defender.x,defender.y,curx,cury);delay(i*15);
  690.             }
  691.         }
  692.     moves=0;
  693.  
  694.     return(out);
  695. }
  696.  
  697. void orbattacked(int ox,int oy)  // little effect for attack on orb
  698.     {
  699.   int i;
  700.     drawsparks(ox,oy);
  701.         for(i=0;i<10;++i)
  702.             {
  703.  
  704.             setrgbpalette(247+sq[ox][oy].whose,0,0,0);
  705.             delay(10);
  706.             setrgbpalette(247+sq[ox][oy].whose,random(120),random(120),0);
  707.             delay(15);
  708.             }
  709.         drawtile(ox,oy,curx,cury);
  710.         cycleballs();
  711. }
  712.  
  713.  
  714.  
  715. drawsparks(int x,int y)    //used by orbattacked only
  716.     {
  717.     int i,px,py;
  718.     for(i=0;i<0x400;++i)
  719.         {
  720.         px=(x-curx+7)*32+(i%32);py=(y-cury+7)*32+(i/32);
  721.         if(sparks[i]!=255)putpixel(px,py,sparks[i]);
  722.         }
  723. }
  724.  
  725.  
  726. // MOVEMENT FNCTN SENTO    MAY CALL FIGHT ---------------------------
  727.                                     //check for enemy trees first.
  728. sento(unsigned char newx, unsigned char newy)
  729.     {
  730.  
  731.     if(adjust(&newx,&newy)){lowbip(3);--moves;return(0);}
  732.     //if(mon[curpla][curmon].fly){flyto(newx,newy);return(0);}
  733.  
  734.     if((sq[newx][newy].land>6)&&(sq[newx][newy].land<10))return(0);
  735.     //dont bother if fire.
  736.  
  737.     if(sq[newx][newy].land==10)//if tries to enter ball
  738.         {
  739.  
  740.         if((curmon==0)&&(sq[newx][newy].whose==curpla))
  741.             {
  742.             moves=0;
  743.             sq[curx][cury].whatside=0xff;
  744.             sq[newx][newy].whatside=curpla;         //if wiz & his ball enter it
  745.             sq[newx][newy].whatmonster=curmon;
  746.             mon[curpla][curmon].x=newx;
  747.             mon[curpla][curmon].y=newy;
  748.             cury=newy;curx=newx;
  749.             drawmap(newx,newy);
  750.             return(0);
  751.             }
  752.         else
  753.             {
  754.             if(sq[newx][newy].whose==curpla)return(0); //if your own ball no nowt
  755.             if(sq[newx][newy].whatside==0xff)
  756.                 {
  757.                 if(random(6))
  758.                     {
  759.                     risingbip(7);
  760.                     sq[newx][newy].whose=curpla;
  761.                     }
  762.                             // 1/6 chance of subverting ball if unoccupied
  763.  
  764.                 return(0);
  765.                 }//if enemy ball but no monster inside it
  766.             //otherwise fight thing will be used later on in this fnctn... i hope
  767.  
  768.             }
  769.  
  770.         }
  771.  
  772.  
  773.     if((sq[newx][newy].land==1)&&sq[newx][newy].whose!=curpla)
  774.         {  //if enemy tree.
  775.         if(decide(mon[curpla][curmon].attack,1))
  776.             {
  777.             s.trecho(mon[curpla][curmon],1); risingbip(3);// kill tree msg
  778.             sq[newx][newy].land=3;sq[newx][newy].whose=4;moves=0;
  779.             }
  780.         else
  781.             {  //failed attack on tree.
  782.             s.trecho(mon[curpla][curmon],0);moves=0;lowbip(2);
  783.             }
  784.  
  785.         return(0); // no point checking for move/fight if there was a tree
  786.         }
  787.     if(sq[newx][newy].land==5)
  788.         { //if mirkwood
  789.         if(decide(mon[curpla][curmon].attack,2))
  790.             {
  791.             s.trecho(mon[curpla][curmon],1);
  792.             sq[newx][newy].land=0;moves=0;risingbip(3);
  793.             }
  794.         else
  795.             {
  796.             s.trecho(mon[curpla][curmon],0);moves=0;lowbip(2);
  797.             }
  798.         return(0);
  799.         }
  800.     if((sq[newx][newy].whatside!=0xff)&&(sq[newx][newy].whatside!=curpla))
  801.         {  //if owned by enemy
  802.         mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster].status=
  803.         fight(mon[curpla][curmon],mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster]);
  804.         if(mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster].status==0)
  805.             {sq[newx][newy].whatmonster=0;sq[newx][newy].whatside=0xff;}
  806.             //if a monster vanished in fight, adjust it's square.
  807.         drawmap(curx,cury);
  808.         // sets defender status to value of fight
  809.         }
  810.  
  811.     else{
  812.             if((sq[newx][newy].land!=2)&&(sq[newx][newy].whatside!=curpla))
  813.             {   // ie if no wall and no other monster in way
  814.             if(sq[newx][newy].land==6)
  815.                 { // if grass
  816.                 if (moves>1)
  817.                     {--moves;}
  818.                 else
  819.                     {return(0);}
  820.                 }
  821.  
  822.             drawjustland(curx,cury,curx,cury);
  823.             spritepath(32*7,32*7,(-curx+newx+7)*32,(-cury+newy+7)*32,tile[mon[curpla][curmon].graphic]);
  824.  
  825.  
  826.             mon[curpla][curmon].y=newy;
  827.             mon[curpla][curmon].x=newx;
  828.             sq[curx][cury].whatmonster=0;sq[curx][cury].whatside=0xff;
  829.             cury=newy;curx=newx;
  830.             sq[curx][cury].whatmonster=curmon;sq[curx][cury].whatside=curpla;
  831.  
  832.             drawmap(curx,cury);
  833.             --moves;
  834.             }
  835.         }
  836. return(0);
  837. }
  838.  
  839.  // FLYTO FOR FLYING MOVES _-_-__--___---____----_____-----______------_______
  840. flyto()
  841.     {
  842.     signed int i,x,y; // needed for random placing of flyers that kill real living enemies
  843.     unsigned char newx=curx,newy=cury,dist;
  844.     m.bitmapoff();m.bitmapon(5,pcol[curpla]);
  845.     cursor=5;
  846.  
  847.     s.modecho(2);
  848.     do{
  849.         select(&newx,&newy,1);
  850.         setcolor(0x00);line(7*32,7*32,8*32,8*32);line(8*32,7*32,7*32,8*32);//norange();
  851.         lowbip(4);
  852.         }
  853.     while((dist=range(newx,newy,curx,cury))>moves);
  854.     moves-=dist;
  855.     //drawmap(curx,cury);//curx=tgx,cury=tgy;
  856.  
  857.  
  858.  
  859.     if(sq[newx][newy].land==10)//if tries to enter ball
  860.         {
  861.  
  862.         if((!curmon)&&(sq[newx][newy].whose==curpla))
  863.             {
  864.             moves=0;
  865.             sq[curx][cury].whatside=0xff;
  866.             sq[newx][newy].whatside=curpla;         //if wiz & his ball enter it
  867.             sq[newx][newy].whatmonster=curmon;
  868.             mon[curpla][curmon].x=newx;
  869.             mon[curpla][curmon].y=newy;
  870.             cury=newy;curx=newx;
  871.             drawmap(newx,newy);
  872.  
  873.             return(0);
  874.             }                                      // if not, do nowt.
  875.         else
  876.             {
  877.             if(sq[newx][newy].whose==curpla)return(0); //if your own ball no nowt
  878.             if(sq[newx][newy].whatside==0xff)return(0);//if enemy ball but no monster inside it
  879.             //otherwise fight thing will be used later on in this fnctn... i hope
  880.             }
  881.         }
  882.  
  883.         //okay, these 2 lines fly the monster out.  It is flown back if
  884.         //necessary elsewhere...
  885.     drawtile(newx,newy,newx,newy);//clears target square, which is now center of screen
  886.     drawjustland(curx,cury,newx,newy); //removes pic of flyer from start square
  887.     spritepath((curx-newx+7)*32,(cury-newy+7)*32,32*7,32*7,tile[mon[curpla][curmon].graphic]);
  888.                                     //moves flyer to taget square... it may be sent back.
  889.  
  890.     if((sq[newx][newy].land==1)&&sq[newx][newy].whose!=curpla)
  891.         {  //if enemy tree.
  892.         if(decide(mon[curpla][curmon].attack,1))
  893.             {
  894.             s.trecho(mon[curpla][curmon],1);risingbip(3); // kill tree msg
  895.             sq[newx][newy].land=3;sq[newx][newy].whose=4;moves=0;
  896.             if(sq[newx][newy].whatside==0xff)       //if no monster there
  897.                 {
  898.                 //drawjustland(curx,cury,newx,newy);
  899.                 //spritepath((curx-newx+7)*32,(cury-newy+7)*32,32*7,32*7,tile[mon[curpla][curmon].graphic]);                                                                        //move
  900.                 sq[curx][cury].whatside=0xff;
  901.                 sq[newx][newy].whatside=curpla;
  902.                 sq[newx][newy].whatmonster=curmon;
  903.                 mon[curpla][curmon].x=newx;
  904.                 mon[curpla][curmon].y=newy;
  905.  
  906.                 drawmap(newx,newy);
  907.                 }
  908.             else
  909.                 {       //fly back if tree destroyed but monster still sitting on stump
  910.                 drawjustland(newx,newy,newx,newy);
  911.                 spritepath(32*7,32*7,(curx-newx+7)*32,(cury-newy+7)*32,tile[mon[curpla][curmon].graphic]);
  912.                 drawtile(curx,cury,newx,newy);
  913.                 }
  914.  
  915.             return(0);
  916.             }
  917.         else
  918.             {  //failed attack on tree. no move after failed attacks
  919.                     //fly back again
  920.             s.trecho(mon[curpla][curmon],0);moves=0;lowbip(2);
  921.  
  922.             drawjustland(newx,newy,newx,newy);
  923.             spritepath(32*7,32*7,(curx-newx+7)*32,(cury-newy+7)*32,tile[mon[curpla][curmon].graphic]);
  924.             drawtile(curx,cury,newx,newy);
  925.  
  926.  
  927.             }
  928.  
  929.         return(0); // no point checking for move/fight if there was a tree
  930.         }
  931.     if(sq[newx][newy].land==5)
  932.         { //if mirkwood
  933.         if(decide(mon[curpla][curmon].attack,2))
  934.             {
  935.             s.trecho(mon[curpla][curmon],1);
  936.             sq[newx][newy].land=0;moves=0;risingbip(3);//kill mwood
  937.             //drawjustland(curx,cury,newx,newy);
  938.             //spritepath((curx-newx+7)*32,(cury-newy+7)*32,32*7,32*7,tile[mon[curpla][curmon].graphic]);
  939.             sq[curx][cury].whatside=0xff;
  940.             sq[newx][newy].whatside=curpla;         //if tree killed, move to stump
  941.             sq[newx][newy].whatmonster=curmon;
  942.             mon[curpla][curmon].x=newx;
  943.             mon[curpla][curmon].y=newy;  //again, move if tree died.
  944.             cury=newy;curx=newx;
  945.             drawmap(newx,newy);
  946.             return(0);
  947.             }
  948.         else
  949.             {
  950.             //fly back if tree still there
  951.             s.trecho(mon[curpla][curmon],0);moves=0;lowbip(2);
  952.  
  953.             drawjustland(newx,newy,newx,newy);
  954.             spritepath(32*7,32*7,(curx-newx+7)*32,(cury-newy+7)*32,tile[mon[curpla][curmon].graphic]);
  955.             drawtile(curx,cury,newx,newy);
  956.  
  957.             }
  958.         return(0);
  959.         }
  960.     if((sq[newx][newy].whatside!=0xff)&&(sq[newx][newy].whatside!=curpla))
  961.         {  //if owned by enemy
  962.         curx=newx;cury=newy;
  963.         mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster].status=fight(mon[curpla][curmon],mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster]);
  964.         curx=mon[curpla][curmon].x;cury=mon[curpla][curmon].y;
  965.         if(mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster].status==0)
  966.             {
  967.             sq[curx][cury].whatside=0xff;
  968.             sq[newx][newy].whatside=curpla;
  969.             sq[newx][newy].whatmonster=curmon;
  970.             mon[curpla][curmon].x=newx;
  971.             mon[curpla][curmon].y=newy;
  972.  
  973.             drawmap(newx,newy);
  974.             return(0);
  975.             }
  976.             //if a monster vanished in fight, adjust it's square and move flyer
  977.         if(mon[sq[newx][newy].whatside][sq[newx][newy].whatmonster].status==0x11)
  978.             {
  979.             for(i=0;i<15;++i) //try 15 times to find a free square to go to
  980.                 {
  981.                 x=random(3)-1;y=random(3)-1;
  982.  
  983.                 if(sq[newx+x][newy+y].whatside==0xff)break;
  984.                 }               // if none, move the damn thing anyway. huh.
  985.             newx+=x;newy+=y;        //the flyer is thus on a different square to
  986.             sq[curx][cury].whatside=0xff;      //the one it was shown flying to.
  987.             sq[newx][newy].whatside=curpla;
  988.             sq[newx][newy].whatmonster=curmon;
  989.             mon[curpla][curmon].x=newx;
  990.             mon[curpla][curmon].y=newy;
  991.  
  992.             drawmap(newx,newy);
  993.             return(0);
  994.             }
  995.             // yo yo again if monster survived flyer's attack
  996.         drawtile(newx,newy,newx,newy);
  997.         spritepath(32*7,32*7,(curx-newx+7)*32,(cury-newy+7)*32,tile[mon[curpla][curmon].graphic]);
  998.         drawtile(curx,cury,newx,newy);
  999.  
  1000.  
  1001.         drawmap(curx,cury); // i dunno... what spaghetti :(
  1002.  
  1003.         }
  1004.  
  1005.     else
  1006.         {
  1007.         if(sq[newx][newy].whatside!=curpla)
  1008.             {   // ie if no other monster in way
  1009.             //drawjustland(curx,cury,newx,newy);
  1010.             //spritepath((curx-newx+7)*32,(cury-newy+7)*32,32*7,32*7,tile[mon[curpla][curmon].graphic]);
  1011.             mon[curpla][curmon].y=newy;
  1012.             mon[curpla][curmon].x=newx;
  1013.             sq[curx][cury].whatmonster=0;sq[curx][cury].whatside=0xff;
  1014.             cury=newy;curx=newx;
  1015.             sq[curx][cury].whatmonster=curmon;sq[curx][cury].whatside=curpla;
  1016.             drawmap(curx,cury);
  1017.  
  1018.             }
  1019.         }
  1020. return(0);
  1021. }
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027. // FIRING FNCTN FIRE ONLY CALLS S.SHECHO etc-----------------------------------
  1028. // this one modifies curx and cury to be the
  1029. //cursor position & map focus, then sets them back
  1030. // to the monster position.  Argh what spaghetti
  1031. fire(char shots,char kind)
  1032.     {
  1033.     int fx,fy,tx,ty;
  1034.     char bonus=0;// this + 10 if defender is in a dome
  1035.                              // and + 10 if defender resists this kind of shot.
  1036.     --moves;--shots;
  1037.     usemouse();
  1038.     m.wheremouse();
  1039.     m.bitmapoff();cursor=3;m.bitmapon(3,pcol[curpla]);
  1040.  
  1041.  
  1042.  
  1043.     for(;;)
  1044.     {
  1045.         while(m.wheremouse())
  1046.             {
  1047.             cycleballs();
  1048.  
  1049.  
  1050.             if(kbhit())
  1051.                 {
  1052.                 getch();
  1053.                 if (rangesight(curx,cury,mon[curpla][curmon].x,mon[curpla][curmon].y,mon[curpla][curmon].range))
  1054.                     {goto selected;}
  1055.                 else
  1056.                     {
  1057.                     setcolor(0x00);line(7*32,7*32,8*32,8*32);line(8*32,7*32,7*32,8*32);
  1058.                     lowbip(4);
  1059.                     }
  1060.  
  1061.  
  1062.                 }
  1063.             }
  1064.         curx=curx+(m.x/32)-7;cury=cury+(m.y/32)-7;
  1065.         drawmap(curx,cury);m.putat(240,240);
  1066.         s.recho(curx,cury);
  1067.     }
  1068.     selected:;
  1069.  
  1070.     /*if(sq[curx][cury].land==10)    //no shooting at domes!
  1071.         {
  1072.         curx=mon[curpla][curmon].x;
  1073.         cury=mon[curpla][curmon].y;
  1074.         lowbip(3);
  1075.         ++moves;
  1076.         return(0);
  1077.         }    */
  1078.  
  1079.     if(mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster].immunities==kind)bonus+=10;
  1080.     drawmap(curx,cury);
  1081.  
  1082.     fx=(mon[curpla][curmon].x-curx+7)*32+16;
  1083.     fy=(mon[curpla][curmon].y-cury+7)*32+16;
  1084.     tx=7*32+16;
  1085.     ty=7*32+16;
  1086.  
  1087.  
  1088.     if((fx==tx)&&(fy==ty)) //if attempts to shoot itself
  1089.         {
  1090.         lowbip(4);
  1091.         setcolor(0x07);setfillstyle(1,0);
  1092.         bar(180,260,320,292);
  1093.         rectangle(180,260,320,292);
  1094.         outtextxy(190,262,"Suicide is not");
  1095.         outtextxy(190,272,"allowed here...");
  1096.         return(1);
  1097.         }
  1098.  
  1099.         if (sq[curx][cury].whatside!=0xff) //only bother if monster is hit
  1100.         {
  1101.         if (sq[curx][cury].land==1)   //give msg if monster in tree
  1102.             {
  1103.             s.shecho(mon[curpla][curmon],mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster],0,mon[curpla][curmon].fire);
  1104.  
  1105.             if(kind==3)
  1106.                 {
  1107.                 sq[curx][cury].land=3; //if fireball hits tree
  1108.                 sq[curx][cury].whose=0xff;
  1109.                 }
  1110.             }
  1111.         else                          //if no tree...
  1112.             {
  1113.             if(sq[curx][cury].land==10)bonus+=10;
  1114.  
  1115.             if (!decide(kind*2,mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster].defend+bonus))
  1116.                 {     //if miss
  1117.                 s.shecho(mon[curpla][curmon],mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster],1,mon[curpla][curmon].fire);
  1118.                 }
  1119.             else
  1120.                 {    //if hit
  1121.                 s.shecho(mon[curpla][curmon],mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster],2,mon[curpla][curmon].fire);
  1122.                 if ((kind!=3)&&(mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster].status==1))
  1123.                     { //if non-fireball hits living monster
  1124.                     mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster].status=0x11;
  1125.                     }
  1126.                 else
  1127.                     {
  1128.                     mon[sq[curx][cury].whatside][sq[curx][cury].whatmonster].status=0;
  1129.                     sq[curx][cury].whatside=0xff;
  1130.                     }
  1131.                 ++kills[curpla];
  1132.                 }
  1133.             }//end of if no tree
  1134.  
  1135.  
  1136.         }
  1137.     else //destroy tree even if no monster.
  1138.         {
  1139.         if((kind==3)&&((sq[curx][cury].land==1)||(sq[curx][cury].land==5)))
  1140.                 {
  1141.                 sq[curx][cury].land=3; //if fireball hits tree
  1142.                 sq[curx][cury].whose=0xff;
  1143.                 }
  1144.         if((kind==3)&&(sq[curx][cury].land==6))
  1145.                 {
  1146.                 sq[curx][cury].land=8;
  1147.                 }
  1148.         }
  1149.  
  1150.     if((kind==3)&&(!random(8))&&(sq[curx][cury].land<10))sq[curx][cury].land=8;
  1151.             //1 in 8 chance of fire with fball
  1152.  
  1153.     m.bitmapoff();
  1154.  
  1155.     showfire(fx,fy,tx,ty,kind);
  1156.  
  1157.     if(sq[curx][cury].land==10)orbattacked(curx,cury); //make dome flash if hit.
  1158.  
  1159.     m.bitmapon(0,pcol[curpla]);cursor=0;
  1160.     curx=mon[curpla][curmon].x,cury=mon[curpla][curmon].y;
  1161.     drawmap(curx,cury);
  1162.     //s.usespace();
  1163.     //getch();
  1164.  
  1165.     return (shots);
  1166.     }
  1167.  
  1168. showfire(int fx,int fy,int tx, int ty,int kind)
  1169.     {
  1170.     int i,j,sx,sy,ssx,ssy;
  1171.  
  1172.     int ax=fx,ay=fy,bx=tx,by=ty;
  1173.             int rtempx, rtempy, i_stage, steps;
  1174.     float ftempx, ftempy;
  1175.     float x_inc, y_inc;
  1176.     float x_sep=abs(ax-bx), y_sep=abs(ay-by);
  1177.  
  1178.  
  1179.     if(kind==1) //arrow,2=ray,3=fball
  1180.     {
  1181.  
  1182.         setwritemode(XOR_PUT);
  1183.         setcolor(0x0d);      //xor to white
  1184.  
  1185.         for(i=0;i<3;++i)
  1186.         {
  1187.         bx+=(random(7)-3);by+=(random(7)-3);
  1188.         x_sep=abs(ax-bx); y_sep=abs(ay-by);
  1189.  
  1190.         if(x_sep > y_sep)
  1191.         {
  1192.             x_inc = 2;
  1193.             y_inc = 2*y_sep/x_sep;
  1194.             steps=x_sep/2;
  1195.         }
  1196.         else
  1197.         {
  1198.             x_inc = 2*x_sep/y_sep;
  1199.             y_inc = 2;
  1200.             steps=y_sep/2;
  1201.         }
  1202.         if (ax > bx) x_inc = -x_inc;
  1203.         if (ay > by) y_inc = -y_inc;
  1204.         ftempx = ax;
  1205.         ftempy = ay;
  1206.         setwritemode(XOR_PUT);
  1207.         for (i_stage=0;i_stage<steps-1;i_stage++)//-1 because arrow shouldnt overwrite target
  1208.         {
  1209.             ftempx += x_inc;
  1210.             ftempy += y_inc;
  1211.  
  1212.             rtempx = ftempx;
  1213.             rtempy = ftempy;
  1214.  
  1215.             if( (ftempx - rtempx) > 0.5 ) rtempx++;
  1216.             if( (ftempy - rtempy) > 0.5 ) rtempy++;
  1217.             line(rtempx,rtempy,rtempx+(x_inc*10),rtempy+(y_inc*10));
  1218.  
  1219.  
  1220.             delay(5);
  1221.  
  1222.             line(rtempx,rtempy,rtempx+(x_inc*10),rtempy+(y_inc*10));
  1223.         }
  1224.  
  1225.         }
  1226.  
  1227.         setwritemode(0);
  1228.         return(0);
  1229.     }
  1230.     if(kind==2)
  1231.     {
  1232.  
  1233.  
  1234.         setwritemode(XOR_PUT);
  1235.         for(i=4;i<12;++i)
  1236.             {
  1237.  
  1238.             setcolor(i);
  1239.             for(j=700;j<740;++j)
  1240.                 {
  1241.                 if(noisy){sound(random(20)+j);delay(3);sound(random(i*4));}else{delay(5);}
  1242.                 line(fx,fy,tx,ty);line(fx,fy,tx+1,ty);
  1243.                 line(fx,fy,tx+2,ty);line(fx,fy,tx,ty+1);
  1244.                 line(fx,fy,tx,ty+2);line(fx,fy,tx-1,ty);
  1245.                 line(fx,fy,tx,ty-1);line(fx,fy,tx-2,ty);
  1246.                 line(fx,fy,tx,ty-2);
  1247.  
  1248.                 }
  1249.             }
  1250.         nosound();
  1251.  
  1252.         setwritemode(0);
  1253.         return(0);
  1254.     }
  1255.     if(kind==3)
  1256.     {
  1257.         setwritemode(XOR_PUT);
  1258.  
  1259.         if(x_sep > y_sep)
  1260.         {
  1261.             x_inc = 1;
  1262.             y_inc = y_sep/x_sep;
  1263.             steps=x_sep;
  1264.         }
  1265.         else
  1266.         {
  1267.             x_inc = x_sep/y_sep;
  1268.             y_inc = 1;
  1269.             steps=y_sep;
  1270.         }
  1271.         if (ax > bx) x_inc = -x_inc;
  1272.         if (ay > by) y_inc = -y_inc;
  1273.         ftempx = ax;
  1274.         ftempy = ay;
  1275.         setwritemode(XOR_PUT);
  1276.         for (i_stage=0;i_stage<steps;i_stage++)
  1277.         {
  1278.             ftempx += x_inc;
  1279.             ftempy += y_inc;
  1280.  
  1281.             rtempx = ftempx;
  1282.             rtempy = ftempy;
  1283.  
  1284.             if( (ftempx - rtempx) > 0.5 ) rtempx++;
  1285.             if( (ftempy - rtempy) > 0.5 ) rtempy++;
  1286.  
  1287.             setcolor(0x0e);
  1288.             sx=rtempx+random(15)-7;sy=rtempy+random(15)-7;
  1289.             ssx=rtempx+random(7)-3;ssy=rtempy+random(7)-3;
  1290.  
  1291.             rectangle(sx-3,sy-3,sx+3,sy+3);
  1292.             moveto(sx,sy-5);linerel(0,5);linerel(-4,-2);
  1293.             moveto(sx,sy+5);linerel(0,-5);linerel(-4,2);
  1294.             moveto(sx+4,sy+2);linerel(-4,-2);linerel(4,-2);
  1295.             setcolor(0x0c);
  1296.             rectangle(ssx-3,ssy-3,ssx+3,ssy+3);
  1297.             moveto(ssx,ssy-5);linerel(0,5);linerel(-4,-2);
  1298.             moveto(ssx,ssy+5);linerel(0,-5);linerel(-4,2);
  1299.             moveto(ssx+4,ssy+2);linerel(-4,-2);linerel(4,-2);
  1300.             delay(6);
  1301.             setcolor(0x0e);
  1302.                 rectangle(sx-3,sy-3,sx+3,sy+3);
  1303.             moveto(sx,sy-5);linerel(0,5);linerel(-4,-2);
  1304.             moveto(sx,sy+5);linerel(0,-5);linerel(-4,2);
  1305.             moveto(sx+4,sy+2);linerel(-4,-2);linerel(4,-2);
  1306.             setcolor(0x0c);
  1307.             rectangle(ssx-3,ssy-3,ssx+3,ssy+3);
  1308.             moveto(ssx,ssy-5);linerel(0,5);linerel(-4,-2);
  1309.             moveto(ssx,ssy+5);linerel(0,-5);linerel(-4,2);
  1310.             moveto(ssx+4,ssy+2);linerel(-4,-2);linerel(4,-2);
  1311.  
  1312.  
  1313.  
  1314.         if(noisy){sound(random(200));sound(100-i_stage);}
  1315.  
  1316.  
  1317.         }
  1318.  
  1319.  
  1320.      setwritemode(0);
  1321.      if(noisy)sound(20);
  1322.      if(sq[curx][cury].land<10)
  1323.         foom(curx,cury);
  1324.  
  1325.  
  1326.  
  1327.      nosound();
  1328.     }
  1329.  
  1330.     }
  1331.  
  1332. spells()
  1333.     {
  1334.  
  1335.     int num,lastnum,i,a=0,real=1;
  1336.  
  1337.     m.wheremouse(); //soak up extra clix.  BAD user!!
  1338.     //drawmap(caster.x,caster.y);
  1339.     m.unsetbounds();
  1340.     m.bitmapoff();cursor=2;
  1341.     s.spells(mon[curpla][curmon]);
  1342.     setwritemode(XOR_PUT);
  1343.     setcolor(0x0b);
  1344.  
  1345.     while(m.wheremouse())
  1346.         {
  1347.         cycleballs();
  1348.  
  1349.         if(!m.right()){real=0;break;}
  1350.         num=(m.y-95)/10;
  1351.         if(num<0)num=0;
  1352.         if(num>=mon[curpla][curmon].spellnum-1)num=mon[curpla][curmon].spellnum-1;
  1353.         if(kbhit())  // get help if keypress
  1354.             {
  1355.             getch();setwritemode(0);s.spellhelp(mon[curpla][curmon].spells[num]);
  1356.             m.bitmapoff();setwritemode(XOR_PUT);
  1357.             setcolor(0x0b);
  1358.             }
  1359.         if (lastnum!=num)
  1360.             {
  1361.             rectangle(481,94+lastnum*10,639,104+lastnum*10);
  1362.             rectangle(481,94+num*10,639,104+num*10);
  1363.             }
  1364.         lastnum=num;
  1365.         }
  1366.  
  1367.     m.setbounds(curx,cury);
  1368.     setwritemode(0);
  1369.     while(kbhit())
  1370.         {
  1371.         if(getch()=='!'){closegraph();bossmsg();exit(0);}
  1372.         }  //naughty user!! bad,bad!!! soak up!
  1373.     bip(mon[curpla][curmon].spells[num]);
  1374.     m.bitmapon(2,pcol[curpla]);
  1375.   //foom(10,10);getch();
  1376.     castspell(mon[curpla][curmon].spells[num],real);
  1377.     s.usespace();getch();
  1378.   
  1379.     setfillstyle(1,0);bar(482,0,639,479);
  1380.     s.logo();
  1381.     s.boxes();
  1382.     drawmap(mon[curpla][curmon].x,mon[curpla][curmon].y);
  1383.     if(mon[curpla][curmon].spells[num]!=99)mon[curpla][curmon].spells[num]=0;
  1384.     for (i=0;i<mon[curpla][curmon].spellnum;++i)
  1385.         {
  1386.         if (mon[curpla][curmon].spells[i])a=1;
  1387.         }
  1388.     if (!a)mon[curpla][curmon].spellnum=0;
  1389.     m.wheremouse();
  1390.     m.bitmapoff();m.bitmapon(0,pcol[curpla]);
  1391.     return(0);
  1392.     }
  1393.  
  1394.  
  1395.  
  1396.  
  1397. void select(char *tgx,char *tgy,int which)
  1398.     {
  1399.     //*tgx=curx;*tgy=cury;
  1400.  
  1401.     for(;;)
  1402.     {
  1403.     while(m.wheremouse())
  1404.         {
  1405.         //m.adjustmouse(*tgx,*tgy);
  1406.         cycleballs();
  1407.  
  1408.  
  1409.         if(kbhit()){getch();
  1410.                                  return;}
  1411.         }
  1412.  
  1413.     *tgx=*tgx+(m.x/32)-7;*tgy=*tgy+(m.y/32)-7;
  1414.  
  1415.         drawmap(*tgx,*tgy);m.putat(240,240);
  1416.         s.recho(*tgx,*tgy);
  1417.  
  1418.     }
  1419.  
  1420. }
  1421.  
  1422. void getadj(char *tgx,char *tgy)
  1423.     {
  1424.     char c,done=0;
  1425.     s.usekeys();
  1426.     rectangle(6*32,6*32,9*32,9*32);
  1427.     while(!done)
  1428.         {
  1429.         c=getch();
  1430.         if (c=='8'){--*tgy;done=1;}if (c=='2'){++*tgy;done=1;}
  1431.         if (c=='4'){--*tgx;done=1;}if (c=='6'){++*tgx;done=1;}
  1432.         if (c=='7'){--*tgy;--*tgx;done=1;}if (c=='9'){--*tgy;++*tgx;done=1;}
  1433.         if (c=='1'){++*tgy;--*tgx;done=1;}if (c=='3'){++*tgy;++*tgx;done=1;}
  1434.         delay(1);
  1435.         }
  1436.  
  1437. }
  1438.  
  1439. void foom(int sqx,int sqy)
  1440.     {
  1441.     m.bitmapoff();
  1442.     int x=(sqx-curx+7)*32,y=(sqy-cury+7)*32,i,px,py,frame;
  1443.  
  1444.     for (frame=0;frame<8;++frame)
  1445.     {
  1446.     for (i=0;i<0x400;++i)
  1447.             {
  1448.             px=x+(i % 32);py=y+(i / 32);
  1449.             if (shroom[frame][i] != 255) putpixel(px,py,shroom[frame][i]);
  1450.             if (shroom[frame][i]==0)
  1451.                 {
  1452.                 m.wheremouse();      //this is 4 debugging
  1453.                 }
  1454.             }
  1455.     delay(50);
  1456.     setfillstyle(1,0x02);
  1457.     bar(x,y,x+31,y+31);
  1458.     }
  1459.     bar(x,y,x+31,y+31);
  1460.     drawtile(sqx,sqy,curx,cury);
  1461.     m.bitmapon(cursor,pcol[curpla]);
  1462.     delay(100);
  1463.  
  1464. }
  1465.  
  1466. void boof(int sqx,int sqy)
  1467.     {
  1468.     int x=((sqx-curx+7)*32)+16,y=((sqy-cury+7)*32)+16,frame;
  1469.  
  1470.  
  1471.     for(frame=20;frame>0;--frame)
  1472.         {
  1473.         setcolor(0x0f);
  1474.         circle(x,y,frame*17);
  1475.         setcolor(0x07);
  1476.         circle(x,y,frame*17+17);
  1477.         setcolor(0x08);
  1478.         circle(x,y,frame*17+34);
  1479.         setcolor(0x00);
  1480.         circle(x,y,frame*20+51);
  1481.         }
  1482.  
  1483. }
  1484.  
  1485.  
  1486. void moof(int sqx,int sqy)
  1487.     {
  1488.     int x=(sqx-curx+7)*32,y=(sqy-cury+7)*32,frame;
  1489.     setcolor(0x0d);
  1490.     setwritemode(XOR_PUT);
  1491.  
  1492.     for (frame=1;frame<9;++frame)
  1493.         {
  1494.         if(noisy)sound(random(1000)+1200+frame*100);
  1495.         moveto(x+16,y-frame*7+16);
  1496.         penty(frame,30);
  1497.         }
  1498.     for (frame=8;frame>0;--frame)
  1499.         {
  1500.         if(noisy)sound(random(1000)+1200+frame*100);
  1501.         moveto(x+16,y-frame*7+16);
  1502.         penty(frame,30);
  1503.         }
  1504.     nosound();
  1505.     setwritemode(0);
  1506. }
  1507.  
  1508.  
  1509.  
  1510. void swarm(int xa,int ya,int xb,int yb,int num) //topleft, lowright.
  1511.     {
  1512.     int xdif=(xb-xa)*32,ydif=(yb-ya)*32;
  1513.     int px=(xa-curx+7)*32,py=(ya-cury+7)*32;
  1514.     int i,j,x,y,a,b;
  1515.     setwritemode(XOR_PUT);setcolor(0x0d);
  1516.     for(i=0;i<num;++i)
  1517.         {
  1518.         x=random(xdif)+px,y=random(ydif)+py;
  1519.         a=random(xdif)+px,b=random(ydif)+py;
  1520.         line(x,y-2,x,y+2);line(x-2,y,x+2,y);
  1521.         line(a,b-2,a,b+2);line(a-2,b,a+2,b);
  1522.         if(noisy)
  1523.             {
  1524.             sound(random(1600)+600);delay(random(15));nosound();
  1525.             }
  1526.         else
  1527.             {
  1528.             delay(20);
  1529.             }
  1530.         line(x,y-2,x,y+2);line(x-2,y,x+2,y);
  1531.         line(a,b-2,a,b+2);line(a-2,b,a+2,b);
  1532.         }
  1533.     setwritemode(0);
  1534.     for(i=0;i<xb-xa;++i)
  1535.         {
  1536.         for(j=0;j<yb-ya;++j)
  1537.         {
  1538.         drawtile(xa+i,ya+j,curx,cury);
  1539.         }
  1540.         }
  1541.  
  1542. }
  1543.  
  1544. void penty(int frame,int del)//frame=size  moveto center and setwrietmode xor first
  1545.     {
  1546.     linerel(5*frame,14*frame);linerel(-14*frame,-9*frame);
  1547.     linerel(18*frame,0);
  1548.     linerel(-14*frame,9*frame);linerel(5*frame,-14*frame);
  1549.     if(!del)return;
  1550.     delay(del);
  1551.     linerel(5*frame,14*frame);linerel(-14*frame,-9*frame);
  1552.     linerel(18*frame,0);
  1553.     linerel(-14*frame,9*frame);linerel(5*frame,-14*frame);
  1554.     return;
  1555. }
  1556. void crawler(int ax,int ay,int bx,int by)
  1557.     {
  1558.     int rtempx, rtempy, i_stage, steps, i;
  1559.     float ftempx, ftempy;
  1560.     float x_inc, y_inc;
  1561.     float x_sep=abs(ax-bx), y_sep=abs(ay-by);
  1562.  
  1563.         if(x_sep > y_sep)
  1564.         {
  1565.             x_inc = 1;
  1566.             y_inc = y_sep/x_sep;
  1567.             steps=x_sep;
  1568.         }
  1569.         else
  1570.         {
  1571.             x_inc = x_sep/y_sep;
  1572.             y_inc = 1;
  1573.             steps=y_sep;
  1574.         }
  1575.         if (ax > bx) x_inc = -x_inc;
  1576.         if (ay > by) y_inc = -y_inc;
  1577.         ftempx = ax;
  1578.         ftempy = ay;
  1579.         //setwritemode(XOR_PUT);
  1580.         for (i_stage=0;i_stage<steps;i_stage++)
  1581.         {
  1582.             ftempx += x_inc;
  1583.             ftempy += y_inc;
  1584.  
  1585.             rtempx = ftempx;
  1586.             rtempy = ftempy;
  1587.  
  1588.             if( (ftempx - rtempx) > 0.5 ) rtempx++;
  1589.             if( (ftempy - rtempy) > 0.5 ) rtempy++;
  1590.  
  1591.         if(sq[rtempx][rtempy].land<10) //dont kill balls
  1592.             {
  1593.             sq[rtempx][rtempy].land=4;sq[rtempx][rtempy].whose=0xff;
  1594.             if((sq[rtempx][rtempy].whatside !=0xff)&&(sq[rtempx][rtempy].whatmonster))
  1595.                 {
  1596.                 mon[sq[rtempx][rtempy].whatside][sq[rtempx][rtempy].whatmonster].status=0;
  1597.                 sq[rtempx][rtempy].whatside=0xff;
  1598.                 }
  1599.             if(noisy)
  1600.                 {
  1601.                 for(i=80;i>20;--i)
  1602.                 {sound(i);delay(3);}
  1603.                 }
  1604.             foom(rtempx,rtempy);
  1605.             nosound();
  1606.             }
  1607.  
  1608.         }
  1609.  
  1610. }
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616. int range(long ax,long ay,long bx,long by)//goes from targ to start
  1617.     {
  1618.     int dist;
  1619.     if((ax==bx)&&(ay==by))return(0);
  1620.     if(ax==bx)return(abs(ay-by));
  1621.     if(ay==by)return(abs(ax-bx));
  1622.     double rdist=sqrt(((ax-bx)*(ax-bx)+(ay-by)*(ay-by)));
  1623.     dist = rdist;
  1624.     if (rdist-dist>0.5)++dist;
  1625.     return(dist);
  1626.  
  1627. }
  1628.  
  1629. int linesight(int ax,int ay,     int bx,int by)
  1630.     {
  1631.  
  1632.  
  1633.  
  1634. int rtempx, rtempy, i_stage, steps;
  1635.  
  1636. float ftempx, ftempy;
  1637.  
  1638. float x_inc, y_inc;
  1639.  
  1640. float x_sep=abs(ax-bx), y_sep=abs(ay-by);
  1641.  
  1642.     if((!x_sep)&&(!y_sep))return(1);
  1643.  
  1644.  
  1645.  
  1646.  
  1647.         if(x_sep > y_sep)
  1648.         {
  1649.             x_inc = 1;
  1650.             y_inc = y_sep/x_sep;
  1651.             steps=x_sep;
  1652.         }
  1653.  
  1654.         else
  1655.         {
  1656.             x_inc = x_sep/y_sep;
  1657.             y_inc = 1;
  1658.             steps=y_sep;
  1659.         }
  1660.  
  1661.  
  1662.  
  1663.         if (ax > bx) x_inc = -x_inc;
  1664.         if (ay > by) y_inc = -y_inc;
  1665.  
  1666.  
  1667.         ftempx = ax;
  1668.         ftempy = ay;
  1669.  
  1670.         for (i_stage=0;i_stage<steps-1;i_stage++)
  1671.         {
  1672.             ftempx += x_inc;
  1673.             ftempy += y_inc;
  1674.  
  1675.             rtempx = ftempx;
  1676.             rtempy = ftempy;
  1677.  
  1678.             if( (ftempx - rtempx) > 0.5 ) rtempx++;
  1679.             if( (ftempy - rtempy) > 0.5 ) rtempy++;
  1680.  
  1681.  
  1682.  
  1683.             if(check(rtempx,rtempy))
  1684.                 return(0);
  1685.  
  1686.         }
  1687.  
  1688.  
  1689.     return(1);
  1690. }
  1691.  
  1692.  
  1693. check(int x,int y) //return 1 if no sight thru sq[x][y]
  1694.     {
  1695.     if((sq[x][y].land==1)||
  1696.          (sq[x][y].land==2)||
  1697.          (sq[x][y].land==5)||
  1698.          (sq[x][y].land==10))
  1699.          return(1);
  1700.  
  1701.     if(sq[x][y].whatside!=0xff) //if monster
  1702.         {
  1703.         if(mon[sq[x][y].whatside][sq[x][y].whatmonster].status==0x11)
  1704.             {                  //if corpse/shade/whatever it is
  1705.             if(sq[x][y].whatside==curpla)
  1706.                 {                  //if shade loyal to you
  1707.                 return(0);
  1708.                 }
  1709.             }
  1710.         return(1);
  1711.         }
  1712.     return(0);
  1713. }
  1714.  
  1715.  
  1716. int rangesight(int ax,int ay,int bx,int by, int mrange)
  1717.     {
  1718.     int dist=range(ax,ay,bx,by);
  1719.     if((linesight(ax,ay,bx,by))&&(mrange>=dist))
  1720.         {
  1721.         return(1);
  1722.         }
  1723.     return(0);
  1724. }
  1725.  
  1726. decide(int attack,int defend) //true if death
  1727.     {
  1728.     attack_history[curpla][thisturn]+=(attack+5)*3;//+5 to iron values flatter
  1729.     if (!defend)return(1);
  1730.     if(!attack)return(0);
  1731.  
  1732.     attack<defend?defend*=1.5:attack*=1.5;// increase spread to make it
  1733.                                         // bad to attack with a 3 against a 7 etc.
  1734.     int total=attack+defend;
  1735.  
  1736.     int r=random(total)+1;
  1737.     if(r>(total/2))luck_history[curpla]+=2;
  1738.     luck_history[curpla]-=1;                //add 1 for a high number, -1 for a low one
  1739.  
  1740.     if((r>defend)&&(random(3)))//give 2/3 chance of success.
  1741.         {
  1742.         return(1);
  1743.         }
  1744.     return(0);
  1745.  
  1746. }
  1747. void usemouse()
  1748. {
  1749. m.bitmapoff();
  1750. setcolor(0x07);setfillstyle(1,0);
  1751.     bar(170,260,330,292);
  1752.     rectangle(170,260,330,292);
  1753.     outtextxy(180,262,"Use the mouse to");
  1754.     outtextxy(180,272,"highlight squares;");
  1755.     outtextxy(180,282,"Space to select.");
  1756.  
  1757.     m.bitmapon(cursor,pcol[curpla]);
  1758. }
  1759.  
  1760. void nospells()
  1761. {
  1762. setcolor(0x07);setfillstyle(1,0);
  1763. m.bitmapoff();
  1764.  bar(180,260,340,292);
  1765.  rectangle(180,260,340,292);
  1766.     outtextxy(190,262,"No spells are");
  1767.     outtextxy(190,272,"available now.");
  1768.     outtextxy(190,282,"Press something...");
  1769.  
  1770.     mygetch();
  1771.     drawmap(curx,cury);
  1772.     //m.bitmapon(cursor,pcol[curpla]);
  1773. }
  1774. /*void norange()
  1775. {
  1776. setcolor(0x07);setfillstyle(1,0);
  1777.  bar(190,260,310,272);
  1778.  rectangle(190,260,310,272);
  1779.     outtextxy(200,262,"Too far away.");
  1780. }           */
  1781.  
  1782. void noshots()
  1783. {
  1784. setcolor(0x07);setfillstyle(1,0);
  1785.  
  1786.  m.bitmapoff();
  1787.  bar(180,260,340,292);
  1788.  rectangle(180,260,340,292);
  1789.     outtextxy(190,262,"You can't fire");
  1790.     outtextxy(190,272,"just now.");
  1791.     outtextxy(190,282,"Press something...");
  1792.  
  1793.     mygetch();
  1794.     drawmap(curx,cury);
  1795.     //m.bitmapon(cursor,pcol[curpla]);
  1796. }
  1797.  
  1798. int adjust(char *newx,char *newy)  //there is no reason at all to have
  1799.     {                                //passed these by address... ho hum.
  1800.     if((*newx>=width)
  1801.     ||(*newx<0)
  1802.     ||(*newy>=height)
  1803.     ||(*newy<0)
  1804.     )
  1805.     return(1);
  1806.     return(0);
  1807. }
  1808.  
  1809. void memerror()                     //this never happens, in fact.
  1810.     {
  1811.     int i;
  1812.     closegraph();
  1813.     for(i=0;i<24;++i)
  1814.         free(tile[i]);
  1815.     for(i=0;i<8;++i)
  1816.         {free(terrt[i]);free(shroom[i]);}
  1817.  
  1818.     printf("Not enough memory.\n");
  1819.     exit(0);
  1820. }
  1821. cycleballs()
  1822.     {
  1823.     static char cycle,cycle_dir;
  1824.     int i,evil=0,good=0,red,green,blue;
  1825.     for(i=0;i<players;++i)
  1826.         {
  1827.     evil=0;good=0;
  1828.         if(alignment[i]>0){good=alignment[i]/10;}else{evil=alignment[i]/-10;}
  1829.  
  1830.         red=cycle+evil-good;if(red<0)red=0;red<<2;
  1831.         green=cycle-good-evil;if(green<0)green=0;green<<2;
  1832.         blue=cycle-evil+good;if(blue<0)blue=0;blue<<2;
  1833.         //values 0-60 leftshifted by 2 should occupy uppper 6 bits like the
  1834.             //gfx regs want...
  1835.  
  1836.         setrgbpalette(247+i,red,green,blue);
  1837.         }
  1838.     if(cycle_dir)
  1839.         {
  1840.         cycle++;
  1841.         if(cycle>30)cycle_dir=0;
  1842.         }
  1843.     else
  1844.         {
  1845.         cycle--;
  1846.         if(cycle<0)cycle_dir=1;
  1847.         }
  1848.     return(cycle); // no need
  1849. }
  1850.  
  1851. char mygetch()
  1852.     {
  1853.     while(!kbhit())
  1854.         {
  1855.         cycleballs();
  1856.         delay(10);
  1857.         }
  1858.     return(getch());
  1859. }
  1860.