home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / collide.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  5.5 KB  |  228 lines

  1. #include "level.hpp"
  2. #include "intsect.hpp"
  3.  
  4. class collide_patch
  5. {
  6.   public :
  7.   long total,x1,y1,x2,y2;
  8.   game_object **touch;  
  9.   collide_patch *next;
  10.   collide_patch(long X1, long Y1, long X2, long Y2, collide_patch *Next)
  11.   { 
  12.     x1=X1; y1=Y1; x2=X2; y2=Y2;
  13.     next=Next;
  14.     total=0;
  15.     touch=NULL;
  16.   }
  17.   void add_collide(long X1, long Y1, long X2, long Y2, game_object *who);
  18.   collide_patch *copy(collide_patch *Next);
  19.   ~collide_patch() { if (total) jfree(touch); }
  20. } ;
  21.  
  22.  
  23. collide_patch *collide_patch::copy(collide_patch *Next)
  24.   collide_patch *p=new collide_patch(x1,y1,x2,y2,Next); 
  25.   p->total=total;
  26.   if (total)    
  27.   {
  28.     p->touch=(game_object **)jmalloc(total*sizeof(game_object *),"collide patches");
  29.     memcpy(p->touch,touch,total*(sizeof(game_object *)));
  30.   }
  31.   else 
  32.     p->touch=NULL; 
  33.   return p;
  34. }
  35.  
  36.  
  37. void add_collide(collide_patch *&first, long x1, long y1, long x2, long y2, 
  38.                 game_object *who)
  39. {  
  40.   collide_patch *last=NULL,*next;
  41.   for (collide_patch *p=first;p;p=next)
  42.   {
  43.     next=p->next;
  44.     // first see if light patch we are adding is enclosed entirely by another patch
  45.     if (x1>=p->x1 && y1>=p->y1 && x2<=p->x2 && y2<=p->y2)
  46.     {
  47.       if (x1>p->x1)
  48.       {
  49.     first=p->copy(first);
  50.     first->x2=x1-1;
  51.       }
  52.       if (x2<p->x2)
  53.       {
  54.     first=p->copy(first);
  55.     first->x1=x2+1;
  56.       }
  57.       if (y1>p->y1)
  58.       {
  59.     first=p->copy(first);
  60.     first->x1=x1;
  61.     first->x2=x2;
  62.     first->y2=y1-1;
  63.       }
  64.       if (y2<p->y2)
  65.       {
  66.     first=p->copy(first);
  67.     first->x1=x1;
  68.     first->x2=x2;
  69.     first->y1=y2+1;
  70.       }
  71.       p->x1=x1; p->y1=y1; p->x2=x2; p->y2=y2;
  72.  
  73.       p->total++;     
  74.       p->touch=(game_object **)jrealloc(p->touch,sizeof(game_object *)*p->total,"object_patch_list");
  75.       p->touch[p->total-1]=who;
  76.       return ;
  77.     }
  78.  
  79.     // see if the patch completly covers another patch.
  80.     if (x1<=p->x1 && y1<=p->y1 && x2>=p->x2 && y2>=p->y2)
  81.     {
  82.       if (x1<p->x1)
  83.         add_collide(first,x1,y1,p->x1-1,y2,who);
  84.       if (x2>p->x2)
  85.         add_collide(first,p->x2+1,y1,x2,y2,who);
  86.       if (y1<p->y1)
  87.         add_collide(first,p->x1,y1,p->x2,p->y1-1,who);
  88.       if (y2>p->y2)
  89.         add_collide(first,p->x1,p->y2+1,p->x2,y2,who);
  90.       p->total++;     
  91.       p->touch=(game_object **)jrealloc(p->touch,sizeof(game_object *)*p->total,"object_patch_list");
  92.       p->touch[p->total-1]=who;
  93.       return ;
  94.     }
  95.  
  96.     // see if we intersect another rect
  97.     if (!(x2<p->x1 || y2<p->y1 || x1>p->x2 || y1>p->y2))  
  98.     {
  99.       int ax1,ay1,ax2,ay2;
  100.       if (x1<p->x1)
  101.       {
  102.         add_collide(first,x1,max(y1,p->y1),p->x1-1,min(y2,p->y2),who);
  103.     ax1=p->x1;
  104.       } else
  105.     ax1=x1;
  106.  
  107.       if (x2>p->x2)
  108.       {
  109.         add_collide(first,p->x2+1,max(y1,p->y1),x2,min(y2,p->y2),who);
  110.     ax2=p->x2;
  111.       } 
  112.       else
  113.     ax2=x2;
  114.  
  115.       if (y1<p->y1)
  116.       {       
  117.         add_collide(first,x1,y1,x2,p->y1-1,who);
  118.     ay1=p->y1;
  119.       } else 
  120.     ay1=y1;
  121.  
  122.       if (y2>p->y2)
  123.       {
  124.         add_collide(first,x1,p->y2+1,x2,y2,who);
  125.     ay2=p->y2;
  126.       } else 
  127.     ay2=y2;
  128.  
  129.        
  130.       add_collide(first,ax1,ay1,ax2,ay2,who);      
  131.  
  132.       return ;    
  133.     }
  134.  
  135.   }
  136.   
  137.   first=new collide_patch(x1,y1,x2,y2,first);
  138.   first->total=1;
  139.   first->touch=(game_object **)jmalloc(sizeof(game_object *)*1,"object_patch_list");
  140.   first->touch[0]=who;
  141. }
  142.  
  143.  
  144.  
  145.  
  146. void level::check_collisions()
  147. {
  148.   game_object *target,*rec,*subject;
  149.   collide_patch *f=NULL;
  150.   long sx1,sy1,sx2,sy2,tx1,ty1,tx2,ty2,hitx,hity,
  151.       s_centerx,t_centerx;
  152.  
  153.   for (int l=0;l<attack_total;l++)
  154.   {
  155.     subject=attack_list[l];
  156.     subject->picture_space(sx1,sy1,sx2,sy2);
  157.     rec=NULL;
  158.     
  159.  
  160.     for (int j=0;j<target_total && !rec;j++)
  161.     {
  162.       target=target_list[j];    
  163.       target->picture_space(tx1,ty1,tx2,ty2);
  164.       if (!(sx2<tx1 || sy2<ty1 || sx1>tx2 || sy1>ty2))  // check to see if picture spaces collide
  165.       {
  166.  
  167.     try_pushback(subject,target);
  168.  
  169.     if (subject->can_hurt(target))    // see if we can hurt him before calculating
  170.     {
  171.       t_centerx=target->x_center();
  172.       point_list *s_hit,*t_damage;
  173.       
  174.       s_hit=subject->current_figure()->hit;
  175.  
  176.       if (target->direction>0)
  177.         t_damage=target->current_figure()->f_damage;
  178.       else
  179.         t_damage=target->current_figure()->b_damage;
  180.  
  181.       unsigned char *s_dat=s_hit->data,*t_dat;
  182.       int i,j;
  183.       for (i=(int)s_hit->tot-1;i>0 && !rec;i--)
  184.       {
  185.         for (t_dat=t_damage->data,j=(int)t_damage->tot-1;j>0 && !rec;j--)
  186.         {
  187.           long x1,y1,x2,y2,          // define the two line segments to check
  188.           xp1,yp1,xp2,yp2;
  189.  
  190.           xp1=target->x+target->tx(*t_dat);  t_dat++;          
  191.           yp1=target->y+target->ty(*t_dat);  t_dat++;
  192.           xp2=target->x+target->tx(*t_dat); 
  193.           yp2=target->y+target->ty(t_dat[1]); 
  194.  
  195.           x1=subject->x+subject->tx(s_dat[0]);  
  196.           y1=subject->y+subject->ty(s_dat[1]); 
  197.           x2=subject->x+subject->tx(s_dat[2]); 
  198.           y2=subject->y+subject->ty(s_dat[3]); 
  199.           
  200.  
  201.           // ok, now we know which line segemnts to check for intersection
  202.           // now check to see if (x1,y1-x2,y2) intercest with (xp1,yp1-xp2,yp2)
  203.           int _x2=x2,_y2=y2;          
  204.           setback_intersect(x1, y1, x2, y2, xp1, yp1, xp2, yp2,0);
  205.  
  206.  
  207.           if (x2!=_x2 || _y2!=y2)
  208.           {
  209.         rec=target;
  210.         hitx=((x1+x2)/2+(xp1+xp2)/2)/2;
  211.         hity=((y1+y1)/2+(yp1+yp2)/2)/2;
  212.           }
  213.         }
  214.         s_dat+=2;
  215.       }        
  216.     }
  217.       }
  218.     }
  219.     if (rec)
  220.     {
  221.       rec->do_damage((int)subject->current_figure()->hit_damage,subject,hitx,hity,0,0);
  222.       subject->note_attack(rec);
  223.     }    
  224.   }
  225. }
  226.  
  227.