|
QuakeZone MOD Coding Tutorials
|
|
|
Introduction Code Notes Exercises |
|
| Introduction |
|
|
Seen the positron blaster in LOX? This tutorial applies the same sort of effect to rockets for deadly killing power. Note that this tutorial requires the Nuclear Rockets tutorial (or at least the relevant bits of) for implementing different rocket types. Thanks to the guys from jblabs for the positron
model from Lox.
|
| Code |
|
|
g_local.h Add the following define at the indicated place: #define MOD_TARGET_BLASTER 33 // <-- insert after this line #define MOD_POSITRON 34 // PJT - positron rockets g_weapon.c Add the following new procedure just before procedure rocket_think:
// PJT - positron rockets - explosion
void positron_explode (edict_t *self)
{
edict_t *ent;
float points;
vec3_t v;
float dist;
// comment out damage - done in touch function
// if (self->s.frame == 0) - do for all frames
{
// the positron effect
ent = NULL;
while ((ent = findradius(ent, self->s.origin, self->dmg_radius)) != NULL)
{
if (!ent->takedamage)
continue;
// let owner take damage
//if (ent == self->owner)
// continue;
if (!CanDamage (ent, self))
continue;
if (!CanDamage (ent, self->owner))
continue;
VectorAdd (ent->mins, ent->maxs, v);
VectorMA (ent->s.origin, 0.5, v, v);
VectorSubtract (self->s.origin, v, v);
dist = VectorLength(v);
points = self->radius_dmg * (1.0 - sqrt(dist/self->dmg_radius));
if (ent == self->owner)
points = points * 0.5;
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_ROCKET_EXPLOSION);
gi.WritePosition (ent->s.origin);
gi.multicast (ent->s.origin, MULTICAST_PHS);
T_Damage (ent, self, self->owner, self->velocity, ent->s.origin, vec3_origin, (int)points, 0, 0, MOD_POSITRON); // last 0 was DAMAGE_ENERGY
}
}
//*/
self->nextthink = level.time + FRAMETIME;
self->s.frame++;
self->dmg_radius = self->dmg_radius * 1.25;
if (self->s.frame == 16)
self->think = G_FreeEdict;
}
// PJT
Then add the following new procedure just after procedure rocket_think:
// PJT - positron rocket impact
void rocket_touch_positron (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
// if (other == self->owner) : allow impact on rocket firer!
// return;
if (surf && (surf->flags & SURF_SKY))
{
G_FreeEdict (self);
return;
}
if (self->owner->client)
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
// core explosion - prevents firing it into the wall/floor
if (other->takedamage)
T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, 200, 0, 0, MOD_BFG_BLAST);
T_RadiusDamage(self, self->owner, 200, other, 100, MOD_POSITRON);
gi.sound (self, CHAN_VOICE, gi.soundindex ("weapons/bfg__x1b.wav"), 1, ATTN_NORM, 0);
self->solid = SOLID_BBOX; // SOLID_NOT;
self->touch = NULL;
VectorMA (self->s.origin, -1 * FRAMETIME, self->velocity, self->s.origin);
VectorClear (self->velocity);
self->s.modelindex = gi.modelindex ("models/positron/tris.md2");
self->s.frame = 0;
self->s.sound = 0;
self->s.effects &= ~EF_ANIM_ALLFAST;
self->think = positron_explode;
self->nextthink = level.time + FRAMETIME;
self->enemy = other;
self->radius_dmg = 100;
self->dmg_radius = 10;
// self->touch = positron_touch;
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_ROCKET_EXPLOSION);
gi.WritePosition (self->s.origin);
gi.multicast (self->s.origin, MULTICAST_PVS);
}
// PJT
Then, in procedure fire_rocket, within the following code (amendment to that code added in the
Nuclear Rokcet tutorial) add the code for positron rockets as indicated:
rocket->owner = self; \\ <- Nuclear Rocket rocket types code inserted here
// PJT - determine rocket type
if (self->client)
{
rocket->touch = rocket_touch;
switch(self->client->pers.nuke_state)
{
case 0: // standard
rocket->touch = rocket_touch;
break;
case 1: // nukes
rocket->touch = rocket_touch_nuke;
rocket->s.renderfx = RF_SHELL_GREEN + RF_SHELL_BLUE + RF_SHELL_RED; // make nuke rockets white.
rocket->s.effects |= EF_COLOR_SHELL;
break;
case 2: // zylon gas (e.g.)
// insert Zylon gas code (e.g.) here
// ** <-- positron code starts here
case 3: // positron rockets
rocket->touch = rocket_touch_positron;
rocket->s.renderfx = RF_SHELL_RED; // make positron rockets red.
rocket->s.effects |= EF_COLOR_SHELL;
break;
// ** <-- positron code ends here
case 4: // PJT - earthquake rockets (e.g.)
// insert earthquake code (e.g.) here
}
}
else
rocket->touch = rocket_touch;
// PJT
p_weapon.c Insert the folloing code into procedure Rocket_Count as indicated (this procedure was created in the Nuclear Rockets tutorial): case 1: // nukes count = 20; break; // insert code from here case 2: // zylon gas count = 1; break; case 3: // positron rockets count = 10; break; case 4: // earthquake rockets count = 10; break; // end of insert g_cmds.c Replace procedure Cmd_Nukes_f, that was created with the Nuclear Rockets tutorial, with the following:
/*
=================
Cmd_Nukes_f
PJT: whole new function for switching rocket type
rewritten for zylon gas rockets
add new rocket types in here
=================
*/
void Cmd_Nukes_f (edict_t *ent)
{
int i;
// update pointer
i = ent->client->pers.nuke_state;
i++;
if (i>4) i = 0; \\ <-- alter for actual number of rocket types you use
ent->client->pers.nuke_state = i;
// any special handling for rocket types
// user display of selected rocket type now done in p_hud.c
switch (i)
{
case 0: // standard rockets
default:
break;
case 1: // nukes
gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0);
break;
case 2: // zylon gas (e.g.)
// insert any special code here
break;
case 3: // positron rockets - no special processing
break;
case 4: // earthquake rockets (e.g.)
// insert any special code here
break;
}
}
// PJT
model Extract the model for the positron explosion from the LOX Pak files, available from jblabs. Use a Pak file extracter such as QPED to extract the model files skin0.pcx and tris.md2 into a folder called models/positron within your game folder. p_client.c Add the following code to ClientObituary at the indicated positions: First:
case MOD_TARGET_BLASTER:
message = "got blasted";
break;
// PJT - positron rocket
case MOD_POSITRON:
message="had his atoms re-arranged";
break;
// PJT
then:
case MOD_HELD_GRENADE: message = "tried to put the pin back in"; break; // PJT - positron rockets case MOD_POSITRON: message = "could not avoid his own positron rocket"; break; // PJTand finally: case MOD_BLASTER: message = "was blasted by"; break; // PJT positron rockets case MOD_POSITRON: message = "did not see"; message2 = "'s positron rocket"; break; // PJT |
| Notes |
|
|
g_weapon.c
g_weapon.c
p_weapon.c
g_cmds.c
p_client.c
|
| Exercises |
|
|