void HandleBlockChange(Player p, ushort x, ushort y, ushort z, BlockID block, bool placing) { if (p.level != Map) { return; } BlockID old = Map.GetBlock(x, y, z); if (Map.Config.BuildType == BuildType.NoModify) { p.RevertBlock(x, y, z); p.cancelBlock = true; return; } if (Map.Config.BuildType == BuildType.ModifyOnly && Map.Props[old].OPBlock) { p.RevertBlock(x, y, z); p.cancelBlock = true; return; } if (p.Game.Referee) { return; } ZSData data = Get(p); // Check pillaring if (placing && !Map.Config.Pillaring) { if (NotPillaring(block, old)) { data.BlocksStacked = 0; } else if (CheckCoords(p, data, x, y, z)) { data.BlocksStacked++; } else { data.BlocksStacked = 0; } if (WarnPillaring(p, data, x, y, z)) { p.cancelBlock = true; return; } } data.LastX = x; data.LastY = y; data.LastZ = z; if (placing || (!placing && p.painting)) { if (data.BlocksLeft <= 0) { p.Message("You have no blocks left."); p.RevertBlock(x, y, z); p.cancelBlock = true; return; } data.BlocksLeft--; if ((data.BlocksLeft % 10) == 0 || data.BlocksLeft <= 10) { p.Message("Blocks Left: &4" + data.BlocksLeft); } } }
void HandleJoinedLevel(Player p, Level prevLevel, Level level, ref bool announce) { HandleJoinedCommon(p, prevLevel, level, ref announce); p.SetPrefix(); // TODO: Kinda hacky, not sure if needed if (level != Map) { return; } ZSData data = Get(p); p.SetPrefix(); if (RoundInProgress) { p.Message("You joined in the middle of a round. &cYou are now infected!"); data.BlocksLeft = 25; InfectPlayer(p, null); } double startLeft = (RoundStart - DateTime.UtcNow).TotalSeconds; if (startLeft >= 0) { p.Message("&a{0} %Sseconds left until the round starts. &aRun!", (int)startLeft); } MessageMapInfo(p); p.Message("This map's win chance is &a{0}%S%", Map.WinChance); }
static void PrintOnlineZSStats(Player p, Player who) { ZSData data = Get(who); PrintZSStats(p, data.TotalRoundsSurvived, data.TotalInfected, data.MaxRoundsSurvived, data.MaxInfected); }
void ResetPlayerState(Player p, ZSData data, bool infected) { data.Infected = infected; data.BlocksLeft = infected ? 25 : 50; ResetInvisibility(p, data); UpdateAllStatus1(); UpdateStatus3(p); }
static void ResetRoundState(Player p, ZSData data) { p.infected = false; data.BlocksLeft = 50; data.CurrentInfected = 0; data.InvisibilityPotions = 0; data.RevivesUsed = 0; data.TimeInfected = DateTime.MinValue; }
public void GoInvisible(Player p, int duration) { ZSData data = Get(p); data.Invisible = true; data.InvisibilityEnd = DateTime.UtcNow.AddSeconds(duration); Map.Message(p.ColoredName + " &Svanished. &a*POOF*"); Entities.GlobalDespawn(p, false, false); }
void ResetInvisibility(Player p, ZSData data) { if (!data.Invisible) { return; } p.SendCpeMessage(CpeMessageType.BottomRight2, ""); data.ResetInvisibility(); Entities.GlobalSpawn(p, false); }
void DoCollisions(Player[] aliveList, Player[] deadList, Random random) { int dist = (int)(Config.HitboxDist * 32); foreach (Player killer in deadList) { ZSData killerData = Get(killer); killerData.Infected = true; aliveList = Alive.Items; foreach (Player alive in aliveList) { if (alive == killer) { continue; } if (!InRange(alive, killer, dist)) { continue; } if (killerData.Infected && !Get(alive).Infected && !alive.Game.Referee && !killer.Game.Referee && killer.level == Map && alive.level == Map) { InfectPlayer(alive, killer); if (lastKiller == killer.name) { infectCombo++; if (infectCombo >= 2) { killer.Message("You gained " + (2 + infectCombo) + " " + Server.Config.Currency); killer.SetMoney(killer.money + (2 + infectCombo)); Map.Message("&c" + killer.DisplayName + " &Sis on a rampage! " + (infectCombo + 1) + " infections in a row!"); } } else { infectCombo = 0; } lastKiller = killer.name; killerData.CurrentInfected++; killerData.TotalInfected++; killerData.MaxInfected = Math.Max(killerData.CurrentInfected, killerData.MaxInfected); ShowInfectMessage(random, alive, killer); Thread.Sleep(50); } } } }
static bool CheckCoords(Player p, ZSData data, ushort x, ushort y, ushort z) { if (data.LastY != y - 1 || data.LastX != x || data.LastZ != z) { return(false); } int minX = (p.Pos.X - 8) / 32, minZ = (p.Pos.Z - 8) / 32; int maxX = (p.Pos.X + 8) / 32, maxZ = (p.Pos.Z + 8) / 32; // Check the four possible coords/blocks the player could be pillaring up on return((minX == x && minZ == z) || (minX == x && maxZ == z) || (maxX == x && minZ == z) || (maxX == x && maxZ == z)); }
public void DisinfectPlayer(Player p) { if (!RoundInProgress) { return; } Infected.Remove(p); Alive.Add(p); ZSData data = Get(p); ResetPlayerState(p, data, false); RespawnPlayer(p); }
void IncreaseAliveStats(Player p) { if (p.Game.PledgeSurvive) { p.Message("You received &a5 &3" + Server.Config.Currency + " &Sfor successfully pledging that you would survive."); p.SetMoney(p.money + 5); } ZSData data = Get(p); data.CurrentRoundsSurvived++; data.TotalRoundsSurvived++; data.MaxRoundsSurvived = Math.Max(data.CurrentRoundsSurvived, data.MaxRoundsSurvived); p.SetPrefix(); // stars before name }
void HandleCanSeeEntity(Player p, ref bool canSee, Entity other) { Player target = other as Player; if (!canSee || p.Game.Referee || target == null) { return; } ZSData data = TryGet(target); if (data == null) { return; } canSee = !(target.Game.Referee || data.Invisible); }
void CheckInvisibilityTime() { DateTime now = DateTime.UtcNow; Player[] players = PlayerInfo.Online.Items; foreach (Player p in players) { if (p.level != Map) { continue; } ZSData data = Get(p); if (!data.Invisible) { continue; } DateTime end = data.InvisibilityEnd; if (now >= end) { p.Message("&cYou are &bvisible &cagain"); ResetInvisibility(p, data); continue; } int left = (int)Math.Ceiling((end - now).TotalSeconds); if (left == data.InvisibilityTime) { continue; } data.InvisibilityTime = left; string msg = "&bInvisibility for &a" + left; if (p.Supports(CpeExt.MessageTypes)) { p.SendCpeMessage(CpeMessageType.BottomRight2, msg); } else { p.Message(msg); } } }
internal static ZSData Get(Player p) { ZSData data = TryGet(p); if (data != null) { return(data); } data = new ZSData(); // TODO: Is this even thread-safe data.InfectMessages = ZSConfig.LoadPlayerInfectMessages(p.name); ZombieStats s = LoadStats(p.name); data.MaxInfected = s.MaxInfected; data.TotalInfected = s.TotalInfected; data.MaxRoundsSurvived = s.MaxRounds; data.TotalRoundsSurvived = s.TotalRounds; p.Extras[zsExtrasKey] = data; return(data); }
static int GetMoneyReward(Player pl, ZSData data, Player[] alive, Random rand) { if (pl.IsLikelyInsideBlock()) { return(-1); } if (alive.Length == 0) { return(rand.Next(1 + data.CurrentInfected, 5 + data.CurrentInfected)); } else if (alive.Length == 1 && !data.Infected) { return(rand.Next(5, 10)); } else if (alive.Length > 1 && !data.Infected) { return(rand.Next(2, 6)); } return(0); }
public void InfectPlayer(Player p, Player killer) { if (!RoundInProgress) { return; } Infected.Add(p); Alive.Remove(p); ZSData data = Get(p); data.CurrentRoundsSurvived = 0; data.TimeInfected = DateTime.UtcNow; p.SetPrefix(); ResetPlayerState(p, data, true); RespawnPlayer(p); CheckHumanPledge(p, killer); CheckBounty(p, killer); }
protected override void EndGame() { RoundEnd = DateTime.MinValue; UnhookStats(); Alive.Clear(); Infected.Clear(); Bounties.Clear(); Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (pl.level != Map) { continue; } ZSData data = Get(pl); data.ResetState(); ResetInvisibility(pl, data); } }
void GiveMoney(Player[] alive) { Player[] online = PlayerInfo.Online.Items; Random rand = new Random(); foreach (Player pl in online) { if (pl.level != Map) { continue; } ZSData data = Get(pl); data.ResetInvisibility(); int reward = GetMoneyReward(pl, data, alive, rand); if (reward == -1) { pl.Message("You may not hide inside a block! No " + Server.Config.Currency + " for you."); reward = 0; } else if (reward > 0) { pl.Message("&6You gained " + reward + " " + Server.Config.Currency); } pl.SetMoney(pl.money + reward); data.ResetState(); pl.Game.PledgeSurvive = false; if (pl.Game.Referee) { pl.Message("You gained one " + Server.Config.Currency + " because you're a ref. Would you like a medal as well?"); pl.SetMoney(pl.money + 1); } RespawnPlayer(pl); UpdateStatus3(pl); } }
protected override void SaveStats(Player p) { ZSData data = TryGet(p); if (data == null || (data.TotalRoundsSurvived == 0 && data.TotalInfected == 0)) { return; } int count = Database.CountRows("ZombieStats", "WHERE Name=@0", p.name); if (count == 0) { Database.AddRow("ZombieStats", "TotalRounds, MaxRounds, TotalInfected, MaxInfected, Name", data.TotalRoundsSurvived, data.MaxRoundsSurvived, data.TotalInfected, data.MaxInfected, p.name); } else { Database.UpdateRows("ZombieStats", "TotalRounds=@0, MaxRounds=@1, TotalInfected=@2, MaxInfected=@3", "WHERE Name=@4", data.TotalRoundsSurvived, data.MaxRoundsSurvived, data.TotalInfected, data.MaxInfected, p.name); } }
static bool WarnPillaring(Player p, ZSData data, ushort x, ushort y, ushort z, bool nonReplacable) { if ((!nonReplacable && data.BlocksStacked == 2) || (nonReplacable && data.BlocksStacked == 1)) { TimeSpan delta = DateTime.UtcNow - data.LastPillarWarn; if (delta.TotalSeconds >= 5) { Chat.MessageFromOps(p, " &cWarning: λNICK %Sis pillaring!"); data.LastPillarWarn = DateTime.UtcNow; } string action = data.PillarFined ? "kicked" : "fined 10 " + Server.Config.Currency; p.Message("You are pillaring! %WStop before you are " + action + "!"); } else if ((!nonReplacable && data.BlocksStacked == 4) || (nonReplacable && data.BlocksStacked == 2)) { if (!data.PillarFined) { Chat.MessageFromOps(p, " &cWarning: λNICK %Sis pillaring!"); Command.Find("Take").Use(Player.Console, p.name + " 10 Auto fine for pillaring"); p.Message(" %WThe next time you pillar, you will be &4kicked!"); } else { ModAction action = new ModAction(p.name, Player.Console, ModActionType.Kicked, "Auto kick for pillaring"); OnModActionEvent.Call(action); p.Kick("No pillaring allowed!"); } p.RevertBlock(x, y, z); data.PillarFined = true; data.BlocksStacked = 0; return(true); } return(false); }