|
|
1.1 root 1: #include "g_local.h"
2:
3: void UpdateChaseCam(edict_t *ent)
4: {
5: vec3_t o, ownerv, goal;
6: edict_t *targ;
7: vec3_t forward, right;
8: trace_t trace;
9: int i;
10: vec3_t oldgoal;
11: vec3_t angles;
12:
13: // is our chase target gone?
14: if (!ent->client->chase_target->inuse
15: || ent->client->chase_target->client->resp.spectator) {
16: edict_t *old = ent->client->chase_target;
17: ChaseNext(ent);
18: if (ent->client->chase_target == old) {
19: ent->client->chase_target = NULL;
20: ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION;
21: return;
22: }
23: }
24:
25: targ = ent->client->chase_target;
26:
27: VectorCopy(targ->s.origin, ownerv);
28: VectorCopy(ent->s.origin, oldgoal);
29:
30: ownerv[2] += targ->viewheight;
31:
32: VectorCopy(targ->client->v_angle, angles);
33: if (angles[PITCH] > 56)
34: angles[PITCH] = 56;
35: AngleVectors (angles, forward, right, NULL);
36: VectorNormalize(forward);
37: VectorMA(ownerv, -30, forward, o);
38:
39: if (o[2] < targ->s.origin[2] + 20)
40: o[2] = targ->s.origin[2] + 20;
41:
42: // jump animation lifts
43: if (!targ->groundentity)
44: o[2] += 16;
45:
46: trace = gi.trace(ownerv, vec3_origin, vec3_origin, o, targ, MASK_SOLID);
47:
48: VectorCopy(trace.endpos, goal);
49:
50: VectorMA(goal, 2, forward, goal);
51:
52: // pad for floors and ceilings
53: VectorCopy(goal, o);
54: o[2] += 6;
55: trace = gi.trace(goal, vec3_origin, vec3_origin, o, targ, MASK_SOLID);
56: if (trace.fraction < 1) {
57: VectorCopy(trace.endpos, goal);
58: goal[2] -= 6;
59: }
60:
61: VectorCopy(goal, o);
62: o[2] -= 6;
63: trace = gi.trace(goal, vec3_origin, vec3_origin, o, targ, MASK_SOLID);
64: if (trace.fraction < 1) {
65: VectorCopy(trace.endpos, goal);
66: goal[2] += 6;
67: }
68:
69: if (targ->deadflag)
70: ent->client->ps.pmove.pm_type = PM_DEAD;
71: else
72: ent->client->ps.pmove.pm_type = PM_FREEZE;
73:
74: VectorCopy(goal, ent->s.origin);
75: for (i=0 ; i<3 ; i++)
76: ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(targ->client->v_angle[i] - ent->client->resp.cmd_angles[i]);
77:
78: if (targ->deadflag) {
79: ent->client->ps.viewangles[ROLL] = 40;
80: ent->client->ps.viewangles[PITCH] = -15;
81: ent->client->ps.viewangles[YAW] = targ->client->killer_yaw;
82: } else {
83: VectorCopy(targ->client->v_angle, ent->client->ps.viewangles);
84: VectorCopy(targ->client->v_angle, ent->client->v_angle);
85: }
86:
87: ent->viewheight = 0;
88: ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
89: gi.linkentity(ent);
90: }
91:
92: void ChaseNext(edict_t *ent)
93: {
94: int i;
95: edict_t *e;
96:
97: if (!ent->client->chase_target)
98: return;
99:
100: i = ent->client->chase_target - g_edicts;
101: do {
102: i++;
103: if (i > maxclients->value)
104: i = 1;
105: e = g_edicts + i;
106: if (!e->inuse)
107: continue;
108: if (!e->client->resp.spectator)
109: break;
110: } while (e != ent->client->chase_target);
111:
112: ent->client->chase_target = e;
113: ent->client->update_chase = true;
114: }
115:
116: void ChasePrev(edict_t *ent)
117: {
118: int i;
119: edict_t *e;
120:
121: if (!ent->client->chase_target)
122: return;
123:
124: i = ent->client->chase_target - g_edicts;
125: do {
126: i--;
127: if (i < 1)
128: i = maxclients->value;
129: e = g_edicts + i;
130: if (!e->inuse)
131: continue;
132: if (!e->client->resp.spectator)
133: break;
134: } while (e != ent->client->chase_target);
135:
136: ent->client->chase_target = e;
137: ent->client->update_chase = true;
138: }
139:
140: void GetChaseTarget(edict_t *ent)
141: {
142: int i;
143: edict_t *other;
144:
145: for (i = 1; i <= maxclients->value; i++) {
146: other = g_edicts + i;
147: if (other->inuse && !other->client->resp.spectator) {
148: ent->client->chase_target = other;
149: ent->client->update_chase = true;
150: UpdateChaseCam(ent);
151: return;
152: }
153: }
154: gi.centerprintf(ent, "No other players to chase.");
155: }
156:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.