diff options
Diffstat (limited to 'src/jake2/game/GameSave.java')
-rw-r--r-- | src/jake2/game/GameSave.java | 594 |
1 files changed, 299 insertions, 295 deletions
diff --git a/src/jake2/game/GameSave.java b/src/jake2/game/GameSave.java index 25b102b..c3d07b1 100644 --- a/src/jake2/game/GameSave.java +++ b/src/jake2/game/GameSave.java @@ -1,302 +1,306 @@ /* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ + * Copyright (C) 1997-2001 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ // Created on 29.12.2003 by RST. -// $Id: GameSave.java,v 1.6 2004-09-10 19:02:54 salomo Exp $ - +// $Id: GameSave.java,v 1.7 2004-09-22 19:22:01 salomo Exp $ package jake2.game; -import jake2.qcommon.Com; +import jake2.Defines; +import jake2.Globals; +import jake2.util.Lib; import jake2.util.QuakeFile; -public class GameSave extends GameFunc { - - public static void CreateEdicts() { - g_edicts= new edict_t[game.maxentities]; - for (int i= 0; i < game.maxentities; i++) - g_edicts[i]= new edict_t(i); - GameBase.g_edicts= g_edicts; - } - - public static void CreateClients() { - game.clients= new gclient_t[game.maxclients]; - for (int i= 0; i < game.maxclients; i++) - game.clients[i]= new gclient_t(i); - - } - - /* - ============ - InitGame - - This will be called when the dll is first loaded, which - only happens when a new game is started or a save game - is loaded. - ============ - */ - public static void InitGame() { - gi.dprintf("==== InitGame ====\n"); - - gun_x= gi.cvar("gun_x", "0", 0); - gun_y= gi.cvar("gun_y", "0", 0); - gun_z= gi.cvar("gun_z", "0", 0); - - //FIXME: sv_ prefix is wrong for these - sv_rollspeed= gi.cvar("sv_rollspeed", "200", 0); - sv_rollangle= gi.cvar("sv_rollangle", "2", 0); - sv_maxvelocity= gi.cvar("sv_maxvelocity", "2000", 0); - sv_gravity= gi.cvar("sv_gravity", "800", 0); - - // noset vars - dedicated= gi.cvar("dedicated", "0", CVAR_NOSET); - - // latched vars - sv_cheats= gi.cvar("cheats", "0", CVAR_SERVERINFO | CVAR_LATCH); - gi.cvar("gamename", GAMEVERSION, CVAR_SERVERINFO | CVAR_LATCH); - gi.cvar("gamedate", __DATE__, CVAR_SERVERINFO | CVAR_LATCH); - - maxclients= gi.cvar("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH); - maxspectators= gi.cvar("maxspectators", "4", CVAR_SERVERINFO); - deathmatch= gi.cvar("deathmatch", "0", CVAR_LATCH); - coop= gi.cvar("coop", "0", CVAR_LATCH); - skill= gi.cvar("skill", "0", CVAR_LATCH); - maxentities= gi.cvar("maxentities", "1024", CVAR_LATCH); - - // change anytime vars - dmflags= gi.cvar("dmflags", "0", CVAR_SERVERINFO); - fraglimit= gi.cvar("fraglimit", "0", CVAR_SERVERINFO); - timelimit= gi.cvar("timelimit", "0", CVAR_SERVERINFO); - password= gi.cvar("password", "", CVAR_USERINFO); - spectator_password= gi.cvar("spectator_password", "", CVAR_USERINFO); - needpass= gi.cvar("needpass", "0", CVAR_SERVERINFO); - filterban= gi.cvar("filterban", "1", 0); - - g_select_empty= gi.cvar("g_select_empty", "0", CVAR_ARCHIVE); - - run_pitch= gi.cvar("run_pitch", "0.002", 0); - run_roll= gi.cvar("run_roll", "0.005", 0); - bob_up= gi.cvar("bob_up", "0.005", 0); - bob_pitch= gi.cvar("bob_pitch", "0.002", 0); - bob_roll= gi.cvar("bob_roll", "0.002", 0); - - // flood control - flood_msgs= gi.cvar("flood_msgs", "4", 0); - flood_persecond= gi.cvar("flood_persecond", "4", 0); - flood_waitdelay= gi.cvar("flood_waitdelay", "10", 0); - - // dm map list - sv_maplist= gi.cvar("sv_maplist", "", 0); - - // items - InitItems(); - - game.helpmessage1= ""; - game.helpmessage2= ""; - - // initialize all entities for this game - game.maxentities= (int) maxentities.value; - CreateEdicts(); - - // initialize all clients for this game - game.maxclients= (int) maxclients.value; - - CreateClients(); - - num_edicts= game.maxclients + 1; - } - - /* - ============ - WriteGame - - This will be called whenever the game goes to a new level, - and when the user explicitly saves the game. - - Game information include cross level data, like multi level - triggers, help computer info, and all client states. - - A single player death will automatically restore from the - last save position. - ============ - */ - public static void WriteGame(String filename, boolean autosave) { - try { - QuakeFile f; - - if (!autosave) - SaveClientData(); - - f= new QuakeFile(filename, "rw"); - - if (f == null) - gi.error("Couldn't write to " + filename); - - game.autosaved= autosave; - game.write(f); - game.autosaved= false; - - for (int i= 0; i < game.maxclients; i++) - game.clients[i].write(f); - - fclose(f); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - public static void ReadGame(String filename) { - - QuakeFile f= null; - - try { - - f= new QuakeFile(filename, "r"); - CreateEdicts(); - - game.load(f); - - for (int i= 0; i < game.maxclients; i++) { - game.clients[i]= new gclient_t(i); - game.clients[i].read(f); - } - - f.close(); - } - - catch (Exception e) { - e.printStackTrace(); - } - } - - /* - ================= - WriteLevel - - ================= - */ - public static void WriteLevel(String filename) { - try { - int i; - edict_t ent; - QuakeFile f; - - f= new QuakeFile(filename, "rw"); - if (f == null) - gi.error("Couldn't open for writing: " + filename); - - // write out level_locals_t - level.write(f); - - // write out all the entities - for (i= 0; i < num_edicts; i++) { - ent= g_edicts[i]; - if (!ent.inuse) - continue; - f.writeInt(i); - ent.write(f); - - } - - i= -1; - f.writeInt(-1); - - f.close(); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - /* - ================= - ReadLevel - - SpawnEntities will allready have been called on the - level the same way it was when the level was saved. - - That is necessary to get the baselines - set up identically. - - The server will have cleared all of the world links before - calling ReadLevel. - - No clients are connected yet. - ================= - */ - public static void ReadLevel(String filename) { - try { - edict_t ent; - - QuakeFile f= new QuakeFile(filename, "r"); - - if (f == null) - gi.error("Couldn't read level file " + filename); - - // wipe all the entities - Game.CreateEdicts(); - - num_edicts= (int) maxclients.value + 1; - - // load the level locals - level.read(f); - - // load all the entities - while (true) { - int entnum= f.readInt(); - if (entnum == -1) - break; - - if (entnum >= num_edicts) - num_edicts= entnum + 1; - - ent= g_edicts[entnum]; - ent.read(f); - ent.cleararealinks(); - gi.linkentity(ent); - } - - fclose(f); - - // mark all clients as unconnected - for (int i= 0; i < maxclients.value; i++) { - ent= g_edicts[i + 1]; - ent.client= game.clients[i]; - ent.client.pers.connected= false; - } - - // do any load time things at this point - for (int i= 0; i < num_edicts; i++) { - ent= g_edicts[i]; - - if (!ent.inuse) - continue; - - // fire any cross-level triggers - if (ent.classname != null) - if (strcmp(ent.classname, "target_crosslevel_target") == 0) - ent.nextthink= level.time + ent.delay; - } - } - catch (Exception e) { - e.printStackTrace(); - } - } -} +public class GameSave { + + public static void CreateEdicts() { + GameBase.g_edicts = new edict_t[GameBase.game.maxentities]; + for (int i = 0; i < GameBase.game.maxentities; i++) + GameBase.g_edicts[i] = new edict_t(i); + GameBase.g_edicts = GameBase.g_edicts; + } + + public static void CreateClients() { + GameBase.game.clients = new gclient_t[GameBase.game.maxclients]; + for (int i = 0; i < GameBase.game.maxclients; i++) + GameBase.game.clients[i] = new gclient_t(i); + + } + + /* + * ============ InitGame + * + * This will be called when the dll is first loaded, which only happens when + * a new game is started or a save game is loaded. ============ + */ + public static void InitGame() { + GameBase.gi.dprintf("==== InitGame ====\n"); + + GameBase.gun_x = GameBase.gi.cvar("gun_x", "0", 0); + GameBase.gun_y = GameBase.gi.cvar("gun_y", "0", 0); + GameBase.gun_z = GameBase.gi.cvar("gun_z", "0", 0); + + //FIXME: sv_ prefix is wrong for these + GameBase.sv_rollspeed = GameBase.gi.cvar("sv_rollspeed", "200", 0); + GameBase.sv_rollangle = GameBase.gi.cvar("sv_rollangle", "2", 0); + GameBase.sv_maxvelocity = GameBase.gi.cvar("sv_maxvelocity", "2000", 0); + GameBase.sv_gravity = GameBase.gi.cvar("sv_gravity", "800", 0); + + // noset vars + GameBase.dedicated = GameBase.gi.cvar("dedicated", "0", + Defines.CVAR_NOSET); + + // latched vars + GameBase.sv_cheats = GameBase.gi.cvar("cheats", "0", + Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); + GameBase.gi.cvar("gamename", Defines.GAMEVERSION, + Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); + GameBase.gi.cvar("gamedate", Globals.__DATE__, Defines.CVAR_SERVERINFO + | Defines.CVAR_LATCH); + + GameBase.maxclients = GameBase.gi.cvar("maxclients", "4", + Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); + GameBase.maxspectators = GameBase.gi.cvar("maxspectators", "4", + Defines.CVAR_SERVERINFO); + GameBase.deathmatch = GameBase.gi.cvar("deathmatch", "0", + Defines.CVAR_LATCH); + GameBase.coop = GameBase.gi.cvar("coop", "0", Defines.CVAR_LATCH); + GameBase.skill = GameBase.gi.cvar("skill", "0", Defines.CVAR_LATCH); + GameBase.maxentities = GameBase.gi.cvar("maxentities", "1024", + Defines.CVAR_LATCH); + + // change anytime vars + GameBase.dmflags = GameBase.gi.cvar("dmflags", "0", + Defines.CVAR_SERVERINFO); + GameBase.fraglimit = GameBase.gi.cvar("fraglimit", "0", + Defines.CVAR_SERVERINFO); + GameBase.timelimit = GameBase.gi.cvar("timelimit", "0", + Defines.CVAR_SERVERINFO); + GameBase.password = GameBase.gi.cvar("password", "", + Defines.CVAR_USERINFO); + GameBase.spectator_password = GameBase.gi.cvar("spectator_password", + "", Defines.CVAR_USERINFO); + GameBase.needpass = GameBase.gi.cvar("needpass", "0", + Defines.CVAR_SERVERINFO); + GameBase.filterban = GameBase.gi.cvar("filterban", "1", 0); + + GameBase.g_select_empty = GameBase.gi.cvar("g_select_empty", "0", + Defines.CVAR_ARCHIVE); + + GameBase.run_pitch = GameBase.gi.cvar("run_pitch", "0.002", 0); + GameBase.run_roll = GameBase.gi.cvar("run_roll", "0.005", 0); + GameBase.bob_up = GameBase.gi.cvar("bob_up", "0.005", 0); + GameBase.bob_pitch = GameBase.gi.cvar("bob_pitch", "0.002", 0); + GameBase.bob_roll = GameBase.gi.cvar("bob_roll", "0.002", 0); + + // flood control + GameBase.flood_msgs = GameBase.gi.cvar("flood_msgs", "4", 0); + GameBase.flood_persecond = GameBase.gi.cvar("flood_persecond", "4", 0); + GameBase.flood_waitdelay = GameBase.gi.cvar("flood_waitdelay", "10", 0); + + // dm map list + GameBase.sv_maplist = GameBase.gi.cvar("sv_maplist", "", 0); + + // items + GameAI.InitItems(); + + GameBase.game.helpmessage1 = ""; + GameBase.game.helpmessage2 = ""; + + // initialize all entities for this game + GameBase.game.maxentities = (int) GameBase.maxentities.value; + CreateEdicts(); + + // initialize all clients for this game + GameBase.game.maxclients = (int) GameBase.maxclients.value; + + CreateClients(); + + GameBase.num_edicts = GameBase.game.maxclients + 1; + } + + /* + * ============ WriteGame + * + * This will be called whenever the game goes to a new level, and when the + * user explicitly saves the game. + * + * Game information include cross level data, like multi level triggers, + * help computer info, and all client states. + * + * A single player death will automatically restore from the last save + * position. ============ + */ + public static void WriteGame(String filename, boolean autosave) { + try { + QuakeFile f; + + if (!autosave) + PlayerClient.SaveClientData(); + + f = new QuakeFile(filename, "rw"); + + if (f == null) + GameBase.gi.error("Couldn't write to " + filename); + + GameBase.game.autosaved = autosave; + GameBase.game.write(f); + GameBase.game.autosaved = false; + + for (int i = 0; i < GameBase.game.maxclients; i++) + GameBase.game.clients[i].write(f); + + Lib.fclose(f); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void ReadGame(String filename) { + + QuakeFile f = null; + + try { + + f = new QuakeFile(filename, "r"); + CreateEdicts(); + + GameBase.game.load(f); + + for (int i = 0; i < GameBase.game.maxclients; i++) { + GameBase.game.clients[i] = new gclient_t(i); + GameBase.game.clients[i].read(f); + } + + f.close(); + } + + catch (Exception e) { + e.printStackTrace(); + } + } + + /* + * ================= WriteLevel + * + * ================= + */ + public static void WriteLevel(String filename) { + try { + int i; + edict_t ent; + QuakeFile f; + + f = new QuakeFile(filename, "rw"); + if (f == null) + GameBase.gi.error("Couldn't open for writing: " + filename); + + // write out level_locals_t + GameBase.level.write(f); + + // write out all the entities + for (i = 0; i < GameBase.num_edicts; i++) { + ent = GameBase.g_edicts[i]; + if (!ent.inuse) + continue; + f.writeInt(i); + ent.write(f); + + } + + i = -1; + f.writeInt(-1); + + f.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /* + * ================= ReadLevel + * + * SpawnEntities will allready have been called on the level the same way it + * was when the level was saved. + * + * That is necessary to get the baselines set up identically. + * + * The server will have cleared all of the world links before calling + * ReadLevel. + * + * No clients are connected yet. ================= + */ + public static void ReadLevel(String filename) { + try { + edict_t ent; + + QuakeFile f = new QuakeFile(filename, "r"); + + if (f == null) + GameBase.gi.error("Couldn't read level file " + filename); + + // wipe all the entities + CreateEdicts(); + + GameBase.num_edicts = (int) GameBase.maxclients.value + 1; + + // load the level locals + GameBase.level.read(f); + + // load all the entities + while (true) { + int entnum = f.readInt(); + if (entnum == -1) + break; + + if (entnum >= GameBase.num_edicts) + GameBase.num_edicts = entnum + 1; + + ent = GameBase.g_edicts[entnum]; + ent.read(f); + ent.cleararealinks(); + GameBase.gi.linkentity(ent); + } + + Lib.fclose(f); + + // mark all clients as unconnected + for (int i = 0; i < GameBase.maxclients.value; i++) { + ent = GameBase.g_edicts[i + 1]; + ent.client = GameBase.game.clients[i]; + ent.client.pers.connected = false; + } + + // do any load time things at this point + for (int i = 0; i < GameBase.num_edicts; i++) { + ent = GameBase.g_edicts[i]; + + if (!ent.inuse) + continue; + + // fire any cross-level triggers + if (ent.classname != null) + if (Lib.strcmp(ent.classname, "target_crosslevel_target") == 0) + ent.nextthink = GameBase.level.time + ent.delay; + } + } catch (Exception e) { + e.printStackTrace(); + } + } +}
\ No newline at end of file |