/* * 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. * */ /* Modifications Copyright 2003-2004 Bytonic Software Copyright 2010 Google Inc. */ package com.googlecode.gwtquake.shared.game; import com.googlecode.gwtquake.shared.common.Com; import com.googlecode.gwtquake.shared.common.ConsoleVariables; import com.googlecode.gwtquake.shared.common.Constants; import com.googlecode.gwtquake.shared.common.Globals; import com.googlecode.gwtquake.shared.server.ServerGame; import com.googlecode.gwtquake.shared.server.World; import com.googlecode.gwtquake.shared.util.Lib; import com.googlecode.gwtquake.shared.util.QuakeFile; public class GameSave { public static void CreateEdicts() { GameBase.g_edicts = new Entity[GameBase.game.maxentities]; for (int i = 0; i < GameBase.game.maxentities; i++) GameBase.g_edicts[i] = new Entity(i); GameBase.g_edicts = GameBase.g_edicts; } public static void CreateClients() { GameBase.game.clients = new GameClient[GameBase.game.maxclients]; for (int i = 0; i < GameBase.game.maxclients; i++) GameBase.game.clients[i] = new GameClient(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() { ServerGame.PF_dprintf("==== InitGame ====\n"); // // preload all classes to register the adapters // for ( int n=0; n < preloadclasslist.length; n++) // { // try // { // Class.forName(preloadclasslist[n]); // } // catch(Exception e) // { // Com.DPrintf("error loading class: " + e.getMessage()); // } // } // GameBase.gun_x = ConsoleVariables.Get("gun_x", "0", 0); GameBase.gun_y = ConsoleVariables.Get("gun_y", "0", 0); GameBase.gun_z = ConsoleVariables.Get("gun_z", "0", 0); //FIXME: sv_ prefix are wrong names for these variables GameBase.sv_rollspeed = ConsoleVariables.Get("sv_rollspeed", "200", 0); GameBase.sv_rollangle = ConsoleVariables.Get("sv_rollangle", "2", 0); GameBase.sv_maxvelocity = ConsoleVariables.Get("sv_maxvelocity", "2000", 0); GameBase.sv_gravity = ConsoleVariables.Get("sv_gravity", "800", 0); // noset vars Globals.dedicated = ConsoleVariables.Get("dedicated", "0", Constants.CVAR_NOSET); // latched vars GameBase.sv_cheats = ConsoleVariables.Get("cheats", "0", Constants.CVAR_SERVERINFO | Constants.CVAR_LATCH); ConsoleVariables.Get("gamename", Constants.GAMEVERSION, Constants.CVAR_SERVERINFO | Constants.CVAR_LATCH); ConsoleVariables.Get("gamedate", Constants.__DATE__, Constants.CVAR_SERVERINFO | Constants.CVAR_LATCH); GameBase.maxclients = ConsoleVariables.Get("maxclients", "4", Constants.CVAR_SERVERINFO | Constants.CVAR_LATCH); GameBase.maxspectators = ConsoleVariables.Get("maxspectators", "4", Constants.CVAR_SERVERINFO); GameBase.deathmatch = ConsoleVariables.Get("deathmatch", "0", Constants.CVAR_LATCH); GameBase.coop = ConsoleVariables.Get("coop", "0", Constants.CVAR_LATCH); GameBase.skill = ConsoleVariables.Get("skill", "0", Constants.CVAR_LATCH); GameBase.maxentities = ConsoleVariables.Get("maxentities", "1024", Constants.CVAR_LATCH); // change anytime vars GameBase.dmflags = ConsoleVariables.Get("dmflags", "0", Constants.CVAR_SERVERINFO); GameBase.fraglimit = ConsoleVariables.Get("fraglimit", "0", Constants.CVAR_SERVERINFO); GameBase.timelimit = ConsoleVariables.Get("timelimit", "0", Constants.CVAR_SERVERINFO); GameBase.password = ConsoleVariables.Get("password", "", Constants.CVAR_USERINFO); GameBase.spectator_password = ConsoleVariables.Get("spectator_password", "", Constants.CVAR_USERINFO); GameBase.needpass = ConsoleVariables.Get("needpass", "0", Constants.CVAR_SERVERINFO); GameBase.filterban = ConsoleVariables.Get("filterban", "1", 0); GameBase.g_select_empty = ConsoleVariables.Get("g_select_empty", "0", Constants.CVAR_ARCHIVE); GameBase.run_pitch = ConsoleVariables.Get("run_pitch", "0.002", 0); GameBase.run_roll = ConsoleVariables.Get("run_roll", "0.005", 0); GameBase.bob_up = ConsoleVariables.Get("bob_up", "0.005", 0); GameBase.bob_pitch = ConsoleVariables.Get("bob_pitch", "0.002", 0); GameBase.bob_roll = ConsoleVariables.Get("bob_roll", "0.002", 0); // flood control GameBase.flood_msgs = ConsoleVariables.Get("flood_msgs", "4", 0); GameBase.flood_persecond = ConsoleVariables.Get("flood_persecond", "4", 0); GameBase.flood_waitdelay = ConsoleVariables.Get("flood_waitdelay", "10", 0); // dm map list GameBase.sv_maplist = ConsoleVariables.Get("sv_maplist", "", 0); // items GameItems.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) Com.Error(Constants.ERR_FATAL, "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 GameClient(i); GameBase.game.clients[i].read(f); } f.close(); } catch (Exception e) { e.printStackTrace(); } } /** * WriteLevel */ public static void WriteLevel(String filename) { try { int i; Entity ent; QuakeFile f; f = new QuakeFile(filename, "rw"); if (f == null) Com.Error(Constants.ERR_FATAL, "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 { Entity ent; QuakeFile f = new QuakeFile(filename, "r"); if (f == null) Com.Error(Constants.ERR_FATAL, "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(); World.SV_LinkEdict(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(); } } }