diff --git a/GUI/PropertyWindow/GamesHelper.cs b/GUI/PropertyWindow/GamesHelper.cs
index 33a886ff4..fd50b43c1 100644
--- a/GUI/PropertyWindow/GamesHelper.cs
+++ b/GUI/PropertyWindow/GamesHelper.cs
@@ -119,6 +119,12 @@ namespace MCGalaxy.Gui {
}
+ public void UpdateMapConfig(string map) {
+ if (game.Running && game.Map.name == map) {
+ game.UpdateMapConfig();
+ }
+ }
+
public void UpdateMaps() {
UpdateUsedMaps();
UpdateNotUsedMaps(null);
diff --git a/GUI/PropertyWindow/PropertyWindow.Games.cs b/GUI/PropertyWindow/PropertyWindow.Games.cs
index 0764b0f6c..2d33077d8 100644
--- a/GUI/PropertyWindow/PropertyWindow.Games.cs
+++ b/GUI/PropertyWindow/PropertyWindow.Games.cs
@@ -193,12 +193,9 @@ namespace MCGalaxy.Gui {
lsCurCfg.RoundTime = ls_numRound.Value;
lsCurCfg.FloodTime = ls_numFlood.Value;
lsCurCfg.LayerInterval = ls_numLayerTime.Value;
- lsCurCfg.Save(lsCurMap);
- LSGame game = LSGame.Instance;
- if (game.Running && game.Map.name == lsCurMap) {
- game.UpdateMapConfig();
- }
+ lsCurCfg.Save(lsCurMap);
+ lsHelper.UpdateMapConfig(lsCurMap);
}
@@ -276,12 +273,9 @@ namespace MCGalaxy.Gui {
twCurCfg.GracePeriodTime = tw_numGrace.Value;
twCurCfg.BalanceTeams = tw_cbBalance.Checked;
twCurCfg.TeamKills = tw_cbKills.Checked;
- twCurCfg.Save(twCurMap);
- TWGame game = TWGame.Instance;
- if (game.Running && game.Map.name == twCurMap) {
- game.UpdateMapConfig();
- }
+ twCurCfg.Save(twCurMap);
+ twHelper.UpdateMapConfig(twCurMap);
}
void tw_btnAbout_Click(object sender, EventArgs e) {
diff --git a/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs b/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs
index 8145f14c3..9e31f194e 100644
--- a/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs
+++ b/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs
@@ -16,8 +16,6 @@
permissions and limitations under the Licenses.
*/
using System;
-using System.Collections.Generic;
-using System.IO;
using MCGalaxy.Games;
using MCGalaxy.Maths;
using BlockID = System.UInt16;
@@ -33,33 +31,34 @@ namespace MCGalaxy.Commands.Fun {
protected override void HandleSet(Player p, RoundsGame game, string[] args) {
string prop = args[1];
- CTFMapConfig cfg = RetrieveConfig(p);
+ CTFMapConfig cfg = new CTFMapConfig();
+ LoadMapConfig(p, cfg);
if (prop.CaselessEq("bluespawn")) {
cfg.BlueSpawn = (Vec3U16)p.Pos.FeetBlockCoords;
p.Message("Set spawn of blue team to &b" + cfg.BlueSpawn);
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
} else if (prop.CaselessEq("redspawn")) {
cfg.RedSpawn = (Vec3U16)p.Pos.FeetBlockCoords;
p.Message("Set spawn of red team to &b" + cfg.RedSpawn);
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
} else if (prop.CaselessEq("blueflag")) {
p.Message("Place or delete a block to set blue team's flag.");
- p.MakeSelection(1, null, BlueFlagCallback);
+ p.MakeSelection(1, cfg, BlueFlagCallback);
} else if (prop.CaselessEq("redflag")) {
p.Message("Place or delete a block to set red team's flag.");
- p.MakeSelection(1, null, RedFlagCallback);
+ p.MakeSelection(1, cfg, RedFlagCallback);
} else if (prop.CaselessEq("divider")) {
cfg.ZDivider = p.Pos.BlockZ;
p.Message("Set Z line divider to {0}.", cfg.ZDivider);
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
} else {
Help(p, "set");
}
}
- static bool BlueFlagCallback(Player p, Vec3S32[] marks, object state, BlockID block) {
- CTFMapConfig cfg = RetrieveConfig(p);
+ bool BlueFlagCallback(Player p, Vec3S32[] marks, object state, BlockID block) {
+ CTFMapConfig cfg = (CTFMapConfig)state;
Vec3U16 P = (Vec3U16)marks[0];
cfg.BlueFlagPos = P;
p.Message("Set flag position of blue team to ({0})", P);
@@ -69,12 +68,12 @@ namespace MCGalaxy.Commands.Fun {
cfg.BlueFlagBlock = block;
p.Message("Set flag block of blue team to {0}", Block.GetName(p, block));
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
return false;
}
- static bool RedFlagCallback(Player p, Vec3S32[] marks, object state, BlockID block) {
- CTFMapConfig cfg = RetrieveConfig(p);
+ bool RedFlagCallback(Player p, Vec3S32[] marks, object state, BlockID block) {
+ CTFMapConfig cfg = (CTFMapConfig)state;
Vec3U16 P = (Vec3U16)marks[0];
cfg.RedFlagPos = P;
p.Message("Set flag position of red team to ({0})", P);
@@ -84,17 +83,10 @@ namespace MCGalaxy.Commands.Fun {
cfg.RedFlagBlock = block;
p.Message("Set flag block of red team to {0}", Block.GetName(p, block));
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
return false;
}
- static CTFMapConfig RetrieveConfig(Player p) {
- CTFMapConfig cfg = new CTFMapConfig();
- cfg.SetDefaults(p.level);
- cfg.Load(p.level.name);
- return cfg;
- }
-
static void UpdateConfig(Player p, CTFMapConfig cfg) {
cfg.Save(p.level.name);
if (p.level == CTFGame.Instance.Map) CTFGame.Instance.UpdateMapConfig();
diff --git a/MCGalaxy/Commands/Fun/CmdLavaSurvival.cs b/MCGalaxy/Commands/Fun/CmdLavaSurvival.cs
index 19d7e5c04..93ca4f3f2 100644
--- a/MCGalaxy/Commands/Fun/CmdLavaSurvival.cs
+++ b/MCGalaxy/Commands/Fun/CmdLavaSurvival.cs
@@ -17,7 +17,6 @@
permissions and limitations under the Licenses.
*/
using System;
-using System.Collections.Generic;
using MCGalaxy.Games;
using MCGalaxy.Maths;
using BlockID = System.UInt16;
@@ -33,12 +32,15 @@ namespace MCGalaxy.Commands.Fun {
protected override void HandleSet(Player p, RoundsGame game, string[] args) {
string prop = args[1];
+ LSMapConfig cfg = new LSMapConfig();
+ LoadMapConfig(p, cfg);
+
if (prop.CaselessEq("spawn")) {
- HandleSetSpawn(p, args);
+ HandleSetSpawn(p, args, cfg);
} else if (prop.CaselessEq("block")) {
- HandleSetBlock(p, args);
+ HandleSetBlock(p, args, cfg);
} else if (prop.CaselessEq("other")) {
- HandleSetOther(p, args);
+ HandleSetOther(p, args, cfg);
} else {
Help(p, "set");
}
@@ -57,8 +59,7 @@ namespace MCGalaxy.Commands.Fun {
}
- void HandleSetSpawn(Player p, string[] args) {
- LSMapConfig cfg = RetrieveConfig(p);
+ void HandleSetSpawn(Player p, string[] args, LSMapConfig cfg) {
if (args.Length < 3) {
p.Message("Flood position: &b" + cfg.FloodPos);
p.Message("Layer position: &b" + cfg.LayerPos);
@@ -94,29 +95,28 @@ namespace MCGalaxy.Commands.Fun {
Help(p, "spawn");
}
- if (ok) UpdateConfig(p, cfg);
+ if (ok) SaveMapConfig(p, cfg);
}
- static bool SetFloodPos(Player p, Vec3S32[] m, object state, BlockID block) {
+ bool SetFloodPos(Player p, Vec3S32[] m, object state, BlockID block) {
LSMapConfig cfg = (LSMapConfig)state;
cfg.FloodPos = (Vec3U16)m[0];
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
p.Message("Flood position set to &b({0})", m[0]);
return false;
}
- static bool SetLayerPos(Player p, Vec3S32[] m, object state, BlockID block) {
+ bool SetLayerPos(Player p, Vec3S32[] m, object state, BlockID block) {
LSMapConfig cfg = (LSMapConfig)state;
cfg.LayerPos = (Vec3U16)m[0];
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
p.Message("Layer position set to &b({0})", m[0]);
return false;
}
- void HandleSetBlock(Player p, string[] args) {
- LSMapConfig cfg = RetrieveConfig(p);
+ void HandleSetBlock(Player p, string[] args, LSMapConfig cfg) {
if (args.Length < 3) {
p.Message("Fast lava chance: &b" + cfg.FastChance + "%");
p.Message("Killer lava/water chance: &b" + cfg.KillerChance + "%");
@@ -141,11 +141,10 @@ namespace MCGalaxy.Commands.Fun {
Help(p, "block");
}
- if (ok) UpdateConfig(p, cfg);
+ if (ok) SaveMapConfig(p, cfg);
}
- void HandleSetOther(Player p, string[] args) {
- LSMapConfig cfg = RetrieveConfig(p);
+ void HandleSetOther(Player p, string[] args, LSMapConfig cfg) {
if (args.Length < 3) {
p.Message("Layer time: &b" + cfg.LayerInterval.Shorten(true));
p.Message("Round time: &b" + cfg.RoundTime.Shorten(true));
@@ -174,31 +173,19 @@ namespace MCGalaxy.Commands.Fun {
Help(p, "other");
}
- if (ok) UpdateConfig(p, cfg);
+ if (ok) SaveMapConfig(p, cfg);
}
- static bool SetSafeZone(Player p, Vec3S32[] m, object state, BlockID block) {
+ bool SetSafeZone(Player p, Vec3S32[] m, object state, BlockID block) {
LSMapConfig cfg = (LSMapConfig)state;
cfg.SafeZoneMin = (Vec3U16)Vec3S32.Min(m[0], m[1]);
cfg.SafeZoneMax = (Vec3U16)Vec3S32.Max(m[0], m[1]);
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
p.Message("Safe zone set! &b({0}) ({1})", cfg.SafeZoneMin, cfg.SafeZoneMax);
return false;
}
- static LSMapConfig RetrieveConfig(Player p) {
- LSMapConfig cfg = new LSMapConfig();
- cfg.SetDefaults(p.level);
- cfg.Load(p.level.name);
- return cfg;
- }
-
- static void UpdateConfig(Player p, LSMapConfig cfg) {
- cfg.Save(p.level.name);
- if (p.level == LSGame.Instance.Map) LSGame.Instance.UpdateMapConfig();
- }
-
public override void Help(Player p, string message) {
if (message.CaselessEq("set")) {
p.Message("%T/Help LS spawn %H- Views help for lava spawn settings");
diff --git a/MCGalaxy/Commands/Fun/CmdTntWars.cs b/MCGalaxy/Commands/Fun/CmdTntWars.cs
index 3aef28be2..fcf39d8ec 100644
--- a/MCGalaxy/Commands/Fun/CmdTntWars.cs
+++ b/MCGalaxy/Commands/Fun/CmdTntWars.cs
@@ -17,7 +17,6 @@
*/
using System;
using System.Collections.Generic;
-using System.Threading;
using MCGalaxy.Games;
using MCGalaxy.Maths;
using BlockID = System.UInt16;
@@ -56,9 +55,10 @@ namespace MCGalaxy.Commands.Fun {
protected override void HandleSet(Player p, RoundsGame game_, string[] args) {
TWGame game = (TWGame)game_;
- TWMapConfig cfg = RetrieveConfig(p);
+ TWMapConfig cfg = new TWMapConfig();
TWConfig gameCfg = TWGame.Config;
+ LoadMapConfig(p, cfg);
if (args.Length == 1) { Help(p, "set"); return; }
if (args.Length == 2) { OutputStatus(p, gameCfg, cfg); return; }
@@ -134,7 +134,7 @@ namespace MCGalaxy.Commands.Fun {
} else {
OutputStatus(p, gameCfg, cfg); return;
}
- UpdateConfig(p, cfg);
+ SaveMapConfig(p, cfg);
}
static void OutputStatus(Player p, TWConfig gameCfg, TWMapConfig cfg) {
@@ -290,18 +290,6 @@ namespace MCGalaxy.Commands.Fun {
p.Message("TNT Wars: {0} is now {1}", name, GetBool(target));
}
- static TWMapConfig RetrieveConfig(Player p) {
- TWMapConfig cfg = new TWMapConfig();
- cfg.SetDefaults(p.level);
- cfg.Load(p.level.name);
- return cfg;
- }
-
- static void UpdateConfig(Player p, TWMapConfig cfg) {
- cfg.Save(p.level.name);
- if (p.level == TWGame.Instance.Map) TWGame.Instance.UpdateMapConfig();
- }
-
public override void Help(Player p, string message) {
if (message.CaselessEq("set")) {
diff --git a/MCGalaxy/Commands/Fun/RoundsGameCmd.cs b/MCGalaxy/Commands/Fun/RoundsGameCmd.cs
index 423cd468d..0f3f5a4cd 100644
--- a/MCGalaxy/Commands/Fun/RoundsGameCmd.cs
+++ b/MCGalaxy/Commands/Fun/RoundsGameCmd.cs
@@ -93,5 +93,16 @@ namespace MCGalaxy.Commands.Fun {
}
protected abstract void HandleSet(Player p, RoundsGame game, string[] args);
+
+ protected void LoadMapConfig(Player p, RoundsGameMapConfig cfg) {
+ cfg.SetDefaults(p.level);
+ cfg.Load(p.level.name);
+ }
+
+ protected void SaveMapConfig(Player p, RoundsGameMapConfig cfg) {
+ RoundsGame game = Game;
+ cfg.Save(p.level.name);
+ if (p.level == game.Map) game.UpdateMapConfig();
+ }
}
}
diff --git a/MCGalaxy/Games/CTF/CtfConfig.cs b/MCGalaxy/Games/CTF/CtfConfig.cs
index 25f513871..ec869b2a2 100644
--- a/MCGalaxy/Games/CTF/CtfConfig.cs
+++ b/MCGalaxy/Games/CTF/CtfConfig.cs
@@ -31,7 +31,7 @@ namespace MCGalaxy.Games {
protected override string PropsPath { get { return "properties/ctf.properties"; } }
}
- public sealed class CTFMapConfig {
+ public sealed class CTFMapConfig : RoundsGameMapConfig {
[ConfigVec3("red-spawn", null)] public Vec3U16 RedSpawn;
[ConfigVec3("red-pos", null)] public Vec3U16 RedFlagPos;
[ConfigBlock("red-block", null, Block.Air)]
@@ -57,22 +57,18 @@ namespace MCGalaxy.Games {
const string propsDir = "properties/CTF/";
- static string Path(string map) { return propsDir + map + ".properties"; }
static ConfigElement[] cfg;
-
- public void Load(string map) {
+ public override void Load(string map) {
if (cfg == null) cfg = ConfigElement.GetAll(typeof(CTFMapConfig));
- ConfigElement.ParseFile(cfg, Path(map), this);
+ LoadFrom(cfg, propsDir, map);
}
- public void Save(string map) {
- if (!Directory.Exists(propsDir)) Directory.CreateDirectory(propsDir);
-
+ public override void Save(string map) {
if (cfg == null) cfg = ConfigElement.GetAll(typeof(CTFMapConfig));
- ConfigElement.SerialiseSimple(cfg, Path(map), this);
+ SaveTo(cfg, propsDir, map);
}
- public void SetDefaults(Level lvl) {
+ public override void SetDefaults(Level lvl) {
ZDivider = lvl.Length / 2;
RedFlagBlock = Block.Red;
BlueFlagBlock = Block.Blue;
diff --git a/MCGalaxy/Games/LavaSurvival/LSConfig.cs b/MCGalaxy/Games/LavaSurvival/LSConfig.cs
index e80d5415f..ff7a64246 100644
--- a/MCGalaxy/Games/LavaSurvival/LSConfig.cs
+++ b/MCGalaxy/Games/LavaSurvival/LSConfig.cs
@@ -35,7 +35,7 @@ namespace MCGalaxy.Games {
protected override string PropsPath { get { return "properties/lavasurvival.properties"; } }
}
- public sealed class LSMapConfig {
+ public sealed class LSMapConfig : RoundsGameMapConfig {
[ConfigInt("fast-chance", null, 0, 0, 100)]
public int FastChance;
[ConfigInt("killer-chance", null, 100, 0, 100)]
@@ -66,22 +66,18 @@ namespace MCGalaxy.Games {
const string propsDir = "properties/lavasurvival/";
- static string Path(string map) { return propsDir + map + ".properties"; }
- static ConfigElement[] cfg;
-
- public void Load(string map) {
+ static ConfigElement[] cfg;
+ public override void Load(string map) {
if (cfg == null) cfg = ConfigElement.GetAll(typeof(LSMapConfig));
- ConfigElement.ParseFile(cfg, Path(map), this);
+ LoadFrom(cfg, propsDir, map);
}
- public void Save(string map) {
- if (!Directory.Exists(propsDir)) Directory.CreateDirectory(propsDir);
-
+ public override void Save(string map) {
if (cfg == null) cfg = ConfigElement.GetAll(typeof(LSMapConfig));
- ConfigElement.SerialiseSimple(cfg, Path(map), this);
+ SaveTo(cfg, propsDir, map);
}
- public void SetDefaults(Level lvl) {
+ public override void SetDefaults(Level lvl) {
ushort x = (ushort)(lvl.Width / 2), y = (ushort)(lvl.Height / 2), z = (ushort)(lvl.Length / 2);
FloodPos = new Vec3U16(x, (ushort)(lvl.Height - 1), z);
LayerPos = new Vec3U16(0, y , 0);
diff --git a/MCGalaxy/Games/RoundsGame/RoundsGame.cs b/MCGalaxy/Games/RoundsGame/RoundsGame.cs
index 1c5c05a51..0a23a6a33 100644
--- a/MCGalaxy/Games/RoundsGame/RoundsGame.cs
+++ b/MCGalaxy/Games/RoundsGame/RoundsGame.cs
@@ -30,12 +30,19 @@ namespace MCGalaxy.Games {
public string LastMap = "";
public LevelPicker Picker;
+ /// Messages general info about current round and players.
+ /// e.g. who is alive, points of each team, etc.
public abstract void OutputStatus(Player p);
+ /// The instance of this game's overall configuration object.
public abstract RoundsGameConfig GetConfig();
+ /// Updates state from the map specific configuration file.
public abstract void UpdateMapConfig();
+ /// Runs a single round of this game.
protected abstract void DoRound();
+ /// Gets the list of all players in this game.
protected abstract List GetPlayers();
+ /// Saves stats to the database for the given player.
protected virtual void SaveStats(Player pl) { }
protected abstract void StartGame();
@@ -69,6 +76,7 @@ namespace MCGalaxy.Games {
t.Start();
}
+ /// Attempts to auto start this game with infinite rounds.
public void AutoStart() {
if (!GetConfig().StartImmediately) return;
try {
diff --git a/MCGalaxy/Games/RoundsGame/RoundsGameConfig.cs b/MCGalaxy/Games/RoundsGame/RoundsGameConfig.cs
index f83f9f0ba..aea786540 100644
--- a/MCGalaxy/Games/RoundsGame/RoundsGameConfig.cs
+++ b/MCGalaxy/Games/RoundsGame/RoundsGameConfig.cs
@@ -17,6 +17,7 @@
*/
using System;
using System.Collections.Generic;
+using System.IO;
using MCGalaxy.Config;
using MCGalaxy.Events.GameEvents;
using MCGalaxy.Events.LevelEvents;
@@ -26,6 +27,30 @@ using MCGalaxy.Network;
namespace MCGalaxy.Games {
+ /// Stores map-specific game configuration state.
+ public abstract class RoundsGameMapConfig {
+
+ protected void LoadFrom(ConfigElement[] cfg, string propsDir, string map) {
+ string path = propsDir + map + ".properties";
+ ConfigElement.ParseFile(cfg, path, this);
+ }
+
+ protected void SaveTo(ConfigElement[] cfg, string propsDir, string map) {
+ string path = propsDir + map + ".properties";
+ if (!Directory.Exists(propsDir)) Directory.CreateDirectory(propsDir);
+ ConfigElement.SerialiseSimple(cfg, path, this);
+ }
+
+ /// Saves this configuration to disc.
+ public abstract void Save(string map);
+ /// Loads this configuration from disc.
+ public abstract void Load(string map);
+ /// Applies default values for config fields which differ per map.
+ /// e.g. spawn positions, zones
+ public abstract void SetDefaults(Level lvl);
+ }
+
+ /// Stores overall game configuration state.
public abstract class RoundsGameConfig {
[ConfigBool("start-on-server-start", "Game", false)]
public bool StartImmediately;
@@ -36,6 +61,8 @@ namespace MCGalaxy.Games {
[ConfigStringList("maps", "Game")]
public List Maps = new List();
+ /// Whether users are allowed to auto-join maps used by this game.
+ /// If false, users can only join these maps when manually /load ed.
public abstract bool AllowAutoload { get; }
protected abstract string PropsPath { get; }
protected abstract string GameName { get; }
diff --git a/MCGalaxy/Games/TntWars/TWConfig.cs b/MCGalaxy/Games/TntWars/TWConfig.cs
index 9bcf7e7c5..88c0d9ce4 100644
--- a/MCGalaxy/Games/TntWars/TWConfig.cs
+++ b/MCGalaxy/Games/TntWars/TWConfig.cs
@@ -38,7 +38,7 @@ namespace MCGalaxy.Games {
public TWDifficulty Difficulty = TWDifficulty.Normal;
}
- public sealed class TWMapConfig {
+ public sealed class TWMapConfig : RoundsGameMapConfig {
[ConfigBool("grace-period", null, true)]
public bool GracePeriod = true;
@@ -75,22 +75,18 @@ namespace MCGalaxy.Games {
[ConfigVec3("blue-spawn", null)] public Vec3U16 BlueSpawn;
const string propsDir = "properties/tntwars/";
- static string Path(string map) { return propsDir + map + ".properties"; }
- static ConfigElement[] cfg;
-
- public void Load(string map) {
+ static ConfigElement[] cfg;
+ public override void Load(string map) {
if (cfg == null) cfg = ConfigElement.GetAll(typeof(TWMapConfig));
- ConfigElement.ParseFile(cfg, Path(map), this);
+ LoadFrom(cfg, propsDir, map);
}
- public void Save(string map) {
- if (!Directory.Exists(propsDir)) Directory.CreateDirectory(propsDir);
-
+ public override void Save(string map) {
if (cfg == null) cfg = ConfigElement.GetAll(typeof(TWMapConfig));
- ConfigElement.SerialiseSimple(cfg, Path(map), this);
+ SaveTo(cfg, propsDir, map);
}
- public void SetDefaults(Level lvl) {
+ public override void SetDefaults(Level lvl) {
ushort midX = (ushort)(lvl.Width / 2);
ushort midY = (ushort)(lvl.Height / 2 + 1);
ushort maxZ = (ushort)(lvl.Length - 1);