
|
Quake Style - Quake 2
Tutorials |
Thunderbolt Tutorial/instructions for Quake2.
Uses TE_LIGHTNING for the effect.
120% as good as the original (lacking the original view model of course)
Build Time: 5 mins for working code, off and on, 4 hours play testing with
friends=)
What you will need:
tut-ThunderBolt-Omega.zip
(you wont *NEED* this, but it helps. because its the graphics/sounds *I*
used/ripped
I wrote this whole thing in DOS Edit, and built it In LCC. (yes, as you've seen
by my other posts, i do use MSVC++ usually, but for this lcc is just damned
quicker.
Part 1: G_LOCAL.H
Find the MeansOfDeath defines, and add these.
//OM-LGUN#define MOD_TBOLT 34#define MOD_TBOLT_WATER 35#define MOD_TBOLT_DISCHARGE 36//OM-LGUN-END
Then scroll down to the prototypes for g_utils.c (just search for
"g_utils.c") and add at the end after vectoangles:
//OM-LGUNvoid vectoangles2 (vec3_t vec, vec3_t angles);//OM-LGUN-END
Now find the rest of the weapon defines and add:
//OM-LGUN#define WEAP_TBOLT 12 // or whatever your last free # is//OM-LGUN-END
Now jump to the *END* of the file, (best place for them) and add the following:
//OM-LGUN#define TBOLT_DAMAGE 20#define TBOLT_CELLS 1//OM-LGUN-END
Part 2: G_ITEMS.C
Add:
//OM-LGUNvoid Weapon_Thunderbolt (edict_t *ent);//OM-LGUN-END
after the BFG (or whatever your last weapon is)
Now add this item after the bfg, or somewhere in your itemlist[].
//OM-LGUN/*QUAKED weapon_thunderbolt (.3 .3 1) (-16 -16 -16) (16 16 16)*/ { "weapon_thunderbolt", Pickup_Weapon, Use_Weapon, Drop_Weapon, Weapon_Thunderbolt, "misc/w_pkup.wav", "models/weapons/g_hyperb/tris.md2", EF_ROTATE, "models/weapons/v_hyperb/tris.md2", "w_tbolt", "Thunderbolt", 0, TBOLT_CELLS, "Cells", IT_WEAPON|IT_STAY_COOP, WEAP_TBOLT, NULL, 0, "weapons/tesla.wav weapons/lstart.wav models/proj/lightning/tris.md2" },//OM-LGUN-END
Part 3: G_UTILS.C
Paste the following two functions in. (replace the old vectoangles function)
//OM-LGUN//NEW vectoangles plus vectoangles2, from rogue source )fixes a bug and adds//something new. void vectoangles (vec3_t value1, vec3_t angles){ float forward; float yaw, pitch; if (value1[1] == 0 && value1[0] == 0) { yaw = 0; if (value1[2] > 0) pitch = 90; else pitch = 270; } else { // PMM - fixed to correct for pitch of 0 if (value1[0]) yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); else if (value1[1] > 0) yaw = 90; else yaw = 270; if (yaw < 0) yaw += 360; forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); pitch = (int) (atan2(value1[2], forward) * 180 / M_PI); if (pitch < 0) pitch += 360; } angles[PITCH] = -pitch; angles[YAW] = yaw; angles[ROLL] = 0;} void vectoangles2 (vec3_t value1, vec3_t angles){ float forward; float yaw, pitch; if (value1[1] == 0 && value1[0] == 0) { yaw = 0; if (value1[2] > 0) pitch = 90; else pitch = 270; } else { // PMM - fixed to correct for pitch of 0 if (value1[0]) yaw = (atan2(value1[1], value1[0]) * 180 / M_PI); else if (value1[1] > 0) yaw = 90; else yaw = 270; if (yaw < 0) yaw += 360; forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); pitch = (atan2(value1[2], forward) * 180 / M_PI); if (pitch < 0) pitch += 360; } angles[PITCH] = -pitch; angles[YAW] = yaw; angles[ROLL] = 0;}
Part 4: G_WEAPON.C
Add the following code at the end:
//OM-LGUNvoid fire_lightning (edict_t *self, vec3_t start, vec3_t aimdir, int damage){ vec3_t from; vec3_t end; vec3_t dir; vec3_t forward, right, up; trace_t tr; int mask; edict_t *tmpobj; vectoangles2 (aimdir, dir); AngleVectors (dir, forward, right, up); VectorMA (start, 8192, forward, end); mask = MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_WATER; tr = gi.trace (start, NULL, NULL, end, self, mask); if (tr.contents & (CONTENTS_SLIME|CONTENTS_LAVA|CONTENTS_WATER)) { tmpobj = G_Spawn(); VectorCopy (tr.endpos, tmpobj->s.origin); tmpobj->movetype = MOVETYPE_NONE; tmpobj->solid = SOLID_NOT; tmpobj->classname = "tmpobject"; tmpobj->s.modelindex = 0; tmpobj->nextthink = level.time + 0.01; tmpobj->think = G_FreeEdict; gi.linkentity (tmpobj); T_RadiusDamage(tmpobj, self, damage*2, NULL, damage*4, MOD_TBOLT_WATER); } else { if ((tr.ent != self) && (tr.ent->takedamage)) T_Damage (tr.ent, self, self, aimdir, tr.endpos, tr.plane.normal, damage, damage, 0, MOD_TBOLT); } // make the lightning bolt from the gun to the wall. (cute huh?) gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_LIGHTNING); gi.WriteShort (tr.ent - g_edicts); gi.WriteShort (self - g_edicts); gi.WritePosition (tr.endpos); gi.WritePosition (start); gi.multicast (start, MULTICAST_PVS); // spawn some sparks at the destination (go sparky go!) gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_WELDING_SPARKS); gi.WriteByte (15); gi.WritePosition (tr.endpos); gi.WriteDir (vec3_origin); gi.WriteByte (0xB2 + (rand()&3)); gi.multicast (tr.endpos, MULTICAST_PVS); if (self->client) PlayerNoise(self, tr.endpos, PNOISE_IMPACT);}//OM-LGUN-END
Part 5: P_WEAPON.C
**paste the following code at the end of the file. (easy shiz eh?)
//OM-LGUNvoid Weapon_Thunderbolt_Fire (edict_t *ent){ vec3_t offset, start; vec3_t forward, right; int ammo; int damage; int toasty; if (!(ent->client->buttons & BUTTON_ATTACK)) { ent->client->ps.gunframe++; } else { if (! ent->client->pers.inventory[ent->client->ammo_index] ) { if (level.time >= ent->pain_debounce_time) { gi.sound(ent, CHAN_VOICE, gi.soundindex("weapons/noammo.wav"), 1, ATTN_NORM, 0); ent->pain_debounce_time = level.time + 1; } NoAmmoWeaponChange (ent); } else { damage = TBOLT_DAMAGE; if (is_quad) { toasty = 8000; damage *= 4; } else toasty = 2000; if (ent->client->ps.gunframe == 6) // if its starting. do the initial bolt sound gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/lfire.wav"), 1, ATTN_NORM, 0); gi.sound(ent, CHAN_AUTO, gi.soundindex("weapons/tesla.wav"), .5, ATTN_NORM, 0); if (ent->waterlevel == 3) //ZZZZZZZZZAAAAAAAAAAAAAAAPPPPPPP!!!!!! { ent->client->pers.inventory[ent->client->ammo_index] = 0; T_RadiusDamage(ent, ent, toasty, NULL, toasty, MOD_TBOLT_DISCHARGE); return; } AngleVectors (ent->client->v_angle, forward, right, NULL); VectorScale (forward, -2, ent->client->kick_origin); VectorSet(offset, 8, 8, ent->viewheight - 8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); fire_lightning (ent, start, forward, damage); PlayerNoise(ent, start, PNOISE_WEAPON); if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ent->client->ammo_index] -= TBOLT_CELLS; } } ent->client->ps.gunframe++; if (ent->client->ps.gunframe == 12 && ent->client->pers.inventory[ent->client->ammo_index]) ent->client->ps.gunframe = 7;} void Weapon_Thunderbolt (edict_t *ent){ static int pause_frames[] = {0}; static int fire_frames[] = {6, 7, 8, 9, 10, 11}; Weapon_Generic (ent, 5, 20, 49, 53, pause_frames, fire_frames, Weapon_Thunderbolt_Fire);}//OM-LGUN-END
Part 6: G_CLIENT.C
Now find the obituaries, and add these reqpectively:
Under if attacker = self ...
//OM-LGUN case MOD_TBOLT_DISCHARGE: message = "made a shocking mistake"; break; case MOD_TBOLT_WATER: message = "feels the tingle from the electrified liquid"; break;
Under if attacker && attacker->client ...
//OM-LGUN case MOD_TBOLT: message = "accepts"; message2 = "'s shaft"; break; case MOD_TBOLT_WATER: message = "feels the tingle from"; message2 = "'s water shock"; break; case MOD_TBOLT_DISCHARGE: message = "suffers the extreme pain of"; message2 = "'s suicidal discharge"; break; //OM-LGUN-END
Part 7: Rebuild
Surely that isn't too hard..
Part 8: Play. Frag. Kill. Fry. Shock. You know!
That should be about it.
If you have any questions, e-mail me.
Editor (nobody)'s note:
You will either have to give this weapon to the player when they spawn, or type
"give Thunderbolt" at the console when you are playing
singleplayer/cheats are enabled.
--
Credits:
Tutorial by Omega
Maelstrom
QS Tutorials
--
Important:
If you do use something from QuakeStyle in your mod, please give
us credit.
Our code is copyrighted, but we give permission to everyone to use
it in any way they see fit, as long as we are recognized.