|
posted 11-24-98 9:43 PM CT (US)
Title: Power Laser Fence
Difficulty: Moderate
By: Philip (aka Maj.Bitch)
Email: peblair@gv.net
Date: 11-24-98
Note: Please give credit where credit is due.
======================================================
I put this tutorial
together because I was experimenting with the laser stuff to see if I could
do some things and I thought that a fence would be neat so, this kind of
popped out..
What is it:
The weapons
designers back at Space Marine Weapons Research had decided that we were
losing too many recruits getting trapped down narrow hallways, corridors,
caves, and the like by badguys who'd follow them into these passageways and
mine it or blast'em. So, we had to come up with a portable fence which can be
erected in seconds and will protect our recruit's asses whenever they feel the
need to cover their asses!! So, now, each marine can pull out of their
backpack their Power Laser Fence! Toss it out in front of them, watch it set
itself up, and in an instant they're backside is protected!
For the cost of 20
powercells (these laser fences take power), you hit your aliased key and 50
units in front of you comes a fence post to the left and a fence post to the
right (in green) and connected between these two posts are 4 red laser rails,
with the a shower of red sparks coming off the tops of each of the two fence
posts! Cool effects!! Check it out for yourself!
The maximum length
of a single fence is 120 units (about 2 lengths of a player) and is enougth
to cross most hallways and passageways. You face in the direction that you
want the fence to cover, for instance, if you want the fence to go across a
hallway, then you face down the hallway and hit your aliased key. The fence
energizes so quickly that the entire thing literally snaps into existance
(with the associated laser humming noises).. The fence posts themselves will
not spawn in solids so their built in computers will make every attempt to
position themselves properly and adjust their dimensions (if you've made a
mistake in setting up the fence)! The power in the fence lasts for 60 seconds
for your 20 cells. After that time, the fence powers itself down quietly. You
can spawn as many as you like as long as you've got the extra cells! Each
laser rail beam (including the posts) causes damage. If someone runs into the
entire fence then they get damage from each of the laser rail and they'll
literally explode! You get all the frags caused by the fence.
You can be killed by your own fence so be careful!!
DEVELOPERS:
I've include #define's for all the known laser colors so feel free to change
the color of the fence posts and the laser rails to whatever you feel is more
appropriate for your mod..
GREAT for blocking
access to power armor, BFG, and other critical items that the other players
are gonna want a bad way.
GREAT for putting
across a narrow passageway or hallway (right around a corner) so that someone
running down the hallway and turning the corner quickly will be sliced and
diced!!
Okay, let's get
started..
============================================================
============================================================
Open up your
g_cmds.c file and go near the bottom of your ClientCommand() function and add
the following as shown by example..
---------- IF-ELSE
STATEMENTS --------
else if (Q_stricmp(cmd, "decoy") == 0 )
SP_Decoy(ent);
else if (Q_stricmp(cmd, "drone") == 0 )
Cmd_LaserDrone_f(ent);
else if (Q_stricmp(cmd, "teleport") == 0)
Cmd_Teleport_f(ent);
----------- ADD THESE LINES ------
else if (Q_stricmp(cmd, "fence") == 0)
Cmd_LaserFence_f(ent);
else if .....
This will spawn your
LaserFence with a single stroke of the player's aliased key (providing
they've got the powercells!).
============================================================
Also, near the top of you g_cmds.c file add this forward
declaration:
void Cmd_LaserFence_f(edict_t
*ent);
============================================================
Lets open you g_target.c file and all all this to the bottom.
NOTE: YOU MAY
ALREADY HAVE THE HELPER FILES!
-------------------
START HERE -----------------------
//======================================================
void G_Spawn_Splash(int type, int count, int color, vec3_t start, vec3_t
movdir, vec3_t origin ) {
gi.WriteByte(svc_temp_entity);
gi.WriteByte(type);
gi.WriteByte(count);
gi.WritePosition(start);
gi.WriteDir(movdir);
gi.WriteByte(color);
gi.multicast(origin, MULTICAST_PVS);
}
//=======================================================
//============= ELECTRIC FENCE ROUTINES =================
//=======================================================
#define FENCE_LENGTH
120
// Laser Beam Color
Codes
#define Laser_Red 0xf2f2f0f0 // bright red
#define Laser_Green 0xd0d1d2d3 // bright green
#define Laser_Blue 0xf3f3f1f1 // bright blue
#define Laser_Yellow 0xdcdddedf // bright yellow
#define Laser_YellowS 0xe0e1e2e3 // yellow strobe
#define Laser_DkPurple 0x80818283 // dark purple
#define Laser_LtBlue 0x70717273 // light blue
#define Laser_Green2 0x90919293 // different green
#define Laser_Purple 0xb0b1b2b3 // purple
#define Laser_Red2 0x40414243 // different red
#define Laser_Orange 0xe2e5e3e6 // orange
#define Laser_Mix 0xd0f1d3f3 // mixture
#define Laser_RedBlue 0xf2f3f0f1 // inner = red, outer = blue
#define Laser_BlueRed 0xf3f2f1f0 // inner = blue, outer = red
#define Laser_GreenY 0xdad0dcd2 // inner = green, outer = yellow
#define Laser_YellowG 0xd0dad2dc // inner = yellow, outer = green
//=======================================================
void abs_vector(vec3_t vec1, vec3_t vec2, vec3_t result){
int j;
for (j=0; j<3; j++)>
result[j]=abs(vec1[j]-vec2[j]);
}
//=======================================================
void min_vector(vec3_t start, vec3_t end1, vec3_t end2, vec3_t result){
vec3_t eorg1=(0,0,0);
vec3_t eorg2=(0,0,0);
abs_vector(start,
end1, eorg1);
abs_vector(start, end2, eorg2);
if (VectorLength(eorg1)
< VectorLength(eorg2))
VectorCopy(end1, result);
else
VectorCopy(end2, result);
}
//=======================================================
void beam_laser_think(edict_t *beam) {
vec3_t end;
vec3_t zvec=(0,0,0);
trace_t tr;
// Has the time
expired?
if (beam->wait < level.time) {
gi.unlinkentity(beam);
return; }
VectorMA(beam->s.origin,
beam->spawnflags, beam->movedir, end);
tr=gi.trace(beam->s.origin,
NULL, NULL, end, beam, MASK_ALL);
// Sparks on top of
Post.
if (beam->spawnflags==55)
G_Spawn_Splash(TE_LASER_SPARKS, 4, Laser_BlueRed, end, zvec, end);
// Anybody step
across these laser beam traces yet?
if ((tr.ent) && (tr.ent->takedamage) && !(tr.ent->flags
& FL_IMMUNE_LASER))
T_Damage(tr.ent, beam, beam->activator, beam->movedir, tr.endpos, zvec,
beam->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER);
VectorCopy(tr.endpos,
beam->s.old_origin);
beam->nextthink =
level.time + 0.1
}
//=======================================================
// Spawns a 2 post fence with 4 electric laser rails.
//=======================================================
void Spawn_LaserFence(edict_t *ent) {
edict_t *beam[6];
int i;
vec3_t post1, post2;
vec3_t forward, up, right, end, torigin, torigin2, len;
trace_t tr;
VectorCopy(ent->s.origin,
torigin);
AngleVectors(ent->s.angles, forward, right, up);
// Move torigin forward 50 units to end.
VectorMA(torigin, 50, forward, end);
// Trace this path to see what we hit.
tr = gi.trace(torigin, NULL, NULL, end, NULL, MASK_SOLID);
// torigin2 is the shorter of these vectors.
min_vector(torigin, tr.endpos, end, torigin2);
VectorClear(end);
// Move left from torigin2 1/2 fence length to end.
VectorMA(torigin2, -FENCE_LENGTH/2, right, end);
// Trace this path to see what we hit.
tr = gi.trace(torigin2, NULL, NULL, end, NULL, MASK_SHOT);
// Left post1 is the shorter of these vectors.
min_vector(torigin2, tr.endpos, end, post1);
VectorClear(end);
// Move right from post1 entire length to end.
VectorMA(post1, FENCE_LENGTH, right, end);
// Trace this path to see what we hit.
tr = gi.trace(torigin2, NULL, NULL, end, NULL, MASK_SHOT);
// Right post2 is the shorter of these vectors.
min_vector(torigin2, tr.endpos, end, post2);
// Get length of
fence.
abs_vector(post1, post2, len);
// Okay, let's make
the damn beam already!!
for (i=0; i<=5; i++) {
beam[i] = G_Spawn();
beam[i]->owner = beam[i];
beam[i]->classname= "LaserFence";
beam[i]->activator = ent; // Must set for frags!!
beam[i]->movetype = MOVETYPE_NONE;
beam[i]->solid = SOLID_NOT;
beam[i]->svflags &= ~SVF_NOCLIENT;
beam[i]->s.renderfx = RF_BEAM;
beam[i]->s.modelindex = 1;
beam[i]->spawnflags = VectorLength(len); // Store Length here..
beam[i]->s.skinnum = Laser_Red;
if (i==0) // Only need sound for first one..
beam[i]->s.sound = gi.soundindex ("world/laser.wav");
else
beam[i]->s.sound=0;
beam[i]->s.frame=2;
VectorSet(beam[i]->mins,-8,-8,-8);
VectorSet(beam[i]->maxs, 8, 8, 8);
beam[i]->dmg = 25; // Each Rail..
VectorClear(beam[i]->s.angles);
VectorCopy(right, beam[i]->movedir);
VectorCopy(post1, beam[i]->s.origin);
VectorCopy(post1, beam[i]->s.old_origin);
switch (i) {
case 0: // Bottom Fence Rail
VectorMA(beam[i]->s.origin,-15, up, beam[i]->s.origin);
break;
case 1: // Mid-Lower Fence Rail
break;
case 2: // Mid-Upper Fence Rail
VectorMA(beam[i]->s.origin, 15, up, beam[i]->s.origin);
break;
case 3: // Top Fence Rail
VectorMA(beam[i]->s.origin, 30, up, beam[i]->s.origin);
break;
case 4: // Make 1st Fence Post.
beam[i]->spawnflags = 55;
beam[i]->s.frame *= 4;
VectorCopy(post1, beam[i]->s.origin);
VectorMA(beam[i]->s.origin, -20, up, beam[i]->s.origin);
VectorCopy(up, beam[i]->movedir);
beam[i]->s.skinnum = Laser_Blue;
break;
case 5: // Make 2nd Fence Post.
beam[i]->spawnflags = 55;
beam[i]->s.frame *= 4;
VectorCopy(post2, beam[i]->s.origin);
VectorMA(beam[i]->s.origin, -20, up, beam[i]->s.origin);
VectorCopy(up, beam[i]->movedir);
beam[i]->s.skinnum = Laser_Blue;
break;
} // end switch
beam[i]->wait = level.time + 60.0; // 1 Minute to beam Destruct.
beam[i]->think = beam_laser_think;
beam[i]->nextthink = level.time + 1.0;
gi.linkentity(beam[i]);
} // end for
}
//===========================================
void Cmd_LaserFence_f(edict_t *ent) {
int index;
index =
ITEM_INDEX(FindItem("cells"));
if (ITEM_IN_ENTS_INVENTORY < 20)
gi.centerprintf(ent, "LaserFence requires 50 PowerCells\n");
else {
ITEM_IN_ENTS_INVENTORY -= 20;
Spawn_LaserFence(ent); }
}
--------------------
STOP HERE -----------------------
===============================================================
Lastly..
Be sure to add the
following to your Autoexec.cfg file as
shown by example..
bind f
"fence"
That's it!! Now get
out there and KILL ALL THOSE BASTARDS!
Have Fun!!
philip
|