Author: Mario[RIP]
Let's make quake2 more net-firendly !
Just replace the 'fire_blaster' function in g_weapon.c with this:
Here Is a break-down of what was happening before, compared to the new
code:
PREVIOUS HYPERBLASTER FIRING ONE ROUND:
I read an article on RUST about making CTF levels,
(http://www.planetquake.com/rust/style/ctfstyle.html) where they
commented that the hyperblaster should be put into CTF levels only
sparingly. It would be a tragedy if we had to start throwing away a
good gun because it was causing trouble for the 'bandwidth challenged'.
Like me and my 33.6kb modem.
Here are some netgraph testing results of two people doing a continuous
spray of fire from old version and new version while in same q2ctf5 flag
room.
Old Hyperblaster's netgraph:
Difficulty: Easy
The code is simple and strait forward. Since the hyperblaster is fired
at a very high speed, so we don't want to waste any of the server's CPU
cycles with a more complicated effect. We also want to use temp
entities instead of spawning full entities to reduce network traffic.
void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage,
int speed, int effect, qboolean hyper)
{
edict_t *bolt;
trace_t tr;
vec3_t from;
vec3_t end;
VectorNormalize (dir);
if(effect & EF_BLASTER)// if blaster, spawn blaster bolt
{
bolt = G_Spawn();
VectorCopy (start, bolt->s.origin);
VectorCopy (start, bolt->s.old_origin);
vectoangles (dir, bolt->s.angles);
VectorScale (dir, speed, bolt->velocity);
bolt->movetype = MOVETYPE_FLYMISSILE;
bolt->clipmask = MASK_SHOT;
bolt->solid = SOLID_BBOX;
bolt->s.effects |= effect;
VectorClear (bolt->mins);
VectorClear (bolt->maxs);
bolt->s.modelindex =
gi.modelindex("models/objects/laser/tris.md2");
bolt->s.sound = gi.soundindex("misc/lasfly.wav");
bolt->owner = self;
bolt->touch = blaster_touch;
bolt->nextthink = level.time + 2;
bolt->think = G_FreeEdict;
bolt->dmg = damage;
bolt->classname = "bolt";
gi.linkentity (bolt);
if (self->client)
check_dodge (self, bolt->s.origin, dir, speed);
tr = gi.trace (self->s.origin, NULL, NULL, bolt->s.origin, bolt,
MASK_SHOT);
if (tr.fraction < 1.0)
{
VectorMA (bolt->s.origin, -10, dir, bolt->s.origin);
bolt->touch (bolt, tr.ent, NULL, NULL);
}
}
else // laser hyperblaster
{
// set origin of laser beam at gun barrel.
// note that the barrel is rotating, so the beams will
// originate from different places each time.
VectorMA (start, 8192, dir, end);
VectorCopy (start, from);
// trace for end point of laser beam.
// the laser aim is perfect.
// no random aim like the machinegun
tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT);
// send laser beam temp entity to clients
VectorCopy (tr.endpos, from);
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BFG_LASER);
gi.WritePosition (start);
gi.WritePosition (tr.endpos);
gi.multicast (self->s.origin, MULTICAST_PHS);
if ((tr.ent != self) && (tr.ent->takedamage))
T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal,
damage, 0, 0, MOD_HYPERBLASTER);
else if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
{ // hit a brush, send clients
// a light flash and sparks temp entity.
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BLASTER);
gi.WritePosition (tr.endpos);
gi.WriteDir (tr.plane.normal);
gi.multicast (self->s.origin, MULTICAST_PVS);
}
}
}
LASER HYPERBLASTER FIRING ONE ROUND:
I wrote this for more reasons than just for grins. The hyperblaster, as
it was, was not very network friendly. It floods clients with info
about position changes for each 'bolt' entity through time. It is also
not good for the server. Remember The server has to do collision
testing for every solid entity you spawn.

New Laser Hyperblaster's netgraph:

Tutorial by Mario[RIP]
|
This site, and all content and graphics displayed on it, |