Skip to content

Commit

Permalink
cgame - game: Implement instant character model changing, remove forc…
Browse files Browse the repository at this point in the history
…e model and defer player model logics, and apply compilation safety in player_die function when attacker parameter is NULL
  • Loading branch information
LegendaryGuard committed Aug 16, 2024
1 parent 1457062 commit ec2085f
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 66 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ A legendary 90s era Quake 3 Arena mod.
- [x] ~~Third person traceable crosshair~~
- [x] ~~Breakable map entities ("func_breakable")~~
- [x] ~~Ki trails (use ki to move, cg_kiTrail >10 )~~
- [x] ~~Instant character model changing~~
- [ ] Make ki energy regeneration, ki use, attacks, charging balance indicated on old docs
- [ ] Powerlevel and Power Tiers indicated on old docs
- [x] ~~Hit Stun (makes player can't use ki, melee, block and charge)~~
Expand Down
4 changes: 2 additions & 2 deletions source/cgame/cg_cvar.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ CG_CVAR( cg_superdeformed, "cg_superdeformed", "0", CVAR_ARCHIVE ) // BFP - Supe
CG_CVAR( cg_yrgolroxor, "cg_yrgolroxor", "0", 0 ) // BFP - Yrgol Roxor easter egg
CG_CVAR( cg_teamChatTime, "cg_teamChatTime", "3000", CVAR_ARCHIVE )
CG_CVAR( cg_teamChatHeight, "cg_teamChatHeight", "0", CVAR_ARCHIVE )
CG_CVAR( cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE )
CG_CVAR( cg_forceModel, "cg_forceModel", "0", CVAR_ARCHIVE ) // BFP - TODO: In the future, remove cg_forceModel, which wasn't removed originally?
CG_CVAR( cg_predictItems, "cg_predictItems", "1", CVAR_ARCHIVE )
CG_CVAR( cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE )
CG_CVAR( cg_deferPlayers, "cg_deferPlayers", "1", CVAR_ARCHIVE ) // BFP - TODO: In the future, remove cg_deferPlayers, which wasn't removed originally?
CG_CVAR( cg_drawTeamOverlay, "cg_drawTeamOverlay", "0", CVAR_ARCHIVE )
CG_CVAR( cg_teamOverlayUserinfo, "teamoverlay", "0", CVAR_ROM | CVAR_USERINFO )
CG_CVAR( cg_stats, "cg_stats", "0", 0 )
Expand Down
12 changes: 9 additions & 3 deletions source/cgame/cg_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// cg_main.c -- initialization and primary entry point for cgame
#include "cg_local.h"

int forceModelModificationCount = -1;
// int forceModelModificationCount = -1;

void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum );
void CG_Shutdown( void );
Expand Down Expand Up @@ -119,15 +119,17 @@ void CG_RegisterCvars( void ) {
trap_Cvar_VariableStringBuffer( "sv_running", var, sizeof( var ) );
cgs.localServer = atoi( var );

forceModelModificationCount = cg_forceModel.modificationCount;
// forceModelModificationCount = cg_forceModel.modificationCount;

trap_Cvar_Register(NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
trap_Cvar_Register(NULL, "headmodel", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
//trap_Cvar_Register(NULL, "team_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
//trap_Cvar_Register(NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE );
}

/*
// BFP - No force model (In the future, remove cg_forceModel, which wasn't removed originally?)
#if 0
/*
===================
CG_ForceModelChange
===================
Expand All @@ -145,6 +147,7 @@ static void CG_ForceModelChange( void ) {
CG_NewClientInfo( i );
}
}
#endif

/*
=================
Expand Down Expand Up @@ -175,11 +178,14 @@ void CG_UpdateCvars( void ) {
trap_Cvar_Set( "teamoverlay", "1" );
}

// BFP - No force model (In the future, remove cg_forceModel, which wasn't removed originally?)
#if 0
// if force model changed
if ( forceModelModificationCount != cg_forceModel.modificationCount ) {
forceModelModificationCount = cg_forceModel.modificationCount;
CG_ForceModelChange();
}
#endif
}

int CG_CrosshairPlayer( void ) {
Expand Down
62 changes: 37 additions & 25 deletions source/cgame/cg_players.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,8 @@ static void CG_LoadClientInfo( clientInfo_t *ci ) {
}
}

// BFP - Unused static functions, remove? I think so
#if 0
/*
======================
CG_CopyClientInfoModel
Expand Down Expand Up @@ -870,6 +872,7 @@ static void CG_SetDeferredClientInfo( clientInfo_t *ci ) {

CG_LoadClientInfo( ci );
}
#endif


/*
Expand Down Expand Up @@ -943,6 +946,8 @@ void CG_NewClientInfo( int clientNum ) {

// model
v = Info_ValueForKey( configstring, "model" );
// BFP - No force model (In the future, remove cg_forceModel, which wasn't removed originally?)
#if 0
if ( cg_forceModel.integer ) {
// forcemodel makes everyone use a single model
// to prevent load hitches
Expand Down Expand Up @@ -971,22 +976,24 @@ void CG_NewClientInfo( int clientNum ) {
Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) );
}
}
} else {
Q_strncpyz( newInfo.modelName, v, sizeof( newInfo.modelName ) );
} else
#endif
Q_strncpyz( newInfo.modelName, v, sizeof( newInfo.modelName ) );

slash = strchr( newInfo.modelName, '/' );
if ( !slash ) {
// modelName didn not include a skin name
Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) );
} else {
Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) );
// truncate modelName
*slash = 0;
}
slash = strchr( newInfo.modelName, '/' );
if ( !slash ) {
// modelName didn not include a skin name
Q_strncpyz( newInfo.skinName, "default", sizeof( newInfo.skinName ) );
} else {
Q_strncpyz( newInfo.skinName, slash + 1, sizeof( newInfo.skinName ) );
// truncate modelName
*slash = 0;
}

// head model
v = Info_ValueForKey( configstring, "hmodel" );
// BFP - No force model (In the future, remove cg_forceModel, which wasn't removed originally?)
#if 0
if ( cg_forceModel.integer ) {
// forcemodel makes everyone use a single model
// to prevent load hitches
Expand Down Expand Up @@ -1015,23 +1022,27 @@ void CG_NewClientInfo( int clientNum ) {
Q_strncpyz( newInfo.headSkinName, slash + 1, sizeof( newInfo.headSkinName ) );
}
}
} else {
Q_strncpyz( newInfo.headModelName, v, sizeof( newInfo.headModelName ) );
} else
#endif
Q_strncpyz( newInfo.headModelName, v, sizeof( newInfo.headModelName ) );

slash = strchr( newInfo.headModelName, '/' );
if ( !slash ) {
// modelName didn not include a skin name
Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) );
} else {
Q_strncpyz( newInfo.headSkinName, slash + 1, sizeof( newInfo.headSkinName ) );
// truncate modelName
*slash = 0;
}
slash = strchr( newInfo.headModelName, '/' );
if ( !slash ) {
// modelName didn not include a skin name
Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) );
} else {
Q_strncpyz( newInfo.headSkinName, slash + 1, sizeof( newInfo.headSkinName ) );
// truncate modelName
*slash = 0;
}

// BFP - Change the model without impeding with defer
// BFP - TODO: Remove cg_deferPlayers cvar and its unnecessary code in the future
#if 0
// scan for an existing clientinfo that matches this modelname
// so we can avoid loading checks if possible
if ( !CG_ScanForExistingClientInfo( &newInfo ) ) {
// if ( !CG_ScanForExistingClientInfo( &newInfo ) )
// {
qboolean forceDefer;

forceDefer = trap_MemoryRemaining() < 4000000;
Expand All @@ -1046,9 +1057,10 @@ void CG_NewClientInfo( int clientNum ) {
newInfo.deferred = qfalse;
}
} else {
#endif
CG_LoadClientInfo( &newInfo );
}
}
// }
// }

// replace whatever was there with the new one
newInfo.infoValid = qtrue;
Expand Down
63 changes: 33 additions & 30 deletions source/game/g_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,10 @@ void ClientUserinfoChanged( int clientNum ) {
char blueTeam[MAX_INFO_STRING];
char userinfo[MAX_INFO_STRING];

// BFP - Model prefix load
char newModelPrefix[MAX_QPATH];
char *oldModelDash, *newModelDash;

ent = g_entities + clientNum;
client = ent->client;

Expand Down Expand Up @@ -779,43 +783,13 @@ void ClientUserinfoChanged( int clientNum ) {
team = client->sess.sessionTeam;
}

/* NOTE: all client side now
// team
switch( team ) {
case TEAM_RED:
ForceClientSkin(client, model, "red");
// ForceClientSkin(client, headModel, "red");
break;
case TEAM_BLUE:
ForceClientSkin(client, model, "blue");
// ForceClientSkin(client, headModel, "blue");
break;
}
// don't ever use a default skin in teamplay, it would just waste memory
// however bots will always join a team but they spawn in as spectator
if ( g_gametype.integer >= GT_TEAM && team == TEAM_SPECTATOR) {
ForceClientSkin(client, model, "red");
// ForceClientSkin(client, headModel, "red");
}
*/

// teamInfo
s = Info_ValueForKey( userinfo, "teamoverlay" );
if ( ! *s || atoi( s ) != 0 ) {
client->pers.teamInfo = qtrue;
} else {
client->pers.teamInfo = qfalse;
}
/*
s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
if ( !*s || atoi( s ) == 0 ) {
client->pers.pmoveFixed = qfalse;
}
else {
client->pers.pmoveFixed = qtrue;
}
*/

// team task (0 = none, 1 = offence, 2 = defence)
teamTask = atoi(Info_ValueForKey(userinfo, "teamtask"));
Expand Down Expand Up @@ -844,6 +818,35 @@ void ClientUserinfoChanged( int clientNum ) {

trap_SetConfigstring( CS_PLAYERS+clientNum, s );

// BFP - Model prefix handling
{
// extract model prefixes safely
oldModelDash = strchr(ent->oldModel, '-');
if ( oldModelDash ) {
Q_strncpyz( ent->oldModelPrefix, ent->oldModel, oldModelDash - ent->oldModel + 1 );
} else {
Q_strncpyz( ent->oldModelPrefix, ent->oldModel, sizeof( ent->oldModelPrefix ) );
}

newModelDash = strchr(model, '-');
if ( newModelDash ) {
Q_strncpyz( newModelPrefix, model, newModelDash - model + 1 );
} else {
Q_strncpyz( newModelPrefix, model, sizeof( newModelPrefix ) );
}

// compare model prefixes
if ( Q_stricmp( ent->oldModelPrefix, newModelPrefix ) ) {
// prefixes differ, kill the player
ent->flags &= ~FL_GODMODE;
ent->client->ps.stats[STAT_HEALTH] = ent->health = 0;
player_die( ent, ent, NULL, 100000, MOD_UNKNOWN );
}

// save the new model as the old model for the next time this function runs
Q_strncpyz( ent->oldModel, model, sizeof( ent->oldModel ) );
}

// this is not the userinfo, more like the configstring actually
G_LogPrintf( "ClientUserinfoChanged: %i %s\n", clientNum, s );
}
Expand Down
18 changes: 12 additions & 6 deletions source/game/g_combat.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,13 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
return;
}

// check for an almost capture
CheckAlmostCapture( self, attacker );
// check for a player that almost brought in cubes
CheckAlmostScored( self, attacker );
// BFP - For compilation safety from shared objects (.so) and dll
if ( attacker != NULL ) {
// check for an almost capture
CheckAlmostCapture( self, attacker );
// check for a player that almost brought in cubes
CheckAlmostScored( self, attacker );
}

// BFP - no hook
#if 0
Expand Down Expand Up @@ -425,8 +428,11 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
AddScore( self, self->r.currentOrigin, -1 );
}

// Add team bonuses
Team_FragBonuses(self, inflictor, attacker);
// BFP - For compilation safety from shared objects (.so) and dll
if ( attacker != NULL ) {
// Add team bonuses
Team_FragBonuses(self, inflictor, attacker);
}

// if I committed suicide, the flag does not fall, it returns.
if (meansOfDeath == MOD_SUICIDE) {
Expand Down
4 changes: 4 additions & 0 deletions source/game/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ struct gentity_s {
char *model;
char *model2;
int freetime; // level.time when the object was freed

// BFP - Model prefix handling
char oldModel[MAX_QPATH];
char oldModelPrefix[MAX_QPATH];

int eventTime; // events will be cleared EVENT_VALID_MSEC after set
qboolean freeAfterEvent;
Expand Down

0 comments on commit ec2085f

Please sign in to comment.