/* ================================================================ 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; }