00001 /* 00002 * Empire - A multi-player, client/server Internet based war game. 00003 * Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak, 00004 * Ken Stevens, Steve McClure 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 * --- 00021 * 00022 * See files README, COPYING and CREDITS in the root of the source 00023 * tree for related information and legal notices. It is expected 00024 * that future projects/authors will amend these files as needed. 00025 * 00026 * --- 00027 * 00028 * game.c: Game file access 00029 * 00030 * Known contributors to this file: 00031 * Markus Armbruster, 2007 00032 */ 00033 00034 /* 00035 * On Empire Time: 00036 * 00037 * An Empire turn is terminated by an update. The Empire clock counts 00038 * turns and ETUs, i.e. it ticks etu_per_update times per turn. When 00039 * updates move around in real time (schedule change, downtime, etc.), 00040 * the Empire clock automatically adapts the duration of an ETU 00041 * accordingly. 00042 */ 00043 00044 #include <config.h> 00045 00046 #include <math.h> 00047 #include "file.h" 00048 #include "game.h" 00049 #include "optlist.h" 00050 #include "prototypes.h" 00051 #include "server.h" 00052 00053 /* 00054 * Disable updates 00055 */ 00056 void 00057 game_ctrl_update(int enable) 00058 { 00059 struct gamestr *game = getgamep(); 00060 00061 game->game_upd_disable = !enable; 00062 putgame(); 00063 } 00064 00065 /* 00066 * Are updates disabled? 00067 */ 00068 int 00069 updates_disabled(void) 00070 { 00071 return getgamep()->game_upd_disable; 00072 } 00073 00074 /* 00075 * Record an update in the game file, the current time is NOW. 00076 */ 00077 void 00078 game_record_update(time_t now) 00079 { 00080 struct gamestr *game = getgamep(); 00081 00082 game->game_turn++; 00083 game->game_tick = 0; 00084 game->game_rt = now; 00085 putgame(); 00086 } 00087 00088 /* 00089 * Return current duration of an ETU in seconds. 00090 * Note: may return HUGE_VAL when the Empire clock is not ticking. 00091 */ 00092 static double 00093 secs_per_etu(struct gamestr *game) 00094 { 00095 double secs; 00096 00097 if (!update_time[0]) 00098 return HUGE_VAL; /* no update scheduled */ 00099 00100 secs = update_time[0] - game->game_rt; 00101 if (secs < 0) 00102 return HUGE_VAL; /* update seems to be late */ 00103 return secs / (etu_per_update - game->game_tick); 00104 } 00105 00106 /* 00107 * Update the Empire clock according to the current real time. 00108 * Return the game struct. 00109 */ 00110 struct gamestr * 00111 game_tick_tick(void) 00112 { 00113 struct gamestr *game = getgamep(); 00114 double dsecs, s_p_etu; 00115 int detu; 00116 00117 dsecs = time(NULL) - game->game_rt; 00118 if (CANT_HAPPEN(dsecs < 0)) 00119 dsecs = 0; 00120 s_p_etu = secs_per_etu(game); 00121 detu = (int)(dsecs / s_p_etu); 00122 if (detu > 0) { 00123 if (CANT_HAPPEN(game->game_tick + detu > etu_per_update)) 00124 detu = etu_per_update - game->game_tick; 00125 game->game_tick += detu; 00126 game->game_rt += detu * s_p_etu; 00127 putgame(); 00128 } 00129 00130 return game; 00131 } 00132 00133 /* 00134 * Set ETU timestamp *TICK to the current ETU time. 00135 * Return by how many ETUs it was increased. 00136 */ 00137 int 00138 game_tick_to_now(short *tick) 00139 { 00140 return game_step_a_tick(game_tick_tick(), tick); 00141 } 00142 00143 /* 00144 * Set ETU timestamp *TICK to the ETU time recorded in the game struct. 00145 * The Empire clock is not updated. 00146 * Return by how many ETUs it was increased. 00147 */ 00148 int 00149 game_step_a_tick(struct gamestr *game, short *tick) 00150 { 00151 int etu; 00152 00153 etu = game->game_tick - *tick; 00154 if (CANT_HAPPEN(etu < 0)) 00155 etu = 0; 00156 *tick = game->game_tick; 00157 return etu; 00158 } 00159 00160 /* 00161 * Reset ETU timestamp *TICK to zero. 00162 * Return how many ETUs it had left until etu_per_update. 00163 */ 00164 int 00165 game_reset_tick(short *tick) 00166 { 00167 int etu; 00168 00169 etu = etu_per_update - *tick; 00170 if (CANT_HAPPEN(etu < 0)) 00171 etu = 0; 00172 *tick = 0; 00173 return etu; 00174 }
1.5.2