Mostly abstract level voting/picking code.

This commit is contained in:
UnknownShadow200 2017-08-06 15:52:08 +10:00
parent 90d19e62b8
commit e9c02198ce
22 changed files with 291 additions and 268 deletions

View File

@ -50,7 +50,7 @@ namespace MCGalaxy.Commands.Fun {
} }
p.Game.PledgeSurvive = true; p.Game.PledgeSurvive = true;
Server.zombie.CurLevel Server.zombie.Map
.ChatLevel(p.ColoredName + " %Spledges that they will not succumb to the infection!"); .ChatLevel(p.ColoredName + " %Spledges that they will not succumb to the infection!");
} }

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Commands.Fun {
public override CommandEnable Enabled { get { return CommandEnable.Zombie; } } public override CommandEnable Enabled { get { return CommandEnable.Zombie; } }
public override void Use(Player p, string message) { public override void Use(Player p, string message) {
List<string> recent = Server.zombie.RecentMaps; List<string> recent = Server.zombie.Picker.RecentMaps;
if (recent.Count == 0) { if (recent.Count == 0) {
Player.Message(p, "No maps have been used yet."); Player.Message(p, "No maps have been used yet.");
} else { } else {

View File

@ -36,16 +36,16 @@ namespace MCGalaxy.Commands.Fun {
Player.Message(p, value + " was queued."); Player.Message(p, value + " was queued.");
Server.zombie.QueuedZombie = who.name; Server.zombie.QueuedZombie = who.name;
if (Server.zombie.CurLevel != null) if (Server.zombie.Map != null)
Server.zombie.CurLevel.ChatLevel(who.ColoredName + " %Swas queued as the next zombie."); Server.zombie.Map.ChatLevel(who.ColoredName + " %Swas queued as the next zombie.");
} else if (args[0].CaselessEq("level")) { } else if (args[0].CaselessEq("level")) {
string map = Matcher.FindMaps(p, value); string map = Matcher.FindMaps(p, value);
if (map == null) return; if (map == null) return;
Player.Message(p, map + " was queued."); Player.Message(p, map + " was queued.");
Server.zombie.QueuedLevel = map.ToLower(); Server.zombie.Picker.QueuedMap = map.ToLower();
if (Server.zombie.CurLevel != null) if (Server.zombie.Map != null)
Server.zombie.CurLevel.ChatLevel(map + " was queued as the next map."); Server.zombie.Map.ChatLevel(map + " was queued as the next map.");
} else { } else {
Help(p); Help(p);
} }

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Commands.Fun {
public override CommandEnable Enabled { get { return CommandEnable.Zombie; } } public override CommandEnable Enabled { get { return CommandEnable.Zombie; } }
public override void Use(Player p, string message) { public override void Use(Player p, string message) {
ShowQueued(p, Server.zombie.QueuedLevel, "level"); ShowQueued(p, Server.zombie.Picker.QueuedMap, "level");
ShowQueued(p, Server.zombie.QueuedZombie, "zombie"); ShowQueued(p, Server.zombie.QueuedZombie, "zombie");
} }

View File

@ -50,7 +50,7 @@ namespace MCGalaxy.Commands.Fun {
if (game.Status == ZombieGameStatus.NotStarted) { if (game.Status == ZombieGameStatus.NotStarted) {
Player.Message(p, "Zombie Survival is not currently running."); return; Player.Message(p, "Zombie Survival is not currently running."); return;
} }
PlayerActions.ChangeMap(p, game.CurLevel); PlayerActions.ChangeMap(p, game.Map);
} }
static void HandleStatus(Player p, ZSGame game, string[] args) { static void HandleStatus(Player p, ZSGame game, string[] args) {
@ -67,8 +67,8 @@ namespace MCGalaxy.Commands.Fun {
Player.Message(p, "Zombie Survival game currently in progress, with this round being the final round."); break; Player.Message(p, "Zombie Survival game currently in progress, with this round being the final round."); break;
} }
if (game.Status == ZombieGameStatus.NotStarted || game.CurLevelName.Length == 0) return; if (game.Status == ZombieGameStatus.NotStarted || game.MapName.Length == 0) return;
Player.Message(p, "Running on map: " + game.CurLevelName); Player.Message(p, "Running on map: " + game.MapName);
} }
static void HandleStart(Player p, ZSGame game, string[] args) { static void HandleStart(Player p, ZSGame game, string[] args) {
@ -103,9 +103,9 @@ namespace MCGalaxy.Commands.Fun {
} }
string src = p == null ? "(console)" : p.ColoredName; string src = p == null ? "(console)" : p.ColoredName;
Level lvl = game.CurLevel; Level lvl = game.Map;
if (lvl != null) { if (lvl != null) {
Chat.MessageLevel(game.CurLevel, "Zombie Survival was stopped by " + src); Chat.MessageLevel(game.Map, "Zombie Survival was stopped by " + src);
} }
src = p == null ? "(console)" : p.name; src = p == null ? "(console)" : p.name;

View File

@ -61,9 +61,9 @@ namespace MCGalaxy.Eco {
int chance = new Random().Next(1, 101); int chance = new Random().Next(1, 101);
if (chance <= ZSConfig.ReviveChance) { if (chance <= ZSConfig.ReviveChance) {
Server.zombie.DisinfectPlayer(p); Server.zombie.DisinfectPlayer(p);
Server.zombie.CurLevel.ChatLevel(p.ColoredName + " %S" + ZSConfig.ReviveSuccessMessage); Server.zombie.Map.ChatLevel(p.ColoredName + " %S" + ZSConfig.ReviveSuccessMessage);
} else { } else {
Server.zombie.CurLevel.ChatLevel(p.ColoredName + " %S" + ZSConfig.ReviveFailureMessage); Server.zombie.Map.ChatLevel(p.ColoredName + " %S" + ZSConfig.ReviveFailureMessage);
} }
Economy.MakePurchase(p, Price, "%3Revive:"); Economy.MakePurchase(p, Price, "%3Revive:");
p.Game.RevivesUsed++; p.Game.RevivesUsed++;

View File

@ -64,7 +64,7 @@ namespace MCGalaxy.Eco {
public override string Name { get { return "QueueLevel"; } } public override string Name { get { return "QueueLevel"; } }
protected override void DoPurchase(Player p, string message, string[] args) { protected override void DoPurchase(Player p, string message, string[] args) {
if (Server.zombie.QueuedLevel != null) { if (Server.zombie.Picker.QueuedMap != null) {
Player.Message(p, "Someone else has already queued a level."); return; Player.Message(p, "Someone else has already queued a level."); return;
} }
string map = Matcher.FindMaps(p, args[1]); string map = Matcher.FindMaps(p, args[1]);
@ -157,7 +157,7 @@ namespace MCGalaxy.Eco {
int left = MaxPotions - p.Game.InvisibilityPotions; int left = MaxPotions - p.Game.InvisibilityPotions;
Player.Message(p, "Lasts for &a{0} %Sseconds. You can buy &a{1} %Smore this round.", Duration, left); Player.Message(p, "Lasts for &a{0} %Sseconds. You can buy &a{1} %Smore this round.", Duration, left);
Server.zombie.CurLevel.ChatLevel(p.ColoredName + " %Svanished. &a*POOF*"); Server.zombie.Map.ChatLevel(p.ColoredName + " %Svanished. &a*POOF*");
Entities.GlobalDespawn(p, false); Entities.GlobalDespawn(p, false);
Economy.MakePurchase(p, Price, "%3Invisibility: " + Duration); Economy.MakePurchase(p, Price, "%3Invisibility: " + Duration);
} }

View File

@ -34,7 +34,7 @@ namespace MCGalaxy.Games {
public CtfData(Player p) { this.p = p; } public CtfData(Player p) { this.p = p; }
} }
public sealed partial class CTFGame { public sealed partial class CTFGame : IGame {
public System.Timers.Timer tagging = new System.Timers.Timer(500); public System.Timers.Timer tagging = new System.Timers.Timer(500);
public bool voting = false; public bool voting = false;
internal int vote1 = 0, vote2 = 0, vote3 = 0; internal int vote1 = 0, vote2 = 0, vote3 = 0;
@ -42,7 +42,6 @@ namespace MCGalaxy.Games {
public bool started = false; public bool started = false;
public CtfTeam2 Red, Blue; public CtfTeam2 Red, Blue;
public Level Map;
List<CtfData> cache = new List<CtfData>(); List<CtfData> cache = new List<CtfData>();
public CTFConfig Config = new CTFConfig(); public CTFConfig Config = new CTFConfig();
@ -70,6 +69,7 @@ namespace MCGalaxy.Games {
/// <summary> Load a map into CTF </summary> /// <summary> Load a map into CTF </summary>
public void SetMap(string mapName) { public void SetMap(string mapName) {
MapName = mapName;
CmdLoad.LoadLevel(null, mapName); CmdLoad.LoadLevel(null, mapName);
Map = LevelInfo.FindExact(mapName); Map = LevelInfo.FindExact(mapName);
Map.SaveChanges = false; Map.SaveChanges = false;
@ -141,8 +141,8 @@ namespace MCGalaxy.Games {
if (started) { if (started) {
Player.Message(p, "CTF game already running."); return false; Player.Message(p, "CTF game already running."); return false;
} }
List<string> maps = GetCtfMaps(); List<string> maps = GetCtfMaps();
if (maps.Count == 0) { if (maps.Count == 0) {
Player.Message(p, "No CTF maps were found."); return false; Player.Message(p, "No CTF maps were found."); return false;
} }

View File

@ -29,9 +29,6 @@ namespace MCGalaxy.Games {
/// <summary> Players who are still alive in the current round. </summary> /// <summary> Players who are still alive in the current round. </summary>
public VolatileArray<Player> Remaining = new VolatileArray<Player>(); public VolatileArray<Player> Remaining = new VolatileArray<Player>();
/// <summary> Map countdown is running on. </summary>
public Level Map;
/// <summary> Current status of the countdown game. </summary> /// <summary> Current status of the countdown game. </summary>
public CountdownGameStatus Status = CountdownGameStatus.Disabled; public CountdownGameStatus Status = CountdownGameStatus.Disabled;
@ -323,6 +320,7 @@ namespace MCGalaxy.Games {
plugin.Game = this; plugin.Game = this;
plugin.Load(false); plugin.Load(false);
MapName = "countdown";
CmdLoad.LoadLevel(null, "countdown"); CmdLoad.LoadLevel(null, "countdown");
Map = LevelInfo.FindExact("countdown"); Map = LevelInfo.FindExact("countdown");

View File

@ -21,6 +21,12 @@ namespace MCGalaxy.Games {
public abstract class IGame { public abstract class IGame {
/// <summary> Name of the map this game is running on. </summary>
public string MapName;
/// <summary> Level instance of the map this game is running on. </summary>
public Level Map;
/// <summary> Whether players are allowed to teleport to others when not in referee mode. </summary> /// <summary> Whether players are allowed to teleport to others when not in referee mode. </summary>
public virtual bool TeleportAllowed { get { return true; } } public virtual bool TeleportAllowed { get { return true; } }

View File

@ -0,0 +1,151 @@
/*
Copyright 2015 MCGalaxy
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.osedu.org/licenses/ECL-2.0
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
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.Collections.Generic;
using System.IO;
using System.Threading;
namespace MCGalaxy.Games {
public abstract class LevelPicker {
/// <summary> Level specifically chosen to be used in the next round. </summary>
public string QueuedMap;
/// <summary> List of maps that have been recently played in this game. </summary>
public List<string> RecentMaps = new List<string>();
internal string Candidate1 = "", Candidate2 = "", Candidate3 = "";
internal int Votes1 = 0, Votes2 = 0, Votes3 = 0;
public string ChooseNextLevel(ZSGame game) {
if (QueuedMap != null) return QueuedMap;
try {
List<string> maps = GetCandidateLevels();
if (maps == null) return null;
RemoveRecentLevels(maps);
Votes1 = 0; Votes2 = 0; Votes3 = 0;
Random r = new Random();
Candidate1 = GetRandomLevel(r, maps);
Candidate2 = GetRandomLevel(r, maps);
Candidate3 = GetRandomLevel(r, maps);
if (!game.Running) return null;
DoLevelVote(game);
if (!game.Running) return null;
return NextLevel(r, maps, game);
} catch (Exception ex) {
Logger.LogError(ex);
return null;
}
}
void RemoveRecentLevels(List<string> maps) {
// Try to avoid recently played levels, avoiding most recent
List<string> recent = RecentMaps;
for (int i = recent.Count - 1; i >= 0; i--) {
if (maps.Count > 3 && maps.CaselessContains(recent[i]))
maps.CaselessRemove(recent[i]);
}
// Try to avoid maps voted last round if possible
if (maps.Count > 3) maps.CaselessRemove(Candidate1);
if (maps.Count > 3) maps.CaselessRemove(Candidate2);
if (maps.Count > 3) maps.CaselessRemove(Candidate3);
}
void DoLevelVote(IGame game) {
Server.votingforlevel = true;
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != game.Map) continue;
SendVoteMessage(pl);
}
VoteCountdown(game);
Server.votingforlevel = false;
}
void VoteCountdown(IGame game) {
// Show message for non-CPE clients
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != game.Map || pl.HasCpeExt(CpeExt.MessageTypes)) continue;
pl.SendMessage("You have 20 seconds to vote for the next map");
}
for (int i = 0; i < 20; i++) {
players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != game.Map || !pl.HasCpeExt(CpeExt.MessageTypes)) continue;
pl.SendCpeMessage(CpeMessageType.BottomRight1, "&e" + (20 - i) + "s %Sleft to vote");
}
Thread.Sleep(1000);
}
}
string NextLevel(Random r, List<string> levels, ZSGame game) {
Player[] online = PlayerInfo.Online.Items;
foreach (Player pl in online) pl.voted = false;
if (Votes1 >= Votes2) {
if (Votes3 > Votes1 && Votes3 > Votes2) {
return Candidate3;
} else {
return Candidate1;
}
} else {
if (Votes3 > Votes1 && Votes3 > Votes2) {
return Candidate3;
} else {
return Candidate2;
}
}
}
internal static string GetRandomLevel(Random r, List<string> maps) {
int i = r.Next(0, maps.Count);
string map = maps[i];
maps.RemoveAt(i);
return map;
}
/// <summary> Returns a list of maps that can be used for a round of this game. </summary>
/// <returns> null if not enough levels are available, otherwise the list of levels. </returns>
public abstract List<string> GetCandidateLevels();
/// <summary> Sends the formatted vote message to the player (using bottom right if supported) </summary>
public void SendVoteMessage(Player p) {
const string line1 = "&eLevel vote - type &a1&e, &b2&e or &c3";
string line2 = "&a" + Candidate1 + "&e, &b" + Candidate2 + "&e, &c" + Candidate3;
if (p.HasCpeExt(CpeExt.MessageTypes)) {
p.SendCpeMessage(CpeMessageType.BottomRight3, line1);
p.SendCpeMessage(CpeMessageType.BottomRight2, line2);
} else {
Player.Message(p, line1);
Player.Message(p, line2);
}
}
}
}

View File

@ -70,16 +70,16 @@ namespace MCGalaxy.Games.ZS {
string timespan = GetTimeLeft(seconds); string timespan = GetTimeLeft(seconds);
if (timespan.Length > 0) { if (timespan.Length > 0) {
const string format = "&a{0} %Salive %S({2}, map: {1})"; const string format = "&a{0} %Salive %S({2}, map: {1})";
return String.Format(format, game.Alive.Count, game.CurLevelName, timespan); return String.Format(format, game.Alive.Count, game.MapName, timespan);
} else { } else {
const string format = "&a{0} %Salive %S(map: {1})"; const string format = "&a{0} %Salive %S(map: {1})";
return String.Format(format, game.Alive.Count, game.CurLevelName); return String.Format(format, game.Alive.Count, game.MapName);
} }
} }
static string FormatSecondary(ZSGame game) { static string FormatSecondary(ZSGame game) {
string pillar = "%SPillaring " + (game.CurLevel.Config.Pillaring ? "&aYes" : "&cNo"); string pillar = "%SPillaring " + (game.Map.Config.Pillaring ? "&aYes" : "&cNo");
string type = "%S, Type is &a" + game.CurLevel.Config.BuildType; string type = "%S, Type is &a" + game.Map.Config.BuildType;
return pillar + type; return pillar + type;
} }
@ -93,7 +93,7 @@ namespace MCGalaxy.Games.ZS {
if (!game.Running) return; if (!game.Running) return;
Player[] online = PlayerInfo.Online.Items; Player[] online = PlayerInfo.Online.Items;
foreach (Player p in online) { foreach (Player p in online) {
if (!p.level.name.CaselessEq(game.CurLevelName)) continue; if (!p.level.name.CaselessEq(game.MapName)) continue;
p.SendCpeMessage(type, message); p.SendCpeMessage(type, message);
} }
} }

View File

@ -19,123 +19,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading;
namespace MCGalaxy.Games.ZS { namespace MCGalaxy.Games.ZS {
internal static class LevelPicker { internal class ZSLevelPicker : LevelPicker {
internal static void ChooseNextLevel(ZSGame game) { public override List<string> GetCandidateLevels() {
if (game.QueuedLevel != null) { game.ChangeLevel(game.QueuedLevel); return; }
if (!ZSConfig.ChangeLevels) return;
try {
List<string> maps = GetCandidateLevels();
if (maps == null) return;
RemoveRecentLevels(maps, game);
game.Votes1 = 0; game.Votes2 = 0; game.Votes3 = 0;
Random r = new Random();
game.Candidate1 = GetRandomLevel(r, maps);
game.Candidate2 = GetRandomLevel(r, maps);
game.Candidate3 = GetRandomLevel(r, maps);
if (!game.Running || game.Status == ZombieGameStatus.LastRound) return;
DoLevelVote(game);
if (!game.Running || game.Status == ZombieGameStatus.LastRound) return;
MoveToNextLevel(r, maps, game);
} catch (Exception ex) {
Logger.LogError(ex);
}
}
static void RemoveRecentLevels(List<string> maps, ZSGame game) {
// Try to avoid recently played levels, avoiding most recent
List<string> recent = game.RecentMaps;
for (int i = recent.Count - 1; i >= 0; i--) {
if (maps.Count > 3 && maps.CaselessContains(recent[i]))
maps.CaselessRemove(recent[i]);
}
// Try to avoid maps voted last round if possible
if (maps.Count > 3 && maps.CaselessContains(game.Candidate1))
maps.CaselessRemove(game.Candidate1);
if (maps.Count > 3 && maps.CaselessContains(game.Candidate2))
maps.CaselessRemove(game.Candidate2);
if (maps.Count > 3 && maps.CaselessContains(game.Candidate3))
maps.CaselessRemove(game.Candidate3);
}
static void DoLevelVote(ZSGame game) {
Server.votingforlevel = true;
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != game.CurLevel) continue;
SendVoteMessage(pl, game);
}
VoteCountdown(game);
Server.votingforlevel = false;
}
static void VoteCountdown(ZSGame game) {
// Show message for non-CPE clients
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != game.CurLevel || pl.HasCpeExt(CpeExt.MessageTypes)) continue;
pl.SendMessage("You have 20 seconds to vote for the next map");
}
for (int i = 0; i < 20; i++) {
players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != game.CurLevel || !pl.HasCpeExt(CpeExt.MessageTypes)) continue;
pl.SendCpeMessage(CpeMessageType.BottomRight1, "&e" + (20 - i) + "s %Sleft to vote");
}
Thread.Sleep(1000);
}
}
/// <summary> Moves all players to the level which has the highest number of votes. </summary>
static void MoveToNextLevel(Random r, List<string> levels, ZSGame game) {
int v1 = game.Votes1, v2 = game.Votes2, v3 = game.Votes3;
if (v1 >= v2) {
if (v3 > v1 && v3 > v2) {
game.ChangeLevel(game.Candidate3);
} else {
game.ChangeLevel(game.Candidate1);
}
} else {
if (v3 > v1 && v3 > v2) {
game.ChangeLevel(game.Candidate3);
} else {
game.ChangeLevel(game.Candidate2);
}
}
Player[] online = PlayerInfo.Online.Items;
foreach (Player pl in online)
pl.voted = false;
}
internal static string GetRandomLevel(Random r, List<string> maps) {
int i = r.Next(0, maps.Count);
string map = maps[i];
maps.RemoveAt(i);
return map;
}
/// <summary> Returns a list of maps that can be used for a round of zombie survival. </summary>
/// <returns> null if not enough levels are available, otherwise the list of levels. </returns>
internal static List<string> GetCandidateLevels() {
List<string> maps = null; List<string> maps = null;
if (ZSConfig.LevelList.Count > 0) { if (ZSConfig.LevelList.Count > 0) {
maps = new List<string>(ZSConfig.LevelList); maps = new List<string>(ZSConfig.LevelList);
} else { } else {
maps = GetAllMaps(); maps = AllMaps();
} }
foreach (string ignore in ZSConfig.IgnoredLevelList) foreach (string ignore in ZSConfig.IgnoredLevelList)
maps.Remove(ignore); maps.Remove(ignore);
@ -153,32 +48,16 @@ namespace MCGalaxy.Games.ZS {
} }
/// <summary> Returns a list of all possible maps (exclusing personal realms if 'ignore realms' setting is true) </summary> /// <summary> Returns a list of all possible maps (exclusing personal realms if 'ignore realms' setting is true) </summary>
internal static List<string> GetAllMaps() { static List<string> AllMaps() {
List<string> maps = new List<string>(); List<string> maps = new List<string>();
string[] files = LevelInfo.AllMapFiles(); string[] files = LevelInfo.AllMapFiles();
foreach (string file in files) { foreach (string file in files) {
string name = Path.GetFileNameWithoutExtension(file); string map = Path.GetFileNameWithoutExtension(file);
if (name.IndexOf('+') >= 0 && ZSConfig.IgnorePersonalWorlds) if (map.IndexOf('+') >= 0 && ZSConfig.IgnorePersonalWorlds) continue;
continue; maps.Add(map);
maps.Add(name);
} }
return maps; return maps;
} }
/// <summary> Sends the formatted vote message to the player (using bottom right if supported) </summary>
internal static void SendVoteMessage(Player p, ZSGame game) {
const string line1 = "&eLevel vote - type &a1&e, &b2&e or &c3";
string line2 = "&a" + game.Candidate1 + "&e, &b"
+ game.Candidate2 + "&e, &c" + game.Candidate3;
if (p.HasCpeExt(CpeExt.MessageTypes)) {
p.SendCpeMessage(CpeMessageType.BottomRight3, line1);
p.SendCpeMessage(CpeMessageType.BottomRight2, line2);
} else {
Player.Message(p, line1);
Player.Message(p, line2);
}
}
} }
} }

View File

@ -27,8 +27,8 @@ namespace MCGalaxy.Games.ZS {
internal static bool Handles(Player p, ushort x, ushort y, ushort z, internal static bool Handles(Player p, ushort x, ushort y, ushort z,
bool placing, ExtBlock block, ExtBlock old, ZSGame game) { bool placing, ExtBlock block, ExtBlock old, ZSGame game) {
if (placing && !game.CurLevel.Config.Pillaring && !p.Game.Referee) { if (placing && !game.Map.Config.Pillaring && !p.Game.Referee) {
if (NotPillaring(game.CurLevel, block, old)) { if (NotPillaring(game.Map, block, old)) {
p.Game.BlocksStacked = 0; p.Game.BlocksStacked = 0;
} else if (CheckCoords(p, x, y, z)) { } else if (CheckCoords(p, x, y, z)) {
p.Game.BlocksStacked++; p.Game.BlocksStacked++;

View File

@ -25,16 +25,16 @@ namespace MCGalaxy.Games.ZS {
public static void HandOut(ZSGame game) { public static void HandOut(ZSGame game) {
Player[] alive = game.Alive.Items, dead = game.Infected.Items; Player[] alive = game.Alive.Items, dead = game.Infected.Items;
game.CurLevel.ChatLevel("&aThe game has ended!"); game.Map.ChatLevel("&aThe game has ended!");
if (alive.Length == 0) game.CurLevel.ChatLevel("&4Zombies have won this round."); if (alive.Length == 0) game.Map.ChatLevel("&4Zombies have won this round.");
else if (alive.Length == 1) game.CurLevel.ChatLevel("&2Congratulations to the sole survivor:"); else if (alive.Length == 1) game.Map.ChatLevel("&2Congratulations to the sole survivor:");
else game.CurLevel.ChatLevel("&2Congratulations to the survivors:"); else game.Map.ChatLevel("&2Congratulations to the survivors:");
AnnounceWinners(game, alive, dead); AnnounceWinners(game, alive, dead);
game.CurLevel.Config.RoundsPlayed++; game.Map.Config.RoundsPlayed++;
if (alive.Length > 0) { if (alive.Length > 0) {
game.CurLevel.Config.RoundsHumanWon++; game.Map.Config.RoundsHumanWon++;
foreach (Player p in alive) foreach (Player p in alive)
IncreaseAliveStats(p, game); IncreaseAliveStats(p, game);
} }
@ -45,7 +45,7 @@ namespace MCGalaxy.Games.ZS {
static void AnnounceWinners(ZSGame game, Player[] alive, Player[] dead) { static void AnnounceWinners(ZSGame game, Player[] alive, Player[] dead) {
if (alive.Length > 0) { if (alive.Length > 0) {
string winners = alive.Join(p => p.ColoredName); string winners = alive.Join(p => p.ColoredName);
game.CurLevel.ChatLevel(winners); game.Map.ChatLevel(winners);
return; return;
} }
@ -61,7 +61,7 @@ namespace MCGalaxy.Games.ZS {
string suffix = maxKills == 1 ? " %Skill" : " %Skills"; string suffix = maxKills == 1 ? " %Skill" : " %Skills";
StringFormatter<Player> formatter = p => p.Game.CurrentInfected == maxKills ? p.ColoredName : null; StringFormatter<Player> formatter = p => p.Game.CurrentInfected == maxKills ? p.ColoredName : null;
game.CurLevel.ChatLevel("&8Best" + group + "%S(&b" + maxKills game.Map.ChatLevel("&8Best" + group + "%S(&b" + maxKills
+ suffix + "%S)&8: " + dead.Join(formatter)); + suffix + "%S)&8: " + dead.Join(formatter));
} }
@ -83,7 +83,7 @@ namespace MCGalaxy.Games.ZS {
Random rand = new Random(); Random rand = new Random();
foreach (Player pl in online) { foreach (Player pl in online) {
if (!pl.level.name.CaselessEq(game.CurLevelName)) continue; if (!pl.level.name.CaselessEq(game.MapName)) continue;
pl.Game.ResetInvisibility(); pl.Game.ResetInvisibility();
int reward = GetMoneyReward(pl, alive, rand); int reward = GetMoneyReward(pl, alive, rand);

View File

@ -53,7 +53,7 @@ namespace MCGalaxy.Games.ZS {
void HandleTabListEntryAdded(Entity entity, ref string tabName, ref string tabGroup, Player dst) { void HandleTabListEntryAdded(Entity entity, ref string tabName, ref string tabGroup, Player dst) {
Player p = entity as Player; Player p = entity as Player;
if (p == null || p.level != Game.CurLevel) return; if (p == null || p.level != Game.Map) return;
if (p.Game.Referee) { if (p.Game.Referee) {
tabGroup = "&2Referees"; tabGroup = "&2Referees";
@ -70,7 +70,7 @@ namespace MCGalaxy.Games.ZS {
} }
void HandleMoneyChanged(Player p) { void HandleMoneyChanged(Player p) {
if (p.level != Game.CurLevel) return; if (p.level != Game.Map) return;
HUD.UpdateTertiary(p); HUD.UpdateTertiary(p);
} }
@ -84,7 +84,7 @@ namespace MCGalaxy.Games.ZS {
} }
void HandlePlayerMove(Player p, Position next, byte rotX, byte rotY) { void HandlePlayerMove(Player p, Position next, byte rotX, byte rotY) {
if (!Game.RoundInProgress || p.level != Game.CurLevel) return; if (!Game.RoundInProgress || p.level != Game.Map) return;
bool reverted = MovementCheck.DetectNoclip(p, next) bool reverted = MovementCheck.DetectNoclip(p, next)
|| MovementCheck.DetectSpeedhack(p, next, ZSConfig.MaxMoveDistance); || MovementCheck.DetectSpeedhack(p, next, ZSConfig.MaxMoveDistance);
@ -93,10 +93,10 @@ namespace MCGalaxy.Games.ZS {
void HandlePlayerAction(Player p, PlayerAction action, string message, bool stealth) { void HandlePlayerAction(Player p, PlayerAction action, string message, bool stealth) {
if (!(action == PlayerAction.Referee || action == PlayerAction.UnReferee)) return; if (!(action == PlayerAction.Referee || action == PlayerAction.UnReferee)) return;
if (p.level != Game.CurLevel) return; if (p.level != Game.Map) return;
if (action == PlayerAction.UnReferee) { if (action == PlayerAction.UnReferee) {
Game.PlayerJoinedLevel(p, Game.CurLevel, Game.CurLevel); Game.PlayerJoinedLevel(p, Game.Map, Game.Map);
Command.all.FindByName("Spawn").Use(p, ""); Command.all.FindByName("Spawn").Use(p, "");
p.Game.Referee = false; p.Game.Referee = false;
@ -117,7 +117,7 @@ namespace MCGalaxy.Games.ZS {
} }
void HandlePlayerSpawning(Player p, ref Position pos, ref byte yaw, ref byte pitch, bool respawning) { void HandlePlayerSpawning(Player p, ref Position pos, ref byte yaw, ref byte pitch, bool respawning) {
if (p.level != Game.CurLevel) return; if (p.level != Game.Map) return;
if (!p.Game.Referee && !p.Game.Infected && Game.RoundInProgress) { if (!p.Game.Referee && !p.Game.Infected && Game.RoundInProgress) {
Game.InfectPlayer(p, null); Game.InfectPlayer(p, null);
@ -125,13 +125,13 @@ namespace MCGalaxy.Games.ZS {
} }
void HandleBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool placing) { void HandleBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool placing) {
if (p.level != Game.CurLevel) return; if (p.level != Game.Map) return;
ExtBlock old = Game.CurLevel.GetBlock(x, y, z); ExtBlock old = Game.Map.GetBlock(x, y, z);
if (Game.CurLevel.Config.BuildType == BuildType.NoModify) { if (Game.Map.Config.BuildType == BuildType.NoModify) {
p.RevertBlock(x, y, z); p.cancelBlock = true; return; p.RevertBlock(x, y, z); p.cancelBlock = true; return;
} }
if (Game.CurLevel.Config.BuildType == BuildType.ModifyOnly && Game.CurLevel.BlockProps[old.Index].OPBlock) { if (Game.Map.Config.BuildType == BuildType.ModifyOnly && Game.Map.BlockProps[old.Index].OPBlock) {
p.RevertBlock(x, y, z); p.cancelBlock = true; return; p.RevertBlock(x, y, z); p.cancelBlock = true; return;
} }

View File

@ -51,8 +51,7 @@ namespace MCGalaxy.Games {
return; return;
} else if (Status == ZombieGameStatus.InfiniteRounds) { } else if (Status == ZombieGameStatus.InfiniteRounds) {
DoRound(); DoRound();
if (ZSConfig.ChangeLevels) MoveToNextLevel();
LevelPicker.ChooseNextLevel(this);
} else if (Status == ZombieGameStatus.SingleRound) { } else if (Status == ZombieGameStatus.SingleRound) {
DoRound(); DoRound();
End(); return; End(); return;
@ -61,14 +60,19 @@ namespace MCGalaxy.Games {
End(); return; End(); return;
} else { } else {
DoRound(); DoRound();
if (ZSConfig.ChangeLevels) MoveToNextLevel();
LevelPicker.ChooseNextLevel(this);
} }
} else if (Status == ZombieGameStatus.LastRound) { } else if (Status == ZombieGameStatus.LastRound) {
End(); return; End(); return;
} }
} }
} }
void MoveToNextLevel() {
if (!ZSConfig.ChangeLevels) return;
string map = Picker.ChooseNextLevel(this);
if (map != null) ChangeLevel(map);
}
void DoRound() { void DoRound() {
if (!Running) return; if (!Running) return;
@ -77,29 +81,29 @@ namespace MCGalaxy.Games {
Random random = new Random(); Random random = new Random();
RoundInProgress = true; RoundInProgress = true;
int roundMins = random.Next(CurLevel.Config.MinRoundTime, CurLevel.Config.MaxRoundTime); int roundMins = random.Next(Map.Config.MinRoundTime, Map.Config.MaxRoundTime);
string suffix = roundMins == 1 ? " %Sminute!" : " %Sminutes!"; string suffix = roundMins == 1 ? " %Sminute!" : " %Sminutes!";
CurLevel.ChatLevel("This round will last for &a" + roundMins + suffix); Map.ChatLevel("This round will last for &a" + roundMins + suffix);
RoundEnd = DateTime.UtcNow.AddMinutes(roundMins); RoundEnd = DateTime.UtcNow.AddMinutes(roundMins);
Player[] online = PlayerInfo.Online.Items; Player[] online = PlayerInfo.Online.Items;
foreach (Player p in online) { foreach (Player p in online) {
if (p.level == null || p.level != CurLevel || p.Game.Referee) continue; if (p.level == null || p.level != Map || p.Game.Referee) continue;
Alive.Add(p); Alive.Add(p);
} }
Infected.Clear(); Infected.Clear();
Player first = PickFirstZombie(random, players); Player first = PickFirstZombie(random, players);
CurLevel.ChatLevel("&c" + first.DisplayName + " %Sstarted the infection!"); Map.ChatLevel("&c" + first.DisplayName + " %Sstarted the infection!");
InfectPlayer(first, null); InfectPlayer(first, null);
DoCoreGame(random); DoCoreGame(random);
if (!Running) { Status = ZombieGameStatus.LastRound; return; } if (!Running) { Status = ZombieGameStatus.LastRound; return; }
EndRound(); EndRound();
if (RecentMaps.Count > 20) if (Picker.RecentMaps.Count > 20)
RecentMaps.RemoveAt(0); Picker.RecentMaps.RemoveAt(0);
RecentMaps.Add(CurLevelName); Picker.RecentMaps.Add(MapName);
} }
Player PickFirstZombie(Random random, List<Player> players) { Player PickFirstZombie(Random random, List<Player> players) {
@ -108,7 +112,7 @@ namespace MCGalaxy.Games {
first = QueuedZombie != null ? first = QueuedZombie != null ?
PlayerInfo.FindExact(QueuedZombie) : players[random.Next(players.Count)]; PlayerInfo.FindExact(QueuedZombie) : players[random.Next(players.Count)];
QueuedZombie = null; QueuedZombie = null;
} while (first == null || !first.level.name.CaselessEq(CurLevelName)); } while (first == null || !first.level.name.CaselessEq(MapName));
return first; return first;
} }
@ -138,7 +142,7 @@ namespace MCGalaxy.Games {
Player[] online = PlayerInfo.Online.Items; Player[] online = PlayerInfo.Online.Items;
foreach (Player p in online) { foreach (Player p in online) {
if (!p.Game.Referee && p.level.name.CaselessEq(CurLevelName)) { if (!p.Game.Referee && p.level.name.CaselessEq(MapName)) {
players.Add(p); players.Add(p);
nonRefPlayers++; nonRefPlayers++;
} }
@ -146,7 +150,7 @@ namespace MCGalaxy.Games {
if (!Running) return null; if (!Running) return null;
if (nonRefPlayers >= 2) return players; if (nonRefPlayers >= 2) return players;
CurLevel.ChatLevel("&cNeed 2 or more non-ref players to start a round."); Map.ChatLevel("&cNeed 2 or more non-ref players to start a round.");
} }
} }
@ -198,8 +202,8 @@ namespace MCGalaxy.Games {
if (killer.Game.Infected && !alive.Game.Infected if (killer.Game.Infected && !alive.Game.Infected
&& !alive.Game.Referee && !killer.Game.Referee && !alive.Game.Referee && !killer.Game.Referee
&& killer.level.name.CaselessEq(CurLevelName) && killer.level.name.CaselessEq(MapName)
&& alive.level.name.CaselessEq(CurLevelName)) && alive.level.name.CaselessEq(MapName))
{ {
InfectPlayer(alive, killer); InfectPlayer(alive, killer);
alive.Game.LastInfecter = killer.name; alive.Game.LastInfecter = killer.name;
@ -209,7 +213,7 @@ namespace MCGalaxy.Games {
if (infectCombo >= 2) { if (infectCombo >= 2) {
killer.SendMessage("You gained " + (2 + infectCombo) + " " + ServerConfig.Currency); killer.SendMessage("You gained " + (2 + infectCombo) + " " + ServerConfig.Currency);
killer.SetMoney(killer.money + (2 + infectCombo)); killer.SetMoney(killer.money + (2 + infectCombo));
CurLevel.ChatLevel("&c" + killer.DisplayName + " %Sis on a rampage! " + (infectCombo + 1) + " infections in a row!"); Map.ChatLevel("&c" + killer.DisplayName + " %Sis on a rampage! " + (infectCombo + 1) + " infections in a row!");
} }
} else { } else {
infectCombo = 0; infectCombo = 0;
@ -231,7 +235,7 @@ namespace MCGalaxy.Games {
void SendLevelRaw(string message, bool announce = false) { void SendLevelRaw(string message, bool announce = false) {
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) { foreach (Player p in players) {
if (p.level != CurLevel) continue; if (p.level != Map) continue;
CpeMessageType type = announce && p.HasCpeExt(CpeExt.MessageTypes) CpeMessageType type = announce && p.HasCpeExt(CpeExt.MessageTypes)
? CpeMessageType.Announcement : CpeMessageType.Normal; ? CpeMessageType.Announcement : CpeMessageType.Normal;
@ -243,7 +247,7 @@ namespace MCGalaxy.Games {
DateTime now = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) { foreach (Player p in players) {
if (!p.Game.Invisible || p.level != CurLevel) continue; if (!p.Game.Invisible || p.level != Map) continue;
DateTime end = p.Game.InvisibilityEnd; DateTime end = p.Game.InvisibilityEnd;
if (now >= end) { if (now >= end) {
Player.Message(p, "&cYou are &bvisible &cagain"); Player.Message(p, "&cYou are &bvisible &cagain");
@ -267,7 +271,7 @@ namespace MCGalaxy.Games {
void CheckHumanPledge(Player p, Player killer) { void CheckHumanPledge(Player p, Player killer) {
if (!p.Game.PledgeSurvive) return; if (!p.Game.PledgeSurvive) return;
p.Game.PledgeSurvive = false; p.Game.PledgeSurvive = false;
CurLevel.ChatLevel("&c" + p.DisplayName + " %Sbroke their pledge of not being infected."); Map.ChatLevel("&c" + p.DisplayName + " %Sbroke their pledge of not being infected.");
if (killer == null) { if (killer == null) {
Player.Message(p, "As this was an automatic infection, you have not lost any &3" + ServerConfig.Currency); Player.Message(p, "As this was an automatic infection, you have not lost any &3" + ServerConfig.Currency);
@ -283,12 +287,12 @@ namespace MCGalaxy.Games {
Player setter = PlayerInfo.FindExact(bounty.Origin); Player setter = PlayerInfo.FindExact(bounty.Origin);
if (pKiller == null) { if (pKiller == null) {
CurLevel.ChatLevel("Bounty on " + p.ColoredName + " %Sis no longer active."); Map.ChatLevel("Bounty on " + p.ColoredName + " %Sis no longer active.");
if (setter != null) setter.SetMoney(setter.money + bounty.Amount); if (setter != null) setter.SetMoney(setter.money + bounty.Amount);
} else if (setter == null) { } else if (setter == null) {
Player.Message(pKiller, "Cannot collect the bounty, as the player who set it is offline."); Player.Message(pKiller, "Cannot collect the bounty, as the player who set it is offline.");
} else { } else {
CurLevel.ChatLevel("&c" + pKiller.DisplayName + " %Scollected the bounty of &a" + Map.ChatLevel("&c" + pKiller.DisplayName + " %Scollected the bounty of &a" +
bounty.Amount + " %S" + ServerConfig.Currency + " on " + p.ColoredName + "%S."); bounty.Amount + " %S" + ServerConfig.Currency + " on " + p.ColoredName + "%S.");
pKiller.SetMoney(pKiller.money + bounty.Amount); pKiller.SetMoney(pKiller.money + bounty.Amount);
} }
@ -303,7 +307,7 @@ namespace MCGalaxy.Games {
text = infectMessages[random.Next(infectMessages.Count)]; text = infectMessages[random.Next(infectMessages.Count)];
} }
CurLevel.ChatLevel(String.Format(text, Map.ChatLevel(String.Format(text,
"&c" + pKiller.DisplayName + "%S", "&c" + pKiller.DisplayName + "%S",
pAlive.ColoredName + "%S")); pAlive.ColoredName + "%S"));
} }

View File

@ -23,6 +23,7 @@ namespace MCGalaxy.Games {
public sealed partial class ZSGame : IGame { public sealed partial class ZSGame : IGame {
public LevelPicker Picker = new ZSLevelPicker();
/// <summary> Whether players are allowed to teleport to others when not in referee mode. </summary> /// <summary> Whether players are allowed to teleport to others when not in referee mode. </summary>
public override bool TeleportAllowed { get { return !RoundInProgress; } } public override bool TeleportAllowed { get { return !RoundInProgress; } }
@ -37,7 +38,7 @@ namespace MCGalaxy.Games {
} }
public override bool HandlesChatMessage(Player p, string message) { public override bool HandlesChatMessage(Player p, string message) {
if (!Running || (p.level == null || !p.level.name.CaselessEq(CurLevelName))) return false; if (!Running || (p.level == null || !p.level.name.CaselessEq(MapName))) return false;
if (Server.votingforlevel && HandleVote(p, message)) return true; if (Server.votingforlevel && HandleVote(p, message)) return true;
if (message[0] == '~' && message.Length > 1) { if (message[0] == '~' && message.Length > 1) {
@ -45,7 +46,7 @@ namespace MCGalaxy.Games {
string type = p.Game.Infected ? " &cto zombies%S: " : " &ato humans%S: "; string type = p.Game.Infected ? " &cto zombies%S: " : " &ato humans%S: ";
foreach (Player pl in players) { foreach (Player pl in players) {
if (!pl.level.name.CaselessEq(CurLevelName)) continue; if (!pl.level.name.CaselessEq(MapName)) continue;
if (pl.Game.Referee || pl.Game.Infected == p.Game.Infected) if (pl.Game.Referee || pl.Game.Infected == p.Game.Infected)
pl.SendMessage(p.ColoredName + type + message.Substring(1)); pl.SendMessage(p.ColoredName + type + message.Substring(1));
} }
@ -62,9 +63,9 @@ namespace MCGalaxy.Games {
bool HandleVote(Player p, string message) { bool HandleVote(Player p, string message) {
message = message.ToLower(); message = message.ToLower();
if (Player.CheckVote(message, p, "1", "one", ref Votes1) || if (Player.CheckVote(message, p, "1", "one", ref Picker.Votes1) ||
Player.CheckVote(message, p, "2", "two", ref Votes2) || Player.CheckVote(message, p, "2", "two", ref Picker.Votes2) ||
Player.CheckVote(message, p, "3", "three", ref Votes3)) Player.CheckVote(message, p, "3", "three", ref Picker.Votes3))
return true; return true;
return false; return false;
} }
@ -75,7 +76,7 @@ namespace MCGalaxy.Games {
if (!(b.Origin.CaselessEq(p.name) || b.Target.CaselessEq(p.name))) continue; if (!(b.Origin.CaselessEq(p.name) || b.Target.CaselessEq(p.name))) continue;
string target = PlayerInfo.GetColoredName(p, b.Target); string target = PlayerInfo.GetColoredName(p, b.Target);
CurLevel.ChatLevel("Bounty on " + target + " %Sis no longer active."); Map.ChatLevel("Bounty on " + target + " %Sis no longer active.");
Bounties.Remove(b); Bounties.Remove(b);
Player setter = PlayerInfo.FindExact(b.Origin); Player setter = PlayerInfo.FindExact(b.Origin);
@ -87,27 +88,27 @@ namespace MCGalaxy.Games {
p.SendCpeMessage(CpeMessageType.BottomRight3, ""); p.SendCpeMessage(CpeMessageType.BottomRight3, "");
p.SendCpeMessage(CpeMessageType.BottomRight2, ""); p.SendCpeMessage(CpeMessageType.BottomRight2, "");
p.SendCpeMessage(CpeMessageType.BottomRight1, ""); p.SendCpeMessage(CpeMessageType.BottomRight1, "");
if (RoundInProgress && lvl.name.CaselessEq(CurLevelName)) { if (RoundInProgress && lvl.name.CaselessEq(MapName)) {
if (Running && p != null) { if (Running && p != null) {
Player.Message(p, "You joined in the middle of a round. &cYou are now infected!"); Player.Message(p, "You joined in the middle of a round. &cYou are now infected!");
p.Game.BlocksLeft = 25; p.Game.BlocksLeft = 25;
InfectPlayer(p, null); InfectPlayer(p, null);
} }
} }
if (RoundInProgress && oldLvl == CurLevel) { if (RoundInProgress && oldLvl == Map) {
PlayerLeftGame(p); PlayerLeftGame(p);
} }
if (lvl.name.CaselessEq(CurLevelName)) { if (lvl.name.CaselessEq(MapName)) {
double startLeft = (RoundStart - DateTime.UtcNow).TotalSeconds; double startLeft = (RoundStart - DateTime.UtcNow).TotalSeconds;
if (startLeft >= 0) if (startLeft >= 0)
Player.Message(p, "%a" + (int)startLeft + " %Sseconds left until the round starts. %aRun!"); Player.Message(p, "%a" + (int)startLeft + " %Sseconds left until the round starts. %aRun!");
Player.Message(p, "This map has &a" + CurLevel.Config.Likes + Player.Message(p, "This map has &a" + Map.Config.Likes +
" likes %Sand &c" + CurLevel.Config.Dislikes + " dislikes"); " likes %Sand &c" + Map.Config.Dislikes + " dislikes");
Player.Message(p, "This map's win chance is &a" + CurLevel.WinChance + "%S%"); Player.Message(p, "This map's win chance is &a" + Map.WinChance + "%S%");
if (CurLevel.Config.Authors.Length > 0) { if (Map.Config.Authors.Length > 0) {
string[] authors = CurLevel.Config.Authors.Replace(" ", "").Split(','); string[] authors = Map.Config.Authors.Replace(" ", "").Split(',');
Player.Message(p, "It was created by {0}", Player.Message(p, "It was created by {0}",
authors.Join(n => PlayerInfo.GetColoredName(p, n))); authors.Join(n => PlayerInfo.GetColoredName(p, n)));
} }
@ -116,8 +117,7 @@ namespace MCGalaxy.Games {
HUD.UpdateSecondary(this, p); HUD.UpdateSecondary(this, p);
HUD.UpdateTertiary(p); HUD.UpdateTertiary(p);
if (Server.votingforlevel) if (Server.votingforlevel) Picker.SendVoteMessage(p);
LevelPicker.SendVoteMessage(p, this);
return; return;
} }
@ -125,13 +125,13 @@ namespace MCGalaxy.Games {
HUD.Reset(p); HUD.Reset(p);
Alive.Remove(p); Alive.Remove(p);
Infected.Remove(p); Infected.Remove(p);
if (oldLvl != null && oldLvl.name.CaselessEq(CurLevelName)) if (oldLvl != null && oldLvl.name.CaselessEq(MapName))
HUD.UpdateAllPrimary(this); HUD.UpdateAllPrimary(this);
} }
public override void OnHeartbeat(ref string name) { public override void OnHeartbeat(ref string name) {
if (!Running || !ZSConfig.IncludeMapInHeartbeat || CurLevelName == null) return; if (!Running || !ZSConfig.IncludeMapInHeartbeat || MapName == null) return;
name += " (map: " + CurLevelName + ")"; name += " (map: " + MapName + ")";
} }
public override void AdjustPrefix(Player p, ref string prefix) { public override void AdjustPrefix(Player p, ref string prefix) {

View File

@ -63,34 +63,19 @@ namespace MCGalaxy.Games {
/// <summary> The name of the level that the last round of zombie survival was played on. </summary> /// <summary> The name of the level that the last round of zombie survival was played on. </summary>
public string LastLevelName = ""; public string LastLevelName = "";
/// <summary> The name of the level that the current round of zombie survival is being played on. </summary>
public string CurLevelName = "";
/// <summary> The level that the current round of zombie survival is being played on. </summary>
public Level CurLevel = null;
/// <summary> List of alive/human players. </summary> /// <summary> List of alive/human players. </summary>
public VolatileArray<Player> Alive = new VolatileArray<Player>(); public VolatileArray<Player> Alive = new VolatileArray<Player>();
/// <summary> List of dead/infected players. </summary> /// <summary> List of dead/infected players. </summary>
public VolatileArray<Player> Infected = new VolatileArray<Player>(); public VolatileArray<Player> Infected = new VolatileArray<Player>();
public List<string> RecentMaps = new List<string>();
/// <summary> Name of the player queued to be the first zombie in the next round. </summary> /// <summary> Name of the player queued to be the first zombie in the next round. </summary>
public string QueuedZombie; public string QueuedZombie;
/// <summary> Name of the level queued to be used for the next round. </summary>
public string QueuedLevel;
List<string> infectMessages = new List<string>(); List<string> infectMessages = new List<string>();
internal string Candidate1 = "", Candidate2 = "", Candidate3 = "";
internal int Votes1 = 0, Votes2 = 0, Votes3 = 0;
string lastPlayerToInfect = ""; string lastPlayerToInfect = "";
int infectCombo = 0; int infectCombo = 0;
/// <summary> List of players who have a bounty on them. </summary> /// <summary> List of players who have a bounty on them. </summary>
public VolatileArray<BountyData> Bounties = new VolatileArray<BountyData>(); public VolatileArray<BountyData> Bounties = new VolatileArray<BountyData>();

View File

@ -52,28 +52,28 @@ namespace MCGalaxy.Games {
bool SetStartLevel(Level level) { bool SetStartLevel(Level level) {
if (level == null) { if (level == null) {
List<string> levels = LevelPicker.GetCandidateLevels(); List<string> levels = Picker.GetCandidateLevels();
if (levels == null) return false; if (levels == null) return false;
CurLevelName = LevelPicker.GetRandomLevel(new Random(), levels); MapName = LevelPicker.GetRandomLevel(new Random(), levels);
CurLevel = LevelInfo.FindExact(CurLevelName) Map = LevelInfo.FindExact(MapName)
?? CmdLoad.LoadLevel(null, CurLevelName); ?? CmdLoad.LoadLevel(null, MapName);
if (CurLevel == null) return false; if (Map == null) return false;
} else { } else {
CurLevelName = level.name; MapName = level.name;
CurLevel = level; Map = level;
} }
CurLevel.SaveChanges = false; Map.SaveChanges = false;
Chat.MessageGlobal("A game of zombie survival is starting on: {0}", CurLevelName); Chat.MessageGlobal("A game of zombie survival is starting on: {0}", MapName);
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player p in players) { foreach (Player p in players) {
if (p.level != CurLevel) continue; if (p.level != Map) continue;
PlayerJoinedLevel(p, p.level, p.level); PlayerJoinedLevel(p, p.level, p.level);
} }
if (ZSConfig.SetMainLevel) if (ZSConfig.SetMainLevel)
Server.mainLevel = CurLevel; Server.mainLevel = Map;
return true; return true;
} }
@ -85,7 +85,7 @@ namespace MCGalaxy.Games {
if (alive.Length == 0) return; if (alive.Length == 0) return;
int index = random.Next(alive.Length); int index = random.Next(alive.Length);
while (alive[index].Game.Referee || !alive[index].level.name.CaselessEq(CurLevelName)) { while (alive[index].Game.Referee || !alive[index].level.name.CaselessEq(MapName)) {
if (index >= alive.Length - 1) { if (index >= alive.Length - 1) {
index = 0; index = 0;
alive = Alive.Items; alive = Alive.Items;
@ -96,7 +96,7 @@ namespace MCGalaxy.Games {
} }
Player zombie = alive[index]; Player zombie = alive[index];
CurLevel.ChatLevel("&c" + zombie.DisplayName + " %Scontinued the infection!"); Map.ChatLevel("&c" + zombie.DisplayName + " %Scontinued the infection!");
InfectPlayer(zombie, null); InfectPlayer(zombie, null);
} }
@ -141,20 +141,20 @@ namespace MCGalaxy.Games {
internal void ChangeLevel(string next) { internal void ChangeLevel(string next) {
Player[] online = PlayerInfo.Online.Items; Player[] online = PlayerInfo.Online.Items;
if (CurLevel != null) { if (Map != null) {
Level.SaveSettings(CurLevel); Level.SaveSettings(Map);
CurLevel.ChatLevel("The next map has been chosen - " + Colors.red + next.ToLower()); Map.ChatLevel("The next map has been chosen - " + Colors.red + next.ToLower());
CurLevel.ChatLevel("Please wait while you are transfered."); Map.ChatLevel("Please wait while you are transfered.");
} }
string lastLevel = CurLevelName; string lastLevel = MapName;
CurLevelName = next; MapName = next;
QueuedLevel = null; Picker.QueuedMap = null;
CmdLoad.LoadLevel(null, next); CmdLoad.LoadLevel(null, next);
CurLevel = LevelInfo.FindExact(next); Map = LevelInfo.FindExact(next);
CurLevel.SaveChanges = ZSConfig.ChangeLevels; Map.SaveChanges = ZSConfig.ChangeLevels;
if (ZSConfig.SetMainLevel) if (ZSConfig.SetMainLevel)
Server.mainLevel = CurLevel; Server.mainLevel = Map;
online = PlayerInfo.Online.Items; online = PlayerInfo.Online.Items;
List<Player> players = new List<Player>(online.Length); List<Player> players = new List<Player>(online.Length);
@ -198,7 +198,7 @@ namespace MCGalaxy.Games {
Infected.Clear(); Infected.Clear();
Bounties.Clear(); Bounties.Clear();
RecentMaps.Clear(); Picker.RecentMaps.Clear();
foreach (Player pl in online) { foreach (Player pl in online) {
pl.Game.Referee = false; pl.Game.Referee = false;
@ -207,14 +207,13 @@ namespace MCGalaxy.Games {
ResetInvisibility(pl); ResetInvisibility(pl);
pl.SetPrefix(); pl.SetPrefix();
if (pl.level == null || !pl.level.name.CaselessEq(CurLevelName)) if (pl.level == null || !pl.level.name.CaselessEq(MapName)) continue;
continue;
HUD.Reset(pl); HUD.Reset(pl);
} }
LastLevelName = ""; LastLevelName = "";
CurLevelName = ""; MapName = "";
CurLevel = null; Map = null;
UnhookStats(); UnhookStats();
} }

View File

@ -118,7 +118,7 @@ namespace MCGalaxy {
public bool ShouldShowJoinMessage(Level prev) { public bool ShouldShowJoinMessage(Level prev) {
ZSGame zs = Server.zombie; ZSGame zs = Server.zombie;
if (zs.Running && name.CaselessEq(zs.CurLevelName) && if (zs.Running && name.CaselessEq(zs.MapName) &&
(prev == this || zs.LastLevelName.Length == 0 || prev.name.CaselessEq(zs.LastLevelName))) (prev == this || zs.LastLevelName.Length == 0 || prev.name.CaselessEq(zs.LastLevelName)))
return false; return false;
if (Server.lava.active && Server.lava.HasMap(name)) if (Server.lava.active && Server.lava.HasMap(name))
@ -129,7 +129,7 @@ namespace MCGalaxy {
/// <summary> The currently active game running on this map, /// <summary> The currently active game running on this map,
/// or null if there is no game running. </summary> /// or null if there is no game running. </summary>
public IGame CurrentGame() { public IGame CurrentGame() {
if (Server.zombie.Running && name.CaselessEq(Server.zombie.CurLevelName)) if (Server.zombie.Running && name.CaselessEq(Server.zombie.MapName))
return Server.zombie; return Server.zombie;
if (Server.lava.active && Server.lava.map == this) if (Server.lava.active && Server.lava.map == this)
return Server.lava; return Server.lava;

View File

@ -503,6 +503,7 @@
<Compile Include="Games\LavaSurvival\LavaSurvival.Game.cs" /> <Compile Include="Games\LavaSurvival\LavaSurvival.Game.cs" />
<Compile Include="Games\LavaSurvival\LavaSurvival.cs" /> <Compile Include="Games\LavaSurvival\LavaSurvival.cs" />
<Compile Include="Games\LavaSurvival\LavaSurvival.Settings.cs" /> <Compile Include="Games\LavaSurvival\LavaSurvival.Settings.cs" />
<Compile Include="Games\LevelPicker.cs" />
<Compile Include="Games\MovementCheck.cs" /> <Compile Include="Games\MovementCheck.cs" />
<Compile Include="Games\Team.cs" /> <Compile Include="Games\Team.cs" />
<Compile Include="Games\Team.List.cs" /> <Compile Include="Games\Team.List.cs" />