b38ba9d05a9313f670f8fa8bdeede09c565ebf2c
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / counting.qh
1 #pragma once
2
3 #include "i18n.qh"
4
5 // ===============================================
6 //  Time processing and counting functions/macros
7 // ===============================================
8
9 #define count_years_decs(time, decs) sprintf(CTX(_("CI_DEC^%s years")), ftos_decimals(time, decs))
10 #define count_years(time) \
11         count_fill(time, \
12         _("CI_ZER^%d years"), /* zeroth */ \
13         _("CI_FIR^%d year"),  /* first */ \
14         _("CI_SEC^%d years"), /* year */ \
15         _("CI_THI^%d years"), /* third */ \
16         _("CI_MUL^%d years")) /* multi */
17
18 #define count_weeks_decs(time, decs) sprintf(CTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs))
19 #define count_weeks(time) \
20         count_fill(time, \
21         _("CI_ZER^%d weeks"), /* zeroth */ \
22         _("CI_FIR^%d week"),  /* first */ \
23         _("CI_SEC^%d weeks"), /* week */ \
24         _("CI_THI^%d weeks"), /* third */ \
25         _("CI_MUL^%d weeks")) /* multi */
26
27 #define count_days_decs(time, decs) sprintf(CTX(_("CI_DEC^%s days")), ftos_decimals(time, decs))
28 #define count_days(time) \
29         count_fill(time, \
30         _("CI_ZER^%d days"), /* zeroth */ \
31         _("CI_FIR^%d day"),  /* first */ \
32         _("CI_SEC^%d days"), /* day */ \
33         _("CI_THI^%d days"), /* third */ \
34         _("CI_MUL^%d days")) /* multi */
35
36 #define count_hours_decs(time, decs) sprintf(CTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs))
37 #define count_hours(time) \
38         count_fill(time, \
39         _("CI_ZER^%d hours"), /* zeroth */ \
40         _("CI_FIR^%d hour"),  /* first */ \
41         _("CI_SEC^%d hours"), /* hour */ \
42         _("CI_THI^%d hours"), /* third */ \
43         _("CI_MUL^%d hours")) /* multi */
44
45
46 #define count_minutes_decs(time, decs) sprintf(CTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs))
47 #define count_minutes(time) \
48         count_fill(time, \
49         _("CI_ZER^%d minutes"), /* zeroth */ \
50         _("CI_FIR^%d minute"),  /* first */ \
51         _("CI_SEC^%d minutes"), /* minute */ \
52         _("CI_THI^%d minutes"), /* third */ \
53         _("CI_MUL^%d minutes")) /* multi */
54
55 #define count_seconds_decs(time, decs) sprintf(CTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs))
56 #define count_seconds(time) \
57         count_fill(time, \
58         _("CI_ZER^%d seconds"), /* zeroth */ \
59         _("CI_FIR^%d second"),  /* first */ \
60         _("CI_SEC^%d seconds"), /* second */ \
61         _("CI_THI^%d seconds"), /* third */ \
62         _("CI_MUL^%d seconds")) /* multi */
63
64 ERASEABLE
65 string count_ordinal(int interval)
66 {
67         // This function is designed primarily for the English language, it's impossible
68         // to accomodate all languages unless we do a specific function for each one...
69         // and since that's not technically feasible/practical, this is all we've got folks.
70
71         // Basically, it just allows you to represent a number or count in different ways
72         // depending on the number... like, with count_ordinal you can provide integers
73         // and retrieve 1st, 2nd, 3rd, nth ordinal numbers in a clean and simple way.
74         if (floor((interval % 100) / 10) * 10 != 10)  // examples: 12th, 111th, 213th will not execute this block
75         {
76                 // otherwise, check normally for 1st,2nd,3rd insertions
77                 switch (interval % 10)
78                 {
79                         case 1: return sprintf(_("%dst"), interval);
80                         case 2: return sprintf(_("%dnd"), interval);
81                         case 3: return sprintf(_("%drd"), interval);
82                         default: return sprintf(_("%dth"), interval);
83                 }
84         }
85         else { return sprintf(_("%dth"), interval); }
86
87         return "";
88 }
89
90 ERASEABLE
91 string count_fill(float interval, string zeroth, string first, string second, string third, string multi)
92 {
93         // This function is designed primarily for the English language, it's impossible
94         // to accomodate all languages unless we do a specific function for each one...
95         // and since that's not technically feasible/practical, this is all we've got folks.
96
97         // Here you can insert specific strings based on the interval number, so you could do
98         // i.e. count_seconds which outputs like this:
99         //   0 seconds
100         //   1 second
101         //   2 seconds
102         //   3 seconds
103         //   etc... minutes, hours, days, etc.
104
105         switch (floor(interval))
106         {
107                 case 0: return sprintf(CTX(zeroth), interval);
108                 case 1:
109                 {
110                         if (interval == 1)  // EXACTLY value of 1
111                                 return sprintf(CTX(first), interval);
112                         else return sprintf(CTX(multi), interval);
113                 }
114                 case 2: return sprintf(CTX(second), interval);
115                 case 3: return sprintf(CTX(third), interval);
116                 default: return sprintf(CTX(multi), interval);
117         }
118         return "";
119 }
120
121 ERASEABLE
122 string process_time(float outputtype, float seconds)
123 {
124         float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0;
125         float tmp_years = 0, tmp_weeks = 0, tmp_days = 0;
126
127         tmp_seconds = floor(seconds);
128
129         if (tmp_seconds)
130         {
131                 tmp_minutes = floor(tmp_seconds / 60);
132
133                 if (tmp_minutes)
134                 {
135                         tmp_seconds -= (tmp_minutes * 60);
136                         tmp_hours = floor(tmp_minutes / 60);
137
138                         if (tmp_hours)
139                         {
140                                 tmp_minutes -= (tmp_hours * 60);
141                                 tmp_days = floor(tmp_hours / 24);
142
143                                 if (tmp_days)
144                                 {
145                                         tmp_hours -= (tmp_days * 24);
146                                         tmp_weeks = floor(tmp_days / 7);
147
148                                         if (tmp_weeks)
149                                         {
150                                                 tmp_days -= (tmp_weeks * 7);
151                                                 tmp_years = floor(tmp_weeks / 52);
152                                         }
153                                 }
154                         }
155                 }
156         }
157
158         switch (outputtype)
159         {
160                 case 1: return sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds);
161                 case 2:
162                 {
163                         string output = "";
164
165                         output = count_seconds(tmp_seconds);
166
167                         if (tmp_minutes)
168                         {
169                                 output = strcat(
170                                         count_minutes(tmp_minutes),
171                                         ((output != "") ? strcat(", ", output) : ""));
172                         }
173
174                         if (tmp_hours)
175                         {
176                                 output = strcat(
177                                         count_hours(tmp_hours),
178                                         ((output != "") ? strcat(", ", output) : ""));
179                         }
180
181                         if (tmp_days)
182                         {
183                                 output = strcat(
184                                         count_days(tmp_days),
185                                         ((output != "") ? strcat(", ", output) : ""));
186                         }
187
188                         if (tmp_weeks)
189                         {
190                                 output = strcat(
191                                         count_weeks(tmp_weeks),
192                                         ((output != "") ? strcat(", ", output) : ""));
193                         }
194
195                         if (tmp_years)
196                         {
197                                 output = strcat(
198                                         count_years(tmp_years),
199                                         ((output != "") ? strcat(", ", output) : ""));
200                         }
201
202                         return output;
203                 }
204                 case 3:
205                 {
206                         string output = "";
207
208                         output = count_hours(tmp_hours);
209
210                         if (tmp_weeks) tmp_days += (tmp_weeks * 7);
211                         if (tmp_years) tmp_days += (tmp_years * 365);
212                         if (tmp_days)
213                         {
214                                 output = sprintf(
215                                         count_days(tmp_days),
216                                         ((output != "") ? strcat(", ", output) : ""));
217                         }
218
219                         return output;
220                 }
221         }
222         return "";
223 }