|
|
|
IMPORTANT BULLETIN: Coliseum2 v2.3 available
!! | |
Tutorial 1: Rail
Spiral By
Steve Kemper (Scatster) & Manuel Tran
(WarMonger) | |
By
popular demand, the following is the spiral rail code developed for the
Coliseum2 Mod You may use this code in your mods but you must include
Manuel Tran and Steve Kemper in your credits.
The
spiral rail is a new function to allow you to switch back and forth to the
regular rail code. Add the new function to the end of
cg_weapon.c.
//Rail spiral by Steve Kemper and
Manuel Tran void
CG_SpiralTrail (clientInfo_t *ci, vec3_t start, vec3_t
end) { vec3_t axis[36], move,
move2, next_move, vec, temp; float len; int i, j, k,
skip;
localEntity_t
*le; refEntity_t *re;
#define RADIUS
9 #define ROTATION 1 #define SPACING
5
//Better line
the spiral with the rail run muzzle.
start[2] -= 4; VectorCopy (start,
move);
//Assign vec a
vector that represents the rail line.
VectorSubtract (end, start, vec);
//Normalizes vec thus making it a directional
vector. len = VectorNormalize
(vec);
//Assign temp a
normalized vector perpendicular to our direction
vector. PerpendicularVector(temp,
vec);
//We are ultra
effecient by knowing that since the spiral will wrap several
times //along the line while moving foraward,
we only have to compute the positions of //the
dots around the circle only ONCE. We store these in a local array and
then //simply project each dot forward a
little to create the spiral effect.
//Index 0 represents 0 and 35 = 350 degrees rotation - each dot is 10
degrees apart. for (i = 0 ; i < 36;
i++)
RotatePointAroundVector(axis[i], vec, temp, i *
10);
//***** Core
***** //We
draw the core first. Since it has a shorter lifespan than the coil
itself, //if we run out of temp entities
while drawing the coil, the temp entity for
the //core will be the first one
"stolen". le =
CG_AllocLocalEntity(); re =
&le->refEntity;
le->leType =
LE_FADE_RGB; le->startTime =
cg.time; le->endTime = cg.time +
750; le->lifeRate = 1.0 / (le->endTime -
le->startTime);
re->shaderTime =
cg.time / 1000.0f; re->reType =
RT_RAIL_CORE; re->customShader =
cgs.media.railCoreShader;
VectorCopy(start, re->origin);
VectorCopy(end, re->oldorigin);
le->color[0] = ci->color[0] * 0.75;
le->color[1] = ci->color[1] * 0.75;
le->color[2] = ci->color[2] * 0.75;
le->color[3] = 1.0f;
AxisClear(
re->axis ); //***** End
core *****
//move it a little forward...
VectorMA(move, 20, vec,
move);
//Copy so it can be
re-used. VectorCopy(move,
next_move);
//Transform vec so it represents a vector of length
SPACING. //This represents the line
segments along the rail line.
VectorScale (vec, SPACING,
vec);
//Indicator
to let us know when to skip a dot. skip
= -1;
//We draw the
spiral skipping every other dot. Then we come back
and //fill in the gaps. That way, if we run
out of temp entities, only //every other dot
will be "stolen" and we will have some remnant of
a //spiral left. Also, if we know the length
is too long (over 2200), //then we dont bother
to come back to fill in gaps, since there
won't //be enough temp entities left
anyways.
for (k = (len > 2200); k < 2;
k++)
{ //Start at 180
degrees j
= 18;
for (i = 0; i < len; i +=
SPACING)
{
if (i !=
skip)
{
skip = i +
SPACING;
le =
CG_AllocLocalEntity(); re
=
&le->refEntity;
le->leFlags =
LEF_PUFF_DONT_SCALE;
le->leType =
LE_MOVE_SCALE_FADE;
//Lifetime is hardcoded to prevent
obscene
//numbers from potentially causing
problems.
le->startTime =
cg.time;
le->endTime = cg.time +
1200;
le->lifeRate = 1.0 / (le->endTime -
le->startTime);
re->shaderTime = cg.time /
1000.0f;
re->reType =
RT_SPRITE;
re->radius =
1.5;
re->customShader = cgs.media.waterBubbleShader;
re->shaderRGBA[0] = ci->color[0] *
255;
re->shaderRGBA[1] = ci->color[1] *
255;
re->shaderRGBA[2] = ci->color[2] *
255;
re->shaderRGBA[3] =
255;
le->color[0] = ci->color[0] *
0.75;
le->color[1] = ci->color[1] *
0.75;
le->color[2] = ci->color[2] *
0.75; le->color[3]
=
1.0f;
le->pos.trType =
TR_LINEAR;
le->pos.trTime =
cg.time;
//Copy the current position into temp
storage.
VectorCopy( move,
move2); //Project the position along the line outwards at the proper
angle.
VectorMA(move2, RADIUS , axis[j],
move2); //Assign position to temp local
entity.
VectorCopy(move2,
le->pos.trBase);
//Set drift speed and direction of the
dot. le->pos.trDelta[0]
=
axis[j][0]*6;
le->pos.trDelta[1] =
axis[j][1]*6;
le->pos.trDelta[2] =
axis[j][2]*6; }
//Step forward along the rail line in increment of
vec. VectorAdd
(move, vec,
move);
//Continue to loop through the array as we draw the
spiral //returning
to the first array element, round and
round.
j = j + ROTATION < 36 ? j + ROTATION : (j + ROTATION) %
36;
}
//Return to beginning of rail
line. VectorCopy(next_move,
move); skip =
0; }
} //End
function
You must
also declare this new function. Add the following to
cg_local.h.
void
CG_SpiralTrail (clientInfo_t *ci, vec3_t start, vec3_t end);
To use
the function, seach the client project for calls to CG_RailTrail and replace it with CG_SpiralTrail.
If you
should have any ideas on how to improve this function please e-mail me.
|