#include "g_local.h" void ChasecamTrack (edict_t *ent); void CheckChasecam_Viewent (edict_t *ent); void ChasecamStart (edict_t *ent) { edict_t *chasecam; if (ent->client->oldplayer) { if (ent->client->oldplayer->client) free(ent->client->oldplayer->client); G_FreeEdict (ent->client->oldplayer); } if (ent->client->chasecam) G_FreeEdict (ent->client->chasecam); ent->client->chasetoggle = 1; ent->client->ps.gunindex = 0; chasecam = G_Spawn (); chasecam->owner = ent; chasecam->solid = SOLID_NOT; chasecam->movetype = MOVETYPE_NONE; ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; ent->svflags |= SVF_NOCLIENT; VectorCopy (ent->s.angles, chasecam->s.angles); VectorClear (chasecam->mins); VectorClear (chasecam->maxs); VectorCopy (ent->s.origin, chasecam->s.origin); chasecam->classname = "chasecam"; chasecam->nextthink = level.time + 0.100; chasecam->think = ChasecamTrack; chasecam->prethink = ChasecamTrack; ent->client->chasecam = chasecam; ent->client->oldplayer = G_Spawn(); } void ChasecamRestart (edict_t *ent) { if (ent->owner->health <= 0) { G_FreeEdict(ent); return; } ChasecamStart (ent->owner); G_FreeEdict (ent); } void ChasecamRemove (edict_t *ent, int opt) { VectorClear (ent->client->chasecam->velocity); if (!level.intermissiontime) ent->client->ps.gunindex = gi.modelindex(ent->client->pers.weapon->view_model); ent->s.modelindex = ent->client->oldplayer->s.modelindex; ent->svflags &= ~SVF_NOCLIENT; if (opt == OPTION_BACKGROUND) { ent->client->oldplayer->client = NULL; ent->client->chasetoggle = 0; G_FreeEdict (ent->client->chasecam); G_FreeEdict (ent->client->oldplayer); ent->client->oldplayer = NULL; ent->client->chasecam = G_Spawn (); ent->client->chasecam->owner = ent; ent->client->chasecam->solid = SOLID_NOT; ent->client->chasecam->movetype = MOVETYPE_FLYMISSILE; VectorClear (ent->client->chasecam->mins); VectorClear (ent->client->chasecam->maxs); ent->client->chasecam->classname = "chasecam"; ent->client->chasecam->prethink = ChasecamRestart; // begin checking for emergence from the water } else if (opt == OPTION_OFF) { ent->client->oldplayer->client = NULL; G_FreeEdict (ent->client->oldplayer); ent->client->oldplayer = NULL; ent->client->chasetoggle = 0; G_FreeEdict (ent->client->chasecam); ent->client->chasecam = NULL; } } /* The "ent" is the chasecam */ void ChasecamTrack (edict_t *ent) { trace_t tr; vec3_t spot2, headorg, angle; vec3_t forward, right, up, end; float dist; ent->nextthink = level.time + 0.100; VectorCopy(ent->owner->s.origin, headorg); if(!(ent->owner->client->ps.pmove.pm_flags & PMF_DUCKED)) headorg[2] += 25; else headorg[2] += 10; if(ent->owner->chasedist1 <= 0) ent->owner->chasedist1 = 50; VectorCopy(ent->owner->client->v_angle, angle); AngleVectors (ent->owner->client->ps.viewangles, forward, right, up); dist = ent->chasedist2 / ent->owner->chasedist1; VectorScale(forward, -ent->owner->chasedist1, spot2); // Find the max spot2[2] += 5.00; VectorScale(spot2, dist, spot2); // Calculate the current distance VectorAdd(headorg, spot2, spot2); tr = gi.trace (headorg, NULL, NULL, spot2, ent->owner, CONTENTS_SOLID); VectorSubtract(spot2, headorg, spot2); VectorScale(spot2, tr.fraction - 0.05, spot2); VectorAdd(spot2, headorg, spot2); VectorCopy(spot2, ent->s.origin); // VectorCopy(angle, ent->s.angles); VectorCopy (ent->s.origin, ent->movedir); if(ent->owner->client->chasetoggle == 2) { ent->chasedist2 -= 20; if (ent->chasedist2 <= 50) ent->chasedist2 = 50; } else { ent->chasedist2 += 30; if (ent->chasedist2 > ent->owner->chasedist1) ent->chasedist2 = ent->owner->chasedist1; } } void Cmd_Chasecam_Toggle (edict_t *ent) { if (!ent->deadflag) { if (ent->client->chasetoggle) ChasecamRemove (ent, OPTION_OFF); else ChasecamStart (ent); } } void CheckChasecam_Viewent (edict_t *ent) { gclient_t *cl; if ((ent->client->chasetoggle >= 1) && (ent->client->oldplayer)) { ent->client->oldplayer->s.frame = ent->s.frame; VectorCopy (ent->s.origin, ent->client->oldplayer->s.origin); VectorCopy (ent->velocity, ent->client->oldplayer->velocity); VectorCopy (ent->s.angles, ent->client->oldplayer->s.angles); ent->client->oldplayer->waterlevel = ent->waterlevel; ent->client->oldplayer->client = ent->client; ent->client->oldplayer->s = ent->s; gi.linkentity (ent->client->oldplayer); } } static void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) { vec3_t _distance; VectorCopy (distance, _distance); if (client->pers.hand == LEFT_HANDED) _distance[1] *= -1; else if (client->pers.hand == CENTER_HANDED) _distance[1] = 0; G_ProjectSource (point, _distance, forward, right, result); }