diff --git a/MCGalaxy/Commands/CommandParser.cs b/MCGalaxy/Commands/CommandParser.cs
index 958ef84a7..a83a0b29a 100644
--- a/MCGalaxy/Commands/CommandParser.cs
+++ b/MCGalaxy/Commands/CommandParser.cs
@@ -43,12 +43,13 @@ namespace MCGalaxy.Commands {
ref TEnum result) where TEnum : struct {
try {
result = (TEnum)Enum.Parse(typeof(TEnum), input, true);
- return true;
- } catch (Exception) {
- string[] names = Enum.GetNames(typeof(TEnum));
- Player.Message(p, argName + " must be one of the following: " + names.Join());
- return false;
+ if (Enum.IsDefined(typeof(TEnum), result)) return true;
+ } catch {
}
+
+ string[] names = Enum.GetNames(typeof(TEnum));
+ Player.Message(p, argName + " must be one of the following: " + names.Join());
+ return false;
}
/// Attempts to parse the given argument as an timespan in short form.
diff --git a/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs b/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs
index 835a932ac..7c67520d0 100644
--- a/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs
+++ b/MCGalaxy/Commands/Fun/CTF/CmdCtf.cs
@@ -16,11 +16,13 @@
permissions and limitations under the Licenses.
*/
using System;
+using System.IO;
using MCGalaxy.Games;
namespace MCGalaxy.Commands.Fun {
public sealed class CmdCTF : Command {
public override string name { get { return "ctf"; } }
+ public override string shortcut { get { return "ctfsetup"; } }
public override string type { get { return CommandTypes.Games; } }
public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
@@ -35,17 +37,44 @@ namespace MCGalaxy.Commands.Fun {
if (!Server.ctf.Start(p)) return;
Chat.MessageGlobal("A CTF GAME IS STARTING AT CTF! TYPE /goto CTF to join!");
- } else if (message == "stop") {
+ } else if (message.CaselessEq("stop")) {
if (Server.ctf == null || !Server.ctf.started) {
Player.Message(p, "No CTF game is active."); return;
}
Server.ctf.Stop();
+ } else if (message.CaselessEq("bluespawn")) {
+ CTFConfig cfg = Retrieve(p);
+ cfg.BlueSpawnX = p.Pos.X; cfg.BlueSpawnY = p.Pos.Y; cfg.BlueSpawnZ = p.Pos.Z;
+
+ Update(p, cfg);
+ Player.Message(p, "Set spawn of blue team to your position.");
+ } else if (message.CaselessEq("redspawn")) {
+ CTFConfig cfg = Retrieve(p);
+ cfg.RedSpawnX = p.Pos.X; cfg.RedSpawnY = p.Pos.Y; cfg.RedSpawnZ = p.Pos.Z;
+
+ Update(p, cfg);
+ Player.Message(p, "Set spawn of red team to your position.");
}
}
+ static CTFConfig Retrieve(Player p) {
+ CTFConfig cfg = new CTFConfig();
+ cfg.SetDefaults(p.level);
+ cfg.Retrieve(p.level.name);
+ return cfg;
+ }
+
+ static void Update(Player p, CTFConfig cfg) {
+ if (!Directory.Exists("CTF")) Directory.CreateDirectory("CTF");
+ cfg.Save(p.level.name);
+ if (Server.ctf != null && p.level == Server.ctf.map) Server.ctf.UpdateConfig();
+ }
+
public override void Help(Player p) {
Player.Message(p, "%T/ctf start/stop");
- Player.Message(p, "%HStarts/Stops the CTF game.");
+ Player.Message(p, "%HStarts/stops the CTF game.");
+ Player.Message(p, "%T/ctf redspawn/bluespawn");
+ Player.Message(p, "%HSets spawn of red/blue team to your position.");
}
}
}
diff --git a/MCGalaxy/Config/ConfigElement.cs b/MCGalaxy/Config/ConfigElement.cs
index 9e090798e..c6992c32a 100644
--- a/MCGalaxy/Config/ConfigElement.cs
+++ b/MCGalaxy/Config/ConfigElement.cs
@@ -58,6 +58,7 @@ namespace MCGalaxy {
return false;
}
+ /// Writes all config elements to the given stream, grouped by named sections.
public static void Serialise(ConfigElement[] elements, string suffix,
StreamWriter dst, object instance) {
Dictionary> sections
@@ -81,5 +82,13 @@ namespace MCGalaxy {
dst.WriteLine();
}
}
+
+ /// Writes all config elements to the given stream.
+ public static void SerialisePlain(ConfigElement[] elements, StreamWriter dst, object instance) {
+ foreach (ConfigElement elem in elements) {
+ object value = elem.Field.GetValue(instance);
+ dst.WriteLine(elem.Attrib.Name + " = " + elem.Attrib.Serialise(value));
+ }
+ }
}
}
diff --git a/MCGalaxy/Games/CTF/CtfConfig.cs b/MCGalaxy/Games/CTF/CtfConfig.cs
index 062ec2dd3..4b01b8820 100644
--- a/MCGalaxy/Games/CTF/CtfConfig.cs
+++ b/MCGalaxy/Games/CTF/CtfConfig.cs
@@ -16,14 +16,15 @@
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
-*/
+ */
using System;
+using System.IO;
using MCGalaxy.Config;
namespace MCGalaxy.Games {
public sealed class CTFConfig {
-
+
[ConfigInt("base.red.x", null, 0)]
public int RedFlagX;
[ConfigInt("base.red.y", null, 0)]
@@ -32,7 +33,7 @@ namespace MCGalaxy.Games {
public int RedFlagZ;
[ConfigByte("base.red.block", null, 0)]
public byte RedFlagBlock;
-
+
[ConfigInt("base.blue.x", null, 0)]
public int BlueFlagX;
[ConfigInt("base.blue.y", null, 0)]
@@ -48,7 +49,7 @@ namespace MCGalaxy.Games {
public int RedSpawnY;
[ConfigInt("base.red.spawnz", null, 0)]
public int RedSpawnZ;
-
+
[ConfigInt("base.blue.spawnx", null, 0)]
public int BlueSpawnX;
[ConfigInt("base.blue.spawny", null, 0)]
@@ -57,7 +58,7 @@ namespace MCGalaxy.Games {
public int BlueSpawnZ;
[ConfigInt("map.line.z", null, 0)]
- public int ZDivider;
+ public int ZDivider;
[ConfigInt("game.maxpoints", null, 0)]
public int MaxPoints;
[ConfigInt("game.tag.points-gain", null, 0)]
@@ -69,13 +70,15 @@ namespace MCGalaxy.Games {
[ConfigInt("game.capture.points-lose", null, 0)]
public int Capture_PointsLost;
+
+ /// Sets the default CTF config values for the given map.
public void SetDefaults(Level map) {
ZDivider = map.Length / 2;
RedFlagBlock = Block.red;
- BlueFlagBlock = Block.blue;
+ BlueFlagBlock = Block.blue;
int midX = map.Width / 2, maxZ = map.Length - 1;
- RedFlagX = midX; RedSpawnX = midX * 32;
+ RedFlagX = midX; RedSpawnX = midX * 32;
RedFlagY = 6; RedSpawnY = 4 * 32 + Entities.CharacterHeight;
RedFlagZ = 0; RedSpawnZ = 0 * 32;
@@ -89,5 +92,24 @@ namespace MCGalaxy.Games {
Capture_PointsGained = 10;
Capture_PointsLost = 10;
}
+
+
+ static ConfigElement[] elems;
+ public void Retrieve(string mapName) {
+ if (elems == null) elems = ConfigElement.GetAll(typeof(CTFConfig));
+ PropertiesFile.Read("CTF/" + mapName + ".config", LineProcessor);
+ }
+
+ public void Save(string mapName) {
+ using (StreamWriter w = new StreamWriter("CTF/" + mapName + ".config")) {
+ ConfigElement.SerialisePlain(elems, w, this);
+ }
+ }
+
+ void LineProcessor(string key, string value) {
+ if (!ConfigElement.Parse(elems, key, value, this)) {
+ Logger.Log(LogType.Warning, "\"{0}\" was not a recognised CTF config key.", key);
+ }
+ }
}
}
diff --git a/MCGalaxy/Games/CTF/CtfGame.cs b/MCGalaxy/Games/CTF/CtfGame.cs
index ae71981bf..2905186e7 100644
--- a/MCGalaxy/Games/CTF/CtfGame.cs
+++ b/MCGalaxy/Games/CTF/CtfGame.cs
@@ -48,12 +48,11 @@ namespace MCGalaxy.Games {
CtfTeam2 red;
CtfTeam2 blue;
- Level map;
+ public Level map;
List maps = new List();
List cache = new List();
public CTFConfig Config = new CTFConfig();
- ConfigElement[] ctfConfigElems;
/// Create a new CTF object
public CTFGame() {
@@ -95,15 +94,12 @@ namespace MCGalaxy.Games {
File.Copy("CTF/maps/" + mapName + ".lvl", "levels/ctf.lvl");
CmdLoad.LoadLevel(null, "ctf");
map = LevelInfo.FindExact("ctf");
- LoadMapConfig();
+ UpdateConfig();
}
- void LoadMapConfig() {
- if (ctfConfigElems == null)
- ctfConfigElems = ConfigElement.GetAll(typeof(CTFConfig));
-
+ public void UpdateConfig() {
Config.SetDefaults(map);
- PropertiesFile.Read("CTF/" + map.name + ".config", LineProcessor);
+ Config.Retrieve(map.name);
CTFConfig cfg = Config;
red.FlagBlock = ExtBlock.FromRaw(cfg.RedFlagBlock);
@@ -115,12 +111,6 @@ namespace MCGalaxy.Games {
blue.SpawnPos = new Position(cfg.BlueSpawnX, cfg.BlueSpawnY, cfg.BlueSpawnZ);
}
- void LineProcessor(string key, string value) {
- if (!ConfigElement.Parse(ctfConfigElems, key, value, Config)) {
- Logger.Log(LogType.Warning, "\"{0}\" was not a recognised CTF config key.", key);
- }
- }
-
bool LoadConfig() {
//Load some configs
if (!Directory.Exists("CTF")) Directory.CreateDirectory("CTF");