home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / plugin / ship / robot.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-10  |  5.8 KB  |  281 lines

  1. #include "game.h"
  2.  
  3. void robot::init()
  4. {
  5.     if (objmesh)
  6.         pos=objmesh->pivotpos;
  7. }
  8.  
  9. void robot::draw()
  10. {
  11.     active=2;
  12.     if (objmesh==0 || shieldmesh==0) 
  13.         return;
  14.     if (node)
  15.         {
  16.         objmesh->color=node->color+dynlight;
  17.         dynlight.null();
  18.         }
  19.     shieldmesh->scrollu=shieldmesh->scrollv=(flyengine->cur_time%750)/750.0f;
  20.     glPushMatrix();
  21.     glTranslatef(pos.x,pos.y,pos.z);
  22.     glMultMatrixf((float *)&mat);
  23.     objmesh->draw();
  24.     if (flyengine->cur_time-lasthittime<500)
  25.         {
  26.         shieldmesh->color=shieldcolor*shieldmesh->color.w;
  27.         shieldmesh->color.w=1.0f-(flyengine->cur_time-lasthittime)/500.0f;
  28.         glDepthMask(GL_FALSE);
  29.         glBlendFunc(GL_ONE, GL_ONE);
  30.         shieldmesh->draw();
  31.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  32.         glDepthMask(GL_TRUE);
  33.         }
  34.     glPopMatrix();
  35. }
  36.  
  37. void robot_find(void *data,bsp_object *e)
  38. {
  39.     robot *r=(robot *)data;
  40.     if (e->type==TYPE_SHIP)
  41.         {
  42.         if (((ship *)e)->flag2 ||
  43.             (((ship *)e)->flag3&SHIP_FLAG3_INVISIBLE))
  44.             return;
  45.  
  46.         vector dir=r->pos-e->pos;
  47.         float dist=dir.length();
  48.         if (dist<r->enemydist)
  49.             {
  50.             dir/=dist;
  51.             if (vec_dot(dir,r->Z)<r->lookangle)
  52.                 return;
  53.             flyengine->excludecollision=e;
  54.             if (flyengine->collision_test(flyengine->bsp,r->pos,e->pos,TYPE_STATIC_MESH,r->radius))
  55.                 {
  56.                 flyengine->excludecollision=0;
  57.                 return;
  58.                 }
  59.             flyengine->excludecollision=0;
  60.             r->enemy=e;
  61.             r->enemydist=dist;
  62.             }
  63.         }
  64. }
  65.  
  66. int robot::step(int dt)
  67. {
  68.     if (active!=2) 
  69.         return 0;
  70.     
  71.     flyengine->stepobj=0;
  72.     
  73.     if (shield<0)
  74.     {
  75.         life=-1;
  76.         if (exp)
  77.             exp->do_explode(pos,Z,-1);
  78.         return 0;
  79.     }
  80.  
  81.     vector dir;
  82.     float dist;
  83.  
  84.     // if enemy, test if enemy is still visible or is dead
  85.     if (enemy)
  86.     {
  87.         flyengine->excludecollision=enemy;
  88.         if (((ship *)enemy)->flag2 ||
  89.             (((ship *)enemy)->flag3&SHIP_FLAG3_INVISIBLE) ||
  90.             flyengine->collision_test(flyengine->bsp,pos,enemy->pos,TYPE_STATIC_MESH,radius))
  91.             {
  92.             flag=((ship *)enemy)->flag2?0:2; 
  93.             enemy=0;
  94.             }
  95.         flyengine->excludecollision=0;
  96.     }
  97.     
  98.     // if no enemy, look around for a possible enemys
  99.     if (enemy==0) 
  100.         {
  101.         enemydist=lookrange;
  102.         flyengine->apply_bsp(flyengine->bsp,pos,lookrange,this,robot_find);
  103.         }
  104.  
  105.     if (enemy)
  106.     {
  107.         enemylastpos=enemy->pos;
  108.         dir=pos-enemylastpos;
  109.         dist=dir.length();
  110.         dir/=dist;
  111.         
  112.         rotate(Z,dir,rotvel*dt); // try to face enemy
  113.         rotate(Y,vector(0,0,1),rotvel*(dt>>2)); // try to align with floor
  114.  
  115.         // if in gun range, fire
  116.         if (g && vec_dot(dir,Z)>fireang)
  117.             if (g->fire_status())
  118.                 g->fire(this,-1);
  119.  
  120.         // if not too close, move behind the enemy
  121.         if (dist>mindist)
  122.             {
  123.             flag=1; // moving
  124.             enemylastpos+=enemy->Z*mindist;
  125.             }
  126.         else flag=0; // stay still
  127.     }
  128.  
  129.     if (flag) // if moving, move in direction of enemylastpos
  130.         {
  131.         dir=enemylastpos-pos;
  132.         dist=dir.length();
  133.         if (dist<0.1f)
  134.             flag=0;
  135.         else 
  136.             {
  137.             vel=dir*(maxvel/dist);
  138.             flyengine->stepobj=this;
  139.             particle::step(dt);
  140.             force.null();
  141.             life=1;
  142.             }
  143.         }
  144.  
  145.     return 1;
  146. }
  147.  
  148. int robot::get_custom_param_desc(int i,param_desc *pd)
  149. {
  150.     if (pd==0)
  151.         return 12;
  152.     else 
  153.     switch(i)
  154.     {
  155.         case 0:
  156.             pd->type='3';
  157.             pd->data=&objmesh;
  158.             strcpy(pd->name,"objmesh");
  159.             break;
  160.         case 1:
  161.             pd->type='3';
  162.             pd->data=&shieldmesh;
  163.             strcpy(pd->name,"shieldmesh");
  164.             break;
  165.         case 2:
  166.             pd->type=TYPE_GUN;
  167.             pd->data=&g;
  168.             strcpy(pd->name,"gun");
  169.             break;
  170.         case 3:
  171.             pd->type='f';
  172.             pd->data=&lookrange;
  173.             strcpy(pd->name,"lookrange");
  174.             break;
  175.         case 4:
  176.             pd->type='a';
  177.             pd->data=&lookangle;
  178.             strcpy(pd->name,"lookangle");
  179.             break;
  180.         case 5:
  181.             pd->type='a';
  182.             pd->data=&fireang;
  183.             strcpy(pd->name,"fireang");
  184.             break;
  185.         case 6:
  186.             pd->type='f';
  187.             pd->data=&maxvel;
  188.             strcpy(pd->name,"maxvel");
  189.             break;
  190.         case 7:
  191.             pd->type='f';
  192.             pd->data=&rotvel;
  193.             strcpy(pd->name,"rotvel");
  194.             break;
  195.         case 8:
  196.             pd->type='f';
  197.             pd->data=&mindist;
  198.             strcpy(pd->name,"mindist");
  199.             break;
  200.         case 9:
  201.             pd->type='f';
  202.             pd->data=&shield;
  203.             strcpy(pd->name,"shield");
  204.             break;
  205.         case 10:
  206.             pd->type='c';
  207.             pd->data=&shieldcolor;
  208.             strcpy(pd->name,"shieldcolor");
  209.             break;
  210.         case 11:
  211.             pd->type=TYPE_EXPLODE;
  212.             pd->data=&exp;
  213.             strcpy(pd->name,"explode");
  214.             break;
  215.     }
  216.     return 0;
  217. }
  218.  
  219. int robot::message(vector& p,float rad,int msg,int param,void *data)
  220. {
  221.     if (msg==FLYOBJM_DAMAGE)
  222.     {
  223.         vector v=pos-p;
  224.         float len=v.length();
  225.         if (len>rad || len<SMALL)
  226.             return 0;
  227.  
  228.         flyengine->excludecollision=this;
  229.         if(flyengine->collision_test(flyengine->bsp, p, pos))
  230.         {
  231.             flyengine->excludecollision=0;
  232.             return 0;
  233.         }
  234.         flyengine->excludecollision=0;
  235.  
  236.         shield-=*((float *)data)*(1.0f-len/rad);
  237.         lasthittime=flyengine->cur_time;
  238.         if (param>=0) 
  239.             enemy=(bsp_object *)directx->players[param].data;
  240.     }
  241.     else
  242.     if (msg==FLYOBJM_ILLUM)
  243.     {
  244.         float fac=(p-pos).length()/rad;
  245.         if (fac<1.0f)
  246.             dynlight+=*((vector *)data)*(1.0f-fac);
  247.     }
  248.  
  249.     return 0;
  250. }
  251.  
  252. mesh *robot::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,int &facenum,float rad)
  253. {
  254.     if (shieldmesh)
  255.     {
  256.         static float d1,d2;
  257.         vector 
  258.             ro_local=(ro-pos)*mat_t,
  259.             rd_local=rd*mat_t;
  260.         if (shieldmesh->bbox.ray_intersect(ro_local,rd_local,d1,d2))
  261.         {
  262.         facenum=shieldmesh->ray_intersect(ro_local,rd_local,ip,dist,rad);
  263.         if (facenum>-1)
  264.             {
  265.             if (flyengine->stepobj && 
  266.                 (flyengine->stepobj->type==TYPE_LASER || flyengine->stepobj->type==TYPE_MISSILE) 
  267.                 && dist<1.0f && ((gun_projectile *)flyengine->stepobj)->damage>0.0f)
  268.                 {
  269.                 shield-=((gun_projectile *)flyengine->stepobj)->damage;
  270.                 lasthittime=flyengine->cur_time;
  271.                 if (((gun_projectile *)flyengine->stepobj)->player>=0) 
  272.                     enemy=(bsp_object *)directx->players[((gun_projectile *)flyengine->stepobj)->player].data;
  273.                 }
  274.             ip=ip*mat+pos;
  275.             return shieldmesh;
  276.             }
  277.         }
  278.     }
  279.     return 0;
  280. }
  281.