Skip to content

Commit 33dcdde

Browse files
authored
Merge pull request #1335 from drzel/fo-skins
Fo skins
2 parents 96faeb8 + 271497b commit 33dcdde

File tree

12 files changed

+262
-192
lines changed

12 files changed

+262
-192
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ sound files are found in `fortress/sound/hitaudio/` and `fortress/sound/announc
7878
* `localinfo fo_matchrated 2` whether match is rated / affects trueskill. 2 is false for 1v1 and 2v2 only.
7979
* `localinfo backend_address <uri>` to specify backend API endpoint. Default: https://www.fortressone.org/
8080
* All-time attack and all-time defence team options.
81+
* `setinfo team<n>color <color>` sets player skins colours for team <n>, where <color> is quake palette 0-15 or hex code beginning with 0x. E.g. `setinfo team1colour 0` makes all team 1 players white, `setinfo team2color 0xFF8800` makes all team 2 players orange. `setinfo team<n>color ""` to restore defaults. Note that `teamcolor` and `enemycolor` cvars will take priority.
8182
* `setinfo precise_grenades on/off` to enable precise timing when throwing grenades. This removes a random, up to, 100ms input delay. (default on)
8283
* `localinfo forcereload 0/1` Option to prevent forced reloads.
8384
* `+grenade1` and `+grenade2` grenade buttons (more reliable than impulses), push to prime, again to throw.

csqc/main.qc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ static void UpdateTeamColorCrosshair() {
621621
break;
622622
case 4:
623623
crosshair_color = "0x00ff00";
624+
break;
624625
}
625626
localcmd("crosshaircolor ", crosshair_color, "\n");
626627
crosshair_team_no = team_no;

share/defs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,12 @@ struct Slot { int id; };
679679
#define YELLOW 13
680680
#define DARKBLUE 14
681681

682+
#define NOTEAMCOLOR "0xffffff"
683+
#define BLUETEAMCOLOR "0x00aaff"
684+
#define REDTEAMCOLOR "0xff3333"
685+
#define YELLOWTEAMCOLOR "0xffdd00"
686+
#define GREENTEAMCOLOR "0x00ff44"
687+
682688
/*======================================================*/
683689
/* Defines for the ENGINEER's Building ability */
684690
/*======================================================*/

ssqc/client.qc

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ float modelindex_null;
1010

1111
float (entity pe_player) Spy_CheckArea;
1212

13-
void () TeamFortress_CheckTeamCheats;
13+
void (entity player) TeamFortress_CheckTeamCheats;
1414
void () TeamFortress_CheckforCheats;
1515
void (entity Viewer, float pc, float rpc) TeamFortress_PrintClassName;
1616
void () TeamFortress_RemoveTimers;
@@ -73,6 +73,8 @@ void StopAssCan();
7373
void Predict_InitPlayer(entity player);
7474
void Predict_Destroy(entity player);
7575

76+
void SetSkinInfoFor(entity pov, entity target);
77+
7678
void () info_intermission =
7779
{
7880
if (CheckExistence() == 0) {
@@ -2768,9 +2770,31 @@ static void ConcUpdate() {
27682770
}
27692771
}
27702772

2773+
// If a forceinfokey and a SVC_SETINFO are both set in the same frame, they
2774+
// will clobber each other. Thus we do skin setinfos like normal, and then
2775+
// per-player custom skin infos are immediately applied for those who need to
2776+
// update on the next frame.
2777+
void () UpdateAllSkins = {
2778+
local entity target = find(world, classname, "player");
2779+
local entity pov;
2780+
2781+
while (target != world) {
2782+
if (target.needs_skin_update) {
2783+
pov = find(world, classname, "player");
2784+
while (pov != world) {
2785+
SetSkinInfoFor(pov, target);
2786+
pov = find(pov, classname, "player");
2787+
}
2788+
target.needs_skin_update = 0;
2789+
}
2790+
target = find(target, classname, "player");
2791+
}
2792+
}
2793+
27712794
void () PlayerPreThink = {
27722795
FO_UpdateClientTime();
27732796
ConcUpdate();
2797+
UpdateAllSkins();
27742798

27752799
if (self.impulse) {
27762800
if (self.impulse == TF_VOTENEXT) {
@@ -3102,7 +3126,7 @@ static void PlayerPostThinkAlive() {
31023126
}
31033127
}
31043128
if (self.cheat_check <= time) {
3105-
TeamFortress_CheckTeamCheats();
3129+
TeamFortress_CheckTeamCheats(self);
31063130
self.cheat_check = time + 3;
31073131
}
31083132
}
@@ -3147,6 +3171,33 @@ void () UpdateAllClientsTeamScores = {
31473171
}
31483172
}
31493173

3174+
void (entity pov, entity target) SetBottomColorInfoFor = {
3175+
local float target_idx = target.colormap - 1;
3176+
local string color = TeamFortress_TeamGetColorFor(pov, target.team_no);
3177+
3178+
msg_entity = pov;
3179+
WriteByte(MSG_ONE, SVC_SETINFO);
3180+
WriteByte(MSG_ONE, target_idx);
3181+
WriteString(MSG_ONE, "bottomcolor");
3182+
WriteString(MSG_ONE, color);
3183+
}
3184+
3185+
void (entity pov, entity target) SetTopColorInfoFor = {
3186+
local float target_idx = target.colormap - 1;
3187+
local string color = TeamFortress_TeamGetColorFor(pov, target.team_no);
3188+
3189+
msg_entity = pov;
3190+
WriteByte(MSG_ONE, SVC_SETINFO);
3191+
WriteByte(MSG_ONE, target_idx);
3192+
WriteString(MSG_ONE, "topcolor");
3193+
WriteString(MSG_ONE, color);
3194+
}
3195+
3196+
void (entity pov, entity target) SetSkinInfoFor = {
3197+
SetTopColorInfoFor(pov, target);
3198+
SetBottomColorInfoFor(pov, target);
3199+
}
3200+
31503201
void () ClientConnect = {
31513202
if (!infokeyf(self,INFOKEY_P_CSQCACTIVE)) {
31523203
sprint(self, PRINT_HIGH, "FTE/CSQC is required for this server, please download the latest client package at www.fortressone.org\n");
@@ -3206,6 +3257,7 @@ void () ClientConnect = {
32063257
UpdateClientTeamScores(self);
32073258
UpdateClientPrematch(self, !cb_prematch);
32083259
UpdateClient_VoteMap_AddAll(self);
3260+
TeamFortress_SetSkin(self);
32093261

32103262
if (cb_prematch)
32113263
sprint(self, PRINT_HIGH, "Currently in \sprematch\s time\n");

ssqc/commands.qc

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void (entity pe) SetEquipmentForPlayer = {
138138
//self.immune_to_check = time + 10;
139139
//self.undercover_team = 0;
140140
stuffcmd(self, "color ");
141-
string st = ftos(TeamFortress_TeamGetColor(self.team_no) - 1);
141+
string st = TeamFortress_TeamGetColor(self.team_no);
142142
stuffcmd(self, st);
143143
stuffcmd(self, "\n");
144144

@@ -313,6 +313,16 @@ void (entity pl) PrintWho = {
313313
strunzone(msg);
314314
}
315315

316+
void (entity pov, string command, string color) UpdateTeamColor = {
317+
forceinfokey(pov, command, color);
318+
319+
local entity target = find(world, classname, "player");
320+
while (target != world) {
321+
SetSkinInfoFor(pov, target);
322+
target = find(target, classname, "player");
323+
}
324+
}
325+
316326
float (string arg1, string arg2, string arg3) ParseCmds = {
317327
local float arg_num = 0, processedCmd, inp;
318328
local string tmp;
@@ -350,22 +360,15 @@ float (string arg1, string arg2, string arg3) ParseCmds = {
350360
}
351361
break;
352362
case "setinfo":
353-
if (arg2)
354-
{
355-
if (arg2 == "topcolor" || arg2 == "bottomcolor")
356-
{
357-
float arg3f = stof(arg3);
358-
if ((self.team_no > 0) && (teamplay > 0)) {
359-
if (arg3f != (TeamFortress_TeamGetColor(self.team_no) - 1)) {
360-
arg3f = TeamFortress_TeamGetColor(self.team_no) - 1;
361-
string st;
362-
st = ftos(arg3f);
363-
stuffcmd(self, strcat("color ", st, "\n"));
364-
sprint(self, PRINT_HIGH,
365-
"Your color has been changed to your team color\n");
366-
processedCmd = TRUE;
367-
}
368-
}
363+
if (arg2) {
364+
switch(arg2) {
365+
case "team1color":
366+
case "team2color":
367+
case "team3color":
368+
case "team4color":
369+
UpdateTeamColor(self, arg2, arg3);
370+
processedCmd = TRUE;
371+
break;
369372
}
370373
}
371374
break;

ssqc/functions.qc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
float (float tno) TeamFortress_TeamSet;
2-
float (float tno) TeamFortress_TeamGetColor;
2+
string (float tno) TeamFortress_TeamGetColor;
3+
string (entity pov, float tno) TeamFortress_TeamGetColorFor;
34
void (entity p) SetTeamName;
45
void (entity pl) Menu_Close;
56

@@ -8,7 +9,7 @@ void (float tno) playerSetTeam = {
89
TeamFortress_TeamSet(tno);
910
self.team_no = tno;
1011
stuffcmd(self, "color ");
11-
st = ftos(TeamFortress_TeamGetColor (tno) - 1);
12+
st = TeamFortress_TeamGetColor(tno);
1213
stuffcmd(self, st);
1314
stuffcmd(self, "\n");
1415
SetTeamName(self);

ssqc/menu.qc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void () lvl2_sentry_stand;
2525
void () lvl3_sentry_stand;
2626

2727
float (float tno) TeamFortress_TeamSet;
28-
float (float tno) TeamFortress_TeamGetColor;
28+
string (float tno) TeamFortress_TeamGetColor;
2929
float () TeamFortress_TeamPutPlayerInTeam;
3030
float (float tno) TeamFortress_TeamIsCivilian;
3131
float (float tno) TeamFortress_TeamGetNoPlayers;

ssqc/qw.qc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ float remote_client_time();
100100
.float building_percentage; // The building percentage shown in status bar
101101
.float fragstreak; // Frag streak
102102
.float caps; // Caps during this game
103+
.float needs_skin_update; // Set true when per-player skins need updating
103104

104105
.entity nopickup; // Don't pick up this backpack/ammobox because it doesn't contain any of your ammo types
105106

ssqc/spy.qc

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -495,19 +495,16 @@ void (entity player, float is_user) FO_Spy_DisguiseLastSpawned = {
495495
}
496496
};
497497

498-
499498
void (entity own) Spy_SetClientSkins = {
500499
entity te;
501-
string color, dcolor, skin, dskin, sendcolor, sendskin, pteam, dsteam, sendteam;
500+
string skin, dskin, sendcolor, sendskin, pteam, dsteam, sendteam;
502501
float dteam, dpc;
503502

504503
dteam = own.undercover_team == 0 ? own.team_no : own.undercover_team;
505504
dpc = own.undercover_skin == 0 ? own.playerclass : own.undercover_skin;
506-
color = ftos(TeamFortress_TeamGetColor(own.team_no) - 1);
507-
dcolor = ftos(TeamFortress_TeamGetColor(dteam) - 1);
508505

509-
skin = TeamFortress_GetSkin(own.team_no, own.playerclass);
510-
dskin = TeamFortress_GetSkin(dteam, dpc);
506+
skin = TeamFortress_GetSkin(own.playerclass);
507+
dskin = TeamFortress_GetSkin(dpc);
511508

512509
pteam = GetTeamName(own.team_no);
513510
dsteam = GetTeamName(dteam);
@@ -520,13 +517,13 @@ void (entity own) Spy_SetClientSkins = {
520517
if (te.team_no == own.team_no)
521518
{
522519
// on same team, send them spy/team (initial spawn etc)
523-
sendcolor = color;
520+
sendcolor = TeamFortress_TeamGetColorFor(te, own.team_no);
524521
sendskin = skin;
525522
sendteam = pteam;
526523
}
527524
else // not on same team, send them disguise
528525
{
529-
sendcolor = dcolor;
526+
sendcolor = TeamFortress_TeamGetColorFor(te, dteam);
530527
sendskin = dskin;
531528
sendteam = dsteam;
532529
}
@@ -701,7 +698,6 @@ void (entity pe_player, float pf_class, float is_user) CF_Spy_ChangeSkin = {
701698

702699
void (entity pe_player, float pf_team_no, float is_user) CF_Spy_ChangeColor = {
703700
local entity e_timer;
704-
local float f_team_color = TeamFortress_TeamGetColor(pf_team_no) - 1;
705701

706702
// stop if you're already disguised as the requested skin
707703
if (pe_player.undercover_team == pf_team_no)
@@ -1211,8 +1207,9 @@ void (entity spy) Spy_RemoveDisguise = {
12111207
timer = find(timer, classname, "spytimer");
12121208
}
12131209

1214-
if (coverblown)
1210+
if (coverblown) {
12151211
Status_Print(self, "\n\n\n\n\n\n\n", "You blew your cover!");
1212+
}
12161213

12171214
local float autodisguise = FO_GetUserSetting(self, "autodisguise", "ad", "off");
12181215
if (self.playerclass == PC_SPY) {

0 commit comments

Comments
 (0)