307 lines
6.3 KiB
C++
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;
|
|
}
|