]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/gamemodes/gamemode/ctf/cl_ctf.qc
Merge branch 'master' into Juhu/strafehud
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / ctf / cl_ctf.qc
1 #include "cl_ctf.qh"
2
3 #include <common/mutators/base.qh>
4 #include <client/draw.qh>
5 #include <client/hud/panel/modicons.qh>
6
7 // CTF HUD modicon section
8 int redflag_prevframe, blueflag_prevframe, yellowflag_prevframe, pinkflag_prevframe, neutralflag_prevframe; // status during previous frame
9 int redflag_prevstatus, blueflag_prevstatus, yellowflag_prevstatus, pinkflag_prevstatus, neutralflag_prevstatus; // last remembered status
10 float redflag_statuschange_time, blueflag_statuschange_time, yellowflag_statuschange_time, pinkflag_statuschange_time, neutralflag_statuschange_time; // time when the status changed
11
12 void HUD_Mod_CTF_Reset()
13 {
14     redflag_prevstatus = blueflag_prevstatus = yellowflag_prevstatus = pinkflag_prevstatus = neutralflag_prevstatus = 0;
15     redflag_prevframe = blueflag_prevframe = yellowflag_prevframe = pinkflag_prevframe = neutralflag_prevframe = 0;
16     redflag_statuschange_time = blueflag_statuschange_time = yellowflag_statuschange_time = pinkflag_statuschange_time = neutralflag_statuschange_time = 0;
17 }
18
19 int autocvar__teams_available;
20 void HUD_Mod_CTF(vector pos, vector mySize)
21 {
22     vector redflag_pos, blueflag_pos, yellowflag_pos, pinkflag_pos, neutralflag_pos;
23     vector flag_size;
24     float f; // every function should have that
25
26     int redflag, blueflag, yellowflag, pinkflag, neutralflag; // current status
27     float redflag_statuschange_elapsedtime = 0, blueflag_statuschange_elapsedtime = 0, yellowflag_statuschange_elapsedtime = 0, pinkflag_statuschange_elapsedtime = 0, neutralflag_statuschange_elapsedtime = 0; // time since the status changed
28     bool ctf_oneflag; // one-flag CTF mode enabled/disabled
29     bool ctf_stalemate; // currently in stalemate
30     int stat_items = STAT(CTF_FLAGSTATUS);
31     float fs, fs2, fs3, size1, size2;
32     vector e1, e2;
33
34     int nteams = autocvar__teams_available;
35
36     redflag = (stat_items/CTF_RED_FLAG_TAKEN) & 3;
37     blueflag = (stat_items/CTF_BLUE_FLAG_TAKEN) & 3;
38     yellowflag = (stat_items/CTF_YELLOW_FLAG_TAKEN) & 3;
39     pinkflag = (stat_items/CTF_PINK_FLAG_TAKEN) & 3;
40     neutralflag = (stat_items/CTF_NEUTRAL_FLAG_TAKEN) & 3;
41
42     ctf_oneflag = (stat_items & CTF_FLAG_NEUTRAL);
43
44     ctf_stalemate = (stat_items & CTF_STALEMATE);
45
46     mod_active = (redflag || blueflag || yellowflag || pinkflag || neutralflag || (stat_items & CTF_SHIELDED));
47
48     if (autocvar__hud_configure) {
49         redflag = 1;
50         blueflag = 2;
51         if (nteams & BIT(2))
52             yellowflag = 2;
53         if (nteams & BIT(3))
54             pinkflag = 3;
55         ctf_oneflag = neutralflag = 0; // disable neutral flag in hud editor?
56     }
57
58     // when status CHANGES, set old status into prevstatus and current status into status
59     #define X(team) MACRO_BEGIN \
60         if (team##flag != team##flag_prevframe) { \
61             team##flag_statuschange_time = time; \
62             team##flag_prevstatus = team##flag_prevframe; \
63             team##flag_prevframe = team##flag; \
64         } \
65         team##flag_statuschange_elapsedtime = time - team##flag_statuschange_time; \
66     MACRO_END
67     X(red);
68     X(blue);
69     X(yellow);
70     X(pink);
71     X(neutral);
72     #undef X
73
74     #define X(team, cond) \
75     string team##_icon = string_null, team##_icon_prevstatus = string_null; \
76     int team##_alpha, team##_alpha_prevstatus; \
77     team##_alpha = team##_alpha_prevstatus = 1; \
78     MACRO_BEGIN \
79         switch (team##flag) { \
80             case 1: team##_icon = "flag_" #team "_taken"; break; \
81             case 2: team##_icon = "flag_" #team "_lost"; break; \
82             case 3: team##_icon = "flag_" #team "_carrying"; team##_alpha = blink(0.85, 0.15, 5); break; \
83             default: \
84                 if ((stat_items & CTF_SHIELDED) && (cond)) { \
85                     team##_icon = "flag_" #team "_shielded"; \
86                 } else { \
87                     team##_icon = string_null; \
88                 } \
89                 break; \
90         } \
91         switch (team##flag_prevstatus) { \
92             case 1: team##_icon_prevstatus = "flag_" #team "_taken"; break; \
93             case 2: team##_icon_prevstatus = "flag_" #team "_lost"; break; \
94             case 3: team##_icon_prevstatus = "flag_" #team "_carrying"; team##_alpha_prevstatus = blink(0.85, 0.15, 5); break; \
95             default: \
96                 if (team##flag == 3) { \
97                     team##_icon_prevstatus = "flag_" #team "_carrying"; /* make it more visible */\
98                 } else if((stat_items & CTF_SHIELDED) && (cond)) { \
99                     team##_icon_prevstatus = "flag_" #team "_shielded"; \
100                 } else { \
101                     team##_icon_prevstatus = string_null; \
102                 } \
103                 break; \
104         } \
105     MACRO_END
106     X(red, myteam != NUM_TEAM_1 && (nteams & BIT(0)));
107     X(blue, myteam != NUM_TEAM_2 && (nteams & BIT(1)));
108     X(yellow, myteam != NUM_TEAM_3 && (nteams & BIT(2)));
109     X(pink, myteam != NUM_TEAM_4 && (nteams & BIT(3)));
110     X(neutral, ctf_oneflag);
111     #undef X
112
113     int tcount = 2;
114     if(nteams & BIT(2))
115         tcount = 3;
116     if(nteams & BIT(3))
117         tcount = 4;
118
119     if (ctf_oneflag) {
120         // hacky, but these aren't needed
121         red_icon = red_icon_prevstatus = blue_icon = blue_icon_prevstatus = yellow_icon = yellow_icon_prevstatus = pink_icon = pink_icon_prevstatus = string_null;
122         fs = fs2 = fs3 = 1;
123     } else switch (tcount) {
124         default:
125         case 2: fs = 0.5; fs2 = 0.5; fs3 = 0.5; break;
126         case 3: fs = 1; fs2 = 0.35; fs3 = 0.35; break;
127         case 4: fs = 0.75; fs2 = 0.25; fs3 = 0.5; break;
128     }
129
130     if (mySize_x > mySize_y) {
131         size1 = mySize_x;
132         size2 = mySize_y;
133         e1 = eX;
134         e2 = eY;
135     } else {
136         size1 = mySize_y;
137         size2 = mySize_x;
138         e1 = eY;
139         e2 = eX;
140     }
141
142     switch (myteam) {
143         default:
144         case NUM_TEAM_1: {
145             redflag_pos = pos;
146             blueflag_pos = pos + eX * fs2 * size1;
147             yellowflag_pos = pos - eX * fs2 * size1;
148             pinkflag_pos = pos + eX * fs3 * size1;
149             break;
150         }
151         case NUM_TEAM_2: {
152             redflag_pos = pos + eX * fs2 * size1;
153             blueflag_pos = pos;
154             yellowflag_pos = pos - eX * fs2 * size1;
155             pinkflag_pos = pos + eX * fs3 * size1;
156             break;
157         }
158         case NUM_TEAM_3: {
159             redflag_pos = pos + eX * fs3 * size1;
160             blueflag_pos = pos - eX * fs2 * size1;
161             yellowflag_pos = pos;
162             pinkflag_pos = pos + eX * fs2 * size1;
163             break;
164         }
165         case NUM_TEAM_4: {
166             redflag_pos = pos - eX * fs2 * size1;
167             blueflag_pos = pos + eX * fs3 * size1;
168             yellowflag_pos = pos + eX * fs2 * size1;
169             pinkflag_pos = pos;
170             break;
171         }
172     }
173     neutralflag_pos = pos;
174     flag_size = e1 * fs * size1 + e2 * size2;
175
176     #define X(team) MACRO_BEGIN \
177         f = bound(0, team##flag_statuschange_elapsedtime * 2, 1); \
178         if (team##_icon && ctf_stalemate) \
179             drawpic_aspect_skin(team##flag_pos, "flag_stalemate", flag_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); \
180         if (team##_icon_prevstatus && f < 1) \
181             drawpic_aspect_skin_expanding(team##flag_pos, team##_icon_prevstatus, flag_size, '1 1 1', panel_fg_alpha * team##_alpha_prevstatus, DRAWFLAG_NORMAL, f); \
182         if (team##_icon) \
183             drawpic_aspect_skin(team##flag_pos, team##_icon, flag_size, '1 1 1', panel_fg_alpha * team##_alpha * f, DRAWFLAG_NORMAL); \
184     MACRO_END
185     X(red);
186     X(blue);
187     X(yellow);
188     X(pink);
189     X(neutral);
190     #undef X
191 }
192
193 bool autocvar_hud_panel_scoreboard_ctf_leaderboard = true;
194
195 REGISTER_MUTATOR(cl_ctf, true);
196
197 MUTATOR_HOOKFUNCTION(cl_ctf, ShowRankings)
198 {
199     if(autocvar_hud_panel_scoreboard_ctf_leaderboard && ISGAMETYPE(CTF) && STAT(CTF_SHOWLEADERBOARD))
200     {
201         M_ARGV(0, string) = _("Capture time rankings");
202         return true;
203     }
204 }