2022-09-18 15:37:21 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Copyright ( C ) 1999 - 2005 , Id Software , Inc .
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 < http : //www.gnu.org/licenses/>.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# include "../cgame/cg_local.h"
# include "Q3_Interface.h"
# include "g_local.h"
# include "wp_saber.h"
# include "g_functions.h"
extern void G_NextTestAxes ( void ) ;
extern void G_ChangePlayerModel ( gentity_t * ent , const char * newModel ) ;
extern void G_InitPlayerFromCvars ( gentity_t * ent ) ;
extern void Q3_SetViewEntity ( int entID , const char * name ) ;
extern qboolean G_ClearViewEntity ( gentity_t * ent ) ;
extern void G_Knockdown ( gentity_t * self , gentity_t * attacker , const vec3_t pushDir , float strength , qboolean breakSaberLock ) ;
extern void WP_SetSaber ( gentity_t * ent , int saberNum , const char * saberName ) ;
extern void WP_RemoveSaber ( gentity_t * ent , int saberNum ) ;
extern saber_colors_t TranslateSaberColor ( const char * name ) ;
extern qboolean WP_SaberBladeUseSecondBladeStyle ( saberInfo_t * saber , int bladeNum ) ;
extern qboolean WP_UseFirstValidSaberStyle ( gentity_t * ent , int * saberAnimLevel ) ;
extern void G_SetWeapon ( gentity_t * self , int wp ) ;
extern stringID_table_t WPTable [ ] ;
extern cvar_t * g_char_model ;
extern cvar_t * g_char_skin_head ;
extern cvar_t * g_char_skin_torso ;
extern cvar_t * g_char_skin_legs ;
extern cvar_t * g_char_color_red ;
extern cvar_t * g_char_color_green ;
extern cvar_t * g_char_color_blue ;
extern cvar_t * g_saber ;
extern cvar_t * g_saber2 ;
extern cvar_t * g_saber_color ;
extern cvar_t * g_saber2_color ;
/*
= = = = = = = = = = = = = = = = = = =
Svcmd_EntityList_f
= = = = = = = = = = = = = = = = = = =
*/
void Svcmd_EntityList_f ( void ) {
int e ;
gentity_t * check ;
check = g_entities ;
for ( e = 0 ; e < globals . num_entities ; e + + , check + + ) {
if ( ! check - > inuse ) {
continue ;
}
gi . Printf ( " %3i: " , e ) ;
switch ( check - > s . eType ) {
case ET_GENERAL :
gi . Printf ( " ET_GENERAL " ) ;
break ;
case ET_PLAYER :
gi . Printf ( " ET_PLAYER " ) ;
break ;
case ET_ITEM :
gi . Printf ( " ET_ITEM " ) ;
break ;
case ET_MISSILE :
gi . Printf ( " ET_MISSILE " ) ;
break ;
case ET_MOVER :
gi . Printf ( " ET_MOVER " ) ;
break ;
case ET_BEAM :
gi . Printf ( " ET_BEAM " ) ;
break ;
case ET_PORTAL :
gi . Printf ( " ET_PORTAL " ) ;
break ;
case ET_SPEAKER :
gi . Printf ( " ET_SPEAKER " ) ;
break ;
case ET_PUSH_TRIGGER :
gi . Printf ( " ET_PUSH_TRIGGER " ) ;
break ;
case ET_TELEPORT_TRIGGER :
gi . Printf ( " ET_TELEPORT_TRIGGER " ) ;
break ;
case ET_INVISIBLE :
gi . Printf ( " ET_INVISIBLE " ) ;
break ;
case ET_THINKER :
gi . Printf ( " ET_THINKER " ) ;
break ;
case ET_CLOUD :
gi . Printf ( " ET_CLOUD " ) ;
break ;
case ET_TERRAIN :
gi . Printf ( " ET_TERRAIN " ) ;
break ;
default :
gi . Printf ( " %-3i " , check - > s . eType ) ;
break ;
}
if ( check - > classname ) {
gi . Printf ( " %s " , check - > classname ) ;
}
gi . Printf ( " \n " ) ;
}
}
//---------------------------
extern void G_StopCinematicSkip ( void ) ;
extern void G_StartCinematicSkip ( void ) ;
extern void ExitEmplacedWeapon ( gentity_t * ent ) ;
static void Svcmd_ExitView_f ( void )
{
extern cvar_t * g_skippingcin ;
static int exitViewDebounce = 0 ;
if ( exitViewDebounce > level . time )
{
return ;
}
exitViewDebounce = level . time + 500 ;
if ( in_camera )
{ //see if we need to exit an in-game cinematic
if ( g_skippingcin - > integer ) // already doing cinematic skip?
{ // yes... so stop skipping...
G_StopCinematicSkip ( ) ;
}
else
{ // no... so start skipping...
G_StartCinematicSkip ( ) ;
}
}
else if ( ! G_ClearViewEntity ( player ) )
{ //didn't exit control of a droid or turret
//okay, now try exiting emplaced guns or AT-ST's
if ( player - > s . eFlags & EF_LOCKED_TO_WEAPON )
{ //get out of emplaced gun
ExitEmplacedWeapon ( player ) ;
}
else if ( player - > client & & player - > client - > NPC_class = = CLASS_ATST )
{ //a player trying to get out of his ATST
GEntity_UseFunc ( player - > activator , player , player ) ;
}
}
}
gentity_t * G_GetSelfForPlayerCmd ( void )
{
if ( g_entities [ 0 ] . client - > ps . viewEntity > 0
& & g_entities [ 0 ] . client - > ps . viewEntity < ENTITYNUM_WORLD
& & g_entities [ g_entities [ 0 ] . client - > ps . viewEntity ] . client
& & g_entities [ g_entities [ 0 ] . client - > ps . viewEntity ] . s . weapon = = WP_SABER )
{ //you're controlling another NPC
return ( & g_entities [ g_entities [ 0 ] . client - > ps . viewEntity ] ) ;
}
else
{
return ( & g_entities [ 0 ] ) ;
}
}
static void Svcmd_Saber_f ( )
{
const char * saber = gi . argv ( 1 ) ;
const char * saber2 = gi . argv ( 2 ) ;
char name [ MAX_CVAR_VALUE_STRING ] = { 0 } ;
if ( gi . argc ( ) < 2 )
{
gi . Printf ( " Usage: saber <saber1> <saber2> \n " ) ;
gi . Cvar_VariableStringBuffer ( " g_saber " , name , sizeof ( name ) ) ;
gi . Printf ( " g_saber is set to %s \n " , name ) ;
gi . Cvar_VariableStringBuffer ( " g_saber2 " , name , sizeof ( name ) ) ;
if ( name [ 0 ] )
gi . Printf ( " g_saber2 is set to %s \n " , name ) ;
return ;
}
if ( ! g_entities [ 0 ] . client | | ! saber | | ! saber [ 0 ] )
{
return ;
}
gi . cvar_set ( " g_saber " , saber ) ;
WP_SetSaber ( & g_entities [ 0 ] , 0 , saber ) ;
if ( saber2 & & saber2 [ 0 ] & & ! ( g_entities [ 0 ] . client - > ps . saber [ 0 ] . saberFlags & SFL_TWO_HANDED ) )
{ //want to use a second saber and first one is not twoHanded
gi . cvar_set ( " g_saber2 " , saber2 ) ;
WP_SetSaber ( & g_entities [ 0 ] , 1 , saber2 ) ;
}
else
{
gi . cvar_set ( " g_saber2 " , " " ) ;
WP_RemoveSaber ( & g_entities [ 0 ] , 1 ) ;
}
}
static void Svcmd_SaberBlade_f ( )
{
if ( gi . argc ( ) < 2 )
{
gi . Printf ( " USAGE: saberblade <sabernum> <bladenum> [0 = off, 1 = on, no arg = toggle] \n " ) ;
return ;
}
if ( & g_entities [ 0 ] = = NULL | | g_entities [ 0 ] . client = = NULL )
{
return ;
}
int sabernum = atoi ( gi . argv ( 1 ) ) - 1 ;
if ( sabernum < 0 | | sabernum > 1 )
{
return ;
}
if ( sabernum > 0 & & ! g_entities [ 0 ] . client - > ps . dualSabers )
{
return ;
}
//FIXME: what if don't even have a single saber at all?
int bladenum = atoi ( gi . argv ( 2 ) ) - 1 ;
if ( bladenum < 0 | | bladenum > = g_entities [ 0 ] . client - > ps . saber [ sabernum ] . numBlades )
{
return ;
}
qboolean turnOn ;
if ( gi . argc ( ) > 2 )
{ //explicit
turnOn = ( qboolean ) ( atoi ( gi . argv ( 3 ) ) ! = 0 ) ;
}
else
{ //toggle
turnOn = ( qboolean ) ! g_entities [ 0 ] . client - > ps . saber [ sabernum ] . blade [ bladenum ] . active ;
}
g_entities [ 0 ] . client - > ps . SaberBladeActivate ( sabernum , bladenum , turnOn ) ;
}
static void Svcmd_SaberColor_f ( )
{ //FIXME: just list the colors, each additional listing sets that blade
int saberNum = atoi ( gi . argv ( 1 ) ) ;
const char * color [ MAX_BLADES ] ;
int bladeNum ;
for ( bladeNum = 0 ; bladeNum < MAX_BLADES ; bladeNum + + )
{
color [ bladeNum ] = gi . argv ( 2 + bladeNum ) ;
}
if ( saberNum < 1 | | saberNum > 2 | | gi . argc ( ) < 3 )
{
gi . Printf ( " Usage: saberColor <saberNum> <blade1 color> <blade2 color> ... <blade8 color> \n " ) ;
gi . Printf ( " valid saberNums: 1 or 2 \n " ) ;
gi . Printf ( " valid colors: red, orange, yellow, green, blue, and purple \n " ) ;
return ;
}
saberNum - - ;
gentity_t * self = G_GetSelfForPlayerCmd ( ) ;
for ( bladeNum = 0 ; bladeNum < MAX_BLADES ; bladeNum + + )
{
if ( ! color [ bladeNum ] | | ! color [ bladeNum ] [ 0 ] )
{
break ;
}
else
{
self - > client - > ps . saber [ saberNum ] . blade [ bladeNum ] . color = TranslateSaberColor ( color [ bladeNum ] ) ;
}
}
if ( saberNum = = 0 )
{
gi . cvar_set ( " g_saber_color " , color [ 0 ] ) ;
}
else if ( saberNum = = 1 )
{
gi . cvar_set ( " g_saber2_color " , color [ 0 ] ) ;
}
}
struct SetForceCmd {
const char * desc ;
const char * cmdname ;
const int maxlevel ;
} ;
SetForceCmd SetForceTable [ NUM_FORCE_POWERS ] = {
{ " forceHeal " , " setForceHeal " , FORCE_LEVEL_3 } ,
{ " forceJump " , " setForceJump " , FORCE_LEVEL_3 } ,
{ " forceSpeed " , " setForceSpeed " , FORCE_LEVEL_3 } ,
{ " forcePush " , " setForcePush " , FORCE_LEVEL_3 } ,
{ " forcePull " , " setForcePull " , FORCE_LEVEL_3 } ,
{ " forceMindTrick " , " setForceMindTrick " , FORCE_LEVEL_4 } ,
{ " forceGrip " , " setForceGrip " , FORCE_LEVEL_3 } ,
{ " forceLightning " , " setForceLightning " , FORCE_LEVEL_3 } ,
{ " saberThrow " , " setSaberThrow " , FORCE_LEVEL_3 } ,
{ " saberDefense " , " setSaberDefense " , FORCE_LEVEL_3 } ,
{ " saberOffense " , " setSaberOffense " , SS_NUM_SABER_STYLES - 1 } ,
{ " forceRage " , " setForceRage " , FORCE_LEVEL_3 } ,
{ " forceProtect " , " setForceProtect " , FORCE_LEVEL_3 } ,
{ " forceAbsorb " , " setForceAbsorb " , FORCE_LEVEL_3 } ,
{ " forceDrain " , " setForceDrain " , FORCE_LEVEL_3 } ,
{ " forceSight " , " setForceSight " , FORCE_LEVEL_3 } ,
} ;
static void Svcmd_ForceSetLevel_f ( int forcePower )
{
if ( ! & g_entities [ 0 ] | | ! g_entities [ 0 ] . client )
{
return ;
}
const char * newVal = gi . argv ( 1 ) ;
if ( ! VALIDSTRING ( newVal ) )
{
gi . Printf ( " Current %s level is %d \n " , SetForceTable [ forcePower ] . desc , g_entities [ 0 ] . client - > ps . forcePowerLevel [ forcePower ] ) ;
gi . Printf ( " Usage: %s <level> (0 - %i) \n " , SetForceTable [ forcePower ] . cmdname , SetForceTable [ forcePower ] . maxlevel ) ;
return ;
}
int val = atoi ( newVal ) ;
if ( val > FORCE_LEVEL_0 )
{
g_entities [ 0 ] . client - > ps . forcePowersKnown | = ( 1 < < forcePower ) ;
}
else
{
g_entities [ 0 ] . client - > ps . forcePowersKnown & = ~ ( 1 < < forcePower ) ;
}
g_entities [ 0 ] . client - > ps . forcePowerLevel [ forcePower ] = val ;
if ( g_entities [ 0 ] . client - > ps . forcePowerLevel [ forcePower ] < FORCE_LEVEL_0 )
{
g_entities [ 0 ] . client - > ps . forcePowerLevel [ forcePower ] = FORCE_LEVEL_0 ;
}
else if ( g_entities [ 0 ] . client - > ps . forcePowerLevel [ forcePower ] > SetForceTable [ forcePower ] . maxlevel )
{
g_entities [ 0 ] . client - > ps . forcePowerLevel [ forcePower ] = SetForceTable [ forcePower ] . maxlevel ;
}
}
extern qboolean PM_SaberInStart ( int move ) ;
extern qboolean PM_SaberInTransition ( int move ) ;
extern qboolean PM_SaberInAttack ( int move ) ;
extern qboolean WP_SaberCanTurnOffSomeBlades ( saberInfo_t * saber ) ;
void Svcmd_SaberAttackCycle_f ( void )
{
if ( ! & g_entities [ 0 ] | | ! g_entities [ 0 ] . client )
{
return ;
}
gentity_t * self = G_GetSelfForPlayerCmd ( ) ;
if ( self - > s . weapon ! = WP_SABER )
{ // saberAttackCycle button also switches to saber
gi . SendConsoleCommand ( " weapon 1 " ) ;
return ;
}
if ( self - > client - > ps . dualSabers )
{ //can't cycle styles with dualSabers, so just toggle second saber on/off
if ( WP_SaberCanTurnOffSomeBlades ( & self - > client - > ps . saber [ 1 ] ) )
{ //can turn second saber off
if ( self - > client - > ps . saber [ 1 ] . ActiveManualOnly ( ) )
{ //turn it off
qboolean skipThisBlade ;
for ( int bladeNum = 0 ; bladeNum < self - > client - > ps . saber [ 1 ] . numBlades ; bladeNum + + )
{
skipThisBlade = qfalse ;
if ( WP_SaberBladeUseSecondBladeStyle ( & self - > client - > ps . saber [ 1 ] , bladeNum ) )
{ //check to see if we should check the secondary style's flags
if ( ( self - > client - > ps . saber [ 1 ] . saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE2 ) )
{
skipThisBlade = qtrue ;
}
}
else
{ //use the primary style's flags
if ( ( self - > client - > ps . saber [ 1 ] . saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE ) )
{
skipThisBlade = qtrue ;
}
}
if ( ! skipThisBlade )
{
self - > client - > ps . saber [ 1 ] . BladeActivate ( bladeNum , qfalse ) ;
G_SoundIndexOnEnt ( self , CHAN_WEAPON , self - > client - > ps . saber [ 1 ] . soundOff ) ;
}
}
}
else if ( ! self - > client - > ps . saber [ 0 ] . ActiveManualOnly ( ) )
{ //first one is off, too, so just turn that one on
if ( ! self - > client - > ps . saberInFlight )
{ //but only if it's in your hand!
self - > client - > ps . saber [ 0 ] . Activate ( ) ;
}
}
else
{ //turn on the second one
self - > client - > ps . saber [ 1 ] . Activate ( ) ;
}
return ;
}
}
else if ( self - > client - > ps . saber [ 0 ] . numBlades > 1
& & WP_SaberCanTurnOffSomeBlades ( & self - > client - > ps . saber [ 0 ] ) ) //self->client->ps.saber[0].type == SABER_STAFF )
{ //can't cycle styles with saberstaff, so just toggles saber blades on/off
if ( self - > client - > ps . saberInFlight )
{ //can't turn second blade back on if it's in the air, you naughty boy!
return ;
}
/*
if ( self - > client - > ps . saber [ 0 ] . singleBladeStyle = = SS_NONE )
{ //can't use just one blade?
return ;
}
*/
qboolean playedSound = qfalse ;
if ( ! self - > client - > ps . saber [ 0 ] . blade [ 0 ] . active )
{ //first one is not even on
//turn only it on
self - > client - > ps . SaberBladeActivate ( 0 , 0 , qtrue ) ;
return ;
}
qboolean skipThisBlade ;
for ( int bladeNum = 1 ; bladeNum < self - > client - > ps . saber [ 0 ] . numBlades ; bladeNum + + )
{
if ( ! self - > client - > ps . saber [ 0 ] . blade [ bladeNum ] . active )
{ //extra is off, turn it on
self - > client - > ps . saber [ 0 ] . BladeActivate ( bladeNum , qtrue ) ;
}
else
{ //turn extra off
skipThisBlade = qfalse ;
if ( WP_SaberBladeUseSecondBladeStyle ( & self - > client - > ps . saber [ 1 ] , bladeNum ) )
{ //check to see if we should check the secondary style's flags
if ( ( self - > client - > ps . saber [ 1 ] . saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE2 ) )
{
skipThisBlade = qtrue ;
}
}
else
{ //use the primary style's flags
if ( ( self - > client - > ps . saber [ 1 ] . saberFlags2 & SFL2_NO_MANUAL_DEACTIVATE ) )
{
skipThisBlade = qtrue ;
}
}
if ( ! skipThisBlade )
{
self - > client - > ps . saber [ 0 ] . BladeActivate ( bladeNum , qfalse ) ;
if ( ! playedSound )
{
G_SoundIndexOnEnt ( self , CHAN_WEAPON , self - > client - > ps . saber [ 0 ] . soundOff ) ;
playedSound = qtrue ;
}
}
}
}
return ;
}
int allowedStyles = self - > client - > ps . saberStylesKnown ;
if ( self - > client - > ps . dualSabers
& & self - > client - > ps . saber [ 0 ] . Active ( )
& & self - > client - > ps . saber [ 1 ] . Active ( ) )
{
allowedStyles | = ( 1 < < SS_DUAL ) ;
for ( int styleNum = SS_NONE + 1 ; styleNum < SS_NUM_SABER_STYLES ; styleNum + + )
{
if ( styleNum = = SS_TAVION
& & ( ( self - > client - > ps . saber [ 0 ] . stylesLearned & ( 1 < < SS_TAVION ) ) | | ( self - > client - > ps . saber [ 1 ] . stylesLearned & ( 1 < < SS_TAVION ) ) ) //was given this style by one of my sabers
& & ! ( self - > client - > ps . saber [ 0 ] . stylesForbidden & ( 1 < < SS_TAVION ) )
& & ! ( self - > client - > ps . saber [ 1 ] . stylesForbidden & ( 1 < < SS_TAVION ) ) )
{ //if have both sabers on, allow tavion only if one of our sabers specifically wanted to use it... (unless specifically forbidden)
}
else if ( styleNum = = SS_DUAL
& & ! ( self - > client - > ps . saber [ 0 ] . stylesForbidden & ( 1 < < SS_DUAL ) )
& & ! ( self - > client - > ps . saber [ 1 ] . stylesForbidden & ( 1 < < SS_DUAL ) ) )
{ //if have both sabers on, only dual style is allowed (unless specifically forbidden)
}
else
{
allowedStyles & = ~ ( 1 < < styleNum ) ;
}
}
}
if ( ! allowedStyles )
{
return ;
}
int saberAnimLevel ;
if ( ! self - > s . number )
{
saberAnimLevel = cg . saberAnimLevelPending ;
}
else
{
saberAnimLevel = self - > client - > ps . saberAnimLevel ;
}
saberAnimLevel + + ;
int sanityCheck = 0 ;
while ( self - > client - > ps . saberAnimLevel ! = saberAnimLevel
& & ! ( allowedStyles & ( 1 < < saberAnimLevel ) )
& & sanityCheck < SS_NUM_SABER_STYLES + 1 )
{
saberAnimLevel + + ;
if ( saberAnimLevel > SS_STAFF )
{
saberAnimLevel = SS_FAST ;
}
sanityCheck + + ;
}
if ( ! ( allowedStyles & ( 1 < < saberAnimLevel ) ) )
{
return ;
}
WP_UseFirstValidSaberStyle ( self , & saberAnimLevel ) ;
if ( ! self - > s . number )
{
cg . saberAnimLevelPending = saberAnimLevel ;
}
else
{
self - > client - > ps . saberAnimLevel = saberAnimLevel ;
}
# ifndef FINAL_BUILD
switch ( saberAnimLevel )
{
case SS_FAST :
gi . Printf ( S_COLOR_BLUE " Lightsaber Combat Style: Fast \n " ) ;
//LIGHTSABERCOMBATSTYLE_FAST
break ;
case SS_MEDIUM :
gi . Printf ( S_COLOR_YELLOW " Lightsaber Combat Style: Medium \n " ) ;
//LIGHTSABERCOMBATSTYLE_MEDIUM
break ;
case SS_STRONG :
gi . Printf ( S_COLOR_RED " Lightsaber Combat Style: Strong \n " ) ;
//LIGHTSABERCOMBATSTYLE_STRONG
break ;
case SS_DESANN :
gi . Printf ( S_COLOR_CYAN " Lightsaber Combat Style: Desann \n " ) ;
//LIGHTSABERCOMBATSTYLE_DESANN
break ;
case SS_TAVION :
gi . Printf ( S_COLOR_MAGENTA " Lightsaber Combat Style: Tavion \n " ) ;
//LIGHTSABERCOMBATSTYLE_TAVION
break ;
case SS_DUAL :
gi . Printf ( S_COLOR_MAGENTA " Lightsaber Combat Style: Dual \n " ) ;
//LIGHTSABERCOMBATSTYLE_TAVION
break ;
case SS_STAFF :
gi . Printf ( S_COLOR_MAGENTA " Lightsaber Combat Style: Staff \n " ) ;
//LIGHTSABERCOMBATSTYLE_TAVION
break ;
}
//gi.Printf("\n");
# endif
}
qboolean G_ReleaseEntity ( gentity_t * grabber )
{
if ( grabber & & grabber - > client & & grabber - > client - > ps . heldClient < ENTITYNUM_WORLD )
{
gentity_t * heldClient = & g_entities [ grabber - > client - > ps . heldClient ] ;
grabber - > client - > ps . heldClient = ENTITYNUM_NONE ;
if ( heldClient & & heldClient - > client )
{
heldClient - > client - > ps . heldByClient = ENTITYNUM_NONE ;
heldClient - > owner = NULL ;
}
return qtrue ;
}
return qfalse ;
}
void G_GrabEntity ( gentity_t * grabber , const char * target )
{
if ( ! grabber | | ! grabber - > client )
{
return ;
}
gentity_t * heldClient = G_Find ( NULL , FOFS ( targetname ) , ( char * ) target ) ;
if ( heldClient & & heldClient - > client & & heldClient ! = grabber ) //don't grab yourself, it's not polite
{ //found him
grabber - > client - > ps . heldClient = heldClient - > s . number ;
heldClient - > client - > ps . heldByClient = grabber - > s . number ;
heldClient - > owner = grabber ;
}
}
static void Svcmd_ICARUS_f ( void )
{
Quake3Game ( ) - > Svcmd ( ) ;
}
template < int32_t power >
static void Svcmd_ForceSetLevel_f ( void )
{
Svcmd_ForceSetLevel_f ( power ) ;
}
static void Svcmd_SetForceAll_f ( void )
{
for ( int i = FP_HEAL ; i < NUM_FORCE_POWERS ; i + + )
{
Svcmd_ForceSetLevel_f ( i ) ;
}
if ( gi . argc ( ) > 1 )
{
for ( int i = SS_NONE + 1 ; i < SS_NUM_SABER_STYLES ; i + + )
{
g_entities [ 0 ] . client - > ps . saberStylesKnown | = ( 1 < < i ) ;
}
}
}
2023-05-12 17:41:08 +00:00
void Svcmd_SaberSetLevel_f ( void )
{
if ( ! & g_entities [ 0 ] | | ! g_entities [ 0 ] . client )
{
return ;
}
gentity_t * self = G_GetSelfForPlayerCmd ( ) ;
if ( self - > s . weapon ! = WP_SABER )
{
return ;
}
const char * newVal = gi . argv ( 1 ) ;
int saberAnimLevel = atoi ( newVal ) ;
if ( ! self - > s . number )
{
cg . saberAnimLevelPending = saberAnimLevel ;
}
else
{
self - > client - > ps . saberAnimLevel = saberAnimLevel ;
}
}
2022-09-18 15:37:21 +00:00
static void Svcmd_SetSaberAll_f ( void )
{
Svcmd_ForceSetLevel_f ( FP_SABERTHROW ) ;
Svcmd_ForceSetLevel_f ( FP_SABER_DEFENSE ) ;
Svcmd_ForceSetLevel_f ( FP_SABER_OFFENSE ) ;
for ( int i = SS_NONE + 1 ; i < SS_NUM_SABER_STYLES ; i + + )
{
g_entities [ 0 ] . client - > ps . saberStylesKnown | = ( 1 < < i ) ;
}
}
static void Svcmd_RunScript_f ( void )
{
const char * cmd2 = gi . argv ( 1 ) ;
if ( cmd2 & & cmd2 [ 0 ] )
{
const char * cmd3 = gi . argv ( 2 ) ;
if ( cmd3 & & cmd3 [ 0 ] )
{
gentity_t * found = NULL ;
if ( ( found = G_Find ( NULL , FOFS ( targetname ) , cmd2 ) ) ! = NULL )
{
Quake3Game ( ) - > RunScript ( found , cmd3 ) ;
}
else
{
//can't find cmd2
gi . Printf ( S_COLOR_RED " runscript: can't find targetname %s \n " , cmd2 ) ;
}
}
else
{
Quake3Game ( ) - > RunScript ( & g_entities [ 0 ] , cmd2 ) ;
}
}
else
{
gi . Printf ( S_COLOR_RED " usage: runscript <ent targetname> scriptname \n " ) ;
}
}
static void Svcmd_PlayerTeam_f ( void )
{
const char * cmd2 = gi . argv ( 1 ) ;
if ( ! * cmd2 | | ! cmd2 [ 0 ] )
{
gi . Printf ( S_COLOR_RED " 'playerteam' - change player team, requires a team name! \n " ) ;
gi . Printf ( S_COLOR_RED " Current team is: %s \n " , GetStringForID ( TeamTable , g_entities [ 0 ] . client - > playerTeam ) ) ;
gi . Printf ( S_COLOR_RED " Valid team names are: \n " ) ;
for ( int n = ( TEAM_FREE + 1 ) ; n < TEAM_NUM_TEAMS ; n + + )
{
gi . Printf ( S_COLOR_RED " %s \n " , GetStringForID ( TeamTable , n ) ) ;
}
}
else
{
team_t team ;
team = ( team_t ) GetIDForString ( TeamTable , cmd2 ) ;
if ( team = = ( team_t ) - 1 )
{
gi . Printf ( S_COLOR_RED " 'playerteam' unrecognized team name %s! \n " , cmd2 ) ;
gi . Printf ( S_COLOR_RED " Current team is: %s \n " , GetStringForID ( TeamTable , g_entities [ 0 ] . client - > playerTeam ) ) ;
gi . Printf ( S_COLOR_RED " Valid team names are: \n " ) ;
for ( int n = TEAM_FREE ; n < TEAM_NUM_TEAMS ; n + + )
{
gi . Printf ( S_COLOR_RED " %s \n " , GetStringForID ( TeamTable , n ) ) ;
}
}
else
{
g_entities [ 0 ] . client - > playerTeam = team ;
//FIXME: convert Imperial, Malon, Hirogen and Klingon to Scavenger?
}
}
}
static void Svcmd_Control_f ( void )
{
const char * cmd2 = gi . argv ( 1 ) ;
if ( ! * cmd2 | | ! cmd2 [ 0 ] )
{
if ( ! G_ClearViewEntity ( & g_entities [ 0 ] ) )
{
gi . Printf ( S_COLOR_RED " control <NPC_targetname> \n " , cmd2 ) ;
}
}
else
{
Q3_SetViewEntity ( 0 , cmd2 ) ;
}
}
static void Svcmd_Grab_f ( void )
{
const char * cmd2 = gi . argv ( 1 ) ;
if ( ! * cmd2 | | ! cmd2 [ 0 ] )
{
if ( ! G_ReleaseEntity ( & g_entities [ 0 ] ) )
{
gi . Printf ( S_COLOR_RED " grab <NPC_targetname> \n " , cmd2 ) ;
}
}
else
{
G_GrabEntity ( & g_entities [ 0 ] , cmd2 ) ;
}
}
static void Svcmd_Knockdown_f ( void )
{
G_Knockdown ( & g_entities [ 0 ] , & g_entities [ 0 ] , vec3_origin , 300 , qtrue ) ;
}
static void Svcmd_PlayerModel_f ( void )
{
if ( gi . argc ( ) = = 1 )
{
gi . Printf ( S_COLOR_RED " USAGE: playerModel <NPC Name> \n playerModel <g2model> <skinhead> <skintorso> <skinlower> \n playerModel player (builds player from customized menu settings) " S_COLOR_WHITE " \n " ) ;
gi . Printf ( " playerModel = %s " , va ( " %s %s %s %s \n " , g_char_model - > string , g_char_skin_head - > string , g_char_skin_torso - > string , g_char_skin_legs - > string ) ) ;
}
else if ( gi . argc ( ) = = 2 )
{
G_ChangePlayerModel ( & g_entities [ 0 ] , gi . argv ( 1 ) ) ;
}
else if ( gi . argc ( ) = = 5 )
{
//instead of setting it directly via a command, we now store it in cvars
//G_ChangePlayerModel( &g_entities[0], va("%s|%s|%s|%s", gi.argv(1), gi.argv(2), gi.argv(3), gi.argv(4)) );
gi . cvar_set ( " g_char_model " , gi . argv ( 1 ) ) ;
gi . cvar_set ( " g_char_skin_head " , gi . argv ( 2 ) ) ;
gi . cvar_set ( " g_char_skin_torso " , gi . argv ( 3 ) ) ;
gi . cvar_set ( " g_char_skin_legs " , gi . argv ( 4 ) ) ;
G_InitPlayerFromCvars ( & g_entities [ 0 ] ) ;
}
}
static void Svcmd_PlayerTint_f ( void )
{
if ( gi . argc ( ) = = 4 )
{
g_entities [ 0 ] . client - > renderInfo . customRGBA [ 0 ] = atoi ( gi . argv ( 1 ) ) ;
g_entities [ 0 ] . client - > renderInfo . customRGBA [ 1 ] = atoi ( gi . argv ( 2 ) ) ;
g_entities [ 0 ] . client - > renderInfo . customRGBA [ 2 ] = atoi ( gi . argv ( 3 ) ) ;
gi . cvar_set ( " g_char_color_red " , gi . argv ( 1 ) ) ;
gi . cvar_set ( " g_char_color_green " , gi . argv ( 2 ) ) ;
gi . cvar_set ( " g_char_color_blue " , gi . argv ( 3 ) ) ;
}
else
{
gi . Printf ( S_COLOR_RED " USAGE: playerTint <red 0 - 255> <green 0 - 255> <blue 0 - 255> \n " ) ;
gi . Printf ( " playerTint = %s \n " , va ( " %d %d %d " , g_char_color_red - > integer , g_char_color_green - > integer , g_char_color_blue - > integer ) ) ;
}
}
static void Svcmd_IKnowKungfu_f ( void )
{
gi . cvar_set ( " g_debugMelee " , " 1 " ) ;
G_SetWeapon ( & g_entities [ 0 ] , WP_MELEE ) ;
for ( int i = FP_FIRST ; i < NUM_FORCE_POWERS ; i + + )
{
g_entities [ 0 ] . client - > ps . forcePowersKnown | = ( 1 < < i ) ;
if ( i = = FP_TELEPATHY )
{
g_entities [ 0 ] . client - > ps . forcePowerLevel [ i ] = FORCE_LEVEL_4 ;
}
else
{
g_entities [ 0 ] . client - > ps . forcePowerLevel [ i ] = FORCE_LEVEL_3 ;
}
}
}
static void Svcmd_Secrets_f ( void )
{
const gentity_t * pl = & g_entities [ 0 ] ;
if ( pl - > client - > sess . missionStats . totalSecrets < 1 )
{
gi . Printf ( " There are " S_COLOR_RED " NO " S_COLOR_WHITE " secrets on this map! \n " ) ;
}
else if ( pl - > client - > sess . missionStats . secretsFound = = pl - > client - > sess . missionStats . totalSecrets )
{
gi . Printf ( " You've found all " S_COLOR_GREEN " %i " S_COLOR_WHITE " secrets on this map! \n " , pl - > client - > sess . missionStats . secretsFound ) ;
}
else
{
gi . Printf ( " You've found " S_COLOR_GREEN " %i " S_COLOR_WHITE " out of " S_COLOR_GREEN " %i " S_COLOR_WHITE " secrets! \n " , pl - > client - > sess . missionStats . secretsFound , pl - > client - > sess . missionStats . totalSecrets ) ;
}
}
// PADAWAN - g_spskill 0 + cg_crosshairForceHint 1 + handicap 100
// JEDI - g_spskill 1 + cg_crosshairForceHint 1 + handicap 100
// JEDI KNIGHT - g_spskill 2 + cg_crosshairForceHint 0 + handicap 100
// JEDI MASTER - g_spskill 2 + cg_crosshairForceHint 0 + handicap 50
extern cvar_t * g_spskill ;
static void Svcmd_Difficulty_f ( void )
{
if ( gi . argc ( ) = = 1 )
{
if ( g_spskill - > integer = = 0 )
{
gi . Printf ( S_COLOR_GREEN " Current Difficulty: Padawan " S_COLOR_WHITE " \n " ) ;
}
else if ( g_spskill - > integer = = 1 )
{
gi . Printf ( S_COLOR_GREEN " Current Difficulty: Jedi " S_COLOR_WHITE " \n " ) ;
}
else if ( g_spskill - > integer = = 2 )
{
int crosshairHint = gi . Cvar_VariableIntegerValue ( " cg_crosshairForceHint " ) ;
int handicap = gi . Cvar_VariableIntegerValue ( " handicap " ) ;
if ( handicap = = 100 & & crosshairHint = = 0 )
{
gi . Printf ( S_COLOR_GREEN " Current Difficulty: Jedi Knight " S_COLOR_WHITE " \n " ) ;
}
else if ( handicap = = 50 & & crosshairHint = = 0 )
{
gi . Printf ( S_COLOR_GREEN " Current Difficulty: Jedi Master " S_COLOR_WHITE " \n " ) ;
}
else
{
gi . Printf ( S_COLOR_GREEN " Current Difficulty: Jedi Knight (Custom) " S_COLOR_WHITE " \n " ) ;
gi . Printf ( S_COLOR_GREEN " Crosshair Force Hint: %i " S_COLOR_WHITE " \n " , crosshairHint ! = 0 ? 1 : 0 ) ;
gi . Printf ( S_COLOR_GREEN " Handicap: %i " S_COLOR_WHITE " \n " , handicap ) ;
}
}
else
{
gi . Printf ( S_COLOR_RED " Invalid difficulty cvar set! g_spskill (%i) [0-2] is valid range only " S_COLOR_WHITE " \n " , g_spskill - > integer ) ;
}
}
}
# define CMD_NONE (0x00000000u)
# define CMD_CHEAT (0x00000001u)
# define CMD_ALIVE (0x00000002u)
typedef struct svcmd_s {
const char * name ;
void ( * func ) ( void ) ;
uint32_t flags ;
} svcmd_t ;
static int svcmdcmp ( const void * a , const void * b ) {
return Q_stricmp ( ( const char * ) a , ( ( svcmd_t * ) b ) - > name ) ;
}
// FIXME some of these should be made CMD_ALIVE too!
static svcmd_t svcmds [ ] = {
{ " entitylist " , Svcmd_EntityList_f , CMD_NONE } ,
{ " game_memory " , Svcmd_GameMem_f , CMD_NONE } ,
{ " nav " , Svcmd_Nav_f , CMD_CHEAT } ,
{ " npc " , Svcmd_NPC_f , CMD_CHEAT } ,
{ " use " , Svcmd_Use_f , CMD_CHEAT } ,
{ " ICARUS " , Svcmd_ICARUS_f , CMD_CHEAT } ,
{ " saberColor " , Svcmd_SaberColor_f , CMD_CHEAT } ,
{ " saber " , Svcmd_Saber_f , CMD_CHEAT } ,
{ " saberBlade " , Svcmd_SaberBlade_f , CMD_CHEAT } ,
{ " setForceJump " , Svcmd_ForceSetLevel_f < FP_LEVITATION > , CMD_CHEAT } ,
{ " setSaberThrow " , Svcmd_ForceSetLevel_f < FP_SABERTHROW > , CMD_CHEAT } ,
{ " setForceHeal " , Svcmd_ForceSetLevel_f < FP_HEAL > , CMD_CHEAT } ,
{ " setForcePush " , Svcmd_ForceSetLevel_f < FP_PUSH > , CMD_CHEAT } ,
{ " setForcePull " , Svcmd_ForceSetLevel_f < FP_PULL > , CMD_CHEAT } ,
{ " setForceSpeed " , Svcmd_ForceSetLevel_f < FP_SPEED > , CMD_CHEAT } ,
{ " setForceGrip " , Svcmd_ForceSetLevel_f < FP_GRIP > , CMD_CHEAT } ,
{ " setForceLightning " , Svcmd_ForceSetLevel_f < FP_LIGHTNING > , CMD_CHEAT } ,
{ " setMindTrick " , Svcmd_ForceSetLevel_f < FP_TELEPATHY > , CMD_CHEAT } ,
{ " setSaberDefense " , Svcmd_ForceSetLevel_f < FP_SABER_DEFENSE > , CMD_CHEAT } ,
{ " setSaberOffense " , Svcmd_ForceSetLevel_f < FP_SABER_OFFENSE > , CMD_CHEAT } ,
{ " setForceRage " , Svcmd_ForceSetLevel_f < FP_RAGE > , CMD_CHEAT } ,
{ " setForceDrain " , Svcmd_ForceSetLevel_f < FP_DRAIN > , CMD_CHEAT } ,
{ " setForceProtect " , Svcmd_ForceSetLevel_f < FP_PROTECT > , CMD_CHEAT } ,
{ " setForceAbsorb " , Svcmd_ForceSetLevel_f < FP_ABSORB > , CMD_CHEAT } ,
{ " setForceSight " , Svcmd_ForceSetLevel_f < FP_SEE > , CMD_CHEAT } ,
{ " setForceAll " , Svcmd_SetForceAll_f , CMD_CHEAT } ,
{ " setSaberAll " , Svcmd_SetSaberAll_f , CMD_CHEAT } ,
2023-05-12 17:41:08 +00:00
{ " setSaberLevel " , Svcmd_SaberSetLevel_f , CMD_NONE } ,
2022-09-18 15:37:21 +00:00
{ " saberAttackCycle " , Svcmd_SaberAttackCycle_f , CMD_NONE } ,
{ " runscript " , Svcmd_RunScript_f , CMD_CHEAT } ,
{ " playerTeam " , Svcmd_PlayerTeam_f , CMD_CHEAT } ,
{ " control " , Svcmd_Control_f , CMD_CHEAT } ,
{ " grab " , Svcmd_Grab_f , CMD_CHEAT } ,
{ " knockdown " , Svcmd_Knockdown_f , CMD_CHEAT } ,
{ " playerModel " , Svcmd_PlayerModel_f , CMD_NONE } ,
{ " playerTint " , Svcmd_PlayerTint_f , CMD_NONE } ,
{ " nexttestaxes " , G_NextTestAxes , CMD_NONE } ,
{ " exitview " , Svcmd_ExitView_f , CMD_NONE } ,
{ " iknowkungfu " , Svcmd_IKnowKungfu_f , CMD_CHEAT } ,
{ " secrets " , Svcmd_Secrets_f , CMD_NONE } ,
{ " difficulty " , Svcmd_Difficulty_f , CMD_NONE } ,
//{ "say", Svcmd_Say_f, qtrue },
//{ "toggleallowvote", Svcmd_ToggleAllowVote_f, qfalse },
//{ "toggleuserinfovalidation", Svcmd_ToggleUserinfoValidation_f, qfalse },
} ;
static const size_t numsvcmds = ARRAY_LEN ( svcmds ) ;
/*
= = = = = = = = = = = = = = = = =
ConsoleCommand
= = = = = = = = = = = = = = = = =
*/
qboolean ConsoleCommand ( void ) {
const char * cmd = gi . argv ( 0 ) ;
const svcmd_t * command = ( const svcmd_t * ) Q_LinearSearch ( cmd , svcmds , numsvcmds , sizeof ( svcmds [ 0 ] ) , svcmdcmp ) ;
if ( ! command )
return qfalse ;
if ( ( command - > flags & CMD_CHEAT )
& & ! g_cheats - > integer )
{
gi . Printf ( " Cheats are not enabled on this server. \n " ) ;
return qtrue ;
}
else if ( ( command - > flags & CMD_ALIVE )
& & ( g_entities [ 0 ] . health < = 0 ) )
{
gi . Printf ( " You must be alive to use this command. \n " ) ;
return qtrue ;
}
else
command - > func ( ) ;
return qtrue ;
}