From 9e74dfc7d21ed95aa9ca7dd6b89eea15f093465a Mon Sep 17 00:00:00 2001 From: ac_stef Date: Wed, 15 Oct 2008 15:16:28 +0000 Subject: [PATCH] local custom player skins git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@3036 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- .../models/playermodels/custom/readme.txt | 25 +++++++++ source/src/client.cpp | 36 +++++++++++++ source/src/clients2c.cpp | 5 +- source/src/entity.h | 9 ++-- source/src/protos.h | 1 + source/src/rendermodel.cpp | 53 +++++++++++-------- 6 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 packages/models/playermodels/custom/readme.txt diff --git a/packages/models/playermodels/custom/readme.txt b/packages/models/playermodels/custom/readme.txt new file mode 100644 index 00000000..8eeb55d3 --- /dev/null +++ b/packages/models/playermodels/custom/readme.txt @@ -0,0 +1,25 @@ +Add custom player skins in this folder. + +The filenames should have the following contents: + +[nickname]_ffa.jpg for non-team modes (optional) +[nickname]_cla.jpg for cla players +[nickname]_rvsf.jpg for rvsf players + +or + +[clan-tag]__ffa.jpg for non-team modes (optional) +[clan-tag]__cla.jpg for cla players +[clan-tag]__rvsf.jpg for rvsf players + +The double underscore marks a clan-tag. + + +Examples: + +set of skins for player 'hobo' (nickname has to match exactly): +hobo_cla.jpg, hobo_rvsf.jpg, hobo_ffa.jpg + +set of skins for players from clan 'FOO' (nickname has to contain substring 'FOO', f.e. 'FOO_bar' or 'bar_FOO'): +FOO__cla.jpg, FOO__rvsf.jpg, FOO__ffa.jpg + diff --git a/source/src/client.cpp b/source/src/client.cpp index 8948614e..d75c0200 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -532,3 +532,39 @@ COMMAND(resetsecuremaps, ARG_NONE); COMMAND(securemap, ARG_1STR); COMMAND(getdemo, ARG_1INT); COMMAND(listdemos, ARG_NONE); + +static cvector playerskinlist; + +const char *getclientskin(const char *name, const char *suf) +{ + static string tmp; + int suflen = strlen(suf), namelen = strlen(name); + const char *s, *r = NULL; + loopv(playerskinlist) + { + s = playerskinlist[i]; + int sl = strlen(s) - suflen; + if(sl > 0 && !strcmp(s + sl, suf)) + { + if(!strncmp(name, s, namelen)) return s; // exact match + if(s[sl - 1] == '_') + { + s_strcpy(tmp, s); + tmp[sl - 1] = '\0'; + if(strstr(name, tmp)) r = s; // partial match + } + } + } + return r; +} + +void updateclientname(playerent *d) +{ + static bool gotlist = false; + if(!gotlist) listfiles("packages/models/playermodels/custom", "jpg", playerskinlist); + gotlist = true; + if(!d || !playerskinlist.length()) return; + d->skin_noteam = getclientskin(d->name, "_ffa"); + d->skin_cla = getclientskin(d->name, "_cla"); + d->skin_rvsf = getclientskin(d->name, "_rvsf"); +} diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 99607129..d3e8cbc6 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -156,7 +156,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) protocoldebug(true); } else protocoldebug(false); - #endif + #endif switch(type) { @@ -282,6 +282,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) flaginfo &f = flaginfos[i]; if(!f.actor) f.actor = getclient(f.actor_cn); } + updateclientname(d); break; } @@ -778,7 +779,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) #ifdef _DEBUG protocoldebug(false); - #endif + #endif } void receivefile(uchar *data, int len) diff --git a/source/src/entity.h b/source/src/entity.h index c3a48e60..1c6e5c18 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -263,8 +263,8 @@ struct playerstate { switch(type) { - case I_CLIPS: - additem(ammostats[GUN_PISTOL], ammo[GUN_PISTOL]); + case I_CLIPS: + additem(ammostats[GUN_PISTOL], ammo[GUN_PISTOL]); additem(ammostats[GUN_AKIMBO], ammo[GUN_AKIMBO]); break; case I_AMMO: additem(ammostats[primary], ammo[primary]); break; @@ -350,6 +350,8 @@ struct playerent : dynent, playerstate poshist history; // Previous stored locations of this player + const char *skin_noteam, *skin_cla, *skin_rvsf; + float deltayaw, deltapitch, newyaw, newpitch; int smoothmillis; @@ -358,7 +360,7 @@ struct playerent : dynent, playerstate playerent() : clientnum(-1), lastupdate(0), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), deaths(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), skin(0), nextskin(0), spectatemode(SM_NONE), followplayercn(-1), eardamagemillis(0), respawnoffset(0), prevweaponsel(NULL), weaponsel(NULL), nextweaponsel(NULL), primweap(NULL), nextprimweap(NULL), lastattackweapon(NULL), - smoothmillis(-1), + smoothmillis(-1), head(-1, -1, -1) { type = ENT_PLAYER; @@ -367,6 +369,7 @@ struct playerent : dynent, playerstate aboveeye = 0.7f; radius = 1.1f; maxspeed = 16.0f; + skin_noteam = skin_cla = skin_rvsf = NULL; respawn(); } diff --git a/source/src/protos.h b/source/src/protos.h index 0d09254d..f58878e4 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -303,6 +303,7 @@ extern bool securemapcheck(char *map, bool msg = true); extern void sendintro(); extern void getdemo(int i); extern void listdemos(); +extern void updateclientname(playerent *d); // clientgame extern flaginfo flaginfos[2]; diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index 23daae5e..dfb3e3b0 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -10,7 +10,7 @@ model *loadingmodel = NULL; #include "vertmodel.h" #include "md2.h" #include "md3.h" - + #define checkmdl if(!loadingmodel) { conoutf("not loading a model"); return; } void mdlcullface(int cullface) @@ -91,8 +91,8 @@ void mapmodel(char *rad, char *h, char *zoff, char *snap, char *name) s_sprintf(mmi.name)("mapmodels/%s", name); } -void mapmodelreset() -{ +void mapmodelreset() +{ if(execcontext==IEXC_MAPCFG) mapmodels.setsize(0); } @@ -165,13 +165,13 @@ static vector modelattached; static int numbatches = -1; void startmodelbatches() -{ +{ numbatches = 0; modelattached.setsizenodelete(0); } batchedmodel &addbatchedmodel(model *m) -{ +{ modelbatch *b = NULL; if(m->batch>=0 && m->batchbatch]->m==m) b = batches[m->batch]; else @@ -198,7 +198,7 @@ void renderbatchedmodel(model *m, batchedmodel &b) m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, a, b.scale); return; } - + int x = (int)b.o.x, y = (int)b.o.y; if(!OUTBORD(x, y)) { @@ -400,15 +400,15 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl { center.z += 0.1f; glColor4f(0, 0, 0, dynshadow/100.0f); - m->rendershadow(anim, varseed, speed, basetime, dynshadowquad ? center : o, yaw, a); + m->rendershadow(anim, varseed, speed, basetime, dynshadowquad ? center : o, yaw, a); } - } + } glColor3ub(s->r, s->g, s->b); } else glColor3f(1, 1, 1); m->setskin(tex); - + if(anim&ANIM_TRANSLUCENT) { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); @@ -423,7 +423,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl glGetFloatv(GL_CURRENT_COLOR, color); glColor4f(color[0], color[1], color[2], m->translucency); } - + m->render(anim, varseed, speed, basetime, o, yaw, pitch, d, a, scale); if(anim&ANIM_TRANSLUCENT) @@ -456,9 +456,9 @@ void loadskin(const char *dir, const char *altdir, Texture *&skin) // model skin { strcpy(path+strlen(path)-3, "png"); ifnoload return; - } - } - } + } + } + } } void preload_playermodels() @@ -488,7 +488,7 @@ void preload_entmodels() if(dynshadow && mdl) mdl->genshadows(8.0f, 2.0f); } } - + void preload_mapmodels() { loopv(ents) @@ -622,7 +622,7 @@ void renderclient(playerent *d, const char *mdlname, const char *vwepname, int t } // FIXME: while networked my state as spectator seems to stay CS_DEAD, not CS_SPECTATE // flowtron: I fixed this for following at least (see followplayer()) - if(player1->isspectating() && d->clientnum == player1->followplayercn && player1->spectatemode == SM_FOLLOW3RD_TRANSPARENT) + if(player1->isspectating() && d->clientnum == player1->followplayercn && player1->spectatemode == SM_FOLLOW3RD_TRANSPARENT) { anim |= ANIM_TRANSLUCENT; // see through followed player if(stenciling) return; @@ -636,19 +636,30 @@ void renderclient(playerent *d, const char *mdlname, const char *vwepname, int t } VARP(teamdisplaymode, 0, 1, 2); +VARP(hidecustomskins, 0, 0, 1); void renderclient(playerent *d) { if(!d) return; + const char *cs = NULL, *skinbase = "packages/models/playermodels"; int team = team_int(d->team); int skinid = 1 + max(0, min(d->skin, (team==TEAM_CLA ? 3 : 5))); - string skinbase = "packages/models/playermodels"; string skin; - if(!m_teammode || !teamdisplaymode) s_sprintf(skin)("%s/%s/%02i.jpg", skinbase, team_string(team), skinid); - else switch(teamdisplaymode) + if(!hidecustomskins) { - case 1: s_sprintf(skin)("%s/%s/%02i_%svest.jpg", skinbase, team_string(team), skinid, team ? "blue" : "red"); break; - case 2: default: s_sprintf(skin)("%s/%s/%s.jpg", skinbase, team_string(team), team ? "blue" : "red"); break; + cs = team ? d->skin_rvsf : d->skin_cla; + if(!m_teammode && d->skin_noteam) cs = d->skin_noteam; + } + if(cs) + s_sprintf(skin)("%s/custom/%s.jpg", skinbase, cs); + else + { + if(!m_teammode || !teamdisplaymode) s_sprintf(skin)("%s/%s/%02i.jpg", skinbase, team_string(team), skinid); + else switch(teamdisplaymode) + { + case 1: s_sprintf(skin)("%s/%s/%02i_%svest.jpg", skinbase, team_string(team), skinid, team ? "blue" : "red"); break; + case 2: default: s_sprintf(skin)("%s/%s/%s.jpg", skinbase, team_string(team), team ? "blue" : "red"); break; + } } string vwep; if(d->weaponsel) s_sprintf(vwep)("weapons/%s/world", d->weaponsel->info.modelname); @@ -657,7 +668,7 @@ void renderclient(playerent *d) } void renderclients() -{ +{ playerent *d; loopv(players) if((d = players[i]) && d->state!=CS_SPAWNING && (!player1->isspectating() || player1->spectatemode != SM_FOLLOW1ST || player1->followplayercn != i)) renderclient(d); if(player1->state==CS_DEAD || (reflecting && !refracting)) renderclient(player1);