Initial WIP on countdown rewrite

This commit is contained in:
UnknownShadow200 2018-06-09 15:47:10 +10:00
parent 1cad019a44
commit 6f84ea301c
21 changed files with 295 additions and 423 deletions

View File

@ -116,6 +116,7 @@ namespace MCGalaxy.Gui
this.rank_numDraw = new System.Windows.Forms.NumericUpDown();
this.rank_numUndo = new System.Windows.Forms.NumericUpDown();
this.rank_numGen = new System.Windows.Forms.NumericUpDown();
this.rank_numCopy = new System.Windows.Forms.NumericUpDown();
this.rank_numAfk = new System.Windows.Forms.NumericUpDown();
this.sec_cbLogNotes = new System.Windows.Forms.CheckBox();
this.sec_cbChatAuto = new System.Windows.Forms.CheckBox();
@ -146,6 +147,7 @@ namespace MCGalaxy.Gui
this.blk_list = new System.Windows.Forms.ListBox();
this.pageRanks = new System.Windows.Forms.TabPage();
this.rank_grpLimits = new System.Windows.Forms.GroupBox();
this.rank_lblCopy = new System.Windows.Forms.Label();
this.rank_lblGen = new System.Windows.Forms.Label();
this.rank_lblMaps = new System.Windows.Forms.Label();
this.rank_lblDraw = new System.Windows.Forms.Label();
@ -190,7 +192,6 @@ namespace MCGalaxy.Gui
this.bak_lblLocation = new System.Windows.Forms.Label();
this.bak_txtLocation = new System.Windows.Forms.TextBox();
this.bak_lblTime = new System.Windows.Forms.Label();
this.chkProfanityFilter = new System.Windows.Forms.CheckBox();
this.pageIRC = new System.Windows.Forms.TabPage();
this.gb_ircSettings = new System.Windows.Forms.GroupBox();
this.irc_txtPrefix = new System.Windows.Forms.TextBox();
@ -374,8 +375,7 @@ namespace MCGalaxy.Gui
this.sec_lblBlocksOnMsgs = new System.Windows.Forms.Label();
this.sec_numBlocksSecs = new System.Windows.Forms.NumericUpDown();
this.sec_lblBlocksOnSecs = new System.Windows.Forms.Label();
this.rank_numCopy = new System.Windows.Forms.NumericUpDown();
this.rank_lblCopy = new System.Windows.Forms.Label();
this.chkProfanityFilter = new System.Windows.Forms.CheckBox();
this.pageChat.SuspendLayout();
this.chat_grpTab.SuspendLayout();
this.chat_grpMessages.SuspendLayout();
@ -388,6 +388,7 @@ namespace MCGalaxy.Gui
((System.ComponentModel.ISupportInitialize)(this.rank_numDraw)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numUndo)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numGen)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numCopy)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numAfk)).BeginInit();
this.pageBlocks.SuspendLayout();
this.blk_grpPhysics.SuspendLayout();
@ -460,12 +461,12 @@ namespace MCGalaxy.Gui
this.sec_grpBlocks.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.sec_numBlocksMsgs)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.sec_numBlocksSecs)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numCopy)).BeginInit();
this.SuspendLayout();
//
// pageChat
//
this.pageChat.BackColor = System.Drawing.SystemColors.Control;
this.pageChat.Controls.Add(this.chkProfanityFilter);
this.pageChat.Controls.Add(this.chat_grpTab);
this.pageChat.Controls.Add(this.chat_grpMessages);
this.pageChat.Controls.Add(this.chat_grpOther);
@ -690,7 +691,7 @@ namespace MCGalaxy.Gui
// chat_lblIRC
//
this.chat_lblIRC.AutoSize = true;
this.chat_lblIRC.Location = new System.Drawing.Point(36, 56);
this.chat_lblIRC.Location = new System.Drawing.Point(36, 54);
this.chat_lblIRC.Name = "chat_lblIRC";
this.chat_lblIRC.Size = new System.Drawing.Size(74, 13);
this.chat_lblIRC.TabIndex = 22;
@ -698,7 +699,7 @@ namespace MCGalaxy.Gui
//
// chat_btnIRC
//
this.chat_btnIRC.Location = new System.Drawing.Point(113, 51);
this.chat_btnIRC.Location = new System.Drawing.Point(113, 49);
this.chat_btnIRC.Name = "chat_btnIRC";
this.chat_btnIRC.Size = new System.Drawing.Size(95, 23);
this.chat_btnIRC.TabIndex = 24;
@ -708,7 +709,7 @@ namespace MCGalaxy.Gui
// chat_lblSyntax
//
this.chat_lblSyntax.AutoSize = true;
this.chat_lblSyntax.Location = new System.Drawing.Point(41, 85);
this.chat_lblSyntax.Location = new System.Drawing.Point(41, 83);
this.chat_lblSyntax.Name = "chat_lblSyntax";
this.chat_lblSyntax.Size = new System.Drawing.Size(68, 13);
this.chat_lblSyntax.TabIndex = 31;
@ -716,7 +717,7 @@ namespace MCGalaxy.Gui
//
// chat_btnSyntax
//
this.chat_btnSyntax.Location = new System.Drawing.Point(113, 80);
this.chat_btnSyntax.Location = new System.Drawing.Point(113, 78);
this.chat_btnSyntax.Name = "chat_btnSyntax";
this.chat_btnSyntax.Size = new System.Drawing.Size(95, 23);
this.chat_btnSyntax.TabIndex = 30;
@ -726,7 +727,7 @@ namespace MCGalaxy.Gui
// chat_lblDesc
//
this.chat_lblDesc.AutoSize = true;
this.chat_lblDesc.Location = new System.Drawing.Point(19, 114);
this.chat_lblDesc.Location = new System.Drawing.Point(19, 112);
this.chat_lblDesc.Name = "chat_lblDesc";
this.chat_lblDesc.Size = new System.Drawing.Size(90, 13);
this.chat_lblDesc.TabIndex = 32;
@ -734,7 +735,7 @@ namespace MCGalaxy.Gui
//
// chat_btnDesc
//
this.chat_btnDesc.Location = new System.Drawing.Point(113, 109);
this.chat_btnDesc.Location = new System.Drawing.Point(113, 107);
this.chat_btnDesc.Name = "chat_btnDesc";
this.chat_btnDesc.Size = new System.Drawing.Size(95, 23);
this.chat_btnDesc.TabIndex = 33;
@ -1217,6 +1218,30 @@ namespace MCGalaxy.Gui
this.toolTip.SetToolTip(this.rank_numGen, "Maximum volume of (number of blocks in) a map that players can generate");
this.rank_numGen.ValueChanged += new System.EventHandler(this.rank_numGen_ValueChanged);
//
// rank_numCopy
//
this.rank_numCopy.Location = new System.Drawing.Point(85, 74);
this.rank_numCopy.Maximum = new decimal(new int[] {
255,
0,
0,
0});
this.rank_numCopy.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.rank_numCopy.Name = "rank_numCopy";
this.rank_numCopy.Size = new System.Drawing.Size(81, 21);
this.rank_numCopy.TabIndex = 23;
this.toolTip.SetToolTip(this.rank_numCopy, "Maximum number of copies player can select in /copyslot");
this.rank_numCopy.Value = new decimal(new int[] {
1,
0,
0,
0});
this.rank_numCopy.ValueChanged += new System.EventHandler(this.rank_numCopy_ValueChanged);
//
// rank_numAfk
//
this.rank_numAfk.Location = new System.Drawing.Point(113, 102);
@ -1544,6 +1569,16 @@ namespace MCGalaxy.Gui
this.rank_grpLimits.TabStop = false;
this.rank_grpLimits.Text = "Rank limits";
//
// rank_lblCopy
//
this.rank_lblCopy.AutoSize = true;
this.rank_lblCopy.Location = new System.Drawing.Point(18, 77);
this.rank_lblCopy.Name = "rank_lblCopy";
this.rank_lblCopy.Size = new System.Drawing.Size(61, 13);
this.rank_lblCopy.TabIndex = 22;
this.rank_lblCopy.Text = "/copy slots:";
this.rank_lblCopy.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// rank_lblGen
//
this.rank_lblGen.AutoSize = true;
@ -1765,7 +1800,6 @@ namespace MCGalaxy.Gui
this.pageMisc.Controls.Add(this.grpPhysics);
this.pageMisc.Controls.Add(this.afk_grp);
this.pageMisc.Controls.Add(this.bak_grp);
this.pageMisc.Controls.Add(this.chkProfanityFilter);
this.pageMisc.Font = new System.Drawing.Font("Calibri", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.pageMisc.Location = new System.Drawing.Point(4, 22);
this.pageMisc.Name = "pageMisc";
@ -2014,17 +2048,6 @@ namespace MCGalaxy.Gui
this.bak_lblTime.TabIndex = 7;
this.bak_lblTime.Text = "Backup time:";
//
// chkProfanityFilter
//
this.chkProfanityFilter.Appearance = System.Windows.Forms.Appearance.Button;
this.chkProfanityFilter.AutoSize = true;
this.chkProfanityFilter.Location = new System.Drawing.Point(535, 325);
this.chkProfanityFilter.Name = "chkProfanityFilter";
this.chkProfanityFilter.Size = new System.Drawing.Size(87, 23);
this.chkProfanityFilter.TabIndex = 30;
this.chkProfanityFilter.Text = "Profanity Filter";
this.chkProfanityFilter.UseVisualStyleBackColor = true;
//
// pageIRC
//
this.pageIRC.BackColor = System.Drawing.SystemColors.Control;
@ -4123,34 +4146,15 @@ namespace MCGalaxy.Gui
this.sec_lblBlocksOnSecs.TabIndex = 33;
this.sec_lblBlocksOnSecs.Text = "secs";
//
// rank_numCopy
// chkProfanityFilter
//
this.rank_numCopy.Location = new System.Drawing.Point(85, 74);
this.rank_numCopy.Maximum = new decimal(new int[] {
255,
0,
0,
0});
this.rank_numCopy.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.rank_numCopy.Name = "rank_numCopy";
this.rank_numCopy.Size = new System.Drawing.Size(81, 21);
this.rank_numCopy.TabIndex = 23;
this.toolTip.SetToolTip(this.rank_numCopy, "Maximum number of copies player can select in /copyslot");
this.rank_numCopy.ValueChanged += new System.EventHandler(this.rank_numCopy_ValueChanged);
//
// rank_lblCopy
//
this.rank_lblCopy.AutoSize = true;
this.rank_lblCopy.Location = new System.Drawing.Point(18, 77);
this.rank_lblCopy.Name = "rank_lblCopy";
this.rank_lblCopy.Size = new System.Drawing.Size(61, 13);
this.rank_lblCopy.TabIndex = 22;
this.rank_lblCopy.Text = "/copy slots:";
this.rank_lblCopy.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.chkProfanityFilter.AutoSize = true;
this.chkProfanityFilter.Location = new System.Drawing.Point(80, 380);
this.chkProfanityFilter.Name = "chkProfanityFilter";
this.chkProfanityFilter.Size = new System.Drawing.Size(96, 17);
this.chkProfanityFilter.TabIndex = 31;
this.chkProfanityFilter.Text = "Profanity Filter";
this.chkProfanityFilter.UseVisualStyleBackColor = true;
//
// PropertyWindow
//
@ -4171,6 +4175,7 @@ namespace MCGalaxy.Gui
this.Load += new System.EventHandler(this.PropertyWindow_Load);
this.Disposed += new System.EventHandler(this.PropertyWindow_Unload);
this.pageChat.ResumeLayout(false);
this.pageChat.PerformLayout();
this.chat_grpTab.ResumeLayout(false);
this.chat_grpTab.PerformLayout();
this.chat_grpMessages.ResumeLayout(false);
@ -4186,6 +4191,7 @@ namespace MCGalaxy.Gui
((System.ComponentModel.ISupportInitialize)(this.rank_numDraw)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numUndo)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numGen)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numCopy)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numAfk)).EndInit();
this.pageBlocks.ResumeLayout(false);
this.blk_grpPhysics.ResumeLayout(false);
@ -4290,7 +4296,6 @@ namespace MCGalaxy.Gui
this.sec_grpBlocks.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.sec_numBlocksMsgs)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.sec_numBlocksSecs)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.rank_numCopy)).EndInit();
this.ResumeLayout(false);
}
private System.Windows.Forms.Label rank_lblCopy;

View File

@ -25,7 +25,7 @@ namespace MCGalaxy.Blocks.Physics {
public static void PhysWater(Level lvl, ushort x, ushort y, ushort z, BlockID type) {
int index;
BlockID block = lvl.GetBlock(x, y, z, out index);
if (Server.lava.running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
if (Server.lava.Running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
return;
switch (block) {
@ -62,7 +62,7 @@ namespace MCGalaxy.Blocks.Physics {
public static void PhysLava(Level lvl, ushort x, ushort y, ushort z, BlockID type) {
int index;
BlockID block = lvl.GetBlock(x, y, z, out index);
if (Server.lava.running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
if (Server.lava.Running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
return;
switch (block) {

View File

@ -149,7 +149,7 @@ namespace MCGalaxy.Blocks.Physics {
static bool WaterBlocked(Level lvl, ushort x, ushort y, ushort z) {
BlockID block = lvl.GetBlock(x, y, z);
if (Server.lava.running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
if (Server.lava.Running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
return true;
switch (block) {
@ -261,7 +261,7 @@ namespace MCGalaxy.Blocks.Physics {
static bool LavaBlocked(Level lvl, ushort x, ushort y, ushort z) {
BlockID block = lvl.GetBlock(x, y, z);
if (Server.lava.running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
if (Server.lava.Running && Server.lava.Map == lvl && Server.lava.InSafeZone(x, y, z))
return true;
switch (block) {

View File

@ -26,125 +26,22 @@ using MCGalaxy.Generator;
namespace MCGalaxy.Commands.Fun {
public sealed class CmdCountdown : Command {
public sealed class CmdCountdown : RoundsGameCmd {
public override string name { get { return "CountDown"; } }
public override string shortcut { get { return "CD"; } }
public override string type { get { return CommandTypes.Games; } }
public override bool museumUsable { get { return false; } }
protected override RoundsGame Game { get { return Server.Countdown; } }
public override bool SuperUseable { get { return false; } }
public override CommandPerm[] ExtraPerms {
get { return new[] { new CommandPerm(LevelPermission.Operator, "+ can manage countdown") }; }
}
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
string[] args = message.ToLower().SplitSpaces();
string cmd = args[0], arg1 = "", arg2 = "", arg3 = "";
if (args.Length > 1) arg1 = args[1];
if (args.Length > 2) arg2 = args[2];
if (args.Length > 3) arg3 = args[3];
CountdownGame game = Server.Countdown;
switch (cmd) {
case "join":
HandleJoin(p, game); return;
case "leave":
HandleLeave(p, game); return;
case "players":
HandlePlayers(p, game); return;
case "rules":
HandleRules(p); return;
case "download":
case "generate":
HandleGenerate(p, game, arg1, arg2, arg3); return;
case "enable":
HandleEnable(p, game); return;
case "disable":
case "cancel":
HandleDisable(p, game); return;
case "start":
case "play":
HandleStart(p, game, arg1, arg2); return;
case "end":
HandleEnd(p, game); return;
case "reset":
HandleReset(p, game, arg1); return;
default:
Help(p); break;
}
}
void HandleJoin(Player p, CountdownGame game) {
switch (game.Status) {
case CountdownGameStatus.Disabled:
Player.Message(p, "Cannot join as countdown is not running.");
return;
case CountdownGameStatus.Enabled:
game.PlayerJoinedGame(p);
return;
case CountdownGameStatus.RoundCountdown:
Player.Message(p, "Cannot join when a round is about to start. Wait until next round.");
return;
case CountdownGameStatus.RoundInProgress:
Player.Message(p, "Cannot join when a round is in progress. Wait until next round.");
return;
}
}
void HandleLeave(Player p, CountdownGame game) {
if (!game.Players.Contains(p)) {
Player.Message(p, "Cannot leave as you did not join countdown to begin with.");
return;
}
switch (game.Status) {
case CountdownGameStatus.Disabled:
Player.Message(p, "Cannot leave as countdown is not running.");
return;
case CountdownGameStatus.Enabled:
game.PlayerLeftGame(p);
return;
case CountdownGameStatus.RoundCountdown:
Player.Message(p, "Cannot leave when a round is about to start.");
return;
case CountdownGameStatus.RoundInProgress:
if (game.Remaining.Contains(p)) {
Player.Message(p, "Cannot leave when a round in progress - please wait until the round ends or you die.");
} else {
game.PlayerLeftGame(p);
}
return;
}
}
void HandlePlayers(Player p, CountdownGame game) {
Player[] players = game.Players.Items;
switch (game.Status) {
case CountdownGameStatus.Disabled:
Player.Message(p, "Countdown is not running.");
break;
case CountdownGameStatus.RoundInProgress:
Player.Message(p, "Players in countdown:");
Player.Message(p, players.Join(pl => FormatPlayer(pl, game)));
break;
default:
Player.Message(p, "Players in countdown: ");
Player.Message(p, players.Join(pl => pl.ColoredName));
break;
}
}
static string FormatPlayer(Player pl, CountdownGame game) {
if (game.Remaining.Contains(pl)) {
return pl.ColoredName + " &a[IN]";
if (message.CaselessEq("rules")) {
HandleRules(p);
} else if (message.CaselessEq("join")) {
HandleJoin(p, Server.Countdown);
} else {
return pl.ColoredName + " &c[OUT]";
base.Use(p, message);
}
}
@ -155,115 +52,78 @@ namespace MCGalaxy.Commands.Fun {
Player.Message(p, "The last person alive wins!");
}
void HandleGenerate(Player p, CountdownGame game, string x, string y, string z) {
if (!CheckExtraPerm(p, 1)) return;
int width, height, length;
if(!int.TryParse(x, out width) || !int.TryParse(y, out height) || !int.TryParse(z, out length)) {
width = 32; height = 32; length = 32;
}
if (width < 32 || !MapGen.OkayAxis(width)) width = 32;
if (height < 32 || !MapGen.OkayAxis(height)) height = 32;
if (length < 32 || !MapGen.OkayAxis(length)) length = 32;
if (!CmdNewLvl.CheckMapVolume(p, width, height, length)) return;
game.GenerateMap(p, width, height, length);
}
void HandleEnable(Player p, CountdownGame game) {
if (!CheckExtraPerm(p, 1)) return;
if (game.Status == CountdownGameStatus.Disabled) {
game.Enable(p);
void HandleJoin(Player p, CountdownGame game) {
if (!game.Running) {
Player.Message(p, "Cannot join as countdown is not running.");
} else if (game.RoundInProgress) {
Player.Message(p, "Cannot join when a round is in progress. Wait until next round.");
} else {
Player.Message(p, "Countdown has already been enabled.");
game.PlayerJoinedGame(p);
}
}
void HandleDisable(Player p, CountdownGame game) {
if (!CheckExtraPerm(p, 1)) return;
if (game.Status == CountdownGameStatus.Disabled) {
Player.Message(p, "Countdown is not running."); return;
}
game.End();
protected override void HandleStatus(Player p, RoundsGame game) {
game.OutputStatus(p);
}
static string FormatPlayer(Player pl, CountdownGame game) {
string suffix = game.Remaining.Contains(pl) ? " &a[IN]" : " &c[OUT]";
return pl.ColoredName + suffix;
}
void HandleStart(Player p, CountdownGame game, string speed, string mode) {
protected override void HandleSet(Player p, RoundsGame game_, string[] args) {
if (!CheckExtraPerm(p, 1)) return;
if (args.Length < 4) { Help(p); return; }
switch (game.Status) {
case CountdownGameStatus.Disabled:
Player.Message(p, "Countdown is not running."); return;
case CountdownGameStatus.RoundCountdown:
Player.Message(p, "A round is already about to begin."); return;
case CountdownGameStatus.RoundInProgress:
Player.Message(p, "A round is already in progress."); return;
case CountdownGameStatus.Enabled:
if (game.Players.Count < 2) {
Player.Message(p, "At least two players must join countdown before a round can begin."); return;
}
break;
if (game_.Running) {
Player.Message(p, "You must stop Countdown before replacing the map."); return;
}
ushort x = 0, y = 0, z = 0;
if (!CmdNewLvl.CheckMapAxis(p, args[1], "Width", ref x)) return;
if (!CmdNewLvl.CheckMapAxis(p, args[2], "Height", ref y)) return;
if (!CmdNewLvl.CheckMapAxis(p, args[3], "Length", ref z)) return;
if (!CmdNewLvl.CheckMapVolume(p, x, y, z)) return;
CountdownGame game = (CountdownGame)game_;
game.GenerateMap(p, x, y, z);
}
protected override void HandleStart(Player p, RoundsGame game_, string[] args) {
if (!CheckExtraPerm(p, 1)) return;
if (game_.Running) { Player.Message(p, "{0} is already running", game_.GameName); return; }
CountdownGame game = (CountdownGame)game_;
string speed = args.Length > 1 ? args[1] : "";
string mode = args.Length > 2 ? args[2] : "";
switch (speed) {
case "slow": game.Interval = 800; break;
case "normal": game.Interval = 650; break;
case "fast": game.Interval = 500; break;
case "extreme": game.Interval = 300; break;
case "slow": game.Interval = 800; break;
case "normal": game.Interval = 650; break;
case "fast": game.Interval = 500; break;
case "extreme": game.Interval = 300; break;
case "ultimate": game.Interval = 150; break;
default:
Player.Message(p, "No speed specified, playing at 'normal' speed.");
game.Interval = 650; speed = "normal"; break;
}
game.FreezeMode = mode == "freeze" || mode == "frozen";
game.SpeedType = speed;
game.BeginRound();
}
void HandleEnd(Player p, CountdownGame game) {
if (!CheckExtraPerm(p, 1)) return;
switch (game.Status) {
case CountdownGameStatus.Disabled:
Player.Message(p, "Countdown is not running."); break;
case CountdownGameStatus.Enabled:
Player.Message(p, "No round is currently running."); break;
default:
game.EndRound(); break;
}
}
void HandleReset(Player p, CountdownGame game, string type) {
if (!CheckExtraPerm(p, 1)) return;
switch (game.Status) {
case CountdownGameStatus.Disabled:
Player.Message(p, "Countdown is not running."); break;
case CountdownGameStatus.RoundCountdown:
Player.Message(p, "Cannot reset map as a round is about to begin."); break;
case CountdownGameStatus.RoundInProgress:
Player.Message(p, "Cannot reset map as a round is already in progress."); break;
default:
Player.Message(p, "Resetting");
game.ResetMap(); break;
}
}
game.SpeedType = speed;
game.Start(p, "countdown", int.MaxValue);
}
public override void Help(Player p) {
Player.Message(p, "%T/CD generate [width] [height] [length] %H- generates the countdown map (default is 32x32x32)");
Player.Message(p, "%T/CD enable/disable %H- enables/disables countdown");
Player.Message(p, "%T/CD start <speed> <mode> %H- starts a round of countdown");
Player.Message(p, "%T/CD set [width] [height] [length]");
Player.Message(p, "%HRe-generates the countdown map at given size (default is 32x32x32)");
Player.Message(p, "%T/CD start <speed> <mode> %H- starts countdown");
Player.Message(p, "%H speed can be: slow, normal, fast, extreme or ultimate");
Player.Message(p, "%H mode can be: normal or freeze");
Player.Message(p, "%T/CD stop %H- stops countdown");
Player.Message(p, "%T/CD end %H- force ends current round of countdown");
Player.Message(p, "%T/CD reset %H- resets the map. %T/CD start %Halso resets map.");
Player.Message(p, "%T/CD join/leave %H- joins/leaves the game");
Player.Message(p, "%T/CD players %H- lists players currently playing");
Player.Message(p, "%T/CD join %H- joins the game");
Player.Message(p, "%T/CD status %H- lists players currently playing");
Player.Message(p, "%T/CD rules %H- view the rules of countdown");
}
}

View File

@ -33,9 +33,7 @@ namespace MCGalaxy.Commands.Fun {
protected override void HandleStatus(Player p, RoundsGame game) {
if (!game.Running) { Player.Message(p, "Lava survival is not running"); return; }
if (!game.RoundInProgress) { Player.Message(p, "The round of Lava Survival hasn't started yet."); return; }
LSGame ls = (LSGame)game;
ls.MessageRoundStatus(p);
game.OutputStatus(p);
}
protected override void HandleSet(Player p, RoundsGame game, string[] args) {

View File

@ -53,7 +53,7 @@ namespace MCGalaxy.Commands.Fun {
}
}
protected void HandleStart(Player p, RoundsGame game, string[] args) {
protected virtual void HandleStart(Player p, RoundsGame game, string[] args) {
if (!CheckExtraPerm(p, 1)) return;
if (game.Running) { Player.Message(p, "{0} is already running", game.GameName); return; }

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Commands.Fun {
case int.MaxValue:
Player.Message(p, "Zombie Survival running with infinite rounds"); break;
case 0:
Player.Message(p, "Zombie Survival running, with this round being the final round"); break;
Player.Message(p, "Zombie Survival running, with this round being the last round"); break;
default:
Player.Message(p, "Zombie Survival running, with " + (game.RoundsLeft + 1) + " rounds left"); break;
}

View File

@ -46,7 +46,7 @@ namespace MCGalaxy.Commands.World {
ushort x = 0, y = 0, z = 0;
if (!CmdNewLvl.CheckMapAxis(p, args[1], "Width", ref x)) return false;
if (!CmdNewLvl.CheckMapAxis(p, args[2], "Height", ref y)) return false;
if (!CmdNewLvl.CheckMapAxis(p, args[3], "Length", ref z)) return false;
if (!CmdNewLvl.CheckMapAxis(p, args[3], "Length", ref z)) return false;
if (!CmdNewLvl.CheckMapVolume(p, x, y, z)) return true;
bool confirmed = args.Length > 4 && args[4].CaselessEq("confirm");

View File

@ -28,18 +28,18 @@ namespace MCGalaxy.Games {
public sealed partial class CTFGame : RoundsGame {
protected override void DoRound() {
if (!running) return;
if (!Running) return;
RoundInProgress = true;
while (Blue.Points < Config.RoundPoints && Red.Points < Config.RoundPoints) {
if (!running) return;
while (Blue.Captures < Config.RoundPoints && Red.Captures < Config.RoundPoints) {
if (!Running) return;
if (!RoundInProgress) break;
Tick();
Thread.Sleep(300);
}
if (running) EndRound();
if (running) VoteAndMoveToNextMap();
if (Running) EndRound();
if (Running) VoteAndMoveToNextMap();
}
void Tick() {
@ -101,16 +101,16 @@ namespace MCGalaxy.Games {
if (!RoundInProgress) return;
RoundInProgress = false;
if (Blue.Points > Red.Points) {
if (Blue.Captures > Red.Captures) {
Map.Message(Blue.ColoredName + " %Swon this round of CTF!");
} else if (Red.Points > Blue.Points) {
} else if (Red.Captures > Blue.Captures) {
Map.Message(Red.ColoredName + " %Swon this round of CTF!");
} else {
Map.Message("The round ended in a tie!");
}
Blue.Points = 0;
Red.Points = 0;
Blue.Captures = 0;
Red.Captures = 0;
ResetFlagsState();
Thread.Sleep(4000);
@ -156,7 +156,7 @@ namespace MCGalaxy.Games {
data.Points += Config.Capture_PointsGained;
data.Captures++;
team.Points++;
team.Captures++;
CtfTeam opposing = Opposing(team);
opposing.RespawnFlag(Map);

View File

@ -36,7 +36,7 @@ namespace MCGalaxy.Games {
public sealed class CtfTeam {
public string Name, Color;
public string ColoredName { get { return Color + Name; } }
public int Points;
public int Captures;
public Vec3U16 FlagPos;
public Position SpawnPos;
public BlockID FlagBlock;
@ -52,8 +52,6 @@ namespace MCGalaxy.Games {
}
public sealed partial class CTFGame : RoundsGame {
bool running = false;
public override bool Running { get { return running; } }
public override string GameName { get { return "CTF"; } }
public CtfTeam Red = new CtfTeam("Red", Colors.red);
@ -105,6 +103,11 @@ namespace MCGalaxy.Games {
playing.AddRange(Blue.Members.Items);
return playing;
}
public override void OutputStatus(Player p) {
Player.Message(p, "{0} %Steam: {1} captures", Blue.ColoredName, Blue.Captures);
Player.Message(p, "{0} %Steam: {1} captures", Red.ColoredName, Red.Captures);
}
public override void Start(Player p, string map, int rounds) {
map = GetStartMap(map);
@ -122,7 +125,7 @@ namespace MCGalaxy.Games {
Logger.Log(LogType.GameActivity, "[CTF] Running...");
Chat.MessageGlobal("A CTF game is starting! Type %T/CTF go %Sto join!");
running = true;
Running = true;
Database.Backend.CreateTable("CTF", createSyntax);
HookEventHandlers();
@ -132,8 +135,8 @@ namespace MCGalaxy.Games {
}
public override void End() {
if (!running) return;
running = false;
if (!Running) return;
Running = false;
UnhookEventHandlers();
ResetTeams();
@ -144,8 +147,8 @@ namespace MCGalaxy.Games {
void ResetTeams() {
Blue.Members.Clear();
Red.Members.Clear();
Blue.Points = 0;
Red.Points = 0;
Blue.Captures = 0;
Red.Captures = 0;
}
void ResetFlagsState() {

View File

@ -21,13 +21,14 @@ using MCGalaxy.Events.PlayerEvents;
namespace MCGalaxy.Games {
public sealed partial class CountdownGame : IGame {
public sealed partial class CountdownGame : RoundsGame {
void HookEventHandlers() {
OnPlayerMoveEvent.Register(HandlePlayerMove, Priority.High);
OnPlayerDisconnectEvent.Register(HandlePlayerDisconnect, Priority.High);
OnLevelUnloadEvent.Register(HandleLevelUnload, Priority.High);
OnPlayerSpawningEvent.Register(HandlePlayerSpawning, Priority.High);
OnJoinedLevelEvent.Register(HandleOnJoinedLevel, Priority.High);
}
void UnhookEventHandlers() {
@ -35,11 +36,12 @@ namespace MCGalaxy.Games {
OnPlayerDisconnectEvent.Unregister(HandlePlayerDisconnect);
OnLevelUnloadEvent.Unregister(HandleLevelUnload);
OnPlayerSpawningEvent.Unregister(HandlePlayerSpawning);
OnJoinedLevelEvent.Unregister(HandleOnJoinedLevel);
}
void HandlePlayerMove(Player p, Position next, byte yaw, byte pitch) {
if (Status != CountdownGameStatus.RoundInProgress || !FreezeMode) return;
if (!RoundInProgress || !FreezeMode) return;
if (!Remaining.Contains(p)) return;
int freezeX = p.Extras.GetInt("MCG_CD_X");
@ -64,16 +66,15 @@ namespace MCGalaxy.Games {
Players.Remove(p);
}
void HandleLevelUnload(Level lvl) {
if (Status == CountdownGameStatus.Disabled || lvl != Map) return;
End();
}
void HandlePlayerSpawning(Player p, ref Position pos, ref byte yaw, ref byte pitch, bool respawning) {
if (!respawning || !Remaining.Contains(p)) return;
Map.Message(p.ColoredName + " %Sis out of countdown!");
Remaining.Remove(p);
UpdatePlayersLeft();
}
void HandleOnJoinedLevel(Player p, Level prevLevel, Level level, ref bool announce) {
if (prevLevel == Map && level != Map) { PlayerLeftGame(p); }
}
}
}

View File

@ -27,16 +27,24 @@ using BlockID = System.UInt16;
namespace MCGalaxy.Games {
public sealed partial class CountdownGame : IGame {
public sealed partial class CountdownGame : RoundsGame {
List<SquarePos> squaresLeft = new List<SquarePos>();
BufferedBlockSender bulk = new BufferedBlockSender();
public void BeginRound() {
Status = CountdownGameStatus.RoundCountdown;
protected override void DoRound() {
BeginRound();
if (FreezeMode) { SetupFreezeMode(); }
CloseOffBoard();
RoundInProgress = true;
RemoveSquares();
}
void BeginRound() {
ResetMap();
SetGlassTube(Block.Glass, Block.Glass);
Map.Message("Countdown is about to start!");
if (Status != CountdownGameStatus.RoundCountdown) return;
if (!Running) return;
int midX = Map.Width / 2, midY = Map.Height / 2, midZ = Map.Length / 2;
Position spawnPos = Position.FromFeetBlockCoords(midX, Map.Height - 2, midZ);
@ -55,28 +63,26 @@ namespace MCGalaxy.Games {
SpawnPlayers(spawnPos);
Map.Message("-----&b5%S-----");
if (Status != CountdownGameStatus.RoundCountdown) return;
if (!Running) return;
Cuboid(midX - 1, midY, midZ - 1, midX, midY, midZ, Block.Air);
bulk.Send(true);
Thread.Sleep(1000);
if (Status != CountdownGameStatus.RoundCountdown) return;
if (!Running) return;
Map.Message("-----&b4%S-----"); Thread.Sleep(1000);
Map.Message("-----&b3%S-----"); Thread.Sleep(1000);
Cuboid(midX, Map.Height - 5, midZ, midX + 1, Map.Height - 5, midZ + 1, Block.Air);
bulk.Send(true);
if (Status != CountdownGameStatus.RoundCountdown) return;
if (!Running) return;
Map.Message("-----&b2%S-----"); Thread.Sleep(1000);
Map.Message("-----&b1%S-----"); Thread.Sleep(1000);
Map.Message("GO!!!!!!!");
if (Status != CountdownGameStatus.RoundCountdown) return;
if (!Running) return;
Player[] players = Players.Items;
Remaining.Clear();
foreach (Player pl in players) { Remaining.Add(pl); }
DoRound();
}
void SpawnPlayers(Position pos) {
@ -92,68 +98,26 @@ namespace MCGalaxy.Games {
pl.SendPos(Entities.SelfID, pos, pl.Rot);
}
}
void DoRound() {
if (FreezeMode) {
MessageFreezeCountdown();
Map.Message("&bPlayers Frozen");
Player[] players = Players.Items;
foreach (Player pl in players) {
Position pos = pl.Pos;
pl.Extras.PutInt("MCG_CD_X", pos.X);
pl.Extras.PutInt("MCG_CD_Z", pos.Z);
}
RemoveAllSquareBorders();
}
CloseOffBoard();
Status = CountdownGameStatus.RoundInProgress;
RemoveSquares();
}
void MessageFreezeCountdown() {
void SetupFreezeMode() {
Thread.Sleep(500);
Map.Message("Welcome to Freeze Mode of countdown");
Map.Message("You have 15 seconds to stand on a square");
if (Status != CountdownGameStatus.RoundCountdown) return;
Map.Message("You won't be able to move from that square once the game starts!");
Thread.Sleep(500);
Map.Message("-----&b15%S-----"); Thread.Sleep(500);
Map.Message("Once the countdown is up, you are stuck on your square");
if (Status != CountdownGameStatus.RoundCountdown) return;
if (!Running) return;
DoCountdown("&b{0} %Sseconds left", 15, 15);
if (!Running) return;
Thread.Sleep(500);
Map.Message("-----&b14%S-----"); Thread.Sleep(500);
Map.Message("The squares then start to disappear");
if (Status != CountdownGameStatus.RoundCountdown) return;
Map.Message("&bPlayers Frozen");
Thread.Sleep(500);
Map.Message("-----&b13%S-----"); Thread.Sleep(500);
Map.Message("Whoever is last out wins!");
if (Status != CountdownGameStatus.RoundCountdown) return;
Thread.Sleep(500);
Map.Message("-----&b12%S-----"); Thread.Sleep(1000);
Map.Message("-----&b11%S-----"); Thread.Sleep(1000);
Map.Message("-----&b10%S-----");
Map.Message("Only 10 Seconds left to pick your places!");
if (Status != CountdownGameStatus.RoundCountdown) return;
Thread.Sleep(1000);
Map.Message("-----&b9%S-----"); Thread.Sleep(1000);
Map.Message("-----&b8%S-----"); Thread.Sleep(1000);
Map.Message("-----&b7%S-----"); Thread.Sleep(1000);
Map.Message("-----&b6%S-----"); Thread.Sleep(1000);
Map.Message("-----&b5%S-----");
Map.Message("5 Seconds left to pick your places!");
if (Status != CountdownGameStatus.RoundCountdown) return;
Thread.Sleep(1000);
Map.Message("-----&b4%S-----"); Thread.Sleep(1000);
Map.Message("-----&b3%S-----"); Thread.Sleep(1000);
Map.Message("-----&b2%S-----"); Thread.Sleep(1000);
Map.Message("-----&b1%S-----"); Thread.Sleep(1000);
Player[] players = Players.Items;
foreach (Player pl in players) {
Position pos = pl.Pos;
pl.Extras.PutInt("MCG_CD_X", pos.X);
pl.Extras.PutInt("MCG_CD_Z", pos.Z);
}
RemoveAllSquareBorders();
}
void CloseOffBoard() {
@ -166,8 +130,7 @@ namespace MCGalaxy.Games {
Cuboid(4, 4, 4, 4, 4, maxZ - 4, Block.Air);
Cuboid(maxX - 4, 4, 4, maxX - 4, 4, maxZ - 4, Block.Air);
bulk.Send(true);
}
}
void RemoveAllSquareBorders() {
int maxX = Map.Width - 1, maxZ = Map.Length - 1;
@ -182,14 +145,14 @@ namespace MCGalaxy.Games {
void RemoveSquares() {
Random rng = new Random();
while (Status == CountdownGameStatus.RoundInProgress && squaresLeft.Count > 0 && Remaining.Count != 0) {
while (RoundInProgress && squaresLeft.Count > 0 && Remaining.Count > 0) {
int i = rng.Next(squaresLeft.Count);
SquarePos nextSquare = squaresLeft[i];
squaresLeft.RemoveAt(i);
RemoveSquare(nextSquare);
if (squaresLeft.Count % 10 == 0) {
if (Status != CountdownGameStatus.RoundInProgress) return;
if (!RoundInProgress) return;
Map.Message(squaresLeft.Count + " squares left and " + Remaining.Count + " players remaining!");
}
}
@ -212,7 +175,7 @@ namespace MCGalaxy.Games {
Cuboid(x1, y, z1, x2, y, z2, Block.Air);
bulk.Send(true);
// Remove glass borders, if neighbouring squares were previously removed
// Remove glass borders, if neighbouring squares were previously removed
bool airMaxX = false, airMinZ = false, airMaxZ = false, airMinX = false;
if (Map.IsAirAt(x1, y, (ushort)(z2 + 2))) {
Map.Blockchange(x1, y, (ushort)(z2 + 1), Block.Air);
@ -251,7 +214,7 @@ namespace MCGalaxy.Games {
}
void UpdatePlayersLeft() {
if (Status != CountdownGameStatus.RoundInProgress) return;
if (!RoundInProgress) return;
Player[] players = Remaining.Items;
switch (players.Length) {
@ -276,7 +239,7 @@ namespace MCGalaxy.Games {
public override void EndRound() { EndRound(null); }
public void EndRound(Player winner) {
squaresLeft.Clear();
Status = CountdownGameStatus.Enabled;
RoundInProgress = false;
Remaining.Clear();
squaresLeft.Clear();
@ -291,6 +254,5 @@ namespace MCGalaxy.Games {
Map.Message("Current round was force ended!");
}
}
}
}

View File

@ -37,44 +37,82 @@ namespace MCGalaxy.Games {
/// <summary> Round is in progress. </summary>
RoundInProgress,
}
class CountdownLevelPicker : LevelPicker {
public override List<string> GetCandidateMaps() { return new List<string>() { "countdown" }; }
}
public sealed partial class CountdownGame : IGame {
public sealed partial class CountdownGame : RoundsGame {
public VolatileArray<Player> Players = new VolatileArray<Player>();
public VolatileArray<Player> Remaining = new VolatileArray<Player>();
public CountdownGameStatus Status = CountdownGameStatus.Disabled;
public override bool Running { get { return Status != CountdownGameStatus.Disabled; } }
public override string GameName { get { return "Countdown"; } }
public bool FreezeMode;
public int Interval;
public string SpeedType;
public void Enable(Player p) {
HookEventHandlers();
CmdLoad.LoadLevel(null, "countdown");
Map = LevelInfo.FindExact("countdown");
if (Map == null) {
public CountdownGame() {
Picker = new CountdownLevelPicker();
}
protected override List<Player> GetPlayers() {
List<Player> playing = new List<Player>();
playing.AddRange(Players.Items);
return playing;
}
public override void OutputStatus(Player p) {
Player[] players = Players.Items;
Player.Message(p, "Players in countdown:");
if (RoundInProgress) {
Player.Message(p, players.Join(pl => FormatPlayer(pl)));
} else {
Player.Message(p, players.Join(pl => pl.ColoredName));
}
Player.Message(p, squaresLeft.Count + " squares left");
}
string FormatPlayer(Player pl) {
string suffix = Remaining.Contains(pl) ? " &a[IN]" : " &c[OUT]";
return pl.ColoredName + suffix;
}
public override void Start(Player p, string map, int rounds) {
map = "countdown";
if (!LevelInfo.MapExists(map)) {
Player.Message(p, "Countdown level not found, generating..");
GenerateMap(p, 32, 32, 32);
Map = LevelInfo.FindExact("countdown");
}
if (!SetMap(map)) {
Player.Message(p, "Failed to load initial map!"); return;
}
bulk.level = Map;
Status = CountdownGameStatus.Enabled;
Chat.MessageGlobal("Countdown has been enabled!");
RoundsLeft = rounds;
Running = true;
HookEventHandlers();
Thread t = new Thread(RunGame);
t.Name = "MCG_CountdownGame";
t.Start();
}
public override void End() {
if (Status == CountdownGameStatus.RoundInProgress) EndRound(null);
Status = CountdownGameStatus.Disabled;
if (!Running) return;
Running = false;
if (RoundInProgress) EndRound(null);
UnhookEventHandlers();
Map.Message("Countdown was disabled.");
Players.Clear();
Remaining.Clear();
squaresLeft.Clear();
EndCommon();
}
public void GenerateMap(Player p, int width, int height, int length) {
@ -90,17 +128,17 @@ namespace MCGalaxy.Games {
Player.Message(p, format, width, height, length);
PlayerActions.ChangeMap(p, "countdown");
Position pos = new Position(16 + 8 * 32, 32 + 23 * 32, 16 + 17 * 32);
Position pos = Position.FromFeetBlockCoords(8, 23, 17);
p.SendPos(Entities.SelfID, pos, p.Rot);
}
public void ResetMap() {
SetGlassTube(Block.Air, Block.Air);
int maxX = Map.Width - 1, maxZ = Map.Length - 1;
Cuboid(4, 4, 4, maxX - 4, 4, maxZ - 4, Block.Glass);
for(int zz = 6; zz < maxZ - 6; zz += 3)
for (int xx = 6; xx < maxX - 6; xx += 3)
for(int zz = 6; zz < Map.Length - 6; zz += 3)
for (int xx = 6; xx < Map.Width - 6; xx += 3)
{
Cuboid(xx, 4, zz, xx + 1, 4, zz + 1, Block.Green);
}

View File

@ -23,7 +23,7 @@ namespace MCGalaxy.Games {
public abstract class IGame {
public Level Map;
public abstract bool Running { get; }
public bool Running;
public abstract string GameName { get; }
public virtual bool TeleportAllowed { get { return true; } }

View File

@ -43,7 +43,7 @@ namespace MCGalaxy.Games {
void HandleOnJoinedLevel(Player p, Level prevLevel, Level level, ref bool announce) {
HandleJoinedCommon(p, prevLevel, level, ref announce);
if (Map != level || !RoundInProgress) return;
MessageRoundStatus(p);
OutputStatus(p);
}
void HandlePlayerConnect(Player p) {

View File

@ -24,7 +24,7 @@ namespace MCGalaxy.Games {
int announceSecs, roundSecs, floodSecs, layerSecs;
protected override void DoRound() {
if (!running) return;
if (!Running) return;
ResetPlayerDeaths();
RoundStart = DateTime.UtcNow;
@ -32,7 +32,7 @@ namespace MCGalaxy.Games {
Logger.Log(LogType.GameActivity, "[Lava Survival] Round started. Map: " + Map.ColoredName);
while (RoundInProgress && roundSecs < data.roundTotalSecs) {
if (!running) return;
if (!Running) return;
if ((announceSecs % 60) == 0 && !Flooded) {
Map.Message(FloodTimeLeftMessage());
}
@ -42,8 +42,8 @@ namespace MCGalaxy.Games {
Thread.Sleep(1000);
}
if (running) EndRound();
if (running) VoteAndMoveToNextMap();
if (Running) EndRound();
if (Running) VoteAndMoveToNextMap();
}
void DoFlood() {
@ -80,8 +80,7 @@ namespace MCGalaxy.Games {
return "&3" + mins + " minute" + (mins == 1 ? "" : "s") + " %Suntil the round ends.";
}
// TODO: common abstract method
internal void MessageRoundStatus(Player p) {
public override void OutputStatus(Player p) {
string block = data.water ? "water" : "lava";
// TODO: send these messages if player is op
@ -98,7 +97,7 @@ namespace MCGalaxy.Games {
if (data.destroy) Player.Message(p, "The " + block + " will &cdestroy plants " + (data.water ? "" : "and flammable blocks ") + "%Sthis round!");
if (!Flooded) Player.Message(p, FloodTimeLeftMessage());
if (!Flooded) Player.Message(p, FloodTimeLeftMessage());
Player.Message(p, RoundTimeLeftMessage());
}

View File

@ -23,7 +23,12 @@ namespace MCGalaxy.Games {
internal sealed class LSData {
public int TimesDied;
}
class LSLevelPicker : LevelPicker {
public List<string> maps;
public override List<string> GetCandidateMaps() { return new List<string>(maps); }
}
public sealed partial class LSGame : RoundsGame {
const string propsDir = "properties/lavasurvival/";
List<string> maps;
@ -32,8 +37,7 @@ namespace MCGalaxy.Games {
MapSettings mapSettings;
public override string GameName { get { return "Lava survival"; } }
public override bool Running { get { return running; } }
public bool running, Flooded, StartOnStartup;
public bool Flooded, StartOnStartup;
public int MaxLives = 3;
public LSGame() {
@ -72,7 +76,6 @@ namespace MCGalaxy.Games {
ResetPlayerDeaths();
Logger.Log(LogType.GameActivity, "[Lava Survival] Game started.");
running = true;
HookEventHandlers();
Thread t = new Thread(RunGame);
@ -81,8 +84,8 @@ namespace MCGalaxy.Games {
}
public override void End() {
if (!running) return;
running = false;
if (!Running) return;
Running = false;
UnhookEventHandlers();
Flooded = false;
@ -129,13 +132,8 @@ namespace MCGalaxy.Games {
public List<string> Maps { get { return new List<string>(maps); } }
public override bool HandlesChatMessage(Player p, string message) {
if (!running || p.level != Map) return false;
if (!Running || p.level != Map) return false;
return Picker.HandlesMessage(p, message);
}
}
internal class LSLevelPicker : LevelPicker {
public List<string> maps;
public override List<string> GetCandidateMaps() { return new List<string>(maps); }
}
}

View File

@ -29,7 +29,9 @@ namespace MCGalaxy.Games {
public string LastMap = "";
public LevelPicker Picker;
public abstract void OutputStatus(Player p);
public abstract void Start(Player p, string map, int rounds);
protected abstract void DoRound();
protected abstract List<Player> GetPlayers();
@ -45,27 +47,31 @@ namespace MCGalaxy.Games {
Logger.LogError(ex);
Chat.MessageGlobal("&c" + GameName + " disabled due to an error.");
try { End(); }
try { End(); }
catch (Exception ex2) { Logger.LogError(ex2); }
}
}
protected void DoCountdown(string format, int delay, int minThreshold) {
const CpeMessageType type = CpeMessageType.Announcement;
for (int i = delay; i > 0 && Running; i--) {
if (i == 1) {
MessageMap(type, String.Format(format, i)
.Replace("seconds", "second"));
} else if (i < minThreshold || (i % 10) == 0) {
MessageMap(type, String.Format(format, i));
}
Thread.Sleep(1000);
}
MessageMap(type, "");
}
protected List<Player> DoRoundCountdown(int delay) {
while (true) {
RoundStart = DateTime.UtcNow.AddSeconds(delay);
if (!Running) return null;
const CpeMessageType type = CpeMessageType.Announcement;
for (int i = delay; i > 0 && Running; i--) {
if (i == 1) {
MessageMap(type, "&4Starting in &f1 &4seconds");
} else if (i < 10 || (i % 10) == 0) {
MessageMap(type, "&4Starting in &f" + i + " &4seconds");
}
Thread.Sleep(1000);
}
MessageMap(type, "");
DoCountdown("&4Starting in &f{0} &4seconds", delay, 10);
if (!Running) return null;
List<Player> players = GetPlayers();

View File

@ -31,18 +31,18 @@ namespace MCGalaxy.Games {
int infectCombo = 0;
protected override void DoRound() {
if (!running) return;
if (!Running) return;
List<Player> players = DoRoundCountdown(30);
if (players == null) return;
if (!running) return;
if (!Running) return;
RoundInProgress = true;
StartRound(players);
if (!running) return;
if (!Running) return;
DoCoreGame();
if (running) EndRound();
if (running) VoteAndMoveToNextMap();
if (Running) EndRound();
if (Running) VoteAndMoveToNextMap();
}
void StartRound(List<Player> players) {
@ -75,7 +75,7 @@ namespace MCGalaxy.Games {
int lastCountdown = -1;
Random random = new Random();
while (alive.Length > 0 && running && RoundInProgress) {
while (alive.Length > 0 && Running && RoundInProgress) {
Player[] infected = Infected.Items;
// Do round end.
int seconds = (int)(RoundEnd - DateTime.UtcNow).TotalSeconds;

View File

@ -72,7 +72,6 @@ namespace MCGalaxy.Games {
public sealed partial class ZSGame : RoundsGame {
public override string GameName { get { return "Zombie survival"; } }
public override bool TeleportAllowed { get { return !RoundInProgress; } }
public override bool Running { get { return running; } }
public ZSGame() { Picker = new ZSLevelPicker(); }
public DateTime RoundEnd;
@ -80,9 +79,7 @@ namespace MCGalaxy.Games {
public VolatileArray<Player> Infected = new VolatileArray<Player>();
public string QueuedZombie;
public VolatileArray<BountyData> Bounties = new VolatileArray<BountyData>();
List<string> infectMessages = new List<string>();
bool running;
const string zsExtrasKey = "MCG_ZS_DATA";
internal ZSData Get(Player p) {
@ -120,6 +117,11 @@ namespace MCGalaxy.Games {
return playing;
}
public override void OutputStatus(Player p) {
Player.Message(p, "{0} out of {1} players are alive",
Alive.Count, Alive.Count + Infected.Count);
}
public override void Start(Player p, string map, int rounds) {
// ZS starts on current map by default
if (!Player.IsSuper(p) && map.Length == 0) map = p.level.name;
@ -141,7 +143,7 @@ namespace MCGalaxy.Games {
RoundsLeft = rounds;
HookStats();
running = true;
Running = true;
HookEventHandlers();
Thread t = new Thread(RunGame);
@ -194,8 +196,8 @@ namespace MCGalaxy.Games {
}
public override void End() {
if (!running) return;
running = false;
if (!Running) return;
Running = false;
UnhookEventHandlers();
RoundStart = DateTime.MinValue;
@ -265,7 +267,7 @@ namespace MCGalaxy.Games {
Get(p).Infected = false;
RemoveAssociatedBounties(p);
if (!running || !RoundInProgress || Infected.Count > 0) return;
if (!Running || !RoundInProgress || Infected.Count > 0) return;
Random random = new Random();
Player[] alive = Alive.Items;
if (alive.Length == 0) return;
@ -315,7 +317,7 @@ namespace MCGalaxy.Games {
}
public override void AdjustPrefix(Player p, ref string prefix) {
if (!running) return;
if (!Running) return;
int winStreak = Get(p).CurrentRoundsSurvived;
if (winStreak == 1) prefix += "&4*" + p.color;

View File

@ -62,7 +62,7 @@ namespace MCGalaxy {
RevertBlock(x, y, z); return;
}
if ( Server.lava.running && Server.lava.Map == level && Server.lava.IsPlayerDead(this) ) {
if ( Server.lava.Running && Server.lava.Map == level && Server.lava.IsPlayerDead(this) ) {
SendMessage("You are out of the round, and cannot build.");
RevertBlock(x, y, z); return;
}