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