UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cp_time.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24 
25 #include "../../cl_shared.h"
26 #include "cp_campaign.h"
27 #include "cp_time.h"
28 
29 static const int monthLength[MONTHS_PER_YEAR] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
30 
31 typedef struct gameLapse_s {
32  const char* name;
33  int scale;
34 } gameLapse_t;
35 
36 #define NUM_TIMELAPSE 8
37 
39 static const gameLapse_t lapse[NUM_TIMELAPSE] = {
40  {N_("stopped"), 0},
41  {N_("5 sec"), 5},
42  {N_("5 mins"), 5 * 60},
43  {N_("20 mins"), SECONDS_PER_HOUR / 3},
44  {N_("1 hour"), SECONDS_PER_HOUR},
45  {N_("12 hours"), 12 * SECONDS_PER_HOUR},
46  {N_("1 day"), 24 * SECONDS_PER_HOUR},
47  {N_("5 days"), 5 * SECONDS_PER_DAY}
48 };
49 CASSERT(lengthof(lapse) == NUM_TIMELAPSE);
50 
56 const char* CP_SecondConvert (int second)
57 {
58  static char buffer[6];
59  const int hour = second / SECONDS_PER_HOUR;
60  const int min = (second - hour * SECONDS_PER_HOUR) / 60;
61  Com_sprintf(buffer, sizeof(buffer), "%2i:%02i", hour, min);
62  return buffer;
63 }
64 
72 void CP_DateConvertLong (const date_t* date, dateLong_t* dateLong)
73 {
74  /* Get the year */
75  dateLong->year = date->day / DAYS_PER_YEAR;
76 
77  /* Get the days in the year. */
78  int d = date->day % DAYS_PER_YEAR;
79 
80  /* Subtract days until no full month is left. */
81  byte i;
82  size_t length = lengthof(monthLength);
83  for (i = 0; i < length; i++) {
84  if (d < monthLength[i])
85  break;
86  d -= monthLength[i];
87  }
88 
89  dateLong->day = d + 1;
90  dateLong->month = i + 1;
91  dateLong->hour = date->sec / SECONDS_PER_HOUR;
92  dateLong->min = (date->sec - dateLong->hour * SECONDS_PER_HOUR) / 60;
93  dateLong->sec = date->sec - dateLong->hour * SECONDS_PER_HOUR - dateLong->min * 60;
94 
95  assert(dateLong->month >= 1 && dateLong->month <= MONTHS_PER_YEAR);
96  assert(dateLong->day >= 1 && dateLong->day <= monthLength[i]);
97 }
98 
104 void CP_UpdateTime (void)
105 {
106  dateLong_t date;
107  CP_DateConvertLong(&ccs.date, &date);
108 
109  /* Update the timelapse text */
110  if (ccs.gameLapse >= 0 && ccs.gameLapse < NUM_TIMELAPSE) {
111  cgi->Cvar_Set("mn_timelapse", "%s", _(lapse[ccs.gameLapse].name));
113  cgi->Cvar_SetValue("mn_timelapse_id", ccs.gameLapse);
114  }
115 
116  /* Update the date */
117  cgi->Cvar_Set("mn_mapdate", _("%i %s %02i"), date.year, Date_GetMonthName(date.month - 1), date.day);
118 
119  /* Update the time. */
120  cgi->Cvar_Set("mn_maptime", _("%02i:%02i"), date.hour, date.min);
121 }
122 
126 void CP_GameTimeStop (void)
127 {
128  /* don't allow time scale in tactical mode - only on the geoscape */
130  ccs.gameLapse = 0;
131 
132  /* Make sure the new lapse state is updated and it (and the time) is show in the menu. */
133  CP_UpdateTime();
134 }
135 
139 bool CP_IsTimeStopped (void)
140 {
141  return !ccs.gameLapse;
142 }
143 
147 static bool CP_AllowTimeScale (void)
148 {
149  /* check the stats value - already build bases might have been destroyed
150  * so the B_GetCount() values is pointless here */
152  return false;
153 
154  return CP_OnGeoscape();
155 }
156 
160 void CP_GameTimeSlow (void)
161 {
162  /* don't allow time scale in tactical mode - only on the geoscape */
163  if (CP_AllowTimeScale()) {
164  if (ccs.gameLapse > 0)
165  ccs.gameLapse--;
166  /* Make sure the new lapse state is updated and it (and the time) is show in the menu. */
167  CP_UpdateTime();
168  }
169 }
170 
174 void CP_GameTimeFast (void)
175 {
176  /* don't allow time scale in tactical mode - only on the geoscape */
177  if (CP_AllowTimeScale()) {
179  ccs.gameLapse++;
180  /* Make sure the new lapse state is updated and it (and the time) is show in the menu. */
181  CP_UpdateTime();
182  }
183 }
184 
189 static void CP_SetGameTime (int gameLapseValue)
190 {
191  if (gameLapseValue == ccs.gameLapse)
192  return;
193 
194  /* check the stats value - already build bases might have been destroyed
195  * so the B_GetCount() values is pointless here */
197  return;
198 
199  if (gameLapseValue < 0 || gameLapseValue >= NUM_TIMELAPSE)
200  return;
201 
202  ccs.gameLapse = gameLapseValue;
203 
204  /* Make sure the new lapse state is updated and it (and the time) is show in the menu. */
205  CP_UpdateTime();
206 }
207 
208 
214 void CP_SetGameTime_f (void)
215 {
216  if (cgi->Cmd_Argc() < 2) {
217  cgi->Com_Printf("Usage: %s <timeid>\n", cgi->Cmd_Argv(0));
218  return;
219  }
220  CP_SetGameTime(atoi(cgi->Cmd_Argv(1)));
221 }
222 
228 int Date_DateToSeconds (const date_t* date)
229 {
230  return date->day * 86400 + date->sec;
231 }
232 
239 bool Date_LaterThan (const date_t* now, const date_t* compare)
240 {
241  if (now->day > compare->day)
242  return true;
243  if (now->day < compare->day)
244  return false;
245  if (now->sec > compare->sec)
246  return true;
247  return false;
248 }
249 
255 bool Date_IsDue (const date_t* date)
256 {
257  if (date->day < ccs.date.day)
258  return true;
259 
260  else if (date->day == ccs.date.day && date->sec <= ccs.date.sec)
261  return true;
262 
263  return false;
264 }
265 
273 {
274  a.sec += b.sec;
275  a.day += (a.sec / SECONDS_PER_DAY) + b.day;
276  a.sec %= SECONDS_PER_DAY;
277  return a;
278 }
279 
286 {
287  a.day -= b.day;
288  a.sec -= b.sec;
289  if (a.sec < 0) {
290  a.day--;
291  a.sec += SECONDS_PER_DAY;
292  }
293  return a;
294 }
295 
302 date_t Date_Random (date_t minFrame, date_t maxFrame)
303 {
304  const int random = (maxFrame.day * SECONDS_PER_DAY + maxFrame.sec) * frand();
305  maxFrame.sec = std::max(minFrame.day * SECONDS_PER_DAY + minFrame.sec, random);
306 
307  maxFrame.day = maxFrame.sec / SECONDS_PER_DAY;
308  maxFrame.sec = maxFrame.sec % SECONDS_PER_DAY;
309  return maxFrame;
310 }
311 
317 const char* Date_GetMonthName (int month)
318 {
319  switch (month) {
320  case 0:
321  return _("Jan");
322  case 1:
323  return _("Feb");
324  case 2:
325  return _("Mar");
326  case 3:
327  return _("Apr");
328  case 4:
329  return _("May");
330  case 5:
331  return _("Jun");
332  case 6:
333  return _("Jul");
334  case 7:
335  return _("Aug");
336  case 8:
337  return _("Sep");
338  case 9:
339  return _("Oct");
340  case 10:
341  return _("Nov");
342  case 11:
343  return _("Dec");
344  default:
345  return "Error";
346  }
347 }
bool CP_IsTimeStopped(void)
Check if time is stopped.
Definition: cp_time.cpp:139
#define NUM_TIMELAPSE
Definition: cp_time.cpp:36
byte hour
Definition: cp_time.h:38
bool Date_IsDue(const date_t *date)
Checks whether a given date is equal or earlier than the current campaign date.
Definition: cp_time.cpp:255
byte min
Definition: cp_time.h:39
bool CP_OnGeoscape(void)
Returns if we are currently on the Geoscape.
CASSERT(lengthof(lapse)==NUM_TIMELAPSE)
void CP_SetGameTime_f(void)
Set a new time game from id.
Definition: cp_time.cpp:214
#define _(String)
Definition: cl_shared.h:43
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
const char * name
Definition: cp_time.cpp:32
#define MONTHS_PER_YEAR
Definition: common.h:299
int Date_DateToSeconds(const date_t *date)
Convert a date_t date to seconds.
Definition: cp_time.cpp:228
int day
Definition: common.h:291
date_t date
Definition: cp_campaign.h:245
int gameTimeScale
Definition: cp_campaign.h:264
static void CP_SetGameTime(int gameLapseValue)
Set game time speed.
Definition: cp_time.cpp:189
byte day
Definition: cp_time.h:37
void CP_GameTimeSlow(void)
Decrease game time speed.
Definition: cp_time.cpp:160
int basesBuilt
Definition: cp_statistics.h:32
#define SECONDS_PER_HOUR
Definition: common.h:302
int integer
Definition: cvar.h:81
#define DAYS_PER_YEAR
Definition: common.h:296
bool Date_LaterThan(const date_t *now, const date_t *compare)
Check whether the given date and time is later than current date.
Definition: cp_time.cpp:239
void CP_GameTimeStop(void)
Stop game time speed.
Definition: cp_time.cpp:126
const char * Date_GetMonthName(int month)
Returns the short monthame to the given month index.
Definition: cp_time.cpp:317
cvar_t *IMPORT * Cvar_Set(const char *varName, const char *value,...) __attribute__((format(__printf__
static const int monthLength[MONTHS_PER_YEAR]
Definition: cp_time.cpp:29
void CP_UpdateTime(void)
Updates date/time and timescale (=timelapse) on the geoscape menu.
Definition: cp_time.cpp:104
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition: r_gl.h:110
const cgame_import_t * cgi
short year
Definition: cp_time.h:35
static bool CP_AllowTimeScale(void)
Definition: cp_time.cpp:147
ccs_t ccs
Definition: cp_campaign.cpp:62
stats_t campaignStats
Definition: cp_campaign.h:378
Engine-side time information in the game.
Definition: common.h:290
int gameLapse
Definition: cp_campaign.h:265
byte month
Definition: cp_time.h:36
date_t Date_Substract(date_t a, const date_t &b)
Substract the second date from the first and return the result.
Definition: cp_time.cpp:285
Campaign geoscape time header.
date_t Date_Add(date_t a, const date_t &b)
Add two dates and return the result.
Definition: cp_time.cpp:272
int sec
Definition: common.h:292
struct gameLapse_s gameLapse_t
Human readable time information in the game.
Definition: cp_time.h:34
float frand(void)
Return random values between 0 and 1.
Definition: mathlib.cpp:506
byte sec
Definition: cp_time.h:40
QGL_EXTERN GLint i
Definition: r_gl.h:113
static const gameLapse_t lapse[NUM_TIMELAPSE]
The possible geoscape time intervalls.
Definition: cp_time.cpp:39
void CP_GameTimeFast(void)
Increase game time speed.
Definition: cp_time.cpp:174
void CP_DateConvertLong(const date_t *date, dateLong_t *dateLong)
Converts a date from the engine in a (longer) human-readable format.
Definition: cp_time.cpp:72
#define SECONDS_PER_DAY
Definition: common.h:301
Header file for single player campaign control.
#define N_(String)
Definition: cl_shared.h:45
#define lengthof(x)
Definition: shared.h:105
date_t Date_Random(date_t minFrame, date_t maxFrame)
Return a random relative date which lies between a lower and upper limit.
Definition: cp_time.cpp:302
uint8_t byte
Definition: ufotypes.h:34
cvar_t * cp_missiontest
Definition: cp_campaign.cpp:63
const char *IMPORT * Cmd_Argv(int n)
const char * CP_SecondConvert(int second)
Converts a number of second into a char to display.
Definition: cp_time.cpp:56