summaryrefslogtreecommitdiff
path: root/src/game/g_playermodel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/g_playermodel.c')
-rw-r--r--src/game/g_playermodel.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/game/g_playermodel.c b/src/game/g_playermodel.c
new file mode 100644
index 0000000..7f79b38
--- /dev/null
+++ b/src/game/g_playermodel.c
@@ -0,0 +1,193 @@
+//
+// Author: blowFish <blowfish@badsec.org>
+//
+
+#include "g_local.h"
+
+//-------------------------------------------------------------------------
+// Player models
+//-------------------------------------------------------------------------
+//
+static qboolean
+_is_playermodel_uniq(const char *model)
+{
+ int i;
+ for ( i = 0; i < level.playerModelCount; i++ )
+ {
+ if ( !strcmp( model, level.playerModel[i] ) )
+ return qfalse;
+ }
+
+ return qtrue;
+}
+
+static void
+G_AddPlayerModel(const char *model)
+{
+ if (!_is_playermodel_uniq(model))
+ return;
+
+ // HACK!
+ if (!strcmp(model, "human_bsuit"))
+ return;
+
+ level.playerModel[ level.playerModelCount ] = G_CopyString(model);
+ level.playerModelCount++;
+}
+
+void G_InitPlayerModel(void)
+{
+ char fileList[ 16*1024 ] = {""};
+ char *filePtr;
+ int numFiles;
+ int fileLen = 0;
+ int i;
+
+ // TODO: Add an FS trap which is does correct file globbing
+ numFiles = trap_FS_GetFilteredFiles( "/models/players", "",
+ "models*players*head_*.skin",
+ fileList, sizeof(fileList) );
+ filePtr = fileList;
+
+ for( i = 0; i < numFiles && level.playerModelCount < MAX_PLAYER_MODEL;
+ i++, filePtr += fileLen + 1 )
+ {
+ char *start, *c;
+
+ fileLen = strlen( filePtr );
+
+ // skip leading '/'
+ start = filePtr + 15;
+
+ // Only want directory names at the current depth.
+ for ( c = start; c != '\0'; c++ )
+ {
+ if ( *c == '/' || *c == '\\' )
+ {
+ *c = '\0';
+ break;
+ }
+ }
+
+ G_AddPlayerModel(start);
+ }
+}
+
+qboolean G_IsValidPlayerModel(const char *model)
+{
+ return !_is_playermodel_uniq(model);
+}
+
+void G_FreePlayerModel(void)
+{
+ int i;
+ for ( i = 0; i < level.playerModelCount; i++ )
+ BG_Free( level.playerModel[i] );
+}
+
+//-------------------------------------------------------------------------
+// Skins
+//-------------------------------------------------------------------------
+
+void G_GetPlayerModelSkins( const char *modelname, char skins[][ 64 ],
+ int maxskins, int *numskins )
+{
+ char fileList[ 16*1024 ] = {""};
+ int nFiles;
+ char *filePtr;
+ int fileLen = 0;
+ int i;
+
+ *numskins = 0;
+ nFiles = trap_FS_GetFilteredFiles("models/players", ".skin",
+ va("models*players*%s*skin", modelname),
+ fileList, sizeof(fileList));
+ filePtr = fileList;
+ for (i = 0; i < nFiles && i < maxskins; i++ )
+ {
+ char *start, *end;
+
+ fileLen = strlen( filePtr );
+
+ start = filePtr;
+ start += strlen(va("models/players/%s/", modelname));
+
+ end = filePtr + fileLen;
+ end -= 5;
+ *end = '\0';
+ filePtr += fileLen + 1;
+
+ // dumb way to filter out the unique skins of segmented and
+ // nonsegmented models.
+ // TODO: Stop writing code at 4am.
+ if ( start[0] == 'h'
+ && start[1] == 'e'
+ && start[2] == 'a'
+ && start[3] == 'd'
+ && start[4] == '_' )
+ start += 5;
+
+ else if ( start[0] == 'n'
+ && start[1] == 'o'
+ && start[2] == 'n'
+ && start[3] == 's'
+ && start[4] == 'e'
+ && start[5] == 'g'
+ && start[6] == '_' )
+ start += 7;
+
+ else
+ continue;
+
+ strncpy(skins[*numskins], start, 64 );
+ (*numskins)++;
+ }
+}
+
+/*
+======================
+GetSkin
+
+Probably should be called GetSkin[or]Default. Tries to recreate what
+appears to be an undocumented set of conventions that must be allowed
+in other q3 derives.
+
+This algorithm is not really good enough for Tremulous considering
+armour + upgrade/advanced in gameplay
+
+XXX Move this into bg_
+======================
+*/
+char *GetSkin( char *modelname, char *wish )
+{
+ char skins[ MAX_PLAYER_MODEL ][ 64 ];
+ int numskins;
+ int i;
+ qboolean foundDefault = qfalse;
+ qboolean foundSelfNamed = qfalse;
+ static char lastpick[ 64 ] = {""};
+ lastpick[0] = '\0'; // reset static buf
+
+ G_GetPlayerModelSkins(modelname, skins, MAX_PLAYER_MODEL, &numskins);
+
+ for (i = 0; i < numskins; i++)
+ {
+ if ( i == 0 )
+ strncpy(lastpick, skins[0], 64 );
+
+ if ( !strcmp(wish, skins[i]) )
+ return wish;
+ else if ( !strcmp("default", skins[i]))
+ foundDefault = qtrue;
+ else if ( !strcmp(modelname, skins[i]))
+ foundSelfNamed = qtrue;
+ }
+
+ if (foundDefault)
+ return "default";
+ else if (foundSelfNamed)
+ return modelname;
+
+ return lastpick;
+}
+