1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 #include "g_headers.h"
24 
25 //g_camera.cpp
26 #include "g_local.h"
27 //#include "Q3_Interface.h"
28 //#include "anims.h"
29 //#include "b_local.h"
30 #include "../cgame/cg_camera.h"
31 #include "g_functions.h"
32 
33 /*
34 #define MAX_CAMERA_GROUP_SUBJECTS	16
35 void misc_camera_focus_think (gentity_t *self)
36 {
37 	//Check to see if I should stop?
38 	gi.linkentity(self);
39 	self->nextthink = level.time + FRAMETIME;
40 }
41 
42 void misc_camera_focus_use (gentity_t *self, gentity_t *other, gentity_t *activator)
43 {
44 	G_ActivateBehavior(self,BSET_USE);
45 
46 	//First, find everyone in my cameraGroup, if I have one
47 
48 	//Now find my first path_corner, if I have one
49 
50 	//Start thinking
51 
52 	self->e_ThinkFunc = thinkF_misc_camera_focus_think;
53 	misc_camera_focus_think(self);
54 
55 	self->e_clThinkFunc = clThinkF_CG_MiscCameraFocusThink;	// blurgh!...
56 	self->s.eType = ET_THINKER;
57 
58 	self->aimDebounceTime = level.time;
59 }
60 */
61 /*QUAK-ED misc_camera_focus (0 0 1) (-4 -4 -4) (4 4 4) lerptostart
62 
63 LERPTOSTART - With interpolate from camera's current angles to this thing's start angle instead of snapping to it, which is the default behavior
64 
65 The focal point for a camera in a scene
66 
67 "targetname" - Use it to get it to find it's cameraGroup and start tracking it, also get started on it's path, if any
68 
69 "cameraGroup" - will find all ents in this group and pick a point in the center of that group.
70 
71 "speed" angular speed modifier - 100 is normal
72 */
SP_misc_camera_focus(gentity_t * self)73 void SP_misc_camera_focus (gentity_t *self)
74 {
75 	if(!self->targetname)
76 	{
77 		gi.Printf(S_COLOR_RED"ERROR: misc_camera_focus with no targetname\n");
78 		G_FreeEntity(self);
79 		return;
80 	}
81 
82 	/*
83 	if(self->speed > 0)
84 	{
85 		self->moveInfo.aspeed = self->speed;
86 	}
87 	else
88 	{
89 		self->moveInfo.aspeed = 100.f;
90 	}
91 	*/
92 	self->speed = 0;
93 	self->script_targetname = self->targetname;
94 //	self->e_UseFunc = useF_misc_camera_focus_use;
95 }
96 
97 /*
98 void misc_camera_track_think (gentity_t *self)
99 {
100 	vec3_t		vec;
101 	float		dist;
102 	//Check to see if I should stop?
103 
104 	gi.linkentity(self);
105 
106 	if(self->enemy)
107 	{//We're already heading to a path_corner
108 		VectorSubtract(self->currentOrigin, self->s.origin2, vec);
109 		dist = VectorLengthSquared(vec);
110 		if(dist < 256)//16 squared
111 		{
112 			G_UseTargets(self, self);
113 			self->target = self->enemy->target;
114 			self->enemy = NULL;
115 		}
116 	}
117 
118 	if( !self->enemy)
119 	{
120 		if( self->target && self->target[0] )
121 		{//Find out next path_corner
122 			self->enemy = G_Find(NULL, FOFS(targetname), self->target);
123 			if(self->enemy)
124 			{
125 				if(self->enemy->radius < 0)
126 				{//Don't bother trying to maintain a radius
127 					self->radius = 0;
128 					self->moveInfo.speed = self->speed/10.0f;
129 				}
130 				else if(self->enemy->radius > 0)
131 				{
132 					self->radius = self->enemy->radius;
133 				}
134 
135 				if(self->enemy->speed < 0)
136 				{//go back to our default speed
137 					self->moveInfo.speed = self->speed/10.0f;
138 				}
139 				else if(self->enemy->speed > 0)
140 				{
141 					self->moveInfo.speed = self->enemy->speed/10.0f;
142 				}
143 			}
144 		}
145 		else
146 		{//stop thinking if this is the last one
147 			self->e_ThinkFunc = thinkF_NULL;
148 			self->e_clThinkFunc = clThinkF_NULL;
149 			self->s.eType = ET_GENERAL;
150 			self->nextthink = -1;
151 		}
152 	}
153 
154 	if(self->enemy)
155 	{//clThink will lerp this
156 		VectorCopy(self->enemy->currentOrigin, self->s.origin2);
157 	}
158 
159 	self->nextthink = level.time + FRAMETIME;
160 }
161 
162 void misc_camera_track_use (gentity_t *self, gentity_t *other, gentity_t *activator)
163 {
164 
165 	G_ActivateBehavior(self,BSET_USE);
166 
167 	//Start thinking
168 
169 	self->e_ThinkFunc = thinkF_misc_camera_track_think;
170 	misc_camera_track_think(self);
171 
172 	self->e_clThinkFunc = clThinkF_CG_MiscCameraTrackThink;
173 	self->s.eType = ET_THINKER;
174 }
175 */
176 /*QUAK-ED misc_camera_track (0 0 1) (-4 -4 -4) (4 4 4)
177 
178 The track for a camera to stay on
179 
180 "targetname" - Use it to get it started on it's path
181 
182 "target" - First point on it's path - if misc_camera_focus is on a path, it will pick the point on it's path closest to the above calced point
183 use "path_corner"s - path it should stay on- if that path_corner has a speed value, it will use this as it's speed to the next path_corner
184 
185 "speed" - How quickly to move, 0 by default
186 
187 "radius" - How far camera should try to stay from it's subject, default is 0 (dist doesn't matter), can pick this up from a path_corner too
188 */
SP_misc_camera_track(gentity_t * self)189 void SP_misc_camera_track (gentity_t *self)
190 {
191 	if(!self->targetname || !self->targetname[0])
192 	{
193 		gi.Printf(S_COLOR_RED"ERROR: misc_camera_track with no targetname\n");
194 		G_FreeEntity(self);
195 		return;
196 	}
197 
198 	self->script_targetname = self->targetname;
199 	//self->moveInfo.speed = self->speed/10;
200 
201 //	self->e_UseFunc = useF_misc_camera_track_use;
202 }
203 
204 
205 //-------------------------------------------------
206 //	Bezier camera stuff
207 //-------------------------------------------------
208 
cam_point_link(gentity_t * ent)209 void cam_point_link( gentity_t *ent )
210 {
211 
212 }
213 
cam_ctrl_point_link(gentity_t * ent)214 void cam_ctrl_point_link( gentity_t *ent )
215 {
216 /*	gentity_t	*target2 = NULL;
217 
218 	target2 = G_Find( NULL, FOFS(targetname), ent->target2 );
219 
220 	if ( !target2 )
221 	{
222 		// Bah, you fool!  Target2 not found
223 		Com_Printf( "cam_point_link: target2 specified but not found: %s\n", ent->target2 );
224 		G_FreeEntity( ent );
225 		return;
226 	}
227 
228 	// Store the control point here
229 	VectorCopy( target2->s.origin, ent->pos1 );
230 
231 	//---------------------
232 	if ( ent->target )
233 	{
234 		gentity_t	*target = NULL;
235 
236 		target = G_Find( NULL, FOFS(targetname), ent->target );
237 
238 		if ( !target )
239 		{
240 			// Bah, you fool!  Target not found
241 			Com_Printf( "cam_point_link: target specified but not found: %s\n", ent->target );
242 			G_FreeEntity( ent );
243 			return;
244 		}
245 
246 		ent->nextTrain = target;
247 	}
248 */
249 }
250 
251 /*QUAK-ED cam_point (0.25 0 0.5) (-2 -2 -2) (2 2 2)
252 Under development -- DONT USE ME!!!!!
253 A camera point used to construct a camera bezier path
254 
255 Every cam_point MUST be targeted (target2) at one and only one control point
256 */
SP_cam_point(gentity_t * ent)257 void SP_cam_point( gentity_t *ent )
258 {
259 /*	if ( !ent->target2 )
260 	{
261 		// Bah, you fool!  Target2 not found so we have no idea how to make the curve
262 		Com_Printf( "cam_point_link: target2 was required but not found\n" );
263 		G_FreeEntity( ent );
264 		return;
265 
266 	}
267 
268 	// The thing we are targeting may not be spawned in yet so, wait a bit to try and link to it
269 	ent->e_ThinkFunc = thinkF_cam_ctrl_point_link;
270 	ent->nextthink = level.time + 200;
271 
272 	// Save our position and link us up!
273 	G_SetOrigin( ent, ent->s.origin );
274 	gi.linkentity( ent );
275 */
276 }