src/lib/common/game.c

Go to the documentation of this file.
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 }

Generated on Fri Mar 28 11:01:14 2008 for empserver by  doxygen 1.5.2