/*
===========================================================================
Copyright (C) 2000 - 2013, Raven Software, Inc.
Copyright (C) 2001 - 2013, Activision, Inc.
Copyright (C) 2013 - 2015, OpenJK contributors
This file is part of the OpenJK source code.
OpenJK is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see .
===========================================================================
*/
// bg_saberLoad.c
// game and cgame, NOT ui
#include "qcommon/q_shared.h"
#include "bg_public.h"
#include "bg_local.h"
#include "w_saber.h"
#ifdef _GAME
#include "g_local.h"
#elif _CGAME
#include "cgame/cg_local.h"
#elif UI_BUILD
#include "ui/ui_local.h"
#endif
extern stringID_table_t animTable[MAX_ANIMATIONS+1];
int BG_SoundIndex( const char *sound ) {
#ifdef _GAME
return G_SoundIndex( sound );
#elif defined(_CGAME) || defined(UI_BUILD)
return trap->S_RegisterSound( sound );
#endif
}
extern stringID_table_t FPTable[];
#define MAX_SABER_DATA_SIZE (1024*1024) // 1mb, was 512kb
static char saberParms[MAX_SABER_DATA_SIZE];
stringID_table_t saberTable[] = {
ENUM2STRING( SABER_NONE ),
ENUM2STRING( SABER_SINGLE ),
ENUM2STRING( SABER_STAFF ),
ENUM2STRING( SABER_BROAD ),
ENUM2STRING( SABER_PRONG ),
ENUM2STRING( SABER_DAGGER ),
ENUM2STRING( SABER_ARC ),
ENUM2STRING( SABER_SAI ),
ENUM2STRING( SABER_CLAW ),
ENUM2STRING( SABER_LANCE ),
ENUM2STRING( SABER_STAR ),
ENUM2STRING( SABER_TRIDENT ),
{ "", -1 }
};
stringID_table_t saberMoveTable[] = {
ENUM2STRING( LS_NONE ),
// Attacks
ENUM2STRING( LS_A_TL2BR ),
ENUM2STRING( LS_A_L2R ),
ENUM2STRING( LS_A_BL2TR ),
ENUM2STRING( LS_A_BR2TL ),
ENUM2STRING( LS_A_R2L ),
ENUM2STRING( LS_A_TR2BL ),
ENUM2STRING( LS_A_T2B ),
ENUM2STRING( LS_A_BACKSTAB ),
ENUM2STRING( LS_A_BACK ),
ENUM2STRING( LS_A_BACK_CR ),
ENUM2STRING( LS_ROLL_STAB ),
ENUM2STRING( LS_A_LUNGE ),
ENUM2STRING( LS_A_JUMP_T__B_ ),
ENUM2STRING( LS_A_FLIP_STAB ),
ENUM2STRING( LS_A_FLIP_SLASH ),
ENUM2STRING( LS_JUMPATTACK_DUAL ),
ENUM2STRING( LS_JUMPATTACK_ARIAL_LEFT ),
ENUM2STRING( LS_JUMPATTACK_ARIAL_RIGHT ),
ENUM2STRING( LS_JUMPATTACK_CART_LEFT ),
ENUM2STRING( LS_JUMPATTACK_CART_RIGHT ),
ENUM2STRING( LS_JUMPATTACK_STAFF_LEFT ),
ENUM2STRING( LS_JUMPATTACK_STAFF_RIGHT ),
ENUM2STRING( LS_BUTTERFLY_LEFT ),
ENUM2STRING( LS_BUTTERFLY_RIGHT ),
ENUM2STRING( LS_A_BACKFLIP_ATK ),
ENUM2STRING( LS_SPINATTACK_DUAL ),
ENUM2STRING( LS_SPINATTACK ),
ENUM2STRING( LS_LEAP_ATTACK ),
ENUM2STRING( LS_SWOOP_ATTACK_RIGHT ),
ENUM2STRING( LS_SWOOP_ATTACK_LEFT ),
ENUM2STRING( LS_TAUNTAUN_ATTACK_RIGHT ),
ENUM2STRING( LS_TAUNTAUN_ATTACK_LEFT ),
ENUM2STRING( LS_KICK_F ),
ENUM2STRING( LS_KICK_B ),
ENUM2STRING( LS_KICK_R ),
ENUM2STRING( LS_KICK_L ),
ENUM2STRING( LS_KICK_S ),
ENUM2STRING( LS_KICK_BF ),
ENUM2STRING( LS_KICK_RL ),
ENUM2STRING( LS_KICK_F_AIR ),
ENUM2STRING( LS_KICK_B_AIR ),
ENUM2STRING( LS_KICK_R_AIR ),
ENUM2STRING( LS_KICK_L_AIR ),
ENUM2STRING( LS_STABDOWN ),
ENUM2STRING( LS_STABDOWN_STAFF ),
ENUM2STRING( LS_STABDOWN_DUAL ),
ENUM2STRING( LS_DUAL_SPIN_PROTECT ),
ENUM2STRING( LS_STAFF_SOULCAL ),
ENUM2STRING( LS_A1_SPECIAL ),
ENUM2STRING( LS_A2_SPECIAL ),
ENUM2STRING( LS_A3_SPECIAL ),
ENUM2STRING( LS_UPSIDE_DOWN_ATTACK ),
ENUM2STRING( LS_PULL_ATTACK_STAB ),
ENUM2STRING( LS_PULL_ATTACK_SWING ),
ENUM2STRING( LS_SPINATTACK_ALORA ),
ENUM2STRING( LS_DUAL_FB ),
ENUM2STRING( LS_DUAL_LR ),
ENUM2STRING( LS_HILT_BASH ),
{ "", -1 }
};
//Also used in npc code
qboolean BG_ParseLiteral( const char **data, const char *string ) {
const char *token;
token = COM_ParseExt( data, qtrue );
if ( !token[0] ) {
Com_Printf( "unexpected EOF\n" );
return qtrue;
}
if ( Q_stricmp( token, string ) ) {
Com_Printf( "required string '%s' missing\n", string );
return qtrue;
}
return qfalse;
}
qboolean BG_ParseLiteralSilent( const char **data, const char *string ) {
const char *token;
token = COM_ParseExt( data, qtrue );
if ( !token[0] ) {
return qtrue;
}
if ( Q_stricmp( token, string ) ) {
return qtrue;
}
return qfalse;
}
saber_colors_t TranslateSaberColor( const char *name ) {
if ( !Q_stricmp( name, "red" ) )
return SABER_RED;
if ( !Q_stricmp( name, "orange" ) )
return SABER_ORANGE;
if ( !Q_stricmp( name, "yellow" ) )
return SABER_YELLOW;
if ( !Q_stricmp( name, "green" ) )
return SABER_GREEN;
if ( !Q_stricmp( name, "blue" ) )
return SABER_BLUE;
if ( !Q_stricmp( name, "purple" ) )
return SABER_PURPLE;
if ( !Q_stricmp( name, "random" ) )
return (saber_colors_t)Q_irand( SABER_ORANGE, SABER_PURPLE );
return SABER_BLUE;
}
const char *SaberColorToString( saber_colors_t color ) {
if ( color == SABER_RED ) return "red";
if ( color == SABER_ORANGE ) return "orange";
if ( color == SABER_YELLOW ) return "yellow";
if ( color == SABER_GREEN ) return "green";
if ( color == SABER_BLUE ) return "blue";
if ( color == SABER_PURPLE ) return "purple";
return NULL;
}
saber_styles_t TranslateSaberStyle( const char *name ) {
if ( !Q_stricmp( name, "fast" ) ) return SS_FAST;
if ( !Q_stricmp( name, "medium" ) ) return SS_MEDIUM;
if ( !Q_stricmp( name, "strong" ) ) return SS_STRONG;
if ( !Q_stricmp( name, "desann" ) ) return SS_DESANN;
if ( !Q_stricmp( name, "tavion" ) ) return SS_TAVION;
if ( !Q_stricmp( name, "dual" ) ) return SS_DUAL;
if ( !Q_stricmp( name, "staff" ) ) return SS_STAFF;
return SS_NONE;
}
saberType_t TranslateSaberType( const char *name ) {
if ( !Q_stricmp( name, "SABER_SINGLE" ) ) return SABER_SINGLE;
if ( !Q_stricmp( name, "SABER_STAFF" ) ) return SABER_STAFF;
if ( !Q_stricmp( name, "SABER_DAGGER" ) ) return SABER_DAGGER;
if ( !Q_stricmp( name, "SABER_BROAD" ) ) return SABER_BROAD;
if ( !Q_stricmp( name, "SABER_PRONG" ) ) return SABER_PRONG;
if ( !Q_stricmp( name, "SABER_ARC" ) ) return SABER_ARC;
if ( !Q_stricmp( name, "SABER_SAI" ) ) return SABER_SAI;
if ( !Q_stricmp( name, "SABER_CLAW" ) ) return SABER_CLAW;
if ( !Q_stricmp( name, "SABER_LANCE" ) ) return SABER_LANCE;
if ( !Q_stricmp( name, "SABER_STAR" ) ) return SABER_STAR;
if ( !Q_stricmp( name, "SABER_TRIDENT" ) ) return SABER_TRIDENT;
if ( !Q_stricmp( name, "SABER_SITH_SWORD" ) ) return SABER_SITH_SWORD;
return SABER_SINGLE;
}
qboolean WP_SaberBladeUseSecondBladeStyle( saberInfo_t *saber, int bladeNum ) {
if ( saber
&& saber->bladeStyle2Start > 0
&& bladeNum >= saber->bladeStyle2Start )
return qtrue;
return qfalse;
}
qboolean WP_SaberBladeDoTransitionDamage( saberInfo_t *saber, int bladeNum ) {
//use first blade style for this blade
if ( !WP_SaberBladeUseSecondBladeStyle( saber, bladeNum ) && (saber->saberFlags2 & SFL2_TRANSITION_DAMAGE) )
return qtrue;
//use second blade style for this blade
else if ( WP_SaberBladeUseSecondBladeStyle( saber, bladeNum ) && (saber->saberFlags2 & SFL2_TRANSITION_DAMAGE2) )
return qtrue;
return qfalse;
}
qboolean WP_UseFirstValidSaberStyle( saberInfo_t *saber1, saberInfo_t *saber2, int saberHolstered, int *saberAnimLevel ) {
qboolean styleInvalid = qfalse;
qboolean saber1Active, saber2Active;
qboolean dualSabers = qfalse;
int validStyles=0, styleNum;
if ( saber2 && saber2->model[0] )
dualSabers = qtrue;
//dual
if ( dualSabers ) {
if ( saberHolstered > 1 )
saber1Active = saber2Active = qfalse;
else if ( saberHolstered > 0 ) {
saber1Active = qtrue;
saber2Active = qfalse;
}
else
saber1Active = saber2Active = qtrue;
}
// single/staff
else {
saber2Active = qfalse;
if ( !saber1 || !saber1->model[0] )
saber1Active = qfalse;
//staff
else if ( saber1->numBlades > 1 ) {
if ( saberHolstered > 1 )
saber1Active = qfalse;
else
saber1Active = qtrue;
}
//single
else {
if ( saberHolstered )
saber1Active = qfalse;
else
saber1Active = qtrue;
}
}
//initially, all styles are valid
validStyles = (1<model[0] && saber1->stylesForbidden ) {
if ( (saber1->stylesForbidden & (1<<*saberAnimLevel)) ) {
//not a valid style for first saber!
styleInvalid = qtrue;
validStyles &= ~saber1->stylesForbidden;
}
}
if ( dualSabers ) {
if ( saber2Active && saber2->stylesForbidden ) {
if ( (saber2->stylesForbidden & (1<<*saberAnimLevel)) ) {
//not a valid style for second saber!
styleInvalid = qtrue;
//only the ones both sabers allow is valid
validStyles &= ~saber2->stylesForbidden;
}
}
}
if ( !validStyles ) {
if ( dualSabers )
Com_Printf( "WARNING: No valid saber styles for %s/%s", saber1->name, saber2->name );
else
Com_Printf( "WARNING: No valid saber styles for %s", saber1->name );
}
//using an invalid style and have at least one valid style to use, so switch to it
else if ( styleInvalid ) {
for ( styleNum=SS_FAST; styleNummodel[0] )
dualSabers = qtrue;
if ( dualSabers ) {
if ( saberHolstered > 1 )
saber1Active = saber2Active = qfalse;
else if ( saberHolstered > 0 ) {
saber1Active = qtrue;
saber2Active = qfalse;
}
else
saber1Active = saber2Active = qtrue;
}
else {
saber2Active = qfalse;
if ( !saber1 || !saber1->model[0] )
saber1Active = qfalse;
//staff
else if ( saber1->numBlades > 1 )
saber1Active = (saberHolstered>1) ? qfalse : qtrue;
//single
else
saber1Active = saberHolstered ? qfalse : qtrue;
}
if ( saber1Active && saber1 && saber1->model[0] && saber1->stylesForbidden ) {
if ( (saber1->stylesForbidden & (1<model[0] )
{
if ( saber2->stylesForbidden ) {
if ( (saber2->stylesForbidden & (1<stylesLearned & (1<stylesLearned & (1<bladeStyle2Start > 0 && saber->numBlades > saber->bladeStyle2Start ) {
// check if all blades are always on
if ( (saber->saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE) && (saber->saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE2) )
return qfalse;
}
else {
// check if all blades are always on
if ( (saber->saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE) )
return qfalse;
}
//you can turn some off
return qtrue;
}
void WP_SaberSetDefaults( saberInfo_t *saber ) {
int i;
//Set defaults so that, if it fails, there's at least something there
for ( i=0; iblade[i].color = SABER_RED;
saber->blade[i].radius = SABER_RADIUS_STANDARD;
saber->blade[i].lengthMax = 32;
}
Q_strncpyz( saber->name, DEFAULT_SABER, sizeof( saber->name ) );
Q_strncpyz( saber->fullName, "lightsaber", sizeof( saber->fullName ) );
Q_strncpyz( saber->model, DEFAULT_SABER_MODEL, sizeof( saber->model ) );
saber->skin = 0;
saber->soundOn = BG_SoundIndex( "sound/weapons/saber/enemy_saber_on.wav" );
saber->soundLoop = BG_SoundIndex( "sound/weapons/saber/saberhum3.wav" );
saber->soundOff = BG_SoundIndex( "sound/weapons/saber/enemy_saber_off.wav" );
saber->numBlades = 1;
saber->type = SABER_SINGLE;
saber->stylesLearned = 0;
saber->stylesForbidden = 0; // allow all styles
saber->maxChain = 0; // 0 = use default behavior
saber->forceRestrictions = 0;
saber->lockBonus = 0;
saber->parryBonus = 0;
saber->breakParryBonus = 0;
saber->breakParryBonus2 = 0;
saber->disarmBonus = 0;
saber->disarmBonus2 = 0;
saber->singleBladeStyle = SS_NONE; // makes it so that you use a different style if you only have the first blade active
//===NEW========================================================================================
//done in cgame (client-side code)
saber->saberFlags = 0; // see all the SFL_ flags
saber->saberFlags2 = 0; // see all the SFL2_ flags
saber->spinSound = 0; // none - if set, plays this sound as it spins when thrown
saber->swingSound[0] = 0; // none - if set, plays one of these 3 sounds when swung during an attack - NOTE: must provide all 3!!!
saber->swingSound[1] = 0; // none - if set, plays one of these 3 sounds when swung during an attack - NOTE: must provide all 3!!!
saber->swingSound[2] = 0; // none - if set, plays one of these 3 sounds when swung during an attack - NOTE: must provide all 3!!!
//done in game (server-side code)
saber->moveSpeedScale = 1.0f; // 1.0 - you move faster/slower when using this saber
saber->animSpeedScale = 1.0f; // 1.0 - plays normal attack animations faster/slower
saber->kataMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they press both attack buttons at the same time
saber->lungeAtkMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they crouch+fwd+attack
saber->jumpAtkUpMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they jump+attack
saber->jumpAtkFwdMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they jump+fwd+attack
saber->jumpAtkBackMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they jump+back+attack
saber->jumpAtkRightMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they jump+rightattack
saber->jumpAtkLeftMove = LS_INVALID; // LS_INVALID - if set, player will execute this move when they jump+left+attack
saber->readyAnim = -1; // -1 - anim to use when standing idle
saber->drawAnim = -1; // -1 - anim to use when drawing weapon
saber->putawayAnim = -1; // -1 - anim to use when putting weapon away
saber->tauntAnim = -1; // -1 - anim to use when hit "taunt"
saber->bowAnim = -1; // -1 - anim to use when hit "bow"
saber->meditateAnim = -1; // -1 - anim to use when hit "meditate"
saber->flourishAnim = -1; // -1 - anim to use when hit "flourish"
saber->gloatAnim = -1; // -1 - anim to use when hit "gloat"
//***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***
saber->bladeStyle2Start = 0; // 0 - if set, blades from this number and higher use the following values (otherwise, they use the normal values already set)
//***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)***
//===PRIMARY BLADES=====================
//done in cgame (client-side code)
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)
saber->g2MarksShader = 0; // none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
saber->g2WeaponMarkShader = 0; // none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
saber->hitSound[0] = 0; // none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
saber->hitSound[1] = 0; // none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
saber->hitSound[2] = 0; // none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
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!!!
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!!!
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!!!
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!!!
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!!!
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!!!
saber->blockEffect = 0; // none - if set, plays this effect when the saber/sword hits another saber/sword (instead of "saber/saber_block.efx")
saber->hitPersonEffect = 0; // none - if set, plays this effect when the saber/sword hits a person (instead of "saber/blood_sparks_mp.efx")
saber->hitOtherEffect = 0; // none - if set, plays this effect when the saber/sword hits something else damagable (instead of "saber/saber_cut.efx")
saber->bladeEffect = 0; // none - if set, plays this effect at the blade tag
//done in game (server-side code)
saber->knockbackScale = 0; // 0 - if non-zero, uses damage done to calculate an appropriate amount of knockback
saber->damageScale = 1.0f; // 1 - scale up or down the damage done by the saber
saber->splashRadius = 0.0f; // 0 - radius of splashDamage
saber->splashDamage = 0; // 0 - amount of splashDamage, 100% at a distance of 0, 0% at a distance = splashRadius
saber->splashKnockback = 0.0f; // 0 - amount of splashKnockback, 100% at a distance of 0, 0% at a distance = splashRadius
//===SECONDARY BLADES===================
//done in cgame (client-side code)
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)
saber->g2MarksShader2 = 0; // none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
saber->g2WeaponMarkShader2 = 0; // none - if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
saber->hit2Sound[0] = 0; // none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
saber->hit2Sound[1] = 0; // none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
saber->hit2Sound[2] = 0; // none - if set, plays one of these 3 sounds when saber hits a person - NOTE: must provide all 3!!!
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!!!
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!!!
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!!!
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!!!
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!!!
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!!!
saber->blockEffect2 = 0; // none - if set, plays this effect when the saber/sword hits another saber/sword (instead of "saber/saber_block.efx")
saber->hitPersonEffect2 = 0; // none - if set, plays this effect when the saber/sword hits a person (instead of "saber/blood_sparks_mp.efx")
saber->hitOtherEffect2 = 0; // none - if set, plays this effect when the saber/sword hits something else damagable (instead of "saber/saber_cut.efx")
saber->bladeEffect2 = 0; // none - if set, plays this effect at the blade tag
//done in game (server-side code)
saber->knockbackScale2 = 0; // 0 - if non-zero, uses damage done to calculate an appropriate amount of knockback
saber->damageScale2 = 1.0f; // 1 - scale up or down the damage done by the saber
saber->splashRadius2 = 0.0f; // 0 - radius of splashDamage
saber->splashDamage2 = 0; // 0 - amount of splashDamage, 100% at a distance of 0, 0% at a distance = splashRadius
saber->splashKnockback2 = 0.0f; // 0 - amount of splashKnockback, 100% at a distance of 0, 0% at a distance = splashRadius
//=========================================================================================================================================
}
static void Saber_ParseName( saberInfo_t *saber, const char **p ) {
const char *value;
if ( COM_ParseString( p, &value ) )
return;
Q_strncpyz( saber->fullName, value, sizeof( saber->fullName ) );
}
static void Saber_ParseSaberType( saberInfo_t *saber, const char **p ) {
const char *value;
int saberType;
if ( COM_ParseString( p, &value ) )
return;
saberType = GetIDForString( saberTable, value );
if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS )
saber->type = (saberType_t)saberType;
}
static void Saber_ParseSaberModel( saberInfo_t *saber, const char **p ) {
const char *value;
if ( COM_ParseString( p, &value ) )
return;
Q_strncpyz( saber->model, value, sizeof( saber->model ) );
}
static void Saber_ParseCustomSkin( saberInfo_t *saber, const char **p ) {
const char *value;
if ( COM_ParseString( p, &value ) )
return;
saber->skin = trap->R_RegisterSkin( value );
}
static void Saber_ParseSoundOn( saberInfo_t *saber, const char **p ) {
const char *value;
if ( COM_ParseString( p, &value ) )
return;
saber->soundOn = BG_SoundIndex( value );
}
static void Saber_ParseSoundLoop( saberInfo_t *saber, const char **p ) {
const char *value;
if ( COM_ParseString( p, &value ) )
return;
saber->soundLoop = BG_SoundIndex( value );
}
static void Saber_ParseSoundOff( saberInfo_t *saber, const char **p ) {
const char *value;
if ( COM_ParseString( p, &value ) )
return;
saber->soundOff = BG_SoundIndex( value );
}
static void Saber_ParseNumBlades( saberInfo_t *saber, const char **p ) {
int n;
if ( COM_ParseInt( p, &n ) ) {
SkipRestOfLine( p );
return;
}
if ( n < 1 || n > MAX_BLADES ) {
Com_Error( ERR_DROP, "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", saber->name, n, MAX_BLADES );
return;
}
saber->numBlades = n;
}
static void Saber_ParseSaberColor( saberInfo_t *saber, const char **p ) {
const char *value;
int i=0;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
for ( i=0; iblade[i].color = color;
}
static void Saber_ParseSaberColor2( saberInfo_t *saber, const char **p ) {
const char *value;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
saber->blade[1].color = color;
}
static void Saber_ParseSaberColor3( saberInfo_t *saber, const char **p ) {
const char *value;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
saber->blade[2].color = color;
}
static void Saber_ParseSaberColor4( saberInfo_t *saber, const char **p ) {
const char *value;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
saber->blade[3].color = color;
}
static void Saber_ParseSaberColor5( saberInfo_t *saber, const char **p ) {
const char *value;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
saber->blade[4].color = color;
}
static void Saber_ParseSaberColor6( saberInfo_t *saber, const char **p ) {
const char *value;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
saber->blade[5].color = color;
}
static void Saber_ParseSaberColor7( saberInfo_t *saber, const char **p ) {
const char *value;
saber_colors_t color;
if ( COM_ParseString( p, &value ) )
return;
color = TranslateSaberColor( value );
saber->blade[6].color = color;
}
static void Saber_ParseSaberLength( saberInfo_t *saber, const char **p ) {
int i=0;
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
for ( i=0; iblade[i].lengthMax = f;
}
static void Saber_ParseSaberLength2( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
saber->blade[1].lengthMax = f;
}
static void Saber_ParseSaberLength3( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
saber->blade[2].lengthMax = f;
}
static void Saber_ParseSaberLength4( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
saber->blade[3].lengthMax = f;
}
static void Saber_ParseSaberLength5( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
saber->blade[4].lengthMax = f;
}
static void Saber_ParseSaberLength6( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
saber->blade[5].lengthMax = f;
}
static void Saber_ParseSaberLength7( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 4.0f )
f = 4.0f;
saber->blade[6].lengthMax = f;
}
static void Saber_ParseSaberRadius( saberInfo_t *saber, const char **p ) {
int i=0;
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
for ( i=0; iblade[i].radius = f;
}
static void Saber_ParseSaberRadius2( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
saber->blade[1].radius = f;
}
static void Saber_ParseSaberRadius3( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
saber->blade[2].radius = f;
}
static void Saber_ParseSaberRadius4( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
saber->blade[3].radius = f;
}
static void Saber_ParseSaberRadius5( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
saber->blade[4].radius = f;
}
static void Saber_ParseSaberRadius6( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
saber->blade[5].radius = f;
}
static void Saber_ParseSaberRadius7( saberInfo_t *saber, const char **p ) {
float f;
if ( COM_ParseFloat( p, &f ) )
return;
if ( f < 0.25f )
f = 0.25f;
saber->blade[6].radius = f;
}
static void Saber_ParseSaberStyle( saberInfo_t *saber, const char **p ) {
const char *value;
int style, styleNum;
if ( COM_ParseString( p, &value ) )
return;
//OLD WAY: only allowed ONE style
style = TranslateSaberStyle( value );
//learn only this style
saber->stylesLearned = (1<