Tutorial *113*
COPYRIGHTS/PERMISSIONS:

This source code cannot be used in anyway without giving me (the author) full credit for its use. It can be distributed freely as long as the distribution includes this text file. This source code is distributed under the GPL (gnu public license, see gnu.txt for details) just as the original Quake source code.


This tutorial will show you how to put a real functional chasecam into your QuakeWorld client, which can be used on any server in any mod.
First you'll need the Quake source code. This tutorial tells you what to do for the QuakeWorld client code, I'm not sure if it'd work the same for Quake or not. Just do what it says to in the appropriate files and you'll be all set.
CL_ENTS.C
---------
In void CL_LinkPlayers (void), find this:


	if (j == cl.playernum)

		continue;

Change it to this:


	if (j == cl.playernum && !cl_chase.value)

		continue;

Now find this:


		CL_SetSolidPlayers (j);

                CL_PredictUsercmd (state, &exact, &state->command, false);

		pmove.numphysent = oldphysent;

                VectorCopy (exact.origin, ent->origin);

	}

Directly under it, add this:


	//RICH

	if (j == cl.playernum) {

                ent->origin[0] = cl.simorg[0];

                ent->origin[1] = cl.simorg[1];

                ent->origin[2] = cl.simorg[2];

	} //we already know our exact location, don't update normally.

	//END RICH

Go up a little and replace the part under "//angles" completely with this:


	//

	// angles

	//



	//RICH

	if (j == cl.playernum) {

                ent->angles[PITCH] = -cl.simangles[PITCH]/3;

                ent->angles[YAW] = cl.simangles[YAW];

                ent->angles[ROLL] = cl.simangles[ROLL];

	} //otherwise you'll see yourself as always facing one way

	else {

                ent->angles[PITCH] = -state->viewangles[PITCH]/3;

                ent->angles[YAW] = state->viewangles[YAW];

                ent->angles[ROLL] = 0;

                ent->angles[ROLL] = V_CalcRoll (ent->angles, state->velocity)*4;

	}

	//END RICH

Go back up, and directly above the CL_LinkPlayers function, add this:


	//RICH

	extern cvar_t cl_chase;

	//END RICH

VIEW.C
------
Find the void V_CalcRefdef (void) function, and put this right above it:


	//RICH

	extern cvar_t cl_chase;

	extern cvar_t cl_chase_dist;

	extern cvar_t cl_chase_vert;

	//END RICH

Now within the function, put this right under static float oldz = 0;:


	//RICH

	int cont = 0;

	vec3_t old_vorg;

	//END RICH

Next scroll down to where you see:


	// offsets

		AngleVectors (cl.simangles, forward, right, up);

Put this right below it:


	//RICH

	if (cl_chase.value) {

		old_vorg[0] = r_refdef.vieworg[0];

		old_vorg[1] = r_refdef.vieworg[1];

		old_vorg[2] = r_refdef.vieworg[2];



		r_refdef.vieworg[0] = r_refdef.vieworg[0] - forward[0]*cl_chase_dist.value;

		r_refdef.vieworg[1] = r_refdef.vieworg[1] - forward[1]*cl_chase_dist.value;

		r_refdef.vieworg[2] = r_refdef.vieworg[2] + cl_chase_vert.value;



		cont = PM_PointContents (r_refdef.vieworg);



		while (cont == CONTENTS_SOLID) { //quick hack for view clipping

                        if (r_refdef.vieworg[2] > old_vorg[2])

				r_refdef.vieworg[2]--; //Go down until we're at the original view

									   //origin to avoid clipping errors.

			if (r_refdef.vieworg[1] != old_vorg[1])

				r_refdef.vieworg[1] += forward[1]*0.1; //slowly trace back up

			if (r_refdef.vieworg[0] != old_vorg[0])

				r_refdef.vieworg[0] += forward[0]*0.1; //slowly trace back up



			cont = PM_PointContents (r_refdef.vieworg);

		}

	}

	//END RICH

Now scroll down to where you see this:


        if (view_message->flags & (PF_GIB|PF_DEAD) )

                view->model = NULL;

 	else

                view->model = cl.model_precache[cl.stats[STAT_WEAPON]];

Put this right below it:


	//RICH

	if (cl_chase.value)

                view->model = NULL; //don't show weapon in cam mode

	//END RICH

CL_MAIN.C
---------
Find the line that says cvar_t localid = {"localid", ""};, and put this right below it:


	//RICH

	cvar_t  cl_chase = {"cl_chase", "1"};

	cvar_t  cl_chase_vert = {"cl_chase_v", "30"};

	cvar_t  cl_chase_dist = {"cl_chase_d", "50"};

	//END RICH

Now go down to void CL_Init (void) and find the line that says Pmove_Init ();. Put this right below it:


	Cvar_RegisterVariable (&cl_chase);

	Cvar_RegisterVariable (&cl_chase_vert);

	Cvar_RegisterVariable (&cl_chase_dist);

Save everything and compile, and you should have yourself a chasecam-enabled QuakeWorld client.

-Rich


 
Not logged in
Sign up
Login:
Passwd: