Adds game speed option to match setup, adds in-game control for single player games, fixes #785.
Refactors some GUI utility functions. This was SVN commit r13340.
This commit is contained in:
parent
62dc594a71
commit
16de5c75ac
@ -134,29 +134,43 @@ function toTitleCase (string)
|
||||
|
||||
// ====================================================================
|
||||
|
||||
// Load default player data, for when it's not otherwise specified
|
||||
function initPlayerDefaults()
|
||||
// Parse and return JSON data from file in simulation/data/*
|
||||
// returns valid object or undefined on error
|
||||
function parseJSONFromDataFile(filename)
|
||||
{
|
||||
var filename = "simulation/data/player_defaults.json";
|
||||
var defaults = [];
|
||||
var rawData = readFile(filename);
|
||||
var path = "simulation/data/"+filename;
|
||||
var rawData = readFile(path);
|
||||
if (!rawData)
|
||||
error("Failed to read player defaults file: "+filename);
|
||||
|
||||
error("Failed to read file: "+path);
|
||||
|
||||
try
|
||||
{ // Catch nasty errors from JSON parsing
|
||||
{
|
||||
// Catch nasty errors from JSON parsing
|
||||
// TODO: Need more info from the parser on why it failed: line number, position, etc!
|
||||
var data = JSON.parse(rawData);
|
||||
if (!data || !data.PlayerData)
|
||||
error("Failed to parse player defaults in: "+filename+" (check for valid JSON data)");
|
||||
|
||||
defaults = data.PlayerData;
|
||||
return data;
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
error(err.toString()+": parsing player defaults in "+filename);
|
||||
error(err.toString()+": parsing JSON data in "+path);
|
||||
}
|
||||
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
|
||||
// Load default player data, for when it's not otherwise specified
|
||||
function initPlayerDefaults()
|
||||
{
|
||||
var defaults = [];
|
||||
|
||||
var data = parseJSONFromDataFile("player_defaults.json");
|
||||
if (!data || !data.PlayerData)
|
||||
error("Failed to parse player defaults in player_defaults.json (check for valid JSON data)");
|
||||
else
|
||||
defaults = data.PlayerData;
|
||||
|
||||
return defaults;
|
||||
}
|
||||
|
||||
@ -165,40 +179,60 @@ function initPlayerDefaults()
|
||||
// Load map size data
|
||||
function initMapSizes()
|
||||
{
|
||||
var filename = "simulation/data/map_sizes.json";
|
||||
var sizes = {
|
||||
names: [],
|
||||
tiles: [],
|
||||
default: 0
|
||||
"names":[],
|
||||
"tiles": [],
|
||||
"default": 0
|
||||
};
|
||||
var rawData = readFile(filename);
|
||||
if (!rawData)
|
||||
error("Failed to read map sizes file: "+filename);
|
||||
|
||||
try
|
||||
{ // Catch nasty errors from JSON parsing
|
||||
// TODO: Need more info from the parser on why it failed: line number, position, etc!
|
||||
var data = JSON.parse(rawData);
|
||||
if (!data || !data.Sizes)
|
||||
error("Failed to parse map sizes in: "+filename+" (check for valid JSON data)");
|
||||
|
||||
|
||||
var data = parseJSONFromDataFile("map_sizes.json");
|
||||
if (!data || !data.Sizes)
|
||||
error("Failed to parse map sizes in map_sizes.json (check for valid JSON data)");
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < data.Sizes.length; ++i)
|
||||
{
|
||||
sizes.names.push(data.Sizes[i].LongName);
|
||||
sizes.tiles.push(data.Sizes[i].Tiles);
|
||||
|
||||
|
||||
if (data.Sizes[i].Default)
|
||||
sizes.default = i;
|
||||
sizes["default"] = i;
|
||||
}
|
||||
}
|
||||
catch(err)
|
||||
{
|
||||
error(err.toString()+": parsing map sizes in "+filename);
|
||||
}
|
||||
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
// ====================================================================
|
||||
|
||||
// Load game speed data
|
||||
function initGameSpeeds()
|
||||
{
|
||||
var gameSpeeds = {
|
||||
"names": [],
|
||||
"speeds": [],
|
||||
"default": 0
|
||||
};
|
||||
|
||||
var data = parseJSONFromDataFile("game_speeds.json");
|
||||
if (!data || !data.Speeds)
|
||||
error("Failed to parse game speeds in game_speeds.json (check for valid JSON data)");
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < data.Speeds.length; ++i)
|
||||
{
|
||||
gameSpeeds.names.push(data.Speeds[i].Name);
|
||||
gameSpeeds.speeds.push(data.Speeds[i].Speed);
|
||||
|
||||
if (data.Speeds[i].Default)
|
||||
gameSpeeds["default"] = i;
|
||||
}
|
||||
}
|
||||
|
||||
return gameSpeeds;
|
||||
}
|
||||
|
||||
|
||||
// ====================================================================
|
||||
|
||||
// Convert integer color values to string (for use in GUI objects)
|
||||
|
@ -36,6 +36,7 @@ var g_GameAttributes = {
|
||||
settings: {}
|
||||
};
|
||||
|
||||
var g_GameSpeeds = {};
|
||||
var g_MapSizes = {};
|
||||
|
||||
var g_AIs = [];
|
||||
@ -97,7 +98,8 @@ function initMain()
|
||||
g_DefaultPlayerData.shift();
|
||||
for (var i = 0; i < g_DefaultPlayerData.length; i++)
|
||||
g_DefaultPlayerData[i].Civ = "random";
|
||||
|
||||
|
||||
g_GameSpeeds = initGameSpeeds();
|
||||
g_MapSizes = initMapSizes();
|
||||
|
||||
// Init civs
|
||||
@ -135,6 +137,22 @@ function initMain()
|
||||
numPlayersSelection.list = players;
|
||||
numPlayersSelection.list_data = players;
|
||||
numPlayersSelection.selected = MAX_PLAYERS - 1;
|
||||
|
||||
var gameSpeed = getGUIObjectByName("gameSpeed");
|
||||
gameSpeed.hidden = false;
|
||||
getGUIObjectByName("gameSpeedText").hidden = true;
|
||||
gameSpeed.list = g_GameSpeeds.names;
|
||||
gameSpeed.list_data = g_GameSpeeds.speeds;
|
||||
gameSpeed.onSelectionChange = function()
|
||||
{
|
||||
// Update attributes so other players can see change
|
||||
if (this.selected != -1)
|
||||
g_GameAttributes.gameSpeed = g_GameSpeeds.speeds[this.selected];
|
||||
|
||||
if (!g_IsInGuiUpdate)
|
||||
updateGameAttributes();
|
||||
}
|
||||
gameSpeed.selected = g_GameSpeeds["default"];
|
||||
|
||||
var populationCaps = getGUIObjectByName("populationCap");
|
||||
populationCaps.list = POPULATION_CAP;
|
||||
@ -245,7 +263,9 @@ function initMain()
|
||||
getGUIObjectByName("mapSelection").hidden = true;
|
||||
getGUIObjectByName("victoryConditionText").hidden = false;
|
||||
getGUIObjectByName("victoryCondition").hidden = true;
|
||||
|
||||
getGUIObjectByName("gameSpeedText").hidden = false;
|
||||
getGUIObjectByName("gameSpeed").hidden = true;
|
||||
|
||||
// Disable player and game options controls
|
||||
// TODO: Shouldn't players be able to choose their own assignment?
|
||||
for (var i = 0; i < MAX_PLAYERS; ++i)
|
||||
@ -955,15 +975,19 @@ function onGameAttributesChange()
|
||||
var enableCheatsText = getGUIObjectByName("enableCheatsText");
|
||||
var populationCapText = getGUIObjectByName("populationCapText");
|
||||
var startingResourcesText = getGUIObjectByName("startingResourcesText");
|
||||
|
||||
var sizeIdx = (g_MapSizes.tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.tiles.indexOf(mapSettings.Size) : g_MapSizes.default);
|
||||
var gameSpeedText = getGUIObjectByName("gameSpeedText");
|
||||
|
||||
var sizeIdx = (g_MapSizes.tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.tiles.indexOf(mapSettings.Size) : g_MapSizes["default"]);
|
||||
var speedIdx = (g_GameAttributes.gameSpeed !== undefined && g_GameSpeeds.speeds.indexOf(g_GameAttributes.gameSpeed) != -1) ? g_GameSpeeds.speeds.indexOf(g_GameAttributes.gameSpeed) : g_GameSpeeds["default"];
|
||||
var victoryIdx = (VICTORY_DATA.indexOf(mapSettings.GameType) != -1 ? VICTORY_DATA.indexOf(mapSettings.GameType) : VICTORY_DEFAULTIDX);
|
||||
enableCheats.checked = (g_GameAttributes.settings.CheatsEnabled === undefined || !g_GameAttributes.settings.CheatsEnabled ? false : true)
|
||||
enableCheatsText.caption = (enableCheats.checked ? "Yes" : "No");
|
||||
gameSpeedText.caption = g_GameSpeeds.names[speedIdx];
|
||||
populationCap.selected = (POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) != -1 ? POPULATION_CAP_DATA.indexOf(mapSettings.PopulationCap) : POPULATION_CAP_DEFAULTIDX);
|
||||
populationCapText.caption = POPULATION_CAP[populationCap.selected];
|
||||
startingResources.selected = (STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) != -1 ? STARTING_RESOURCES_DATA.indexOf(mapSettings.StartingResources) : STARTING_RESOURCES_DEFAULTIDX);
|
||||
startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];
|
||||
|
||||
// Handle map type specific logic
|
||||
switch (g_GameAttributes.mapType)
|
||||
{
|
||||
|
@ -178,20 +178,28 @@
|
||||
</object>
|
||||
|
||||
<!-- More Options -->
|
||||
<object name="moreOptions" type="image" sprite="StoneWindow" size="50%-200 50%-120 50%+200 50%+155" z="70" hidden="true">
|
||||
<object name="moreOptions" type="image" sprite="StoneWindow" size="50%-200 50%-150 50%+200 50%+155" z="70" hidden="true">
|
||||
<object style="TitleText" type="text" size="50%-128 11 50%+128 27">
|
||||
More Options
|
||||
</object>
|
||||
|
||||
<object size="14 38 94% 66">
|
||||
<object size="0 0 40% 28">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Victory condition:</object>
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Game Speed:</object>
|
||||
</object>
|
||||
<object name="gameSpeedText" size="40% 0 100% 100%" type="text" style="LeftLabelText"/>
|
||||
<object name="gameSpeed" size="40% 0 100% 28" type="dropdown" style="StoneDropDown" hidden="true" tooltip_style="onscreenToolTip" tooltip="Select game speed."/>
|
||||
</object>
|
||||
|
||||
<object size="14 68 94% 96">
|
||||
<object size="0 0 40% 28">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Victory Condition:</object>
|
||||
</object>
|
||||
<object name="victoryConditionText" size="40% 0 100% 100%" type="text" style="LeftLabelText"/>
|
||||
<object name="victoryCondition" size="40% 0 100% 28" type="dropdown" style="StoneDropDown" hidden="true" tooltip_style="onscreenToolTip" tooltip="Select victory condition."/>
|
||||
</object>
|
||||
|
||||
<object size="14 68 94% 96">
|
||||
<object size="14 98 94% 126">
|
||||
<object size="0 0 40% 28">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Population Cap:</object>
|
||||
</object>
|
||||
@ -199,7 +207,7 @@
|
||||
<object name="populationCap" size="40% 0 100% 28" type="dropdown" style="StoneDropDown" hidden="true" tooltip_style="onscreenToolTip" tooltip="Select population cap."/>
|
||||
</object>
|
||||
|
||||
<object size="14 98 94% 126">
|
||||
<object size="14 128 94% 156">
|
||||
<object size="0 0 40% 28">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Starting Resources:</object>
|
||||
</object>
|
||||
@ -207,12 +215,12 @@
|
||||
<object name="startingResources" size="40% 0 100% 28" type="dropdown" style="StoneDropDown" hidden="true" tooltip_style="onscreenToolTip" tooltip="Select the game's starting resources."/>
|
||||
</object>
|
||||
|
||||
<object size="14 128 94% 216">
|
||||
<object size="14 158 94% 246">
|
||||
<object size="0 0 40% 28">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Reveal map:</object>
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Reveal Map:</object>
|
||||
</object>
|
||||
<object size="0 30 40% 58">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Teams locked:</object>
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Teams Locked:</object>
|
||||
</object>
|
||||
<object size="0 60 40% 88" name="enableCheatsDesc" hidden="true">
|
||||
<object size="0 0 100% 100%" type="text" style="RightLabelText">Cheats:</object>
|
||||
@ -237,7 +245,7 @@
|
||||
name="hideMoreOptions"
|
||||
type="button"
|
||||
style="StoneButton"
|
||||
size="50%-70 218 50%+70 246"
|
||||
size="50%-70 248 50%+70 274"
|
||||
tooltip_style="onscreenToolTip"
|
||||
tooltip="Close more game options window"
|
||||
>
|
||||
|
@ -361,6 +361,12 @@ function toggleDiplomacy()
|
||||
openDiplomacy();
|
||||
};
|
||||
|
||||
function toggleGameSpeed()
|
||||
{
|
||||
var gameSpeed = getGUIObjectByName("gameSpeed");
|
||||
gameSpeed.hidden = !gameSpeed.hidden;
|
||||
}
|
||||
|
||||
function pauseGame()
|
||||
{
|
||||
getGUIObjectByName("pauseButtonText").caption = RESUME;
|
||||
|
@ -6,6 +6,9 @@ var g_Players = [];
|
||||
// Cache the useful civ data
|
||||
var g_CivData = {};
|
||||
|
||||
var g_GameSpeeds = {};
|
||||
var g_CurrentSpeed;
|
||||
|
||||
var g_PlayerAssignments = { "local": { "name": "You", "player": 1 } };
|
||||
|
||||
// Cache dev-mode settings that are frequently or widely used
|
||||
@ -85,9 +88,9 @@ function init(initData, hotloadData)
|
||||
g_Players = getPlayerData(g_PlayerAssignments);
|
||||
|
||||
if (initData.savedGUIData)
|
||||
{
|
||||
restoreSavedGameData(initData.savedGUIData);
|
||||
}
|
||||
|
||||
getGUIObjectByName("gameSpeedButton").hidden = g_IsNetworked;
|
||||
}
|
||||
else // Needed for autostart loading option
|
||||
{
|
||||
@ -98,6 +101,15 @@ function init(initData, hotloadData)
|
||||
g_CivData = loadCivData();
|
||||
g_CivData["gaia"] = { "Code": "gaia", "Name": "Gaia" };
|
||||
|
||||
g_GameSpeeds = initGameSpeeds();
|
||||
g_CurrentSpeed = Engine.GetSimRate();
|
||||
var gameSpeed = getGUIObjectByName("gameSpeed");
|
||||
gameSpeed.list = g_GameSpeeds.names;
|
||||
gameSpeed.list_data = g_GameSpeeds.speeds;
|
||||
var idx = g_GameSpeeds.speeds.indexOf(g_CurrentSpeed);
|
||||
gameSpeed.selected = idx != -1 ? idx : g_GameSpeeds["default"];
|
||||
gameSpeed.onSelectionChange = function() { changeGameSpeed(+this.list_data[this.selected]); }
|
||||
|
||||
getGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[Engine.GetPlayerID()].civ].Emblem;
|
||||
getGUIObjectByName("civIcon").tooltip = g_CivData[g_Players[Engine.GetPlayerID()].civ].Name;
|
||||
initMenuPosition(); // set initial position
|
||||
@ -353,6 +365,16 @@ function checkPlayerState()
|
||||
}
|
||||
}
|
||||
|
||||
function changeGameSpeed(speed)
|
||||
{
|
||||
// For non-networked games only
|
||||
if (!g_IsNetworked)
|
||||
{
|
||||
Engine.SetSimRate(speed);
|
||||
g_CurrentSpeed = speed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recomputes GUI state that depends on simulation state or selection state. Called directly every simulation
|
||||
* update (see session.xml), or from onTick when the selection has changed.
|
||||
@ -562,8 +584,9 @@ function updateResearchDisplay()
|
||||
|
||||
function updateTimeElapsedCounter(simState)
|
||||
{
|
||||
var speed = g_CurrentSpeed != 1.0 ? " (" + g_CurrentSpeed + "x)" : "";
|
||||
var timeElapsedCounter = getGUIObjectByName("timeElapsedCounter");
|
||||
timeElapsedCounter.caption = timeToString(simState.timeElapsed);
|
||||
timeElapsedCounter.caption = timeToString(simState.timeElapsed) + speed;
|
||||
}
|
||||
|
||||
// Toggles the display of status bars for all of the player's entities.
|
||||
|
@ -220,7 +220,8 @@
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Time elapsed counter -->
|
||||
<!-- ================================ ================================ -->
|
||||
<object size="100%-100 50 100%-10 70" type="text" name="timeElapsedCounter" style="SettingsText" hotkey="timeelapsedcounter.toggle" hidden="true">
|
||||
|
||||
<object size="100%-120 45 100%-10 65" type="text" name="timeElapsedCounter" style="SettingsText" hotkey="timeelapsedcounter.toggle" hidden="true">
|
||||
<action on="Press">this.hidden = !this.hidden;</action>
|
||||
</object>
|
||||
|
||||
@ -513,7 +514,7 @@
|
||||
<!-- ================================ ================================ -->
|
||||
|
||||
<!-- Displays Alpha name and number -->
|
||||
<object size="70%-128 0 70%+128 100%" name="alphaLabel" type="text" style="CenteredLabelText" text_valign="top" ghost="true">
|
||||
<object size="50%+48 0 100%-226 100%" name="alphaLabel" type="text" style="CenteredLabelText" text_valign="top" ghost="true">
|
||||
ALPHA XIII : Magadha<!-- IMPORTANT: remember to update pregame/mainmenu.xml in sync with this -->
|
||||
|
||||
<!-- Displays build date and revision number-->
|
||||
@ -522,12 +523,30 @@
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Game Speed Button -->
|
||||
<!-- ================================ ================================ -->
|
||||
<object type="button"
|
||||
name="gameSpeedButton"
|
||||
size="100%-226 4 100%-198 32"
|
||||
style="iconButton"
|
||||
tooltip_style="sessionToolTip"
|
||||
tooltip="Game speed"
|
||||
>
|
||||
<object size="5 5 100%-5 100%-5" type="image" sprite="stretched:session/icons/resources/time_small.png" ghost="true"/>
|
||||
<action on="Press">
|
||||
toggleGameSpeed();
|
||||
</action>
|
||||
</object>
|
||||
|
||||
<object size="100%-230 45 100%-140 70" name="gameSpeed" type="dropdown" buffer_zone="5" style="StoneDropDown" hidden="true" tooltip="Choose game speed" tooltip_style="sessionToolTip"/>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Diplomacy Button -->
|
||||
<!-- ================================ ================================ -->
|
||||
<object type="button"
|
||||
name="diplomacyButton1"
|
||||
size="100%-196 0 100%-164 32"
|
||||
size="100%-194 4 100%-166 32"
|
||||
style="iconButton"
|
||||
tooltip_style="sessionToolTip"
|
||||
tooltip="Diplomacy"
|
||||
|
30
binaries/data/mods/public/simulation/data/game_speeds.json
Normal file
30
binaries/data/mods/public/simulation/data/game_speeds.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"Speeds":
|
||||
[
|
||||
{
|
||||
"Name": "Turtle",
|
||||
"Speed": 0.50
|
||||
},
|
||||
{
|
||||
"Name": "Slow",
|
||||
"Speed": 0.75
|
||||
},
|
||||
{
|
||||
"Name": "Normal",
|
||||
"Speed": 1.0,
|
||||
"Default": true
|
||||
},
|
||||
{
|
||||
"Name": "Fast",
|
||||
"Speed": 1.5
|
||||
},
|
||||
{
|
||||
"Name": "Very Fast",
|
||||
"Speed": 2.0
|
||||
},
|
||||
{
|
||||
"Name": "Insane",
|
||||
"Speed": 4.0
|
||||
}
|
||||
]
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2012 Wildfire Games.
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -526,6 +526,11 @@ void SetSimRate(void* UNUSED(cbdata), float rate)
|
||||
g_Game->SetSimRate(rate);
|
||||
}
|
||||
|
||||
float GetSimRate(void* UNUSED(cbdata))
|
||||
{
|
||||
return g_Game->GetSimRate();
|
||||
}
|
||||
|
||||
void SetTurnLength(void* UNUSED(cbdata), int length)
|
||||
{
|
||||
if (g_NetServer)
|
||||
@ -680,6 +685,7 @@ void GuiScriptingInit(ScriptInterface& scriptInterface)
|
||||
|
||||
// Development/debugging functions
|
||||
scriptInterface.RegisterFunction<void, float, &SetSimRate>("SetSimRate");
|
||||
scriptInterface.RegisterFunction<float, &GetSimRate>("GetSimRate");
|
||||
scriptInterface.RegisterFunction<void, int, &SetTurnLength>("SetTurnLength");
|
||||
scriptInterface.RegisterFunction<void, float, float, float, &SetCameraTarget>("SetCameraTarget");
|
||||
scriptInterface.RegisterFunction<int, &Crash>("Crash");
|
||||
|
@ -126,6 +126,10 @@ void CGame::RegisterInit(const CScriptValRooted& attribs, const std::string& sav
|
||||
std::string mapType;
|
||||
m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "mapType", mapType);
|
||||
|
||||
float speed;
|
||||
if (m_Simulation2->GetScriptInterface().HasProperty(attribs.get(), "gameSpeed") && m_Simulation2->GetScriptInterface().GetProperty(attribs.get(), "gameSpeed", speed))
|
||||
SetSimRate(speed);
|
||||
|
||||
LDR_BeginRegistering();
|
||||
|
||||
RegMemFun(m_Simulation2, &CSimulation2::ProgressiveLoad, L"Simulation init", 1000);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
/* Copyright (C) 2013 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -145,7 +145,10 @@ public:
|
||||
* clamped to 0.0f.
|
||||
**/
|
||||
inline void SetSimRate(float simRate)
|
||||
{ m_SimRate = std::max(simRate, 0.0f); }
|
||||
{ if (isfinite(simRate)) m_SimRate = std::max(simRate, 0.0f); }
|
||||
|
||||
inline float GetSimRate()
|
||||
{ return m_SimRate; }
|
||||
|
||||
/**
|
||||
* Replace the current turn manager.
|
||||
|
Loading…
Reference in New Issue
Block a user