Author: SumFuka
Do you remember in star wars when Luke and Han and Chewy have just rescued Princess
Leia and they are in the garbage compactor ? Then Han fires a blaster at the
door but it richochets around the room, bouncing from wall to wall ? Can you
see where I'm coming from ?
Difficulty: Easy

A new movetype: 'MOVETYPE_FLYRICOCHET'
// edict->movetype values
typedef enum
{
MOVETYPE_NONE, // never moves
MOVETYPE_NOCLIP, // origin and angles change with no interaction
MOVETYPE_PUSH, // no clip to world, push on box contact
MOVETYPE_STOP, // no clip to world, stops on box contact
MOVETYPE_WALK, // gravity
MOVETYPE_STEP, // gravity, special edge handling
MOVETYPE_FLY,
MOVETYPE_TOSS, // gravity
MOVETYPE_FLYMISSILE, // extra size to monsters
MOVETYPE_BOUNCE, // STEVE added a comma here
MOVETYPE_FLYRICOCHET // STEVE added this so bolts can bounce off walls !
} movetype_t;
Changing the blaster bolt behaviour.Now open up g_weapon.c. Man I love this file. Go to line 305 and find this section of code :
gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTER); gi.WritePosition (self->s.origin); if (!plane) gi.WriteDir (vec3_origin); else gi.WriteDir (plane->normal); gi.multicast (self->s.origin, MULTICAST_PVS);Now add a 'return;' ABOVE that section of code, it should look something like this :
// STEVE: return here, we don't want the blast to die when it hits a wall... return; // code below not used : gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BLASTER); gi.WritePosition (self->s.origin); if (!plane) gi.WriteDir (vec3_origin); else gi.WriteDir (plane->normal); gi.multicast (self->s.origin, MULTICAST_PVS);Now find the fire_blaster function and change line 330 from this :
bolt->movetype = MOVETYPE_FLYMISSILE;to this :
bolt->movetype = MOVETYPE_FLYRICOCHET;
Changing the game physics: 'MOVETYPE_FLYRICOCHET'
// add gravity if (ent->movetype != MOVETYPE_FLY && ent->movetype != MOVETYPE_FLYMISSILE SV_AddGravity (ent);to this :
// add gravity if (ent->movetype != MOVETYPE_FLY && ent->movetype != MOVETYPE_FLYMISSILE && ent->movetype != MOVETYPE_FLYRICOCHET) // STEVE SV_AddGravity (ent);
That ensures that gravity does not affect things that are 'MOVETYPE_FLYRICOCHET' Now on line 692 change this :
if (ent->movetype == MOVETYPE_BOUNCE) backoff = 1.5; else backoff = 1;to this :
if (ent->movetype == MOVETYPE_FLYRICOCHET) backoff = 2; //steve else if (ent->movetype == MOVETYPE_BOUNCE) backoff = 1.5; else backoff = 1;We are saying here that a missile of type 'fly ricochet' will bounce off walls with equal and opposite velocity (in contrast to a grenade which, for example, bounces off a wall with half off it's previous velocity).
Making the bolt face the direction it travels
ClipVelocity (ent->velocity, trace.plane.normal, ent->velocity, backoff);and insert these lines below it :
// STEVE... added this part to re-align the entity's angles after
// it bounces off a wall. Simply set its angles to its velocity vector.
if (ent->movetype == MOVETYPE_FLYRICOCHET)
{
vectoangles (ent->velocity, ent->s.angles);
}
This step ensures that when a blaster bolt (which is movetype 'MOVETYPE_FLYRICOCHET')
bounces off a wall, the bolt actually faces the direction it is now travelling. Bolts
look VERY strange when they bounce backwards off a wall and are pointed at weird angles !
Now go to line 709 and change this :
if (trace.plane.normal[2] > 0.7 )
{
if (ent->velocity[2] < 60 || ent->movetype != MOVETYPE_BOUNCE )
{
ent->groundentity = trace.ent;
ent->groundentity_linkcount = trace.ent->linkcount;
VectorCopy (vec3_origin, ent->velocity);
VectorCopy (vec3_origin, ent->avelocity);
}
}
to this :
// stop if on ground STEVE changed next line so bolts dont 'stop' on the ground
if (trace.plane.normal[2] > 0.7 && ent->movetype != MOVETYPE_FLYRICOCHET)
{
if (ent->velocity[2] < 60 || ent->movetype != MOVETYPE_BOUNCE )
{
ent->groundentity = trace.ent;
ent->groundentity_linkcount = trace.ent->linkcount;
VectorCopy (vec3_origin, ent->velocity);
VectorCopy (vec3_origin, ent->avelocity);
}
}
The 'if (trace.plane.normal[2] > 0.7)' bit is designed to detect if a missile
object (such as a grenade) is bouncing at an angle that is very close to the floor.
Watch when you throw a grenade, and it will bounce 2 or 3 times, then come to rest.
This code is what makes the grenade stop moving and sit still on the ground (rather
than bouncing infinitely with smaller and smaller bounces). Anyway with this effect
on our blaster bolts 'stick' to the walls if they hit the wall at a very small angle.
We turn this off with the '&& ent->movetype != MOVETYPE_FLYRICOCHET' bit.
One last thing...
case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: case MOVETYPE_FLY: case MOVETYPE_FLYMISSILE: SV_Physics_Toss (ent); break;to look like this :
case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: case MOVETYPE_FLY: case MOVETYPE_FLYMISSILE: case MOVETYPE_FLYRICOCHET: // New SV_Physics_Toss (ent); break;That simply adds our new missile type to the physics processing code, without doing this the game would complain about an 'invalid movement type'.
Rock and Roll(tm) !
Next week... Lets play 'laser tag', but with real lasers...
Tutorial by SumFuka
|
This site, and all content and graphics displayed
on it, |