📄 robot.cpp
字号:
#include "game.h"
void robot::init()
{
if (objmesh)
pos=objmesh->pivotpos;
}
void robot::draw()
{
active=2;
if (objmesh==0 || shieldmesh==0)
return;
if (node)
{
objmesh->color=node->color+dynlight;
dynlight.null();
}
shieldmesh->scrollu=shieldmesh->scrollv=(flyengine->cur_time%750)/750.0f;
glPushMatrix();
glTranslatef(pos.x,pos.y,pos.z);
glMultMatrixf((float *)&mat);
objmesh->draw();
if (flyengine->cur_time-lasthittime<500)
{
shieldmesh->color=shieldcolor*shieldmesh->color.w;
shieldmesh->color.w=1.0f-(flyengine->cur_time-lasthittime)/500.0f;
glDepthMask(GL_FALSE);
glBlendFunc(GL_ONE, GL_ONE);
shieldmesh->draw();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_TRUE);
}
glPopMatrix();
}
void robot_find(void *data,bsp_object *e)
{
robot *r=(robot *)data;
if (e->type==TYPE_SHIP)
{
if (((ship *)e)->flag2 ||
(((ship *)e)->flag3&SHIP_FLAG3_INVISIBLE))
return;
vector dir=r->pos-e->pos;
float dist=dir.length();
if (dist<r->enemydist)
{
dir/=dist;
if (vec_dot(dir,r->Z)<r->lookangle)
return;
flyengine->excludecollision=e;
if (flyengine->collision_test(flyengine->bsp,r->pos,e->pos,TYPE_STATIC_MESH,r->radius))
{
flyengine->excludecollision=0;
return;
}
flyengine->excludecollision=0;
r->enemy=e;
r->enemydist=dist;
}
}
}
int robot::step(int dt)
{
if (active!=2)
return 0;
flyengine->stepobj=0;
if (shield<0)
{
life=-1;
if (exp)
exp->do_explode(pos,Z,-1);
return 0;
}
vector dir;
float dist;
// if enemy, test if enemy is still visible or is dead
if (enemy)
{
flyengine->excludecollision=enemy;
if (((ship *)enemy)->flag2 ||
(((ship *)enemy)->flag3&SHIP_FLAG3_INVISIBLE) ||
flyengine->collision_test(flyengine->bsp,pos,enemy->pos,TYPE_STATIC_MESH,radius))
{
flag=((ship *)enemy)->flag2?0:2;
enemy=0;
}
flyengine->excludecollision=0;
}
// if no enemy, look around for a possible enemys
if (enemy==0)
{
enemydist=lookrange;
flyengine->apply_bsp(flyengine->bsp,pos,lookrange,this,robot_find);
}
if (enemy)
{
enemylastpos=enemy->pos;
dir=pos-enemylastpos;
dist=dir.length();
dir/=dist;
rotate(Z,dir,rotvel*dt); // try to face enemy
rotate(Y,vector(0,0,1),rotvel*(dt>>2)); // try to align with floor
// if in gun range, fire
if (g && vec_dot(dir,Z)>fireang)
if (g->fire_status())
g->fire(this,-1);
// if not too close, move behind the enemy
if (dist>mindist)
{
flag=1; // moving
enemylastpos+=enemy->Z*mindist;
}
else flag=0; // stay still
}
if (flag) // if moving, move in direction of enemylastpos
{
dir=enemylastpos-pos;
dist=dir.length();
if (dist<0.1f)
flag=0;
else
{
vel=dir*(maxvel/dist);
flyengine->stepobj=this;
particle::step(dt);
force.null();
life=1;
}
}
return 1;
}
int robot::get_custom_param_desc(int i,param_desc *pd)
{
if (pd==0)
return 12;
else
switch(i)
{
case 0:
pd->type='3';
pd->data=&objmesh;
strcpy(pd->name,"objmesh");
break;
case 1:
pd->type='3';
pd->data=&shieldmesh;
strcpy(pd->name,"shieldmesh");
break;
case 2:
pd->type=TYPE_GUN;
pd->data=&g;
strcpy(pd->name,"gun");
break;
case 3:
pd->type='f';
pd->data=&lookrange;
strcpy(pd->name,"lookrange");
break;
case 4:
pd->type='a';
pd->data=&lookangle;
strcpy(pd->name,"lookangle");
break;
case 5:
pd->type='a';
pd->data=&fireang;
strcpy(pd->name,"fireang");
break;
case 6:
pd->type='f';
pd->data=&maxvel;
strcpy(pd->name,"maxvel");
break;
case 7:
pd->type='f';
pd->data=&rotvel;
strcpy(pd->name,"rotvel");
break;
case 8:
pd->type='f';
pd->data=&mindist;
strcpy(pd->name,"mindist");
break;
case 9:
pd->type='f';
pd->data=&shield;
strcpy(pd->name,"shield");
break;
case 10:
pd->type='c';
pd->data=&shieldcolor;
strcpy(pd->name,"shieldcolor");
break;
case 11:
pd->type=TYPE_EXPLODE;
pd->data=&exp;
strcpy(pd->name,"explode");
break;
}
return 0;
}
int robot::message(vector& p,float rad,int msg,int param,void *data)
{
if (msg==FLYOBJM_DAMAGE)
{
vector v=pos-p;
float len=v.length();
if (len>rad || len<SMALL)
return 0;
flyengine->excludecollision=this;
if(flyengine->collision_test(flyengine->bsp, p, pos))
{
flyengine->excludecollision=0;
return 0;
}
flyengine->excludecollision=0;
shield-=*((float *)data)*(1.0f-len/rad);
lasthittime=flyengine->cur_time;
if (param>=0)
enemy=(bsp_object *)directx->players[param].data;
}
else
if (msg==FLYOBJM_ILLUM)
{
float fac=(p-pos).length()/rad;
if (fac<1.0f)
dynlight+=*((vector *)data)*(1.0f-fac);
}
return 0;
}
mesh *robot::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,int &facenum,float rad)
{
if (shieldmesh)
{
static float d1,d2;
vector
ro_local=(ro-pos)*mat_t,
rd_local=rd*mat_t;
if (shieldmesh->bbox.ray_intersect(ro_local,rd_local,d1,d2))
{
facenum=shieldmesh->ray_intersect(ro_local,rd_local,ip,dist,rad);
if (facenum>-1)
{
if (flyengine->stepobj &&
(flyengine->stepobj->type==TYPE_LASER || flyengine->stepobj->type==TYPE_MISSILE)
&& dist<1.0f && ((gun_projectile *)flyengine->stepobj)->damage>0.0f)
{
shield-=((gun_projectile *)flyengine->stepobj)->damage;
lasthittime=flyengine->cur_time;
if (((gun_projectile *)flyengine->stepobj)->player>=0)
enemy=(bsp_object *)directx->players[((gun_projectile *)flyengine->stepobj)->player].data;
}
ip=ip*mat+pos;
return shieldmesh;
}
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -