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 // bg_saberLoad.c
24 // game and cgame, NOT ui
25 
26 #include "qcommon/q_shared.h"
27 #include "bg_public.h"
28 #include "bg_local.h"
29 #include "w_saber.h"
30 
31 #ifdef _GAME
32 	#include "g_local.h"
33 #elif _CGAME
34 	#include "cgame/cg_local.h"
35 #elif UI_BUILD
36 	#include "ui/ui_local.h"
37 #endif
38 
39 extern stringID_table_t animTable[MAX_ANIMATIONS+1];
40 
BG_SoundIndex(const char * sound)41 int BG_SoundIndex( const char *sound ) {
42 #ifdef _GAME
43 	return G_SoundIndex( sound );
44 #elif defined(_CGAME) || defined(UI_BUILD)
45 	return trap->S_RegisterSound( sound );
46 #endif
47 }
48 
49 extern stringID_table_t FPTable[];
50 
51 #define MAX_SABER_DATA_SIZE (1024*1024) // 1mb, was 512kb
52 static char saberParms[MAX_SABER_DATA_SIZE];
53 
54 stringID_table_t saberTable[] = {
55 	ENUM2STRING( SABER_NONE ),
56 	ENUM2STRING( SABER_SINGLE ),
57 	ENUM2STRING( SABER_STAFF ),
58 	ENUM2STRING( SABER_BROAD ),
59 	ENUM2STRING( SABER_PRONG ),
60 	ENUM2STRING( SABER_DAGGER ),
61 	ENUM2STRING( SABER_ARC ),
62 	ENUM2STRING( SABER_SAI ),
63 	ENUM2STRING( SABER_CLAW ),
64 	ENUM2STRING( SABER_LANCE ),
65 	ENUM2STRING( SABER_STAR ),
66 	ENUM2STRING( SABER_TRIDENT ),
67 	{ "", -1 }
68 };
69 
70 stringID_table_t saberMoveTable[] = {
71 	ENUM2STRING( LS_NONE ),
72 	// Attacks
73 	ENUM2STRING( LS_A_TL2BR ),
74 	ENUM2STRING( LS_A_L2R ),
75 	ENUM2STRING( LS_A_BL2TR ),
76 	ENUM2STRING( LS_A_BR2TL ),
77 	ENUM2STRING( LS_A_R2L ),
78 	ENUM2STRING( LS_A_TR2BL ),
79 	ENUM2STRING( LS_A_T2B ),
80 	ENUM2STRING( LS_A_BACKSTAB ),
81 	ENUM2STRING( LS_A_BACK ),
82 	ENUM2STRING( LS_A_BACK_CR ),
83 	ENUM2STRING( LS_ROLL_STAB ),
84 	ENUM2STRING( LS_A_LUNGE ),
85 	ENUM2STRING( LS_A_JUMP_T__B_ ),
86 	ENUM2STRING( LS_A_FLIP_STAB ),
87 	ENUM2STRING( LS_A_FLIP_SLASH ),
88 	ENUM2STRING( LS_JUMPATTACK_DUAL ),
89 	ENUM2STRING( LS_JUMPATTACK_ARIAL_LEFT ),
90 	ENUM2STRING( LS_JUMPATTACK_ARIAL_RIGHT ),
91 	ENUM2STRING( LS_JUMPATTACK_CART_LEFT ),
92 	ENUM2STRING( LS_JUMPATTACK_CART_RIGHT ),
93 	ENUM2STRING( LS_JUMPATTACK_STAFF_LEFT ),
94 	ENUM2STRING( LS_JUMPATTACK_STAFF_RIGHT ),
95 	ENUM2STRING( LS_BUTTERFLY_LEFT ),
96 	ENUM2STRING( LS_BUTTERFLY_RIGHT ),
97 	ENUM2STRING( LS_A_BACKFLIP_ATK ),
98 	ENUM2STRING( LS_SPINATTACK_DUAL ),
99 	ENUM2STRING( LS_SPINATTACK ),
100 	ENUM2STRING( LS_LEAP_ATTACK ),
101 	ENUM2STRING( LS_SWOOP_ATTACK_RIGHT ),
102 	ENUM2STRING( LS_SWOOP_ATTACK_LEFT ),
103 	ENUM2STRING( LS_TAUNTAUN_ATTACK_RIGHT ),
104 	ENUM2STRING( LS_TAUNTAUN_ATTACK_LEFT ),
105 	ENUM2STRING( LS_KICK_F ),
106 	ENUM2STRING( LS_KICK_B ),
107 	ENUM2STRING( LS_KICK_R ),
108 	ENUM2STRING( LS_KICK_L ),
109 	ENUM2STRING( LS_KICK_S ),
110 	ENUM2STRING( LS_KICK_BF ),
111 	ENUM2STRING( LS_KICK_RL ),
112 	ENUM2STRING( LS_KICK_F_AIR ),
113 	ENUM2STRING( LS_KICK_B_AIR ),
114 	ENUM2STRING( LS_KICK_R_AIR ),
115 	ENUM2STRING( LS_KICK_L_AIR ),
116 	ENUM2STRING( LS_STABDOWN ),
117 	ENUM2STRING( LS_STABDOWN_STAFF ),
118 	ENUM2STRING( LS_STABDOWN_DUAL ),
119 	ENUM2STRING( LS_DUAL_SPIN_PROTECT ),
120 	ENUM2STRING( LS_STAFF_SOULCAL ),
121 	ENUM2STRING( LS_A1_SPECIAL ),
122 	ENUM2STRING( LS_A2_SPECIAL ),
123 	ENUM2STRING( LS_A3_SPECIAL ),
124 	ENUM2STRING( LS_UPSIDE_DOWN_ATTACK ),
125 	ENUM2STRING( LS_PULL_ATTACK_STAB ),
126 	ENUM2STRING( LS_PULL_ATTACK_SWING ),
127 	ENUM2STRING( LS_SPINATTACK_ALORA ),
128 	ENUM2STRING( LS_DUAL_FB ),
129 	ENUM2STRING( LS_DUAL_LR ),
130 	ENUM2STRING( LS_HILT_BASH ),
131 	{ "", -1 }
132 };
133 
134 //Also used in npc code
BG_ParseLiteral(const char ** data,const char * string)135 qboolean BG_ParseLiteral( const char **data, const char *string ) {
136 	const char *token;
137 
138 	token = COM_ParseExt( data, qtrue );
139 	if ( !token[0] ) {
140 		Com_Printf( "unexpected EOF\n" );
141 		return qtrue;
142 	}
143 
144 	if ( Q_stricmp( token, string ) ) {
145 		Com_Printf( "required string '%s' missing\n", string );
146 		return qtrue;
147 	}
148 
149 	return qfalse;
150 }
151 
BG_ParseLiteralSilent(const char ** data,const char * string)152 qboolean BG_ParseLiteralSilent( const char **data, const char *string ) {
153 	const char *token;
154 
155 	token = COM_ParseExt( data, qtrue );
156 	if ( !token[0] ) {
157 		return qtrue;
158 	}
159 
160 	if ( Q_stricmp( token, string ) ) {
161 
162 		return qtrue;
163 	}
164 
165 	return qfalse;
166 }
167 
TranslateSaberColor(const char * name)168 saber_colors_t TranslateSaberColor( const char *name ) {
169 	if ( !Q_stricmp( name, "red" ) )
170 		return SABER_RED;
171 	if ( !Q_stricmp( name, "orange" ) )
172 		return SABER_ORANGE;
173 	if ( !Q_stricmp( name, "yellow" ) )
174 		return SABER_YELLOW;
175 	if ( !Q_stricmp( name, "green" ) )
176 		return SABER_GREEN;
177 	if ( !Q_stricmp( name, "blue" ) )
178 		return SABER_BLUE;
179 	if ( !Q_stricmp( name, "purple" ) )
180 		return SABER_PURPLE;
181 	if ( !Q_stricmp( name, "random" ) )
182 		return (saber_colors_t)Q_irand( SABER_ORANGE, SABER_PURPLE );
183 
184 	return SABER_BLUE;
185 }
186 
SaberColorToString(saber_colors_t color)187 const char *SaberColorToString( saber_colors_t color ) {
188 	if ( color == SABER_RED )		return "red";
189 	if ( color == SABER_ORANGE )	return "orange";
190 	if ( color == SABER_YELLOW )	return "yellow";
191 	if ( color == SABER_GREEN )		return "green";
192 	if ( color == SABER_BLUE )		return "blue";
193 	if ( color == SABER_PURPLE )	return "purple";
194 
195 	return NULL;
196 }
197 
TranslateSaberStyle(const char * name)198 saber_styles_t TranslateSaberStyle( const char *name ) {
199 	if ( !Q_stricmp( name, "fast" ) )		return SS_FAST;
200 	if ( !Q_stricmp( name, "medium" ) ) 	return SS_MEDIUM;
201 	if ( !Q_stricmp( name, "strong" ) ) 	return SS_STRONG;
202 	if ( !Q_stricmp( name, "desann" ) ) 	return SS_DESANN;
203 	if ( !Q_stricmp( name, "tavion" ) ) 	return SS_TAVION;
204 	if ( !Q_stricmp( name, "dual" ) )		return SS_DUAL;
205 	if ( !Q_stricmp( name, "staff" ) )		return SS_STAFF;
206 
207 	return SS_NONE;
208 }
209 
TranslateSaberType(const char * name)210 saberType_t TranslateSaberType( const char *name ) {
211 	if ( !Q_stricmp( name, "SABER_SINGLE" ) )		return SABER_SINGLE;
212 	if ( !Q_stricmp( name, "SABER_STAFF" ) ) 		return SABER_STAFF;
213 	if ( !Q_stricmp( name, "SABER_DAGGER" ) ) 		return SABER_DAGGER;
214 	if ( !Q_stricmp( name, "SABER_BROAD" ) ) 		return SABER_BROAD;
215 	if ( !Q_stricmp( name, "SABER_PRONG" ) ) 		return SABER_PRONG;
216 	if ( !Q_stricmp( name, "SABER_ARC" ) )			return SABER_ARC;
217 	if ( !Q_stricmp( name, "SABER_SAI" ) )			return SABER_SAI;
218 	if ( !Q_stricmp( name, "SABER_CLAW" ) )			return SABER_CLAW;
219 	if ( !Q_stricmp( name, "SABER_LANCE" ) )		return SABER_LANCE;
220 	if ( !Q_stricmp( name, "SABER_STAR" ) )			return SABER_STAR;
221 	if ( !Q_stricmp( name, "SABER_TRIDENT" ) )		return SABER_TRIDENT;
222 	if ( !Q_stricmp( name, "SABER_SITH_SWORD" ) )	return SABER_SITH_SWORD;
223 
224 	return SABER_SINGLE;
225 }
226 
WP_SaberBladeUseSecondBladeStyle(saberInfo_t * saber,int bladeNum)227 qboolean WP_SaberBladeUseSecondBladeStyle( saberInfo_t *saber, int bladeNum ) {
228 	if ( saber
229 		&& saber->bladeStyle2Start > 0
230 		&& bladeNum >= saber->bladeStyle2Start )
231 		return qtrue;
232 
233 	return qfalse;
234 }
235 
WP_SaberBladeDoTransitionDamage(saberInfo_t * saber,int bladeNum)236 qboolean WP_SaberBladeDoTransitionDamage( saberInfo_t *saber, int bladeNum ) {
237 	//use first blade style for this blade
238 	if ( !WP_SaberBladeUseSecondBladeStyle( saber, bladeNum ) && (saber->saberFlags2 & SFL2_TRANSITION_DAMAGE) )
239 		return qtrue;
240 
241 	//use second blade style for this blade
242 	else if ( WP_SaberBladeUseSecondBladeStyle( saber, bladeNum ) && (saber->saberFlags2 & SFL2_TRANSITION_DAMAGE2) )
243 		return qtrue;
244 
245 	return qfalse;
246 }
247 
WP_UseFirstValidSaberStyle(saberInfo_t * saber1,saberInfo_t * saber2,int saberHolstered,int * saberAnimLevel)248 qboolean WP_UseFirstValidSaberStyle( saberInfo_t *saber1, saberInfo_t *saber2, int saberHolstered, int *saberAnimLevel ) {
249 	qboolean styleInvalid = qfalse;
250 	qboolean saber1Active, saber2Active;
251 	qboolean dualSabers = qfalse;
252 	int	validStyles=0, styleNum;
253 
254 	if ( saber2 && saber2->model[0] )
255 		dualSabers = qtrue;
256 
257 	//dual
258 	if ( dualSabers ) {
259 		if ( saberHolstered > 1 )
260 			saber1Active = saber2Active = qfalse;
261 		else if ( saberHolstered > 0 ) {
262 			saber1Active = qtrue;
263 			saber2Active = qfalse;
264 		}
265 		else
266 			saber1Active = saber2Active = qtrue;
267 	}
268 	// single/staff
269 	else {
270 		saber2Active = qfalse;
271 		if ( !saber1 || !saber1->model[0] )
272 			saber1Active = qfalse;
273 		//staff
274 		else if ( saber1->numBlades > 1 ) {
275 			if ( saberHolstered > 1 )
276 				saber1Active = qfalse;
277 			else
278 				saber1Active = qtrue;
279 		}
280 		//single
281 		else {
282 			if ( saberHolstered )
283 				saber1Active = qfalse;
284 			else
285 				saber1Active = qtrue;
286 		}
287 	}
288 
289 	//initially, all styles are valid
290 	validStyles = (1<<SS_NUM_SABER_STYLES)-2; // mask off 1<<SS_NONE
291 
292 	// check for invalid styles
293 	if ( saber1Active && saber1 && saber1->model[0] && saber1->stylesForbidden ) {
294 		if ( (saber1->stylesForbidden & (1<<*saberAnimLevel)) ) {
295 			//not a valid style for first saber!
296 			styleInvalid = qtrue;
297 			validStyles &= ~saber1->stylesForbidden;
298 		}
299 	}
300 	if ( dualSabers ) {
301 		if ( saber2Active && saber2->stylesForbidden ) {
302 			if ( (saber2->stylesForbidden & (1<<*saberAnimLevel)) ) {
303 				//not a valid style for second saber!
304 				styleInvalid = qtrue;
305 				//only the ones both sabers allow is valid
306 				validStyles &= ~saber2->stylesForbidden;
307 			}
308 		}
309 	}
310 
311 	if ( !validStyles ) {
312 		if ( dualSabers )
313 			Com_Printf( "WARNING: No valid saber styles for %s/%s", saber1->name, saber2->name );
314 		else
315 			Com_Printf( "WARNING: No valid saber styles for %s", saber1->name );
316 	}
317 
318 	//using an invalid style and have at least one valid style to use, so switch to it
319 	else if ( styleInvalid ) {
320 		for ( styleNum=SS_FAST; styleNum<SS_NUM_SABER_STYLES; styleNum++ ) {
321 			if ( (validStyles & (1<<styleNum)) ) {
322 				*saberAnimLevel = styleNum;
323 				return qtrue;
324 			}
325 		}
326 	}
327 	return qfalse;
328 }
329 
WP_SaberStyleValidForSaber(saberInfo_t * saber1,saberInfo_t * saber2,int saberHolstered,int saberAnimLevel)330 qboolean WP_SaberStyleValidForSaber( saberInfo_t *saber1, saberInfo_t *saber2, int saberHolstered, int saberAnimLevel ) {
331 	qboolean saber1Active, saber2Active;
332 	qboolean dualSabers = qfalse;
333 
334 	if ( saber2 && saber2->model[0] )
335 		dualSabers = qtrue;
336 
337 	if ( dualSabers ) {
338 		if ( saberHolstered > 1 )
339 			saber1Active = saber2Active = qfalse;
340 		else if ( saberHolstered > 0 ) {
341 			saber1Active = qtrue;
342 			saber2Active = qfalse;
343 		}
344 		else
345 			saber1Active = saber2Active = qtrue;
346 	}
347 	else {
348 		saber2Active = qfalse;
349 		if ( !saber1 || !saber1->model[0] )
350 			saber1Active = qfalse;
351 
352 		//staff
353 		else if ( saber1->numBlades > 1 )
354 			saber1Active = (saberHolstered>1) ? qfalse : qtrue;
355 
356 		//single
357 		else
358 			saber1Active = saberHolstered ? qfalse : qtrue;
359 	}
360 
361 	if ( saber1Active && saber1 && saber1->model[0] && saber1->stylesForbidden ) {
362 		if ( (saber1->stylesForbidden & (1<<saberAnimLevel)) )
363 			return qfalse;
364 	}
365 	if ( dualSabers && saber2Active && saber2 && saber2->model[0] )
366 	{
367 		if ( saber2->stylesForbidden ) {
368 			if ( (saber2->stylesForbidden & (1<<saberAnimLevel)) )
369 				return qfalse;
370 		}
371 		//now: if using dual sabers, only dual and tavion (if given with this saber) are allowed
372 		if ( saberAnimLevel != SS_DUAL ) {
373 			if ( saberAnimLevel != SS_TAVION )
374 				return qfalse;
375 			else {
376 				//see if "tavion" style is okay
377 				if ( !(saber1Active && (saber1->stylesLearned & (1<<SS_TAVION)))
378 					|| !(saber2->stylesLearned & (1<<SS_TAVION)) )
379 					return qfalse;
380 			}
381 		}
382 	}
383 
384 	return qtrue;
385 }
386 
WP_SaberCanTurnOffSomeBlades(saberInfo_t * saber)387 qboolean WP_SaberCanTurnOffSomeBlades( saberInfo_t *saber ) {
388 	if ( saber->bladeStyle2Start > 0 && saber->numBlades > saber->bladeStyle2Start ) {
389 		// check if all blades are always on
390 		if ( (saber->saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE) && (saber->saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE2) )
391 			return qfalse;
392 	}
393 	else {
394 		// check if all blades are always on
395 		if ( (saber->saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE) )
396 			return qfalse;
397 	}
398 	//you can turn some off
399 	return qtrue;
400 }
401 
WP_SaberSetDefaults(saberInfo_t * saber)402 void WP_SaberSetDefaults( saberInfo_t *saber ) {
403 	int i;
404 
405 	//Set defaults so that, if it fails, there's at least something there
406 	for ( i=0; i<MAX_BLADES; i++ ) {
407 		saber->blade[i].color = SABER_RED;
408 		saber->blade[i].radius = SABER_RADIUS_STANDARD;
409 		saber->blade[i].lengthMax = 32;
410 	}
411 
412 	Q_strncpyz( saber->name, DEFAULT_SABER, sizeof( saber->name ) );
413 	Q_strncpyz( saber->fullName, "lightsaber", sizeof( saber->fullName ) );
414 	Q_strncpyz( saber->model, DEFAULT_SABER_MODEL, sizeof( saber->model ) );
415 	saber->skin					= 0;
416 	saber->soundOn				= BG_SoundIndex( "sound/weapons/saber/enemy_saber_on.wav" );
417 	saber->soundLoop			= BG_SoundIndex( "sound/weapons/saber/saberhum3.wav" );
418 	saber->soundOff				= BG_SoundIndex( "sound/weapons/saber/enemy_saber_off.wav" );
419 	saber->numBlades			= 1;
420 	saber->type					= SABER_SINGLE;
421 	saber->stylesLearned		= 0;
422 	saber->stylesForbidden		= 0;			// allow all styles
423 	saber->maxChain				= 0;			// 0 = use default behavior
424 	saber->forceRestrictions	= 0;
425 	saber->lockBonus			= 0;
426 	saber->parryBonus			= 0;
427 	saber->breakParryBonus		= 0;
428 	saber->breakParryBonus2		= 0;
429 	saber->disarmBonus			= 0;
430 	saber->disarmBonus2			= 0;
431 	saber->singleBladeStyle		= SS_NONE;		// makes it so that you use a different style if you only have the first blade active
432 
433 //===NEW========================================================================================
434 	//done in cgame (client-side code)
435 	saber->saberFlags			= 0;			// see all the SFL_ flags
436 	saber->saberFlags2			= 0;			// see all the SFL2_ flags
437 
438 	saber->spinSound			= 0;			// none - if set, plays this sound as it spins when thrown
439 	saber->swingSound[0]		= 0;			// none - if set, plays one of these 3 sounds when swung during an attack - NOTE: must provide all 3!!!
440 	saber->swingSound[1]		= 0;			// none - if set, plays one of these 3 sounds when swung during an attack - NOTE: must provide all 3!!!
441 	saber->swingSound[2]		= 0;			// none - if set, plays one of these 3 sounds when swung during an attack - NOTE: must provide all 3!!!
442 
443 	//done in game (server-side code)
444 	saber->moveSpeedScale		= 1.0f;			// 1.0 - you move faster/slower when using this saber
445 	saber->animSpeedScale		= 1.0f;			// 1.0 - plays normal attack animations faster/slower
446 
447 	saber->kataMove				= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they press both attack buttons at the same time
448 	saber->lungeAtkMove			= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they crouch+fwd+attack
449 	saber->jumpAtkUpMove		= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they jump+attack
450 	saber->jumpAtkFwdMove		= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they jump+fwd+attack
451 	saber->jumpAtkBackMove		= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they jump+back+attack
452 	saber->jumpAtkRightMove		= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they jump+rightattack
453 	saber->jumpAtkLeftMove		= LS_INVALID;	// LS_INVALID - if set, player will execute this move when they jump+left+attack
454 	saber->readyAnim			= -1;			// -1 - anim to use when standing idle
455 	saber->drawAnim				= -1;			// -1 - anim to use when drawing weapon
456 	saber->putawayAnim			= -1;			// -1 - anim to use when putting weapon away
457 	saber->tauntAnim			= -1;			// -1 - anim to use when hit "taunt"
458 	saber->bowAnim				= -1;			// -1 - anim to use when hit "bow"
459 	saber->meditateAnim			= -1;			// -1 - anim to use when hit "meditate"
460 	saber->flourishAnim			= -1;			// -1 - anim to use when hit "flourish"
461 	saber->gloatAnim			= -1;			// -1 - anim to use when hit "gloat"
462 
463 	//***NOTE: you can only have a maximum of 2 "styles" of blades, so this next value, "bladeStyle2Start" is the number of the first blade to use these value on... all blades before this use the normal values above, all blades at and after this number use the secondary values below***
464 	saber->bladeStyle2Start		= 0;			// 0 - if set, blades from this number and higher use the following values (otherwise, they use the normal values already set)
465 
466 	//***The following can be different for the extra blades - not setting them individually defaults them to the value for the whole saber (and first blade)***
467 
468 	//===PRIMARY BLADES=====================
469 	//done in cgame (client-side code)
470 	saber->trailStyle			= 0;			// 0 - default (0) is normal, 1 is a motion blur and 2 is no trail at all (good for real-sword type mods)
471 	saber->g2MarksShader		= 0;			// none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
472 	saber->g2WeaponMarkShader	= 0;			// none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
473 	saber->hitSound[0]			= 0;			// none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
474 	saber->hitSound[1]			= 0;			// none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
475 	saber->hitSound[2]			= 0;			// none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
476 	saber->blockSound[0]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits another saber/sword - NOTE: must provide all 3!!!
477 	saber->blockSound[1]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits another saber/sword - NOTE: must provide all 3!!!
478 	saber->blockSound[2]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits another saber/sword - NOTE: must provide all 3!!!
479 	saber->bounceSound[0]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits a wall and bounces off (must set bounceOnWall to 1 to use these sounds) - NOTE: must provide all 3!!!
480 	saber->bounceSound[1]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits a wall and bounces off (must set bounceOnWall to 1 to use these sounds) - NOTE: must provide all 3!!!
481 	saber->bounceSound[2]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits a wall and bounces off (must set bounceOnWall to 1 to use these sounds) - NOTE: must provide all 3!!!
482 	saber->blockEffect			= 0;			// none - if set, plays this effect when the saber/sword hits another saber/sword (instead of "saber/saber_block.efx")
483 	saber->hitPersonEffect		= 0;			// none - if set, plays this effect when the saber/sword hits a person (instead of "saber/blood_sparks_mp.efx")
484 	saber->hitOtherEffect		= 0;			// none - if set, plays this effect when the saber/sword hits something else damagable (instead of "saber/saber_cut.efx")
485 	saber->bladeEffect			= 0;			// none - if set, plays this effect at the blade tag
486 
487 	//done in game (server-side code)
488 	saber->knockbackScale		= 0;			// 0 - if non-zero, uses damage done to calculate an appropriate amount of knockback
489 	saber->damageScale			= 1.0f;			// 1 - scale up or down the damage done by the saber
490 	saber->splashRadius			= 0.0f;			// 0 - radius of splashDamage
491 	saber->splashDamage			= 0;			// 0 - amount of splashDamage, 100% at a distance of 0, 0% at a distance = splashRadius
492 	saber->splashKnockback		= 0.0f;			// 0 - amount of splashKnockback, 100% at a distance of 0, 0% at a distance = splashRadius
493 
494 	//===SECONDARY BLADES===================
495 	//done in cgame (client-side code)
496 	saber->trailStyle2			= 0;			// 0 - default (0) is normal, 1 is a motion blur and 2 is no trail at all (good for real-sword type mods)
497 	saber->g2MarksShader2		= 0;			// none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
498 	saber->g2WeaponMarkShader2	= 0;			// none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
499 	saber->hit2Sound[0]			= 0;			// none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
500 	saber->hit2Sound[1]			= 0;			// none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
501 	saber->hit2Sound[2]			= 0;			// none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
502 	saber->block2Sound[0]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits another saber/sword - NOTE: must provide all 3!!!
503 	saber->block2Sound[1]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits another saber/sword - NOTE: must provide all 3!!!
504 	saber->block2Sound[2]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits another saber/sword - NOTE: must provide all 3!!!
505 	saber->bounce2Sound[0]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits a wall and bounces off (must set bounceOnWall to 1 to use these sounds) - NOTE: must provide all 3!!!
506 	saber->bounce2Sound[1]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits a wall and bounces off (must set bounceOnWall to 1 to use these sounds) - NOTE: must provide all 3!!!
507 	saber->bounce2Sound[2]		= 0;			// none - if set, plays one of these 3 sounds when saber/sword hits a wall and bounces off (must set bounceOnWall to 1 to use these sounds) - NOTE: must provide all 3!!!
508 	saber->blockEffect2			= 0;			// none - if set, plays this effect when the saber/sword hits another saber/sword (instead of "saber/saber_block.efx")
509 	saber->hitPersonEffect2		= 0;			// none - if set, plays this effect when the saber/sword hits a person (instead of "saber/blood_sparks_mp.efx")
510 	saber->hitOtherEffect2		= 0;			// none - if set, plays this effect when the saber/sword hits something else damagable (instead of "saber/saber_cut.efx")
511 	saber->bladeEffect2			= 0;			// none - if set, plays this effect at the blade tag
512 
513 	//done in game (server-side code)
514 	saber->knockbackScale2		= 0;			// 0 - if non-zero, uses damage done to calculate an appropriate amount of knockback
515 	saber->damageScale2			= 1.0f;			// 1 - scale up or down the damage done by the saber
516 	saber->splashRadius2		= 0.0f;			// 0 - radius of splashDamage
517 	saber->splashDamage2		= 0;			// 0 - amount of splashDamage, 100% at a distance of 0, 0% at a distance = splashRadius
518 	saber->splashKnockback2		= 0.0f;			// 0 - amount of splashKnockback, 100% at a distance of 0, 0% at a distance = splashRadius
519 //=========================================================================================================================================
520 }
521 
522 
Saber_ParseName(saberInfo_t * saber,const char ** p)523 static void Saber_ParseName( saberInfo_t *saber, const char **p ) {
524 	const char *value;
525 	if ( COM_ParseString( p, &value ) )
526 		return;
527 	Q_strncpyz( saber->fullName, value, sizeof( saber->fullName ) );
528 }
Saber_ParseSaberType(saberInfo_t * saber,const char ** p)529 static void Saber_ParseSaberType( saberInfo_t *saber, const char **p ) {
530 	const char *value;
531 	int saberType;
532 	if ( COM_ParseString( p, &value ) )
533 		return;
534 	saberType = GetIDForString( saberTable, value );
535 	if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS )
536 		saber->type = (saberType_t)saberType;
537 }
Saber_ParseSaberModel(saberInfo_t * saber,const char ** p)538 static void Saber_ParseSaberModel( saberInfo_t *saber, const char **p ) {
539 	const char *value;
540 	if ( COM_ParseString( p, &value ) )
541 		return;
542 	Q_strncpyz( saber->model, value, sizeof( saber->model ) );
543 }
Saber_ParseCustomSkin(saberInfo_t * saber,const char ** p)544 static void Saber_ParseCustomSkin( saberInfo_t *saber, const char **p ) {
545 	const char *value;
546 	if ( COM_ParseString( p, &value ) )
547 		return;
548 	saber->skin = trap->R_RegisterSkin( value );
549 }
Saber_ParseSoundOn(saberInfo_t * saber,const char ** p)550 static void Saber_ParseSoundOn( saberInfo_t *saber, const char **p ) {
551 	const char *value;
552 	if ( COM_ParseString( p, &value ) )
553 		return;
554 	saber->soundOn = BG_SoundIndex( value );
555 }
Saber_ParseSoundLoop(saberInfo_t * saber,const char ** p)556 static void Saber_ParseSoundLoop( saberInfo_t *saber, const char **p ) {
557 	const char *value;
558 	if ( COM_ParseString( p, &value ) )
559 		return;
560 	saber->soundLoop = BG_SoundIndex( value );
561 }
Saber_ParseSoundOff(saberInfo_t * saber,const char ** p)562 static void Saber_ParseSoundOff( saberInfo_t *saber, const char **p ) {
563 	const char *value;
564 	if ( COM_ParseString( p, &value ) )
565 		return;
566 	saber->soundOff = BG_SoundIndex( value );
567 }
Saber_ParseNumBlades(saberInfo_t * saber,const char ** p)568 static void Saber_ParseNumBlades( saberInfo_t *saber, const char **p ) {
569 	int n;
570 	if ( COM_ParseInt( p, &n ) ) {
571 		SkipRestOfLine( p );
572 		return;
573 	}
574 	if ( n < 1 || n > MAX_BLADES ) {
575 		Com_Error( ERR_DROP, "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", saber->name, n, MAX_BLADES );
576 		return;
577 	}
578 	saber->numBlades = n;
579 }
Saber_ParseSaberColor(saberInfo_t * saber,const char ** p)580 static void Saber_ParseSaberColor( saberInfo_t *saber, const char **p ) {
581 	const char *value;
582 	int i=0;
583 	saber_colors_t color;
584 
585 	if ( COM_ParseString( p, &value ) )
586 		return;
587 
588 	color = TranslateSaberColor( value );
589 	for ( i=0; i<MAX_BLADES; i++ )
590 		saber->blade[i].color = color;
591 }
Saber_ParseSaberColor2(saberInfo_t * saber,const char ** p)592 static void Saber_ParseSaberColor2( saberInfo_t *saber, const char **p ) {
593 	const char *value;
594 	saber_colors_t color;
595 
596 	if ( COM_ParseString( p, &value ) )
597 		return;
598 
599 	color = TranslateSaberColor( value );
600 	saber->blade[1].color = color;
601 }
Saber_ParseSaberColor3(saberInfo_t * saber,const char ** p)602 static void Saber_ParseSaberColor3( saberInfo_t *saber, const char **p ) {
603 	const char *value;
604 	saber_colors_t color;
605 
606 	if ( COM_ParseString( p, &value ) )
607 		return;
608 
609 	color = TranslateSaberColor( value );
610 	saber->blade[2].color = color;
611 }
Saber_ParseSaberColor4(saberInfo_t * saber,const char ** p)612 static void Saber_ParseSaberColor4( saberInfo_t *saber, const char **p ) {
613 	const char *value;
614 	saber_colors_t color;
615 
616 	if ( COM_ParseString( p, &value ) )
617 		return;
618 
619 	color = TranslateSaberColor( value );
620 	saber->blade[3].color = color;
621 }
Saber_ParseSaberColor5(saberInfo_t * saber,const char ** p)622 static void Saber_ParseSaberColor5( saberInfo_t *saber, const char **p ) {
623 	const char *value;
624 	saber_colors_t color;
625 
626 	if ( COM_ParseString( p, &value ) )
627 		return;
628 
629 	color = TranslateSaberColor( value );
630 	saber->blade[4].color = color;
631 }
Saber_ParseSaberColor6(saberInfo_t * saber,const char ** p)632 static void Saber_ParseSaberColor6( saberInfo_t *saber, const char **p ) {
633 	const char *value;
634 	saber_colors_t color;
635 
636 	if ( COM_ParseString( p, &value ) )
637 		return;
638 
639 	color = TranslateSaberColor( value );
640 	saber->blade[5].color = color;
641 }
Saber_ParseSaberColor7(saberInfo_t * saber,const char ** p)642 static void Saber_ParseSaberColor7( saberInfo_t *saber, const char **p ) {
643 	const char *value;
644 	saber_colors_t color;
645 
646 	if ( COM_ParseString( p, &value ) )
647 		return;
648 
649 	color = TranslateSaberColor( value );
650 	saber->blade[6].color = color;
651 }
Saber_ParseSaberLength(saberInfo_t * saber,const char ** p)652 static void Saber_ParseSaberLength( saberInfo_t *saber, const char **p ) {
653 	int i=0;
654 	float f;
655 
656 	if ( COM_ParseFloat( p, &f ) )
657 		return;
658 
659 	if ( f < 4.0f )
660 		f = 4.0f;
661 
662 	for ( i=0; i<MAX_BLADES; i++ )
663 		saber->blade[i].lengthMax = f;
664 }
Saber_ParseSaberLength2(saberInfo_t * saber,const char ** p)665 static void Saber_ParseSaberLength2( saberInfo_t *saber, const char **p ) {
666 	float f;
667 
668 	if ( COM_ParseFloat( p, &f ) )
669 		return;
670 
671 	if ( f < 4.0f )
672 		f = 4.0f;
673 
674 	saber->blade[1].lengthMax = f;
675 }
Saber_ParseSaberLength3(saberInfo_t * saber,const char ** p)676 static void Saber_ParseSaberLength3( saberInfo_t *saber, const char **p ) {
677 	float f;
678 
679 	if ( COM_ParseFloat( p, &f ) )
680 		return;
681 
682 	if ( f < 4.0f )
683 		f = 4.0f;
684 
685 	saber->blade[2].lengthMax = f;
686 }
Saber_ParseSaberLength4(saberInfo_t * saber,const char ** p)687 static void Saber_ParseSaberLength4( saberInfo_t *saber, const char **p ) {
688 	float f;
689 
690 	if ( COM_ParseFloat( p, &f ) )
691 		return;
692 
693 	if ( f < 4.0f )
694 		f = 4.0f;
695 
696 	saber->blade[3].lengthMax = f;
697 }
Saber_ParseSaberLength5(saberInfo_t * saber,const char ** p)698 static void Saber_ParseSaberLength5( saberInfo_t *saber, const char **p ) {
699 	float f;
700 
701 	if ( COM_ParseFloat( p, &f ) )
702 		return;
703 
704 	if ( f < 4.0f )
705 		f = 4.0f;
706 
707 	saber->blade[4].lengthMax = f;
708 }
Saber_ParseSaberLength6(saberInfo_t * saber,const char ** p)709 static void Saber_ParseSaberLength6( saberInfo_t *saber, const char **p ) {
710 	float f;
711 
712 	if ( COM_ParseFloat( p, &f ) )
713 		return;
714 
715 	if ( f < 4.0f )
716 		f = 4.0f;
717 
718 	saber->blade[5].lengthMax = f;
719 }
Saber_ParseSaberLength7(saberInfo_t * saber,const char ** p)720 static void Saber_ParseSaberLength7( saberInfo_t *saber, const char **p ) {
721 	float f;
722 
723 	if ( COM_ParseFloat( p, &f ) )
724 		return;
725 
726 	if ( f < 4.0f )
727 		f = 4.0f;
728 
729 	saber->blade[6].lengthMax = f;
730 }
Saber_ParseSaberRadius(saberInfo_t * saber,const char ** p)731 static void Saber_ParseSaberRadius( saberInfo_t *saber, const char **p ) {
732 	int i=0;
733 	float f;
734 
735 	if ( COM_ParseFloat( p, &f ) )
736 		return;
737 
738 	if ( f < 0.25f )
739 		f = 0.25f;
740 
741 	for ( i=0; i<MAX_BLADES; i++ )
742 		saber->blade[i].radius = f;
743 }
Saber_ParseSaberRadius2(saberInfo_t * saber,const char ** p)744 static void Saber_ParseSaberRadius2( saberInfo_t *saber, const char **p ) {
745 	float f;
746 
747 	if ( COM_ParseFloat( p, &f ) )
748 		return;
749 
750 	if ( f < 0.25f )
751 		f = 0.25f;
752 
753 	saber->blade[1].radius = f;
754 }
Saber_ParseSaberRadius3(saberInfo_t * saber,const char ** p)755 static void Saber_ParseSaberRadius3( saberInfo_t *saber, const char **p ) {
756 	float f;
757 
758 	if ( COM_ParseFloat( p, &f ) )
759 		return;
760 
761 	if ( f < 0.25f )
762 		f = 0.25f;
763 
764 	saber->blade[2].radius = f;
765 }
Saber_ParseSaberRadius4(saberInfo_t * saber,const char ** p)766 static void Saber_ParseSaberRadius4( saberInfo_t *saber, const char **p ) {
767 	float f;
768 
769 	if ( COM_ParseFloat( p, &f ) )
770 		return;
771 
772 	if ( f < 0.25f )
773 		f = 0.25f;
774 
775 	saber->blade[3].radius = f;
776 }
Saber_ParseSaberRadius5(saberInfo_t * saber,const char ** p)777 static void Saber_ParseSaberRadius5( saberInfo_t *saber, const char **p ) {
778 	float f;
779 
780 	if ( COM_ParseFloat( p, &f ) )
781 		return;
782 
783 	if ( f < 0.25f )
784 		f = 0.25f;
785 
786 	saber->blade[4].radius = f;
787 }
Saber_ParseSaberRadius6(saberInfo_t * saber,const char ** p)788 static void Saber_ParseSaberRadius6( saberInfo_t *saber, const char **p ) {
789 	float f;
790 
791 	if ( COM_ParseFloat( p, &f ) )
792 		return;
793 
794 	if ( f < 0.25f )
795 		f = 0.25f;
796 
797 	saber->blade[5].radius = f;
798 }
Saber_ParseSaberRadius7(saberInfo_t * saber,const char ** p)799 static void Saber_ParseSaberRadius7( saberInfo_t *saber, const char **p ) {
800 	float f;
801 
802 	if ( COM_ParseFloat( p, &f ) )
803 		return;
804 
805 	if ( f < 0.25f )
806 		f = 0.25f;
807 
808 	saber->blade[6].radius = f;
809 }
Saber_ParseSaberStyle(saberInfo_t * saber,const char ** p)810 static void Saber_ParseSaberStyle( saberInfo_t *saber, const char **p ) {
811 	const char *value;
812 	int style, styleNum;
813 
814 	if ( COM_ParseString( p, &value ) )
815 		return;
816 
817 	//OLD WAY: only allowed ONE style
818 	style = TranslateSaberStyle( value );
819 	//learn only this style
820 	saber->stylesLearned = (1<<style);
821 	//forbid all other styles
822 	saber->stylesForbidden = 0;
823 	for ( styleNum=SS_NONE+1; styleNum<SS_NUM_SABER_STYLES; styleNum++ ) {
824 		if ( styleNum != style )
825 			saber->stylesForbidden |= (1<<styleNum);
826 	}
827 }
Saber_ParseSaberStyleLearned(saberInfo_t * saber,const char ** p)828 static void Saber_ParseSaberStyleLearned( saberInfo_t *saber, const char **p ) {
829 	const char *value;
830 	if ( COM_ParseString( p, &value ) )
831 		return;
832 	saber->stylesLearned |= (1<<TranslateSaberStyle( value ));
833 }
Saber_ParseSaberStyleForbidden(saberInfo_t * saber,const char ** p)834 static void Saber_ParseSaberStyleForbidden( saberInfo_t *saber, const char **p ) {
835 	const char *value;
836 	if ( COM_ParseString( p, &value ) )
837 		return;
838 	saber->stylesForbidden |= (1<<TranslateSaberStyle( value ));
839 }
Saber_ParseMaxChain(saberInfo_t * saber,const char ** p)840 static void Saber_ParseMaxChain( saberInfo_t *saber, const char **p ) {
841 	int n;
842 	if ( COM_ParseInt( p, &n ) ) {
843 		SkipRestOfLine( p );
844 		return;
845 	}
846 	saber->maxChain = n;
847 }
Saber_ParseLockable(saberInfo_t * saber,const char ** p)848 static void Saber_ParseLockable( saberInfo_t *saber, const char **p ) {
849 	int n;
850 	if ( COM_ParseInt( p, &n ) ) {
851 		SkipRestOfLine( p );
852 		return;
853 	}
854 	if ( n == 0 )
855 		saber->saberFlags |= SFL_NOT_LOCKABLE;
856 }
Saber_ParseThrowable(saberInfo_t * saber,const char ** p)857 static void Saber_ParseThrowable( saberInfo_t *saber, const char **p ) {
858 	int n;
859 	if ( COM_ParseInt( p, &n ) ) {
860 		SkipRestOfLine( p );
861 		return;
862 	}
863 	if ( n == 0 )
864 		saber->saberFlags |= SFL_NOT_THROWABLE;
865 }
Saber_ParseDisarmable(saberInfo_t * saber,const char ** p)866 static void Saber_ParseDisarmable( saberInfo_t *saber, const char **p ) {
867 	int n;
868 	if ( COM_ParseInt( p, &n ) ) {
869 		SkipRestOfLine( p );
870 		return;
871 	}
872 	if ( n == 0 )
873 		saber->saberFlags |= SFL_NOT_DISARMABLE;
874 }
Saber_ParseBlocking(saberInfo_t * saber,const char ** p)875 static void Saber_ParseBlocking( saberInfo_t *saber, const char **p ) {
876 	int n;
877 	if ( COM_ParseInt( p, &n ) ) {
878 		SkipRestOfLine( p );
879 		return;
880 	}
881 	if ( n == 0 )
882 		saber->saberFlags |= SFL_NOT_ACTIVE_BLOCKING;
883 }
Saber_ParseTwoHanded(saberInfo_t * saber,const char ** p)884 static void Saber_ParseTwoHanded( saberInfo_t *saber, const char **p ) {
885 	int n;
886 	if ( COM_ParseInt( p, &n ) ) {
887 		SkipRestOfLine( p );
888 		return;
889 	}
890 	if ( n )
891 		saber->saberFlags |= SFL_TWO_HANDED;
892 }
Saber_ParseForceRestrict(saberInfo_t * saber,const char ** p)893 static void Saber_ParseForceRestrict( saberInfo_t *saber, const char **p ) {
894 	const char *value;
895 	int fp;
896 
897 	if ( COM_ParseString( p, &value ) )
898 		return;
899 
900 	fp = GetIDForString( FPTable, value );
901 	if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS )
902 		saber->forceRestrictions |= (1<<fp);
903 }
Saber_ParseLockBonus(saberInfo_t * saber,const char ** p)904 static void Saber_ParseLockBonus( saberInfo_t *saber, const char **p ) {
905 	int n;
906 	if ( COM_ParseInt( p, &n ) ) {
907 		SkipRestOfLine( p );
908 		return;
909 	}
910 	saber->lockBonus = n;
911 }
Saber_ParseParryBonus(saberInfo_t * saber,const char ** p)912 static void Saber_ParseParryBonus( saberInfo_t *saber, const char **p ) {
913 	int n;
914 	if ( COM_ParseInt( p, &n ) ) {
915 		SkipRestOfLine( p );
916 		return;
917 	}
918 	saber->parryBonus = n;
919 }
Saber_ParseBreakParryBonus(saberInfo_t * saber,const char ** p)920 static void Saber_ParseBreakParryBonus( saberInfo_t *saber, const char **p ) {
921 	int n;
922 	if ( COM_ParseInt( p, &n ) ) {
923 		SkipRestOfLine( p );
924 		return;
925 	}
926 	saber->breakParryBonus = n;
927 }
Saber_ParseBreakParryBonus2(saberInfo_t * saber,const char ** p)928 static void Saber_ParseBreakParryBonus2( saberInfo_t *saber, const char **p ) {
929 	int n;
930 	if ( COM_ParseInt( p, &n ) ) {
931 		SkipRestOfLine( p );
932 		return;
933 	}
934 	saber->breakParryBonus2 = n;
935 }
Saber_ParseDisarmBonus(saberInfo_t * saber,const char ** p)936 static void Saber_ParseDisarmBonus( saberInfo_t *saber, const char **p ) {
937 	int n;
938 	if ( COM_ParseInt( p, &n ) ) {
939 		SkipRestOfLine( p );
940 		return;
941 	}
942 	saber->disarmBonus = n;
943 }
Saber_ParseDisarmBonus2(saberInfo_t * saber,const char ** p)944 static void Saber_ParseDisarmBonus2( saberInfo_t *saber, const char **p ) {
945 	int n;
946 	if ( COM_ParseInt( p, &n ) ) {
947 		SkipRestOfLine( p );
948 		return;
949 	}
950 	saber->disarmBonus2 = n;
951 }
Saber_ParseSingleBladeStyle(saberInfo_t * saber,const char ** p)952 static void Saber_ParseSingleBladeStyle( saberInfo_t *saber, const char **p ) {
953 	const char *value;
954 	if ( COM_ParseString( p, &value ) )
955 		return;
956 	saber->singleBladeStyle = TranslateSaberStyle( value );
957 }
Saber_ParseSingleBladeThrowable(saberInfo_t * saber,const char ** p)958 static void Saber_ParseSingleBladeThrowable( saberInfo_t *saber, const char **p ) {
959 	int n;
960 	if ( COM_ParseInt( p, &n ) ) {
961 		SkipRestOfLine( p );
962 		return;
963 	}
964 	if ( n )
965 		saber->saberFlags |= SFL_SINGLE_BLADE_THROWABLE;
966 }
Saber_ParseBrokenSaber1(saberInfo_t * saber,const char ** p)967 static void Saber_ParseBrokenSaber1( saberInfo_t *saber, const char **p ) {
968 	const char *value;
969 	if ( COM_ParseString( p, &value ) )
970 		return;
971 	//saber->brokenSaber1 = G_NewString( value );
972 }
Saber_ParseBrokenSaber2(saberInfo_t * saber,const char ** p)973 static void Saber_ParseBrokenSaber2( saberInfo_t *saber, const char **p ) {
974 	const char *value;
975 	if ( COM_ParseString( p, &value ) )
976 		return;
977 	//saber->brokenSaber2 = G_NewString( value );
978 }
Saber_ParseReturnDamage(saberInfo_t * saber,const char ** p)979 static void Saber_ParseReturnDamage( saberInfo_t *saber, const char **p ) {
980 	int n;
981 	if ( COM_ParseInt( p, &n ) ) {
982 		SkipRestOfLine( p );
983 		return;
984 	}
985 	if ( n )
986 		saber->saberFlags |= SFL_RETURN_DAMAGE;
987 }
Saber_ParseSpinSound(saberInfo_t * saber,const char ** p)988 static void Saber_ParseSpinSound( saberInfo_t *saber, const char **p ) {
989 	const char *value;
990 	if ( COM_ParseString( p, &value ) )
991 		return;
992 	saber->spinSound = BG_SoundIndex( value );
993 }
Saber_ParseSwingSound1(saberInfo_t * saber,const char ** p)994 static void Saber_ParseSwingSound1( saberInfo_t *saber, const char **p ) {
995 	const char *value;
996 	if ( COM_ParseString( p, &value ) )
997 		return;
998 	saber->swingSound[0] = BG_SoundIndex( value );
999 }
Saber_ParseSwingSound2(saberInfo_t * saber,const char ** p)1000 static void Saber_ParseSwingSound2( saberInfo_t *saber, const char **p ) {
1001 	const char *value;
1002 	if ( COM_ParseString( p, &value ) )
1003 		return;
1004 	saber->swingSound[1] = BG_SoundIndex( value );
1005 }
Saber_ParseSwingSound3(saberInfo_t * saber,const char ** p)1006 static void Saber_ParseSwingSound3( saberInfo_t *saber, const char **p ) {
1007 	const char *value;
1008 	if ( COM_ParseString( p, &value ) )
1009 		return;
1010 	saber->swingSound[2] = BG_SoundIndex( value );
1011 }
Saber_ParseMoveSpeedScale(saberInfo_t * saber,const char ** p)1012 static void Saber_ParseMoveSpeedScale( saberInfo_t *saber, const char **p ) {
1013 	float f;
1014 	if ( COM_ParseFloat( p, &f ) ) {
1015 		SkipRestOfLine( p );
1016 		return;
1017 	}
1018 	saber->moveSpeedScale = f;
1019 }
Saber_ParseAnimSpeedScale(saberInfo_t * saber,const char ** p)1020 static void Saber_ParseAnimSpeedScale( saberInfo_t *saber, const char **p ) {
1021 	float f;
1022 	if ( COM_ParseFloat( p, &f ) ) {
1023 		SkipRestOfLine( p );
1024 		return;
1025 	}
1026 	saber->animSpeedScale = f;
1027 }
Saber_ParseBounceOnWalls(saberInfo_t * saber,const char ** p)1028 static void Saber_ParseBounceOnWalls( saberInfo_t *saber, const char **p ) {
1029 	int n;
1030 	if ( COM_ParseInt( p, &n ) ) {
1031 		SkipRestOfLine( p );
1032 		return;
1033 	}
1034 	if ( n )
1035 		saber->saberFlags |= SFL_BOUNCE_ON_WALLS;
1036 }
Saber_ParseBoltToWrist(saberInfo_t * saber,const char ** p)1037 static void Saber_ParseBoltToWrist( saberInfo_t *saber, const char **p ) {
1038 	int n;
1039 	if ( COM_ParseInt( p, &n ) ) {
1040 		SkipRestOfLine( p );
1041 		return;
1042 	}
1043 	if ( n )
1044 		saber->saberFlags |= SFL_BOLT_TO_WRIST;
1045 }
Saber_ParseKataMove(saberInfo_t * saber,const char ** p)1046 static void Saber_ParseKataMove( saberInfo_t *saber, const char **p ) {
1047 	const char *value;
1048 	int saberMove = LS_INVALID;
1049 	if ( COM_ParseString( p, &value ) )
1050 		return;
1051 	saberMove = GetIDForString( saberMoveTable, value );
1052 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1053 		saber->kataMove = saberMove; //LS_INVALID - if set, player will execute this move when they press both attack buttons at the same time
1054 }
Saber_ParseLungeAtkMove(saberInfo_t * saber,const char ** p)1055 static void Saber_ParseLungeAtkMove( saberInfo_t *saber, const char **p ) {
1056 	const char *value;
1057 	int saberMove = LS_INVALID;
1058 	if ( COM_ParseString( p, &value ) )
1059 		return;
1060 	saberMove = GetIDForString( saberMoveTable, value );
1061 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1062 		saber->lungeAtkMove = saberMove;
1063 }
Saber_ParseJumpAtkUpMove(saberInfo_t * saber,const char ** p)1064 static void Saber_ParseJumpAtkUpMove( saberInfo_t *saber, const char **p ) {
1065 	const char *value;
1066 	int saberMove = LS_INVALID;
1067 	if ( COM_ParseString( p, &value ) )
1068 		return;
1069 	saberMove = GetIDForString( saberMoveTable, value );
1070 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1071 		saber->jumpAtkUpMove = saberMove;
1072 }
Saber_ParseJumpAtkFwdMove(saberInfo_t * saber,const char ** p)1073 static void Saber_ParseJumpAtkFwdMove( saberInfo_t *saber, const char **p ) {
1074 	const char *value;
1075 	int saberMove = LS_INVALID;
1076 	if ( COM_ParseString( p, &value ) )
1077 		return;
1078 	saberMove = GetIDForString( saberMoveTable, value );
1079 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1080 		saber->jumpAtkFwdMove = saberMove;
1081 }
Saber_ParseJumpAtkBackMove(saberInfo_t * saber,const char ** p)1082 static void Saber_ParseJumpAtkBackMove( saberInfo_t *saber, const char **p ) {
1083 	const char *value;
1084 	int saberMove = LS_INVALID;
1085 	if ( COM_ParseString( p, &value ) )
1086 		return;
1087 	saberMove = GetIDForString( saberMoveTable, value );
1088 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1089 		saber->jumpAtkBackMove = saberMove;
1090 }
Saber_ParseJumpAtkRightMove(saberInfo_t * saber,const char ** p)1091 static void Saber_ParseJumpAtkRightMove( saberInfo_t *saber, const char **p ) {
1092 	const char *value;
1093 	int saberMove = LS_INVALID;
1094 	if ( COM_ParseString( p, &value ) )
1095 		return;
1096 	saberMove = GetIDForString( saberMoveTable, value );
1097 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1098 		saber->jumpAtkRightMove = saberMove;
1099 }
Saber_ParseJumpAtkLeftMove(saberInfo_t * saber,const char ** p)1100 static void Saber_ParseJumpAtkLeftMove( saberInfo_t *saber, const char **p ) {
1101 	const char *value;
1102 	int saberMove = LS_INVALID;
1103 	if ( COM_ParseString( p, &value ) )
1104 		return;
1105 	saberMove = GetIDForString( saberMoveTable, value );
1106 	if ( saberMove >= LS_INVALID && saberMove < LS_MOVE_MAX )
1107 		saber->jumpAtkLeftMove = saberMove;
1108 }
Saber_ParseReadyAnim(saberInfo_t * saber,const char ** p)1109 static void Saber_ParseReadyAnim( saberInfo_t *saber, const char **p ) {
1110 	const char *value;
1111 	int anim = -1;
1112 	if ( COM_ParseString( p, &value ) )
1113 		return;
1114 	anim = GetIDForString( animTable, value );
1115 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1116 		saber->readyAnim = anim;
1117 }
Saber_ParseDrawAnim(saberInfo_t * saber,const char ** p)1118 static void Saber_ParseDrawAnim( saberInfo_t *saber, const char **p ) {
1119 	const char *value;
1120 	int anim = -1;
1121 	if ( COM_ParseString( p, &value ) )
1122 		return;
1123 	anim = GetIDForString( animTable, value );
1124 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1125 		saber->drawAnim = anim;
1126 }
Saber_ParsePutawayAnim(saberInfo_t * saber,const char ** p)1127 static void Saber_ParsePutawayAnim( saberInfo_t *saber, const char **p ) {
1128 	const char *value;
1129 	int anim = -1;
1130 	if ( COM_ParseString( p, &value ) )
1131 		return;
1132 	anim = GetIDForString( animTable, value );
1133 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1134 		saber->putawayAnim = anim;
1135 }
Saber_ParseTauntAnim(saberInfo_t * saber,const char ** p)1136 static void Saber_ParseTauntAnim( saberInfo_t *saber, const char **p ) {
1137 	const char *value;
1138 	int anim = -1;
1139 	if ( COM_ParseString( p, &value ) )
1140 		return;
1141 	anim = GetIDForString( animTable, value );
1142 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1143 		saber->tauntAnim = anim;
1144 }
Saber_ParseBowAnim(saberInfo_t * saber,const char ** p)1145 static void Saber_ParseBowAnim( saberInfo_t *saber, const char **p ) {
1146 	const char *value;
1147 	int anim = -1;
1148 	if ( COM_ParseString( p, &value ) )
1149 		return;
1150 
1151 	anim = GetIDForString( animTable, value );
1152 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1153 		saber->bowAnim = anim;
1154 }
Saber_ParseMeditateAnim(saberInfo_t * saber,const char ** p)1155 static void Saber_ParseMeditateAnim( saberInfo_t *saber, const char **p ) {
1156 	const char *value;
1157 	int anim = -1;
1158 	if ( COM_ParseString( p, &value ) )
1159 		return;
1160 	anim = GetIDForString( animTable, value );
1161 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1162 		saber->meditateAnim = anim;
1163 }
Saber_ParseFlourishAnim(saberInfo_t * saber,const char ** p)1164 static void Saber_ParseFlourishAnim( saberInfo_t *saber, const char **p ) {
1165 	const char *value;
1166 	int anim = -1;
1167 	if ( COM_ParseString( p, &value ) )
1168 		return;
1169 	anim = GetIDForString( animTable, value );
1170 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1171 		saber->flourishAnim = anim;
1172 }
Saber_ParseGloatAnim(saberInfo_t * saber,const char ** p)1173 static void Saber_ParseGloatAnim( saberInfo_t *saber, const char **p ) {
1174 	const char *value;
1175 	int anim = -1;
1176 	if ( COM_ParseString( p, &value ) )
1177 		return;
1178 	anim = GetIDForString( animTable, value );
1179 	if ( anim >= 0 && anim < MAX_ANIMATIONS )
1180 		saber->gloatAnim = anim;
1181 }
Saber_ParseNoRollStab(saberInfo_t * saber,const char ** p)1182 static void Saber_ParseNoRollStab( saberInfo_t *saber, const char **p ) {
1183 	int n;
1184 	if ( COM_ParseInt( p, &n ) ) {
1185 		SkipRestOfLine( p );
1186 		return;
1187 	}
1188 	if ( n )
1189 		saber->saberFlags |= SFL_NO_ROLL_STAB;
1190 }
Saber_ParseNoPullAttack(saberInfo_t * saber,const char ** p)1191 static void Saber_ParseNoPullAttack( saberInfo_t *saber, const char **p ) {
1192 	int n;
1193 	if ( COM_ParseInt( p, &n ) ) {
1194 		SkipRestOfLine( p );
1195 		return;
1196 	}
1197 	if ( n )
1198 		saber->saberFlags |= SFL_NO_PULL_ATTACK;
1199 }
Saber_ParseNoBackAttack(saberInfo_t * saber,const char ** p)1200 static void Saber_ParseNoBackAttack( saberInfo_t *saber, const char **p ) {
1201 	int n;
1202 	if ( COM_ParseInt( p, &n ) ) {
1203 		SkipRestOfLine( p );
1204 		return;
1205 	}
1206 	if ( n )
1207 		saber->saberFlags |= SFL_NO_BACK_ATTACK;
1208 }
Saber_ParseNoStabDown(saberInfo_t * saber,const char ** p)1209 static void Saber_ParseNoStabDown( saberInfo_t *saber, const char **p ) {
1210 	int n;
1211 	if ( COM_ParseInt( p, &n ) ) {
1212 		SkipRestOfLine( p );
1213 		return;
1214 	}
1215 	if ( n )
1216 		saber->saberFlags |= SFL_NO_STABDOWN;
1217 }
Saber_ParseNoWallRuns(saberInfo_t * saber,const char ** p)1218 static void Saber_ParseNoWallRuns( saberInfo_t *saber, const char **p ) {
1219 	int n;
1220 	if ( COM_ParseInt( p, &n ) ) {
1221 		SkipRestOfLine( p );
1222 		return;
1223 	}
1224 	if ( n )
1225 		saber->saberFlags |= SFL_NO_WALL_RUNS;
1226 }
Saber_ParseNoWallFlips(saberInfo_t * saber,const char ** p)1227 static void Saber_ParseNoWallFlips( saberInfo_t *saber, const char **p ) {
1228 	int n;
1229 	if ( COM_ParseInt( p, &n ) ) {
1230 		SkipRestOfLine( p );
1231 		return;
1232 	}
1233 	if ( n )
1234 		saber->saberFlags |= SFL_NO_WALL_FLIPS;
1235 }
Saber_ParseNoWallGrab(saberInfo_t * saber,const char ** p)1236 static void Saber_ParseNoWallGrab( saberInfo_t *saber, const char **p ) {
1237 	int n;
1238 	if ( COM_ParseInt( p, &n ) ) {
1239 		SkipRestOfLine( p );
1240 		return;
1241 	}
1242 	if ( n )
1243 		saber->saberFlags |= SFL_NO_WALL_GRAB;
1244 }
Saber_ParseNoRolls(saberInfo_t * saber,const char ** p)1245 static void Saber_ParseNoRolls( saberInfo_t *saber, const char **p ) {
1246 	int n;
1247 	if ( COM_ParseInt( p, &n ) ) {
1248 		SkipRestOfLine( p );
1249 		return;
1250 	}
1251 	if ( n )
1252 		saber->saberFlags |= SFL_NO_ROLLS;
1253 }
Saber_ParseNoFlips(saberInfo_t * saber,const char ** p)1254 static void Saber_ParseNoFlips( saberInfo_t *saber, const char **p ) {
1255 	int n;
1256 	if ( COM_ParseInt( p, &n ) ) {
1257 		SkipRestOfLine( p );
1258 		return;
1259 	}
1260 	if ( n )
1261 		saber->saberFlags |= SFL_NO_FLIPS;
1262 }
Saber_ParseNoCartwheels(saberInfo_t * saber,const char ** p)1263 static void Saber_ParseNoCartwheels( saberInfo_t *saber, const char **p ) {
1264 	int n;
1265 	if ( COM_ParseInt( p, &n ) ) {
1266 		SkipRestOfLine( p );
1267 		return;
1268 	}
1269 	if ( n )
1270 		saber->saberFlags |= SFL_NO_CARTWHEELS;
1271 }
Saber_ParseNoKicks(saberInfo_t * saber,const char ** p)1272 static void Saber_ParseNoKicks( saberInfo_t *saber, const char **p ) {
1273 	int n;
1274 	if ( COM_ParseInt( p, &n ) ) {
1275 		SkipRestOfLine( p );
1276 		return;
1277 	}
1278 	if ( n )
1279 		saber->saberFlags |= SFL_NO_KICKS;
1280 }
Saber_ParseNoMirrorAttacks(saberInfo_t * saber,const char ** p)1281 static void Saber_ParseNoMirrorAttacks( saberInfo_t *saber, const char **p ) {
1282 	int n;
1283 	if ( COM_ParseInt( p, &n ) ) {
1284 		SkipRestOfLine( p );
1285 		return;
1286 	}
1287 	if ( n )
1288 		saber->saberFlags |= SFL_NO_MIRROR_ATTACKS;
1289 }
Saber_ParseOnInWater(saberInfo_t * saber,const char ** p)1290 static void Saber_ParseOnInWater( saberInfo_t *saber, const char **p ) {
1291 	SkipRestOfLine( p );
1292 }
Saber_ParseNotInMP(saberInfo_t * saber,const char ** p)1293 static void Saber_ParseNotInMP( saberInfo_t *saber, const char **p ) {
1294 	SkipRestOfLine( p );
1295 }
Saber_ParseBladeStyle2Start(saberInfo_t * saber,const char ** p)1296 static void Saber_ParseBladeStyle2Start( saberInfo_t *saber, const char **p ) {
1297 	int n;
1298 	if ( COM_ParseInt( p, &n ) ) {
1299 		SkipRestOfLine( p );
1300 		return;
1301 	}
1302 	saber->bladeStyle2Start = n;
1303 }
Saber_ParseNoWallMarks(saberInfo_t * saber,const char ** p)1304 static void Saber_ParseNoWallMarks( saberInfo_t *saber, const char **p ) {
1305 	int n;
1306 	if ( COM_ParseInt( p, &n ) ) {
1307 		SkipRestOfLine( p );
1308 		return;
1309 	}
1310 	if ( n )
1311 		saber->saberFlags2 |= SFL2_NO_WALL_MARKS;
1312 }
Saber_ParseNoDLight(saberInfo_t * saber,const char ** p)1313 static void Saber_ParseNoDLight( saberInfo_t *saber, const char **p ) {
1314 	int n;
1315 	if ( COM_ParseInt( p, &n ) ) {
1316 		SkipRestOfLine( p );
1317 		return;
1318 	}
1319 	if ( n )
1320 		saber->saberFlags2 |= SFL2_NO_DLIGHT;
1321 }
Saber_ParseNoBlade(saberInfo_t * saber,const char ** p)1322 static void Saber_ParseNoBlade( saberInfo_t *saber, const char **p ) {
1323 	int n;
1324 	if ( COM_ParseInt( p, &n ) ) {
1325 		SkipRestOfLine( p );
1326 		return;
1327 	}
1328 	if ( n )
1329 		saber->saberFlags2 |= SFL2_NO_BLADE;
1330 }
Saber_ParseTrailStyle(saberInfo_t * saber,const char ** p)1331 static void Saber_ParseTrailStyle( saberInfo_t *saber, const char **p ) {
1332 	int n;
1333 	if ( COM_ParseInt( p, &n ) ) {
1334 		SkipRestOfLine( p );
1335 		return;
1336 	}
1337 	saber->trailStyle = n;
1338 }
Saber_ParseG2MarksShader(saberInfo_t * saber,const char ** p)1339 static void Saber_ParseG2MarksShader( saberInfo_t *saber, const char **p ) {
1340 	const char *value;
1341 	if ( COM_ParseString( p, &value ) ) {
1342 		SkipRestOfLine( p );
1343 		return;
1344 	}
1345 #ifdef _CGAME
1346 	saber->g2MarksShader = trap->R_RegisterShader( value );
1347 #else
1348 	SkipRestOfLine( p );
1349 #endif
1350 }
Saber_ParseG2WeaponMarkShader(saberInfo_t * saber,const char ** p)1351 static void Saber_ParseG2WeaponMarkShader( saberInfo_t *saber, const char **p ) {
1352 	const char *value;
1353 	if ( COM_ParseString( p, &value ) ) {
1354 		SkipRestOfLine( p );
1355 		return;
1356 	}
1357 #ifdef _CGAME
1358 	saber->g2WeaponMarkShader = trap->R_RegisterShader( value );
1359 #else
1360 	SkipRestOfLine( p );
1361 #endif
1362 }
Saber_ParseKnockbackScale(saberInfo_t * saber,const char ** p)1363 static void Saber_ParseKnockbackScale( saberInfo_t *saber, const char **p ) {
1364 	float f;
1365 	if ( COM_ParseFloat( p, &f ) ) {
1366 		SkipRestOfLine( p );
1367 		return;
1368 	}
1369 	saber->knockbackScale = f;
1370 }
Saber_ParseDamageScale(saberInfo_t * saber,const char ** p)1371 static void Saber_ParseDamageScale( saberInfo_t *saber, const char **p ) {
1372 	float f;
1373 	if ( COM_ParseFloat( p, &f ) ) {
1374 		SkipRestOfLine( p );
1375 		return;
1376 	}
1377 	saber->damageScale = f;
1378 }
Saber_ParseNoDismemberment(saberInfo_t * saber,const char ** p)1379 static void Saber_ParseNoDismemberment( saberInfo_t *saber, const char **p ) {
1380 	int n;
1381 	if ( COM_ParseInt( p, &n ) ) {
1382 		SkipRestOfLine( p );
1383 		return;
1384 	}
1385 	if ( n )
1386 		saber->saberFlags2 |= SFL2_NO_DISMEMBERMENT;
1387 }
Saber_ParseNoIdleEffect(saberInfo_t * saber,const char ** p)1388 static void Saber_ParseNoIdleEffect( saberInfo_t *saber, const char **p ) {
1389 	int n;
1390 	if ( COM_ParseInt( p, &n ) ) {
1391 		SkipRestOfLine( p );
1392 		return;
1393 	}
1394 	if ( n )
1395 		saber->saberFlags2 |= SFL2_NO_IDLE_EFFECT;
1396 }
Saber_ParseAlwaysBlock(saberInfo_t * saber,const char ** p)1397 static void Saber_ParseAlwaysBlock( saberInfo_t *saber, const char **p ) {
1398 	int n;
1399 	if ( COM_ParseInt( p, &n ) ) {
1400 		SkipRestOfLine( p );
1401 		return;
1402 	}
1403 	if ( n )
1404 		saber->saberFlags2 |= SFL2_ALWAYS_BLOCK;
1405 }
Saber_ParseNoManualDeactivate(saberInfo_t * saber,const char ** p)1406 static void Saber_ParseNoManualDeactivate( saberInfo_t *saber, const char **p ) {
1407 	int n;
1408 	if ( COM_ParseInt( p, &n ) ) {
1409 		SkipRestOfLine( p );
1410 		return;
1411 	}
1412 	if ( n )
1413 		saber->saberFlags2 |= SFL2_NO_MANUAL_DEACTIVATE;
1414 }
Saber_ParseTransitionDamage(saberInfo_t * saber,const char ** p)1415 static void Saber_ParseTransitionDamage( saberInfo_t *saber, const char **p ) {
1416 	int n;
1417 	if ( COM_ParseInt( p, &n ) ) {
1418 		SkipRestOfLine( p );
1419 		return;
1420 	}
1421 	if ( n )
1422 		saber->saberFlags2 |= SFL2_TRANSITION_DAMAGE;
1423 }
Saber_ParseSplashRadius(saberInfo_t * saber,const char ** p)1424 static void Saber_ParseSplashRadius( saberInfo_t *saber, const char **p ) {
1425 	float f;
1426 	if ( COM_ParseFloat( p, &f ) ) {
1427 		SkipRestOfLine( p );
1428 		return;
1429 	}
1430 	saber->splashRadius = f;
1431 }
Saber_ParseSplashDamage(saberInfo_t * saber,const char ** p)1432 static void Saber_ParseSplashDamage( saberInfo_t *saber, const char **p ) {
1433 	int n;
1434 	if ( COM_ParseInt( p, &n ) ) {
1435 		SkipRestOfLine( p );
1436 		return;
1437 	}
1438 	saber->splashDamage = n;
1439 }
Saber_ParseSplashKnockback(saberInfo_t * saber,const char ** p)1440 static void Saber_ParseSplashKnockback( saberInfo_t *saber, const char **p ) {
1441 	float f;
1442 	if ( COM_ParseFloat( p, &f ) ) {
1443 		SkipRestOfLine( p );
1444 		return;
1445 	}
1446 	saber->splashKnockback = f;
1447 }
Saber_ParseHitSound1(saberInfo_t * saber,const char ** p)1448 static void Saber_ParseHitSound1( saberInfo_t *saber, const char **p ) {
1449 	const char *value;
1450 	if ( COM_ParseString( p, &value ) )
1451 		return;
1452 	saber->hitSound[0] = BG_SoundIndex( value );
1453 }
Saber_ParseHitSound2(saberInfo_t * saber,const char ** p)1454 static void Saber_ParseHitSound2( saberInfo_t *saber, const char **p ) {
1455 	const char *value;
1456 	if ( COM_ParseString( p, &value ) )
1457 		return;
1458 	saber->hitSound[1] = BG_SoundIndex( value );
1459 }
Saber_ParseHitSound3(saberInfo_t * saber,const char ** p)1460 static void Saber_ParseHitSound3( saberInfo_t *saber, const char **p ) {
1461 	const char *value;
1462 	if ( COM_ParseString( p, &value ) )
1463 		return;
1464 	saber->hitSound[2] = BG_SoundIndex( value );
1465 }
Saber_ParseBlockSound1(saberInfo_t * saber,const char ** p)1466 static void Saber_ParseBlockSound1( saberInfo_t *saber, const char **p ) {
1467 	const char *value;
1468 	if ( COM_ParseString( p, &value ) )
1469 		return;
1470 	saber->blockSound[0] = BG_SoundIndex( value );
1471 }
Saber_ParseBlockSound2(saberInfo_t * saber,const char ** p)1472 static void Saber_ParseBlockSound2( saberInfo_t *saber, const char **p ) {
1473 	const char *value;
1474 	if ( COM_ParseString( p, &value ) )
1475 		return;
1476 	saber->blockSound[1] = BG_SoundIndex( value );
1477 }
Saber_ParseBlockSound3(saberInfo_t * saber,const char ** p)1478 static void Saber_ParseBlockSound3( saberInfo_t *saber, const char **p ) {
1479 	const char *value;
1480 	if ( COM_ParseString( p, &value ) )
1481 		return;
1482 	saber->blockSound[2] = BG_SoundIndex( value );
1483 }
Saber_ParseBounceSound1(saberInfo_t * saber,const char ** p)1484 static void Saber_ParseBounceSound1( saberInfo_t *saber, const char **p ) {
1485 	const char *value;
1486 	if ( COM_ParseString( p, &value ) )
1487 		return;
1488 	saber->bounceSound[0] = BG_SoundIndex( value );
1489 }
Saber_ParseBounceSound2(saberInfo_t * saber,const char ** p)1490 static void Saber_ParseBounceSound2( saberInfo_t *saber, const char **p ) {
1491 	const char *value;
1492 	if ( COM_ParseString( p, &value ) )
1493 		return;
1494 	saber->bounceSound[1] = BG_SoundIndex( value );
1495 }
Saber_ParseBounceSound3(saberInfo_t * saber,const char ** p)1496 static void Saber_ParseBounceSound3( saberInfo_t *saber, const char **p ) {
1497 	const char *value;
1498 	if ( COM_ParseString( p, &value ) )
1499 		return;
1500 	saber->bounceSound[2] = BG_SoundIndex( value );
1501 }
Saber_ParseBlockEffect(saberInfo_t * saber,const char ** p)1502 static void Saber_ParseBlockEffect( saberInfo_t *saber, const char **p ) {
1503 	const char *value;
1504 	if ( COM_ParseString( p, &value ) )
1505 		return;
1506 #ifdef _CGAME
1507 	saber->blockEffect = trap->FX_RegisterEffect( value );
1508 #else
1509 	SkipRestOfLine( p );
1510 #endif
1511 }
Saber_ParseHitPersonEffect(saberInfo_t * saber,const char ** p)1512 static void Saber_ParseHitPersonEffect( saberInfo_t *saber, const char **p ) {
1513 	const char *value;
1514 	if ( COM_ParseString( p, &value ) )
1515 		return;
1516 #ifdef _CGAME
1517 	saber->hitPersonEffect = trap->FX_RegisterEffect( value );
1518 #else
1519 	SkipRestOfLine( p );
1520 #endif
1521 }
Saber_ParseHitOtherEffect(saberInfo_t * saber,const char ** p)1522 static void Saber_ParseHitOtherEffect( saberInfo_t *saber, const char **p ) {
1523 	const char *value;
1524 	if ( COM_ParseString( p, &value ) )
1525 		return;
1526 #ifdef _CGAME
1527 	saber->hitOtherEffect = trap->FX_RegisterEffect( value );
1528 #else
1529 	SkipRestOfLine( p );
1530 #endif
1531 }
Saber_ParseBladeEffect(saberInfo_t * saber,const char ** p)1532 static void Saber_ParseBladeEffect( saberInfo_t *saber, const char **p ) {
1533 	const char *value;
1534 	if ( COM_ParseString( p, &value ) )
1535 		return;
1536 #ifdef _CGAME
1537 	saber->bladeEffect = trap->FX_RegisterEffect( value );
1538 #else
1539 	SkipRestOfLine( p );
1540 #endif
1541 }
Saber_ParseNoClashFlare(saberInfo_t * saber,const char ** p)1542 static void Saber_ParseNoClashFlare( saberInfo_t *saber, const char **p ) {
1543 	int n;
1544 	if ( COM_ParseInt( p, &n ) ) {
1545 		SkipRestOfLine( p );
1546 		return;
1547 	}
1548 	if ( n )
1549 		saber->saberFlags2 |= SFL2_NO_CLASH_FLARE;
1550 }
Saber_ParseNoWallMarks2(saberInfo_t * saber,const char ** p)1551 static void Saber_ParseNoWallMarks2( saberInfo_t *saber, const char **p ) {
1552 	int n;
1553 	if ( COM_ParseInt( p, &n ) ) {
1554 		SkipRestOfLine( p );
1555 		return;
1556 	}
1557 	if ( n )
1558 		saber->saberFlags2 |= SFL2_NO_WALL_MARKS2;
1559 }
Saber_ParseNoDLight2(saberInfo_t * saber,const char ** p)1560 static void Saber_ParseNoDLight2( saberInfo_t *saber, const char **p ) {
1561 	int n;
1562 	if ( COM_ParseInt( p, &n ) ) {
1563 		SkipRestOfLine( p );
1564 		return;
1565 	}
1566 	if ( n )
1567 		saber->saberFlags2 |= SFL2_NO_DLIGHT2;
1568 }
Saber_ParseNoBlade2(saberInfo_t * saber,const char ** p)1569 static void Saber_ParseNoBlade2( saberInfo_t *saber, const char **p ) {
1570 	int n;
1571 	if ( COM_ParseInt( p, &n ) ) {
1572 		SkipRestOfLine( p );
1573 		return;
1574 	}
1575 	if ( n )
1576 		saber->saberFlags2 |= SFL2_NO_BLADE2;
1577 }
Saber_ParseTrailStyle2(saberInfo_t * saber,const char ** p)1578 static void Saber_ParseTrailStyle2( saberInfo_t *saber, const char **p ) {
1579 	int n;
1580 	if ( COM_ParseInt( p, &n ) ) {
1581 		SkipRestOfLine( p );
1582 		return;
1583 	}
1584 	saber->trailStyle2 = n;
1585 }
Saber_ParseG2MarksShader2(saberInfo_t * saber,const char ** p)1586 static void Saber_ParseG2MarksShader2( saberInfo_t *saber, const char **p ) {
1587 	const char *value;
1588 	if ( COM_ParseString( p, &value ) ) {
1589 		SkipRestOfLine( p );
1590 		return;
1591 	}
1592 #ifdef _CGAME
1593 	saber->g2MarksShader2 = trap->R_RegisterShader( value );
1594 #else
1595 	SkipRestOfLine( p );
1596 #endif
1597 }
Saber_ParseG2WeaponMarkShader2(saberInfo_t * saber,const char ** p)1598 static void Saber_ParseG2WeaponMarkShader2( saberInfo_t *saber, const char **p ) {
1599 	const char *value;
1600 	if ( COM_ParseString( p, &value ) ) {
1601 		SkipRestOfLine( p );
1602 		return;
1603 	}
1604 #ifdef _CGAME
1605 	saber->g2WeaponMarkShader2 = trap->R_RegisterShader( value );
1606 #else
1607 	SkipRestOfLine( p );
1608 #endif
1609 }
Saber_ParseKnockbackScale2(saberInfo_t * saber,const char ** p)1610 static void Saber_ParseKnockbackScale2( saberInfo_t *saber, const char **p ) {
1611 	float f;
1612 	if ( COM_ParseFloat( p, &f ) ) {
1613 		SkipRestOfLine( p );
1614 		return;
1615 	}
1616 	saber->knockbackScale2 = f;
1617 }
Saber_ParseDamageScale2(saberInfo_t * saber,const char ** p)1618 static void Saber_ParseDamageScale2( saberInfo_t *saber, const char **p ) {
1619 	float f;
1620 	if ( COM_ParseFloat( p, &f ) ) {
1621 		SkipRestOfLine( p );
1622 		return;
1623 	}
1624 	saber->damageScale2 = f;
1625 }
Saber_ParseNoDismemberment2(saberInfo_t * saber,const char ** p)1626 static void Saber_ParseNoDismemberment2( saberInfo_t *saber, const char **p ) {
1627 	int n;
1628 	if ( COM_ParseInt( p, &n ) ) {
1629 		SkipRestOfLine( p );
1630 		return;
1631 	}
1632 	if ( n )
1633 		saber->saberFlags2 |= SFL2_NO_DISMEMBERMENT2;
1634 }
Saber_ParseNoIdleEffect2(saberInfo_t * saber,const char ** p)1635 static void Saber_ParseNoIdleEffect2( saberInfo_t *saber, const char **p ) {
1636 	int n;
1637 	if ( COM_ParseInt( p, &n ) ) {
1638 		SkipRestOfLine( p );
1639 		return;
1640 	}
1641 	if ( n )
1642 		saber->saberFlags2 |= SFL2_NO_IDLE_EFFECT2;
1643 }
Saber_ParseAlwaysBlock2(saberInfo_t * saber,const char ** p)1644 static void Saber_ParseAlwaysBlock2( saberInfo_t *saber, const char **p ) {
1645 	int n;
1646 	if ( COM_ParseInt( p, &n ) ) {
1647 		SkipRestOfLine( p );
1648 		return;
1649 	}
1650 	if ( n )
1651 		saber->saberFlags2 |= SFL2_ALWAYS_BLOCK2;
1652 }
Saber_ParseNoManualDeactivate2(saberInfo_t * saber,const char ** p)1653 static void Saber_ParseNoManualDeactivate2( saberInfo_t *saber, const char **p ) {
1654 	int n;
1655 	if ( COM_ParseInt( p, &n ) ) {
1656 		SkipRestOfLine( p );
1657 		return;
1658 	}
1659 	if ( n )
1660 		saber->saberFlags2 |= SFL2_NO_MANUAL_DEACTIVATE2;
1661 }
Saber_ParseTransitionDamage2(saberInfo_t * saber,const char ** p)1662 static void Saber_ParseTransitionDamage2( saberInfo_t *saber, const char **p ) {
1663 	int n;
1664 	if ( COM_ParseInt( p, &n ) ) {
1665 		SkipRestOfLine( p );
1666 		return;
1667 	}
1668 	if ( n )
1669 		saber->saberFlags2 |= SFL2_TRANSITION_DAMAGE2;
1670 }
Saber_ParseSplashRadius2(saberInfo_t * saber,const char ** p)1671 static void Saber_ParseSplashRadius2( saberInfo_t *saber, const char **p ) {
1672 	float f;
1673 	if ( COM_ParseFloat( p, &f ) ) {
1674 		SkipRestOfLine( p );
1675 		return;
1676 	}
1677 	saber->splashRadius2 = f;
1678 }
Saber_ParseSplashDamage2(saberInfo_t * saber,const char ** p)1679 static void Saber_ParseSplashDamage2( saberInfo_t *saber, const char **p ) {
1680 	int n;
1681 	if ( COM_ParseInt( p, &n ) ) {
1682 		SkipRestOfLine( p );
1683 		return;
1684 	}
1685 	saber->splashDamage2 = n;
1686 }
Saber_ParseSplashKnockback2(saberInfo_t * saber,const char ** p)1687 static void Saber_ParseSplashKnockback2( saberInfo_t *saber, const char **p ) {
1688 	float f;
1689 	if ( COM_ParseFloat( p, &f ) ) {
1690 		SkipRestOfLine( p );
1691 		return;
1692 	}
1693 	saber->splashKnockback2 = f;
1694 }
Saber_ParseHit2Sound1(saberInfo_t * saber,const char ** p)1695 static void Saber_ParseHit2Sound1( saberInfo_t *saber, const char **p ) {
1696 	const char *value;
1697 	if ( COM_ParseString( p, &value ) )
1698 		return;
1699 	saber->hit2Sound[0] = BG_SoundIndex( value );
1700 }
Saber_ParseHit2Sound2(saberInfo_t * saber,const char ** p)1701 static void Saber_ParseHit2Sound2( saberInfo_t *saber, const char **p ) {
1702 	const char *value;
1703 	if ( COM_ParseString( p, &value ) )
1704 		return;
1705 	saber->hit2Sound[1] = BG_SoundIndex( value );
1706 }
Saber_ParseHit2Sound3(saberInfo_t * saber,const char ** p)1707 static void Saber_ParseHit2Sound3( saberInfo_t *saber, const char **p ) {
1708 	const char *value;
1709 	if ( COM_ParseString( p, &value ) )
1710 		return;
1711 	saber->hit2Sound[2] = BG_SoundIndex( value );
1712 }
Saber_ParseBlock2Sound1(saberInfo_t * saber,const char ** p)1713 static void Saber_ParseBlock2Sound1( saberInfo_t *saber, const char **p ) {
1714 	const char *value;
1715 	if ( COM_ParseString( p, &value ) )
1716 		return;
1717 	saber->block2Sound[0] = BG_SoundIndex( value );
1718 }
Saber_ParseBlock2Sound2(saberInfo_t * saber,const char ** p)1719 static void Saber_ParseBlock2Sound2( saberInfo_t *saber, const char **p ) {
1720 	const char *value;
1721 	if ( COM_ParseString( p, &value ) )
1722 		return;
1723 	saber->block2Sound[1] = BG_SoundIndex( value );
1724 }
Saber_ParseBlock2Sound3(saberInfo_t * saber,const char ** p)1725 static void Saber_ParseBlock2Sound3( saberInfo_t *saber, const char **p ) {
1726 	const char *value;
1727 	if ( COM_ParseString( p, &value ) )
1728 		return;
1729 	saber->block2Sound[2] = BG_SoundIndex( value );
1730 }
Saber_ParseBounce2Sound1(saberInfo_t * saber,const char ** p)1731 static void Saber_ParseBounce2Sound1( saberInfo_t *saber, const char **p ) {
1732 	const char *value;
1733 	if ( COM_ParseString( p, &value ) )
1734 		return;
1735 	saber->bounce2Sound[0] = BG_SoundIndex( value );
1736 }
Saber_ParseBounce2Sound2(saberInfo_t * saber,const char ** p)1737 static void Saber_ParseBounce2Sound2( saberInfo_t *saber, const char **p ) {
1738 	const char *value;
1739 	if ( COM_ParseString( p, &value ) )
1740 		return;
1741 	saber->bounce2Sound[1] = BG_SoundIndex( value );
1742 }
Saber_ParseBounce2Sound3(saberInfo_t * saber,const char ** p)1743 static void Saber_ParseBounce2Sound3( saberInfo_t *saber, const char **p ) {
1744 	const char *value;
1745 	if ( COM_ParseString( p, &value ) )
1746 		return;
1747 	saber->bounce2Sound[2] = BG_SoundIndex( value );
1748 }
Saber_ParseBlockEffect2(saberInfo_t * saber,const char ** p)1749 static void Saber_ParseBlockEffect2( saberInfo_t *saber, const char **p ) {
1750 	const char *value;
1751 	if ( COM_ParseString( p, &value ) )
1752 		return;
1753 #ifdef _CGAME
1754 	saber->blockEffect2 = trap->FX_RegisterEffect( value );
1755 #else
1756 	SkipRestOfLine( p );
1757 #endif
1758 }
Saber_ParseHitPersonEffect2(saberInfo_t * saber,const char ** p)1759 static void Saber_ParseHitPersonEffect2( saberInfo_t *saber, const char **p ) {
1760 	const char *value;
1761 	if ( COM_ParseString( p, &value ) )
1762 		return;
1763 #ifdef _CGAME
1764 	saber->hitPersonEffect2 = trap->FX_RegisterEffect( value );
1765 #else
1766 	SkipRestOfLine( p );
1767 #endif
1768 }
Saber_ParseHitOtherEffect2(saberInfo_t * saber,const char ** p)1769 static void Saber_ParseHitOtherEffect2( saberInfo_t *saber, const char **p ) {
1770 	const char *value;
1771 	if ( COM_ParseString( p, &value ) )
1772 		return;
1773 #ifdef _CGAME
1774 	saber->hitOtherEffect2 = trap->FX_RegisterEffect( value );
1775 #else
1776 	SkipRestOfLine( p );
1777 #endif
1778 }
Saber_ParseBladeEffect2(saberInfo_t * saber,const char ** p)1779 static void Saber_ParseBladeEffect2( saberInfo_t *saber, const char **p ) {
1780 	const char *value;
1781 	if ( COM_ParseString( p, &value ) )
1782 		return;
1783 #ifdef _CGAME
1784 	saber->bladeEffect2 = trap->FX_RegisterEffect( value );
1785 #else
1786 	SkipRestOfLine( p );
1787 #endif
1788 }
Saber_ParseNoClashFlare2(saberInfo_t * saber,const char ** p)1789 static void Saber_ParseNoClashFlare2( saberInfo_t *saber, const char **p ) {
1790 	int n;
1791 	if ( COM_ParseInt( p, &n ) ) {
1792 		SkipRestOfLine( p );
1793 		return;
1794 	}
1795 	if ( n )
1796 		saber->saberFlags2 |= SFL2_NO_CLASH_FLARE2;
1797 }
1798 
1799 
1800 /*
1801 ===============
1802 Keyword Hash
1803 ===============
1804 */
1805 
1806 #define KEYWORDHASH_SIZE (512)
1807 
1808 typedef struct keywordHash_s {
1809 	char	*keyword;
1810 	void	(*func)(saberInfo_t *saber, const char **p);
1811 
1812 	struct keywordHash_s *next;
1813 } keywordHash_t;
1814 
KeywordHash_Key(const char * keyword)1815 static int KeywordHash_Key( const char *keyword ) {
1816 	int register hash, i;
1817 
1818 	hash = 0;
1819 	for ( i=0; keyword[i]; i++ ) {
1820 		if ( keyword[i] >= 'A' && keyword[i] <= 'Z' )
1821 			hash += (keyword[i] + ('a'-'A')) * (119 + i);
1822 		else
1823 			hash += keyword[i] * (119 + i);
1824 	}
1825 
1826 	hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (KEYWORDHASH_SIZE-1);
1827 	return hash;
1828 }
1829 
KeywordHash_Add(keywordHash_t * table[],keywordHash_t * key)1830 static void KeywordHash_Add( keywordHash_t *table[], keywordHash_t *key ) {
1831 	int hash = KeywordHash_Key( key->keyword );
1832 
1833 	key->next = table[hash];
1834 	table[hash] = key;
1835 }
1836 
KeywordHash_Find(keywordHash_t * table[],const char * keyword)1837 static keywordHash_t *KeywordHash_Find( keywordHash_t *table[], const char *keyword ) {
1838 	keywordHash_t *key;
1839 	int hash = KeywordHash_Key(keyword);
1840 
1841 	for ( key=table[hash]; key; key=key->next ) {
1842 		if ( !Q_stricmp( key->keyword, keyword ) )
1843 			return key;
1844 	}
1845 
1846 	return NULL;
1847 }
1848 
1849 static keywordHash_t saberParseKeywords[] = {
1850 	{ "name",					Saber_ParseName,				NULL	},
1851 	{ "saberType",				Saber_ParseSaberType,			NULL	},
1852 	{ "saberModel",				Saber_ParseSaberModel,			NULL	},
1853 	{ "customSkin",				Saber_ParseCustomSkin,			NULL	},
1854 	{ "soundOn",				Saber_ParseSoundOn,				NULL	},
1855 	{ "soundLoop",				Saber_ParseSoundLoop,			NULL	},
1856 	{ "soundOff",				Saber_ParseSoundOff,			NULL	},
1857 	{ "numBlades",				Saber_ParseNumBlades,			NULL	},
1858 	{ "saberColor",				Saber_ParseSaberColor,			NULL	},
1859 	{ "saberColor2",			Saber_ParseSaberColor2,			NULL	},
1860 	{ "saberColor3",			Saber_ParseSaberColor3,			NULL	},
1861 	{ "saberColor4",			Saber_ParseSaberColor4,			NULL	},
1862 	{ "saberColor5",			Saber_ParseSaberColor5,			NULL	},
1863 	{ "saberColor6",			Saber_ParseSaberColor6,			NULL	},
1864 	{ "saberColor7",			Saber_ParseSaberColor7,			NULL	},
1865 	{ "saberLength",			Saber_ParseSaberLength,			NULL	},
1866 	{ "saberLength2",			Saber_ParseSaberLength2,		NULL	},
1867 	{ "saberLength3",			Saber_ParseSaberLength3,		NULL	},
1868 	{ "saberLength4",			Saber_ParseSaberLength4,		NULL	},
1869 	{ "saberLength5",			Saber_ParseSaberLength5,		NULL	},
1870 	{ "saberLength6",			Saber_ParseSaberLength6,		NULL	},
1871 	{ "saberLength7",			Saber_ParseSaberLength7,		NULL	},
1872 	{ "saberRadius",			Saber_ParseSaberRadius,			NULL	},
1873 	{ "saberRadius2",			Saber_ParseSaberRadius2,		NULL	},
1874 	{ "saberRadius3",			Saber_ParseSaberRadius3,		NULL	},
1875 	{ "saberRadius4",			Saber_ParseSaberRadius4,		NULL	},
1876 	{ "saberRadius5",			Saber_ParseSaberRadius5,		NULL	},
1877 	{ "saberRadius6",			Saber_ParseSaberRadius6,		NULL	},
1878 	{ "saberRadius7",			Saber_ParseSaberRadius7,		NULL	},
1879 	{ "saberStyle",				Saber_ParseSaberStyle,			NULL	},
1880 	{ "saberStyleLearned",		Saber_ParseSaberStyleLearned,	NULL	},
1881 	{ "saberStyleForbidden",	Saber_ParseSaberStyleForbidden,	NULL	},
1882 	{ "maxChain",				Saber_ParseMaxChain,			NULL	},
1883 	{ "lockable",				Saber_ParseLockable,			NULL	},
1884 	{ "throwable",				Saber_ParseThrowable,			NULL	},
1885 	{ "disarmable",				Saber_ParseDisarmable,			NULL	},
1886 	{ "blocking",				Saber_ParseBlocking,			NULL	},
1887 	{ "twoHanded",				Saber_ParseTwoHanded,			NULL	},
1888 	{ "forceRestrict",			Saber_ParseForceRestrict,		NULL	},
1889 	{ "lockBonus",				Saber_ParseLockBonus,			NULL	},
1890 	{ "parryBonus",				Saber_ParseParryBonus,			NULL	},
1891 	{ "breakParryBonus",		Saber_ParseBreakParryBonus,		NULL	},
1892 	{ "breakParryBonus2",		Saber_ParseBreakParryBonus2,	NULL	},
1893 	{ "disarmBonus",			Saber_ParseDisarmBonus,			NULL	},
1894 	{ "disarmBonus2",			Saber_ParseDisarmBonus2,		NULL	},
1895 	{ "singleBladeStyle",		Saber_ParseSingleBladeStyle,	NULL	},
1896 	{ "singleBladeThrowable",	Saber_ParseSingleBladeThrowable,NULL	},
1897 	{ "brokenSaber1",			Saber_ParseBrokenSaber1,		NULL	},
1898 	{ "brokenSaber2",			Saber_ParseBrokenSaber2,		NULL	},
1899 	{ "returnDamage",			Saber_ParseReturnDamage,		NULL	},
1900 	{ "spinSound",				Saber_ParseSpinSound,			NULL	},
1901 	{ "swingSound1",			Saber_ParseSwingSound1,			NULL	},
1902 	{ "swingSound2",			Saber_ParseSwingSound2,			NULL	},
1903 	{ "swingSound3",			Saber_ParseSwingSound3,			NULL	},
1904 	{ "moveSpeedScale",			Saber_ParseMoveSpeedScale,		NULL	},
1905 	{ "animSpeedScale",			Saber_ParseAnimSpeedScale,		NULL	},
1906 	{ "bounceOnWalls",			Saber_ParseBounceOnWalls,		NULL	},
1907 	{ "boltToWrist",			Saber_ParseBoltToWrist,			NULL	},
1908 	{ "kataMove",				Saber_ParseKataMove,			NULL	},
1909 	{ "lungeAtkMove",			Saber_ParseLungeAtkMove,		NULL	},
1910 	{ "jumpAtkUpMove",			Saber_ParseJumpAtkUpMove,		NULL	},
1911 	{ "jumpAtkFwdMove",			Saber_ParseJumpAtkFwdMove,		NULL	},
1912 	{ "jumpAtkBackMove",		Saber_ParseJumpAtkBackMove,		NULL	},
1913 	{ "jumpAtkRightMove",		Saber_ParseJumpAtkRightMove,	NULL	},
1914 	{ "jumpAtkLeftMove",		Saber_ParseJumpAtkLeftMove,		NULL	},
1915 	{ "readyAnim",				Saber_ParseReadyAnim,			NULL	},
1916 	{ "drawAnim",				Saber_ParseDrawAnim,			NULL	},
1917 	{ "putawayAnim",			Saber_ParsePutawayAnim,			NULL	},
1918 	{ "tauntAnim",				Saber_ParseTauntAnim,			NULL	},
1919 	{ "bowAnim",				Saber_ParseBowAnim,				NULL	},
1920 	{ "meditateAnim",			Saber_ParseMeditateAnim,		NULL	},
1921 	{ "flourishAnim",			Saber_ParseFlourishAnim,		NULL	},
1922 	{ "gloatAnim",				Saber_ParseGloatAnim,			NULL	},
1923 	{ "noRollStab",				Saber_ParseNoRollStab,			NULL	},
1924 	{ "noPullAttack",			Saber_ParseNoPullAttack,		NULL	},
1925 	{ "noBackAttack",			Saber_ParseNoBackAttack,		NULL	},
1926 	{ "noStabDown",				Saber_ParseNoStabDown,			NULL	},
1927 	{ "noWallRuns",				Saber_ParseNoWallRuns,			NULL	},
1928 	{ "noWallFlips",			Saber_ParseNoWallFlips,			NULL	},
1929 	{ "noWallGrab",				Saber_ParseNoWallGrab,			NULL	},
1930 	{ "noRolls",				Saber_ParseNoRolls,				NULL	},
1931 	{ "noFlips",				Saber_ParseNoFlips,				NULL	},
1932 	{ "noCartwheels",			Saber_ParseNoCartwheels,		NULL	},
1933 	{ "noKicks",				Saber_ParseNoKicks,				NULL	},
1934 	{ "noMirrorAttacks",		Saber_ParseNoMirrorAttacks,		NULL	},
1935 	{ "onInWater",				Saber_ParseOnInWater,			NULL	},
1936 	{ "notInMP",				Saber_ParseNotInMP,				NULL	},
1937 	{ "bladeStyle2Start",		Saber_ParseBladeStyle2Start,	NULL	},
1938 	{ "noWallMarks",			Saber_ParseNoWallMarks,			NULL	},
1939 	{ "noWallMarks2",			Saber_ParseNoWallMarks2,		NULL	},
1940 	{ "noDlight",				Saber_ParseNoDLight,			NULL	},
1941 	{ "noDlight2",				Saber_ParseNoDLight2,			NULL	},
1942 	{ "noBlade",				Saber_ParseNoBlade,				NULL	},
1943 	{ "noBlade2",				Saber_ParseNoBlade2,			NULL	},
1944 	{ "trailStyle",				Saber_ParseTrailStyle,			NULL	},
1945 	{ "trailStyle2",			Saber_ParseTrailStyle2,			NULL	},
1946 	{ "g2MarksShader",			Saber_ParseG2MarksShader,		NULL	},
1947 	{ "g2MarksShader2",			Saber_ParseG2MarksShader2,		NULL	},
1948 	{ "g2WeaponMarkShader",		Saber_ParseG2WeaponMarkShader,	NULL	},
1949 	{ "g2WeaponMarkShader2",	Saber_ParseG2WeaponMarkShader2,	NULL	},
1950 	{ "knockbackScale",			Saber_ParseKnockbackScale,		NULL	},
1951 	{ "knockbackScale2",		Saber_ParseKnockbackScale2,		NULL	},
1952 	{ "damageScale",			Saber_ParseDamageScale,			NULL	},
1953 	{ "damageScale2",			Saber_ParseDamageScale2,		NULL	},
1954 	{ "noDismemberment",		Saber_ParseNoDismemberment,		NULL	},
1955 	{ "noDismemberment2",		Saber_ParseNoDismemberment2,	NULL	},
1956 	{ "noIdleEffect",			Saber_ParseNoIdleEffect,		NULL	},
1957 	{ "noIdleEffect2",			Saber_ParseNoIdleEffect2,		NULL	},
1958 	{ "alwaysBlock",			Saber_ParseAlwaysBlock,			NULL	},
1959 	{ "alwaysBlock2",			Saber_ParseAlwaysBlock2,		NULL	},
1960 	{ "noManualDeactivate",		Saber_ParseNoManualDeactivate,	NULL	},
1961 	{ "noManualDeactivate2",	Saber_ParseNoManualDeactivate2,	NULL	},
1962 	{ "transitionDamage",		Saber_ParseTransitionDamage,	NULL	},
1963 	{ "transitionDamage2",		Saber_ParseTransitionDamage2,	NULL	},
1964 	{ "splashRadius",			Saber_ParseSplashRadius,		NULL	},
1965 	{ "splashRadius2",			Saber_ParseSplashRadius2,		NULL	},
1966 	{ "splashDamage",			Saber_ParseSplashDamage,		NULL	},
1967 	{ "splashDamage2",			Saber_ParseSplashDamage2,		NULL	},
1968 	{ "splashKnockback",		Saber_ParseSplashKnockback,		NULL	},
1969 	{ "splashKnockback2",		Saber_ParseSplashKnockback2,	NULL	},
1970 	{ "hitSound1",				Saber_ParseHitSound1,			NULL	},
1971 	{ "hit2Sound1",				Saber_ParseHit2Sound1,			NULL	},
1972 	{ "hitSound2",				Saber_ParseHitSound2,			NULL	},
1973 	{ "hit2Sound2",				Saber_ParseHit2Sound2,			NULL	},
1974 	{ "hitSound3",				Saber_ParseHitSound3,			NULL	},
1975 	{ "hit2Sound3",				Saber_ParseHit2Sound3,			NULL	},
1976 	{ "blockSound1",			Saber_ParseBlockSound1,			NULL	},
1977 	{ "block2Sound1",			Saber_ParseBlock2Sound1,		NULL	},
1978 	{ "blockSound2",			Saber_ParseBlockSound2,			NULL	},
1979 	{ "block2Sound2",			Saber_ParseBlock2Sound2,		NULL	},
1980 	{ "blockSound3",			Saber_ParseBlockSound3,			NULL	},
1981 	{ "block2Sound3",			Saber_ParseBlock2Sound3,		NULL	},
1982 	{ "bounceSound1",			Saber_ParseBounceSound1,		NULL	},
1983 	{ "bounce2Sound1",			Saber_ParseBounce2Sound1,		NULL	},
1984 	{ "bounceSound2",			Saber_ParseBounceSound2,		NULL	},
1985 	{ "bounce2Sound2",			Saber_ParseBounce2Sound2,		NULL	},
1986 	{ "bounceSound3",			Saber_ParseBounceSound3,		NULL	},
1987 	{ "bounce2Sound3",			Saber_ParseBounce2Sound3,		NULL	},
1988 	{ "blockEffect",			Saber_ParseBlockEffect,			NULL	},
1989 	{ "blockEffect2",			Saber_ParseBlockEffect2,		NULL	},
1990 	{ "hitPersonEffect",		Saber_ParseHitPersonEffect,		NULL	},
1991 	{ "hitPersonEffect2",		Saber_ParseHitPersonEffect2,	NULL	},
1992 	{ "hitOtherEffect",			Saber_ParseHitOtherEffect,		NULL	},
1993 	{ "hitOtherEffect2",		Saber_ParseHitOtherEffect2,		NULL	},
1994 	{ "bladeEffect",			Saber_ParseBladeEffect,			NULL	},
1995 	{ "bladeEffect2",			Saber_ParseBladeEffect2,		NULL	},
1996 	{ "noClashFlare",			Saber_ParseNoClashFlare,		NULL	},
1997 	{ "noClashFlare2",			Saber_ParseNoClashFlare2,		NULL	},
1998 	{ NULL,						NULL,							NULL	}
1999 };
2000 static keywordHash_t *saberParseKeywordHash[KEYWORDHASH_SIZE];
2001 static qboolean hashSetup = qfalse;
2002 
WP_SaberSetupKeywordHash(void)2003 static void WP_SaberSetupKeywordHash( void ) {
2004 	int i;
2005 
2006 	memset( saberParseKeywordHash, 0, sizeof( saberParseKeywordHash ) );
2007 	for ( i=0; saberParseKeywords[i].keyword; i++ )
2008 		KeywordHash_Add( saberParseKeywordHash, &saberParseKeywords[i] );
2009 
2010 	hashSetup = qtrue;
2011 }
2012 
WP_SaberParseParms(const char * saberName,saberInfo_t * saber)2013 qboolean WP_SaberParseParms( const char *saberName, saberInfo_t *saber ) {
2014 	const char	*token, *p;
2015 	char		useSaber[SABER_NAME_LENGTH];
2016 	qboolean	triedDefault = qfalse;
2017 	keywordHash_t *key;
2018 
2019 	// make sure the hash table has been setup
2020 	if ( !hashSetup )
2021 		WP_SaberSetupKeywordHash();
2022 
2023 	if ( !saber )
2024 		return qfalse;
2025 
2026 	//Set defaults so that, if it fails, there's at least something there
2027 	WP_SaberSetDefaults( saber );
2028 
2029 	if ( !VALIDSTRING( saberName ) ) {
2030 		Q_strncpyz( useSaber, DEFAULT_SABER, sizeof( useSaber ) );
2031 		triedDefault = qtrue;
2032 	}
2033 	else
2034 		Q_strncpyz( useSaber, saberName, sizeof( useSaber ) );
2035 
2036 	//try to parse it out
2037 	p = saberParms;
2038 	COM_BeginParseSession( "saberinfo" );
2039 
2040 	// look for the right saber
2041 	while ( p ) {
2042 		token = COM_ParseExt( &p, qtrue );
2043 		if ( !token[0] ) {
2044 			if ( !triedDefault ) {
2045 				// fall back to default and restart, should always be there
2046 				p = saberParms;
2047 				COM_BeginParseSession( "saberinfo" );
2048 				Q_strncpyz( useSaber, DEFAULT_SABER, sizeof( useSaber ) );
2049 				triedDefault = qtrue;
2050 			}
2051 			else
2052 				return qfalse;
2053 		}
2054 
2055 		if ( !Q_stricmp( token, useSaber ) )
2056 			break;
2057 
2058 		SkipBracedSection( &p, 0 );
2059 	}
2060 
2061 	// even the default saber isn't found?
2062 	if ( !p )
2063 		return qfalse;
2064 
2065 	// got the name we're using for sure
2066 	Q_strncpyz( saber->name, useSaber, sizeof( saber->name ) );
2067 
2068 	if ( BG_ParseLiteral( &p, "{" ) )
2069 		return qfalse;
2070 
2071 	// parse the saber info block
2072 	while ( 1 ) {
2073 		token = COM_ParseExt( &p, qtrue );
2074 		if ( !token[0] ) {
2075 			Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s' (WP_SaberParseParms)\n", useSaber );
2076 			return qfalse;
2077 		}
2078 
2079 		if ( !Q_stricmp( token, "}" ) )
2080 			break;
2081 
2082 		key = KeywordHash_Find( saberParseKeywordHash, token );
2083 		if ( key ) {
2084 			key->func( saber, &p );
2085 			continue;
2086 		}
2087 
2088 		Com_Printf( "WARNING: unknown keyword '%s' while parsing saber '%s'\n", token, useSaber );
2089 		SkipRestOfLine( &p );
2090 	}
2091 
2092 	//FIXME: precache the saberModel(s)?
2093 
2094 	return qtrue;
2095 }
2096 
WP_SaberParseParm(const char * saberName,const char * parmname,char * saberData)2097 qboolean WP_SaberParseParm( const char *saberName, const char *parmname, char *saberData )
2098 {
2099 	const char	*token;
2100 	const char	*value;
2101 	const char	*p;
2102 
2103 	if ( !saberName || !saberName[0] )
2104 	{
2105 		return qfalse;
2106 	}
2107 
2108 	//try to parse it out
2109 	p = saberParms;
2110 	COM_BeginParseSession("saberinfo");
2111 
2112 	// look for the right saber
2113 	while ( p )
2114 	{
2115 		token = COM_ParseExt( &p, qtrue );
2116 		if ( token[0] == 0 )
2117 		{
2118 			return qfalse;
2119 		}
2120 
2121 		if ( !Q_stricmp( token, saberName ) )
2122 		{
2123 			break;
2124 		}
2125 
2126 		SkipBracedSection( &p, 0 );
2127 	}
2128 	if ( !p )
2129 	{
2130 		return qfalse;
2131 	}
2132 
2133 	if ( BG_ParseLiteral( &p, "{" ) )
2134 	{
2135 		return qfalse;
2136 	}
2137 
2138 	// parse the saber info block
2139 	while ( 1 )
2140 	{
2141 		token = COM_ParseExt( &p, qtrue );
2142 		if ( !token[0] )
2143 		{
2144 			Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", saberName );
2145 			return qfalse;
2146 		}
2147 
2148 		if ( !Q_stricmp( token, "}" ) )
2149 		{
2150 			break;
2151 		}
2152 
2153 		if ( !Q_stricmp( token, parmname ) )
2154 		{
2155 			if ( COM_ParseString( &p, &value ) )
2156 			{
2157 				continue;
2158 			}
2159 			strcpy( saberData, value );
2160 			return qtrue;
2161 		}
2162 
2163 		SkipRestOfLine( &p );
2164 		continue;
2165 	}
2166 
2167 	return qfalse;
2168 }
2169 
WP_SaberValidForPlayerInMP(const char * saberName)2170 qboolean WP_SaberValidForPlayerInMP( const char *saberName )
2171 {
2172 	char allowed [8]={0};
2173 	if ( !WP_SaberParseParm( saberName, "notInMP", allowed ) )
2174 	{//not defined, default is yes
2175 		return qtrue;
2176 	}
2177 	if ( !allowed[0] )
2178 	{//not defined, default is yes
2179 		return qtrue;
2180 	}
2181 	else
2182 	{//return value
2183 		return ((qboolean)(atoi(allowed)==0));
2184 	}
2185 }
2186 
WP_RemoveSaber(saberInfo_t * sabers,int saberNum)2187 void WP_RemoveSaber( saberInfo_t *sabers, int saberNum )
2188 {
2189 	if ( !sabers )
2190 	{
2191 		return;
2192 	}
2193 	//reset everything for this saber just in case
2194 	WP_SaberSetDefaults( &sabers[saberNum] );
2195 
2196 	strcpy(sabers[saberNum].name, "none");
2197 	sabers[saberNum].model[0] = 0;
2198 
2199 	//ent->client->ps.dualSabers = qfalse;
2200 	BG_SI_Deactivate(&sabers[saberNum]);
2201 	BG_SI_SetLength(&sabers[saberNum], 0.0f);
2202 //	if ( ent->weaponModel[saberNum] > 0 )
2203 //	{
2204 //		trap->G2API_RemoveGhoul2Model( ent->ghoul2, ent->weaponModel[saberNum] );
2205 //		ent->weaponModel[saberNum] = -1;
2206 //	}
2207 //	if ( saberNum == 1 )
2208 //	{
2209 //		ent->client->ps.dualSabers = qfalse;
2210 //	}
2211 }
2212 
WP_SetSaber(int entNum,saberInfo_t * sabers,int saberNum,const char * saberName)2213 void WP_SetSaber( int entNum, saberInfo_t *sabers, int saberNum, const char *saberName )
2214 {
2215 	if ( !sabers )
2216 	{
2217 		return;
2218 	}
2219 	if ( Q_stricmp( "none", saberName ) == 0 || Q_stricmp( "remove", saberName ) == 0 )
2220 	{
2221 		if (saberNum != 0)
2222 		{ //can't remove saber 0 ever
2223 			WP_RemoveSaber( sabers, saberNum );
2224 		}
2225 		return;
2226 	}
2227 
2228 	if ( entNum < MAX_CLIENTS &&
2229 		!WP_SaberValidForPlayerInMP( saberName ) )
2230 	{
2231 		WP_SaberParseParms( DEFAULT_SABER, &sabers[saberNum] );//get saber info
2232 	}
2233 	else
2234 	{
2235 		WP_SaberParseParms( saberName, &sabers[saberNum] );//get saber info
2236 	}
2237 	if ((sabers[1].saberFlags&SFL_TWO_HANDED))
2238 	{//not allowed to use a 2-handed saber as second saber
2239 		WP_RemoveSaber( sabers, 1 );
2240 		return;
2241 	}
2242 	else if ((sabers[0].saberFlags&SFL_TWO_HANDED) &&
2243 		sabers[1].model[0])
2244 	{ //you can't use a two-handed saber with a second saber, so remove saber 2
2245 		WP_RemoveSaber( sabers, 1 );
2246 		return;
2247 	}
2248 }
2249 
WP_SaberSetColor(saberInfo_t * sabers,int saberNum,int bladeNum,char * colorName)2250 void WP_SaberSetColor( saberInfo_t *sabers, int saberNum, int bladeNum, char *colorName )
2251 {
2252 	if ( !sabers )
2253 	{
2254 		return;
2255 	}
2256 	sabers[saberNum].blade[bladeNum].color = TranslateSaberColor( colorName );
2257 }
2258 
2259 static char bgSaberParseTBuffer[MAX_SABER_DATA_SIZE];
2260 
WP_SaberLoadParms(void)2261 void WP_SaberLoadParms( void )
2262 {
2263 	int				len, totallen, saberExtFNLen, fileCnt, i;
2264 	char			*holdChar, *marker;
2265 	char			saberExtensionListBuf[2048];			//	The list of file names read in
2266 	fileHandle_t	f;
2267 
2268 	len = 0;
2269 
2270 	//remember where to store the next one
2271 	totallen = len;
2272 	marker = saberParms+totallen;
2273 	*marker = 0;
2274 
2275 	//now load in the extra .sab extensions
2276 	fileCnt = trap->FS_GetFileList( "ext_data/sabers", ".sab", saberExtensionListBuf, sizeof( saberExtensionListBuf ) );
2277 
2278 	holdChar = saberExtensionListBuf;
2279 	for ( i=0; i<fileCnt; i++, holdChar += saberExtFNLen+1 ) {
2280 		saberExtFNLen = strlen( holdChar );
2281 
2282 		len = trap->FS_Open( va( "ext_data/sabers/%s", holdChar ), &f, FS_READ );
2283 
2284 		if ( !f ) {
2285 			Com_Printf( "WP_SaberLoadParms: error reading file: %s\n", holdChar );
2286 			continue;
2287 		}
2288 
2289 		if ( (totallen + len+1) >= MAX_SABER_DATA_SIZE ) {
2290 			trap->FS_Close( f );
2291 #ifdef UI_BUILD
2292 			Com_Error( ERR_FATAL, "WP_SaberLoadParms: Saber extensions (*.sab) are too large!\nRan out of space before reading %s", holdChar );
2293 #else
2294 			Com_Error( ERR_DROP, "WP_SaberLoadParms: Saber extensions (*.sab) are too large!\nRan out of space before reading %s", holdChar );
2295 #endif
2296 		}
2297 
2298 		trap->FS_Read(bgSaberParseTBuffer, len, f);
2299 		bgSaberParseTBuffer[len] = 0;
2300 
2301 		len = COM_Compress( bgSaberParseTBuffer );
2302 
2303 		Q_strcat( marker, MAX_SABER_DATA_SIZE-totallen, bgSaberParseTBuffer );
2304 		trap->FS_Close(f);
2305 
2306 		//get around the stupid problem of not having an endline at the bottom
2307 		//of a sab file -rww
2308 		Q_strcat(marker, MAX_SABER_DATA_SIZE-totallen, "\n");
2309 		len++;
2310 
2311 		totallen += len;
2312 		marker = saberParms+totallen;
2313 	}
2314 }
2315 
2316 #ifdef UI_BUILD
WP_IsSaberTwoHanded(const char * saberName)2317 qboolean WP_IsSaberTwoHanded( const char *saberName )
2318 {
2319 	int twoHanded;
2320 	char	twoHandedString[8]={0};
2321 	WP_SaberParseParm( saberName, "twoHanded", twoHandedString );
2322 	if ( !twoHandedString[0] )
2323 	{//not defined defaults to "no"
2324 		return qfalse;
2325 	}
2326 	twoHanded = atoi( twoHandedString );
2327 	return ((qboolean)(twoHanded!=0));
2328 }
2329 
WP_SaberGetHiltInfo(const char * singleHilts[MAX_SABER_HILTS],const char * staffHilts[MAX_SABER_HILTS])2330 void WP_SaberGetHiltInfo( const char *singleHilts[MAX_SABER_HILTS], const char *staffHilts[MAX_SABER_HILTS] )
2331 {
2332 	int	numSingleHilts = 0, numStaffHilts = 0;
2333 	const char	*saberName;
2334 	const char	*token;
2335 	const char	*p;
2336 
2337 	//go through all the loaded sabers and put the valid ones in the proper list
2338 	p = saberParms;
2339 	COM_BeginParseSession("saberlist");
2340 
2341 	// look for a saber
2342 	while ( p )
2343 	{
2344 		token = COM_ParseExt( &p, qtrue );
2345 		if ( token[0] == 0 )
2346 		{//invalid name
2347 			continue;
2348 		}
2349 		saberName = String_Alloc( token );
2350 		//see if there's a "{" on the next line
2351 		SkipRestOfLine( &p );
2352 
2353 		if ( BG_ParseLiteralSilent( &p, "{" ) )
2354 		{//nope, not a name, keep looking
2355 			continue;
2356 		}
2357 
2358 		//this is a saber name
2359 		if ( !WP_SaberValidForPlayerInMP( saberName ) )
2360 		{
2361 			SkipBracedSection( &p, 0 );
2362 			continue;
2363 		}
2364 
2365 		if ( WP_IsSaberTwoHanded( saberName ) )
2366 		{
2367 			if ( numStaffHilts < MAX_SABER_HILTS-1 )//-1 because we have to NULL terminate the list
2368 			{
2369 				staffHilts[numStaffHilts++] = saberName;
2370 			}
2371 			else
2372 			{
2373 				Com_Printf( "WARNING: too many two-handed sabers, ignoring saber '%s'\n", saberName );
2374 			}
2375 		}
2376 		else
2377 		{
2378 			if ( numSingleHilts < MAX_SABER_HILTS-1 )//-1 because we have to NULL terminate the list
2379 			{
2380 				singleHilts[numSingleHilts++] = saberName;
2381 			}
2382 			else
2383 			{
2384 				Com_Printf( "WARNING: too many one-handed sabers, ignoring saber '%s'\n", saberName );
2385 			}
2386 		}
2387 		//skip the whole braced section and move on to the next entry
2388 		SkipBracedSection( &p, 0 );
2389 	}
2390 	//null terminate the list so the UI code knows where to stop listing them
2391 	singleHilts[numSingleHilts] = NULL;
2392 	staffHilts[numStaffHilts] = NULL;
2393 }
2394 #endif
2395 
2396 /*
2397 rww -
2398 The following were struct functions in SP. Of course
2399 we can't have that in this codebase so I'm having to
2400 externalize them. Which is why this probably seems
2401 structured a bit oddly. But it's to make porting stuff
2402 easier on myself. SI indicates it was under saberinfo,
2403 and BLADE indicates it was under bladeinfo.
2404 */
2405 
2406 //---------------------------------------
BG_BLADE_ActivateTrail(bladeInfo_t * blade,float duration)2407 void BG_BLADE_ActivateTrail ( bladeInfo_t *blade, float duration )
2408 {
2409 	blade->trail.inAction = qtrue;
2410 	blade->trail.duration = duration;
2411 }
2412 
BG_BLADE_DeactivateTrail(bladeInfo_t * blade,float duration)2413 void BG_BLADE_DeactivateTrail ( bladeInfo_t *blade, float duration )
2414 {
2415 	blade->trail.inAction = qfalse;
2416 	blade->trail.duration = duration;
2417 }
2418 //---------------------------------------
BG_SI_Activate(saberInfo_t * saber)2419 void BG_SI_Activate( saberInfo_t *saber )
2420 {
2421 	int i;
2422 
2423 	for ( i = 0; i < saber->numBlades; i++ )
2424 	{
2425 		saber->blade[i].active = qtrue;
2426 	}
2427 }
2428 
BG_SI_Deactivate(saberInfo_t * saber)2429 void BG_SI_Deactivate( saberInfo_t *saber )
2430 {
2431 	int i;
2432 
2433 	for ( i = 0; i < saber->numBlades; i++ )
2434 	{
2435 		saber->blade[i].active = qfalse;
2436 	}
2437 }
2438 
2439 // Description: Activate a specific Blade of this Saber.
2440 // Created: 10/03/02 by Aurelio Reis, Modified: 10/03/02 by Aurelio Reis.
2441 //	[in]		int iBlade		Which Blade to activate.
2442 //	[in]		bool bActive	Whether to activate it (default true), or deactivate it (false).
2443 //	[return]	void
BG_SI_BladeActivate(saberInfo_t * saber,int iBlade,qboolean bActive)2444 void BG_SI_BladeActivate( saberInfo_t *saber, int iBlade, qboolean bActive )
2445 {
2446 	// Validate blade ID/Index.
2447 	if ( iBlade < 0 || iBlade >= saber->numBlades )
2448 		return;
2449 
2450 	saber->blade[iBlade].active = bActive;
2451 }
2452 
BG_SI_Active(saberInfo_t * saber)2453 qboolean BG_SI_Active(saberInfo_t *saber)
2454 {
2455 	int i;
2456 
2457 	for ( i = 0; i < saber->numBlades; i++ )
2458 	{
2459 		if ( saber->blade[i].active )
2460 		{
2461 			return qtrue;
2462 		}
2463 	}
2464 	return qfalse;
2465 }
2466 
BG_SI_SetLength(saberInfo_t * saber,float length)2467 void BG_SI_SetLength( saberInfo_t *saber, float length )
2468 {
2469 	int i;
2470 
2471 	for ( i = 0; i < saber->numBlades; i++ )
2472 	{
2473 		saber->blade[i].length = length;
2474 	}
2475 }
2476 
2477 //not in sp, added it for my own convenience
BG_SI_SetDesiredLength(saberInfo_t * saber,float len,int bladeNum)2478 void BG_SI_SetDesiredLength(saberInfo_t *saber, float len, int bladeNum )
2479 {
2480 	int i, startBlade = 0, maxBlades = saber->numBlades;
2481 
2482 	if ( bladeNum >= 0 && bladeNum < saber->numBlades)
2483 	{//doing this on a specific blade
2484 		startBlade = bladeNum;
2485 		maxBlades = bladeNum+1;
2486 	}
2487 	for (i = startBlade; i < maxBlades; i++)
2488 	{
2489 		saber->blade[i].desiredLength = len;
2490 	}
2491 }
2492 
2493 //also not in sp, added it for my own convenience
BG_SI_SetLengthGradual(saberInfo_t * saber,int time)2494 void BG_SI_SetLengthGradual(saberInfo_t *saber, int time)
2495 {
2496 	int i;
2497 	float amt, dLen;
2498 
2499 	for (i = 0; i < saber->numBlades; i++)
2500 	{
2501 		dLen = saber->blade[i].desiredLength;
2502 
2503 		if (dLen == -1)
2504 		{ //assume we want max blade len
2505 			dLen = saber->blade[i].lengthMax;
2506 		}
2507 
2508 		if (saber->blade[i].length == dLen)
2509 		{
2510 			continue;
2511 		}
2512 
2513 		if (saber->blade[i].length == saber->blade[i].lengthMax ||
2514 			saber->blade[i].length == 0)
2515 		{
2516 			saber->blade[i].extendDebounce = time;
2517 			if (saber->blade[i].length == 0)
2518 			{
2519 				saber->blade[i].length++;
2520 			}
2521 			else
2522 			{
2523 				saber->blade[i].length--;
2524 			}
2525 		}
2526 
2527 		amt = (time - saber->blade[i].extendDebounce)*0.01;
2528 
2529 		if (amt < 0.2f)
2530 		{
2531 			amt = 0.2f;
2532 		}
2533 
2534 		if (saber->blade[i].length < dLen)
2535 		{
2536 			saber->blade[i].length += amt;
2537 
2538 			if (saber->blade[i].length > dLen)
2539 			{
2540 				saber->blade[i].length = dLen;
2541 			}
2542 			if (saber->blade[i].length > saber->blade[i].lengthMax)
2543 			{
2544 				saber->blade[i].length = saber->blade[i].lengthMax;
2545 			}
2546 		}
2547 		else if (saber->blade[i].length > dLen)
2548 		{
2549 			saber->blade[i].length -= amt;
2550 
2551 			if (saber->blade[i].length < dLen)
2552 			{
2553 				saber->blade[i].length = dLen;
2554 			}
2555 			if (saber->blade[i].length < 0)
2556 			{
2557 				saber->blade[i].length = 0;
2558 			}
2559 		}
2560 	}
2561 }
2562 
BG_SI_Length(saberInfo_t * saber)2563 float BG_SI_Length(saberInfo_t *saber)
2564 {//return largest length
2565 	int len1 = 0;
2566 	int i;
2567 
2568 	for ( i = 0; i < saber->numBlades; i++ )
2569 	{
2570 		if ( saber->blade[i].length > len1 )
2571 		{
2572 			len1 = saber->blade[i].length;
2573 		}
2574 	}
2575 	return len1;
2576 }
2577 
BG_SI_LengthMax(saberInfo_t * saber)2578 float BG_SI_LengthMax(saberInfo_t *saber)
2579 {
2580 	int len1 = 0;
2581 	int i;
2582 
2583 	for ( i = 0; i < saber->numBlades; i++ )
2584 	{
2585 		if ( saber->blade[i].lengthMax > len1 )
2586 		{
2587 			len1 = saber->blade[i].lengthMax;
2588 		}
2589 	}
2590 	return len1;
2591 }
2592 
BG_SI_ActivateTrail(saberInfo_t * saber,float duration)2593 void BG_SI_ActivateTrail ( saberInfo_t *saber, float duration )
2594 {
2595 	int i;
2596 
2597 	for ( i = 0; i < saber->numBlades; i++ )
2598 	{
2599 		//saber->blade[i].ActivateTrail( duration );
2600 		BG_BLADE_ActivateTrail(&saber->blade[i], duration);
2601 	}
2602 }
2603 
BG_SI_DeactivateTrail(saberInfo_t * saber,float duration)2604 void BG_SI_DeactivateTrail ( saberInfo_t *saber, float duration )
2605 {
2606 	int i;
2607 
2608 	for ( i = 0; i < saber->numBlades; i++ )
2609 	{
2610 		//saber->blade[i].DeactivateTrail( duration );
2611 		BG_BLADE_DeactivateTrail(&saber->blade[i], duration);
2612 	}
2613 }
2614 
2615