sin-2015/informergun.cpp
1999-04-22 00:00:00 +00:00

307 lines
6.3 KiB
C++

/*
================================================================
INFORMER GUN
================================================================
Copyright (C) 1998 by 2015, Inc.
All rights reserved.
This source is may not be distributed and/or modified without
expressly written permission by 2015, Inc.
*/
#include "informergun.h"
#include "worldspawn.h"
#include "specialfx.h"
CLASS_DECLARATION(Beam, InformerBeam, NULL);
Event EV_InformerBeam_FadeBeam("fadebeam");
ResponseDef InformerBeam::Responses[] =
{
{ &EV_InformerBeam_FadeBeam, ( Response )InformerBeam::FadeBeam },
{ NULL, NULL }
};
InformerBeam::InformerBeam()
{
hideModel();
edict->s.frame = 0;
edict->s.skinnum = 0;
setMoveType( MOVETYPE_NONE );
setSolidType( SOLID_NOT );
edict->s.renderfx |= RF_BEAM;
edict->s.modelindex = 1; // must be non-zero
}
void InformerBeam::setBeam
(
Vector startpos,
Vector endpos,
int diameter,
float r,
float g,
float b,
float alpha,
float lifespan
)
{
showModel();
if ( lifespan )
{
PostEvent( EV_Remove, lifespan );
}
start = startpos;
end = endpos;
setOrigin( start );
edict->s.old_origin[ 0 ] = end[ 0 ];
edict->s.old_origin[ 1 ] = end[ 1 ];
edict->s.old_origin[ 2 ] = end[ 2 ];
edict->s.frame = diameter;
edict->s.skinnum = 255;
edict->s.color_r = r;
edict->s.color_g = g;
edict->s.color_b = b;
edict->s.alpha = alpha;
link();
}
void InformerBeam::FadeBeam(Event *ev)
{
Vector beamvec, newstart, newend;
float newalpha;
edict->s.renderfx |= RF_TRANSLUCENT;
beamvec = end - start;
switch(beamstate)
{
case 1:
newalpha = 0.3;
newstart = start;
newend = start + beamvec*0.5;
break;
case 2:
newalpha = 0.25;
newstart = start + beamvec*0.25;
newend = start + beamvec*0.75;
break;
case 3:
newalpha = 0.2;
newstart = start + beamvec*0.5;
newend = start + beamvec;
break;
default:
PostEvent(EV_Remove, 0);
return;
break;
}
beamstate++;
setOrigin(newstart);
edict->s.old_origin[0] = newend[0];
edict->s.old_origin[1] = newend[1];
edict->s.old_origin[2] = newend[2];
edict->s.frame = 2;
edict->s.skinnum = 255;
edict->s.color_r = 0.3;
edict->s.color_g = 0.3;
edict->s.color_b = 1;
edict->s.alpha = newalpha;
link();
PostEvent(EV_InformerBeam_FadeBeam, 0.1);
}
//========================================================
CLASS_DECLARATION( Weapon, InformerGun, NULL );
ResponseDef InformerGun::Responses[] =
{
{ &EV_Weapon_Shoot, ( Response )InformerGun::Shoot },
{ NULL, NULL }
};
InformerGun::InformerGun()
{
SetModels( "informergun.def", "view_informergun.def" );
SetAmmo(NULL, 0, 0);
SetRank( 0, 0 );
SetType( WEAPON_2HANDED_LO );
}
void InformerGun::Informify(Entity *ent)
{
char userinfo[MAX_INFO_STRING];
int i;
edict_t *tmpent;
// first make owner not the informer
owner->client->resp.informer = false;
// correct the owner's model and skin
memcpy(userinfo, owner->client->pers.userinfo, sizeof(userinfo));
G_ClientUserinfoChanged(owner->edict, userinfo);
// now make our victim into the informer
ent->client->resp.informer = true;
// correct the victim's model and skin
memcpy(userinfo, ent->client->pers.userinfo, sizeof(userinfo));
G_ClientUserinfoChanged(ent->edict, userinfo);
// make the "I'm the informer" effects
ent->sound("environment/levelsnds/druglab/ping-sound.wav", 0.75, CHAN_BODY, ATTN_IDLE);
SpawnTeleportEffect(ent->centroid, 165);
// broadcast a messages about who the new informer is
for(i = 1; i <= maxclients->value; i++)
{
if(!g_edicts[i].inuse)
{
continue;
}
tmpent = &g_edicts[i];
if(tmpent == ent->edict)
gi.centerprintf(tmpent, "jcx yv -80 boxtext \"You are the Informer!\"");
else
gi.centerprintf(tmpent, "jcx yv -80 string \"%s is the Informer!\"", ent->client->pers.netname);
}
}
void InformerGun::Shoot (Event *ev)
{
Vector pos;
Vector dir;
Vector end;
trace_t trace;
InformerBeam *beam;
Vector right, up;
int mask;
assert( owner );
if ( !owner )
{
return;
}
NextAttack( 0.8 );
GetMuzzlePosition( &pos, &dir, &right, &up);
pos -= up*4;
if(!fadingbeam)
{
beam = new InformerBeam;
fadingbeam = beam;
}
else
{
beam = (InformerBeam *)fadingbeam.Ptr();
}
beamstate = 1;
mask = MASK_PROJECTILE;
mask &= ~CONTENTS_FENCE;
end = pos + dir*8192;
trace = G_Trace(pos, vec_zero, vec_zero, end, owner, mask, "InformerGun::Shoot");
beamstart = pos;
beamvec = Vector(trace.endpos) - pos;
if(trace.ent)
{
Entity *ent;
ent = trace.ent->entity;
if(ent->isClient() && !ent->deadflag)
{
// informify the poor bastard
Informify(ent);
}
else
{
ent->Damage(owner, owner, 15 + G_Random(5), Vector(trace.endpos), dir, vec_zero, 0, 0, 0, -1, -1, 0);
}
}
else
{
trace = G_Trace(pos, Vector(-4, -4, -4), Vector(4, 4, 4), end, owner, mask, "InformerGun::Shoot");
beamstart = pos;
beamvec = Vector(trace.endpos) - pos;
if(trace.ent)
{
Entity *ent;
ent = trace.ent->entity;
if(ent->isClient() && !ent->deadflag)
{
// informify the poor bastard
Informify(ent);
}
else
{
ent->Damage(owner, owner, 15 + G_Random(5), Vector(trace.endpos), dir, vec_zero, 0, 0, 0, -1, -1, 0);
}
}
else
{
trace = G_Trace(pos, Vector(-8, -8, -8), Vector(8, 8, 8), end, owner, mask, "InformerGun::Shoot");
beamstart = pos;
beamvec = Vector(trace.endpos) - pos;
if(trace.ent)
{
Entity *ent;
ent = trace.ent->entity;
if(ent->isClient() && !ent->deadflag)
{
// informify the poor bastard
Informify(ent);
}
else
{
ent->Damage(owner, owner, 15 + G_Random(5), Vector(trace.endpos), dir, vec_zero, 0, 0, 0, -1, -1, 0);
}
}
}
}
pos = beamstart + beamvec;
beam->setBeam(beamstart, pos, 4, 0.5, 0.5, 1, 0.5, 0.5);
beam->beamstate = 1;
beam->CancelEventsOfType(EV_InformerBeam_FadeBeam);
beam->PostEvent(EV_InformerBeam_FadeBeam, 0.1);
}
qboolean InformerGun::AutoChange (void)
{
return false;
}
// Don't drop informerguns
qboolean InformerGun::Drop (void)
{
return false;
}
qboolean InformerGun::ReadyToChange (void)
{
return false;
}