//==================================================================// //============< #DeathMatch GAMEMODE BY #OCTOTHORP >=============// //============< v1.0 >=============// //==================================================================// //========================< #DM - settings >========================// //=========================================================// private const float RESPAWN_DELAY = (float) 3000; private const bool GIB_CORPSES_ON_RESPAWN = true; private const int KILLS_LIMIT = 25; //==================================================================// //=================< DO NOT TOUCH ANYTHING IN BELOW >===============// //==============< IF YOU'RE NOT SURE WHAT YOU'RE DOING >============// //==================================================================// private class PlyData { private IPlayer Body = null; private IUser User = null; private PlayerTeam Team = PlayerTeam.Independent; private float RespawnTime = 0f; public PlyData(IPlayer ply, IUser user, PlayerTeam team, float respawnTime){ this.Body = ply; this.User = user; this.Team = team; this.RespawnTime = respawnTime; } public float GetRespawnTime() {return this.RespawnTime;} public IPlayer GetBody() {return this.Body;} public IUser GetUser() {return this.User;} public PlayerTeam GetTeam() {return this.Team;} } private class ModData{ private IGame Game; private string Version = "1.0"; public int Kills = 0; // we'll add something else later // constructor public ModData(IGame game){ this.Game = game; } public string GetVersion() {return this.Version;} public void Message(string text){ Game.RunCommand("/MSG #DeathMatch: " + text); } } string[] restrictedMaps = new string[]{ // these maps are hard-scripted, though their MapType is Versus "#Abadoned Subway (BG)" }; Random rand = new Random(); private ModData Mod = null; private List spawnQueue = new List(); private int usersAmount = 0; private int lastKills = 0; // =====< THE CODE >===== // public void OnStartup(){ // check if map is not hard-scripted so that scripts won't conflict bool mapIsGood = true; if (Game.GetMapType() == MapType.Custom) mapIsGood = false; else foreach (string mapName in restrictedMaps) if (mapName == Game.MapName) mapIsGood = false; if (mapIsGood){ Mod = new ModData(Game); Game.SetMapType(MapType.Custom); usersAmount = Game.GetActiveUsers().Length; // death trigger IObjectTrigger deathTrigger = (IObjectTrigger)Game.CreateObject("OnPlayerDeathTrigger"); deathTrigger.SetScriptMethod("Death"); // tick triggers // respawn tick trigger CreateTimer(150, 0, "Tick_Respawn", ""); // check connected users tick trigger CreateTimer(250, 0, "Tick_CheckUsers", ""); // check connected users tick trigger CreateTimer(15000, 0, "Tick_CleanUp", ""); // some annotations CheckGameOver(); Mod.Message("v" + Mod.GetVersion()); } else { Mod.Message("This map is restricted."); } } public void Death(TriggerArgs args){ IPlayer ply = (IPlayer)args.Sender; IUser user = ply.GetUser(); if (user != null && UserStillHere(user)){ spawnQueue.Add(new PlyData(ply, user, ply.GetTeam(), FromNow(RESPAWN_DELAY))); Mod.Kills ++; //Mod.Message(user.GetProfile().Name + " died!"); } else { Game.PlayEffect("PWT", ply.GetWorldPosition(), "PLAYER LEFT"); Game.TriggerExplosion(ply.GetWorldPosition()); ply.Gib(); } CheckGameOver(); } public void Tick_Respawn(TriggerArgs args){ if (!Game.IsGameOver){ for (int i = spawnQueue.Count - 1; i >= 0; i--){ PlyData data = spawnQueue[i]; if (Game.TotalElapsedGameTime >= data.GetRespawnTime()){ // respawn player if user is here if (UserStillHere(data.GetUser())){ SpawnPlayer(data.GetUser(), data.GetTeam()); //Mod.Message(data.GetUser().GetProfile().Name + " spawned!"); } // remove the corpse if (data.GetBody() != null){ if (GIB_CORPSES_ON_RESPAWN) data.GetBody().Gib(); else data.GetBody().Remove(); } // remove entry from spawning queue spawnQueue.RemoveAt(i); } } } else { spawnQueue.Clear(); foreach (IPlayer ply in Game.GetPlayers()){ Game.TriggerExplosion(ply.GetWorldPosition()); ply.Gib(); } } } public void Tick_CleanUp(TriggerArgs args){ IObject[] objectsToRemove = Game.GetObjectsByName(new string[]{ "GIBLET00", "GIBLET01", "GIBLET02", "GIBLET03", "GIBLET04"}); for (int i = 0; i < objectsToRemove.Length; i ++) objectsToRemove[i].Remove(); } public void Tick_CheckUsers(TriggerArgs args){ if (usersAmount < Game.GetActiveUsers().Length){ foreach (IUser user in Game.GetActiveUsers()){ if (user.GetPlayer() == null){ bool justConnected = true; foreach (PlyData data in spawnQueue) if (data.GetUser().UserId == user.UserId) justConnected = false; if (justConnected) spawnQueue.Add(new PlyData(null, user, TeamAutoChoose(), FromNow(5000f))); } } } usersAmount = Game.GetActiveUsers().Length; } private void SpawnPlayer(IUser user, PlayerTeam team){ IObject[] spawns = Game.GetObjectsByName("SpawnPlayer"); Vector2 spawnPos = spawns[rand.Next(spawns.Length)].GetWorldPosition(); IPlayer revivedPlayer = Game.CreatePlayer(spawnPos); revivedPlayer.SetUser(user); revivedPlayer.SetProfile(user.GetProfile()); revivedPlayer.SetTeam(team); Game.PlayEffect("PWT", spawnPos, "Spawned!"); Game.PlayEffect("Electric", spawnPos + new Vector2(0, 8)); Game.PlaySound("ItemSpawn", spawnPos, 1f); CheckGameOver(); } private void CheckGameOver(){ Color col = new Color(100,220,255); if (Mod.Kills != lastKills){ if ((KILLS_LIMIT - Mod.Kills) % 10 == 0 && Mod.Kills != KILLS_LIMIT) Mod.Message((KILLS_LIMIT - Mod.Kills).ToString() + " kills remaining!"); switch (Mod.Kills){ case KILLS_LIMIT - 5: Mod.Message("5 kills remaining!"); break; case KILLS_LIMIT - 1: Mod.Message("Last kill remaining!"); break; } } if (Mod.Kills >= KILLS_LIMIT){ Game.SetGameOver("Kills limit reached"); Game.ShowPopupMessage("Total kills: " + KILLS_LIMIT.ToString() + " / " + KILLS_LIMIT.ToString(), col); } else { Game.ShowPopupMessage("Total kills: " + Mod.Kills.ToString() + " / " + KILLS_LIMIT.ToString(), col); } lastKills = Mod.Kills; } // =====< helpers >===== // private float FromNow(float delay) {return Game.TotalElapsedGameTime + delay;} private bool UserStillHere(IUser user){ foreach (IUser usr in Game.GetActiveUsers()) if (usr.UserId == user.UserId) return true; return false; } private PlayerTeam TeamAutoChoose(){ Dictionary teams = new Dictionary(); // create list of teams and amount of players in it foreach (IUser user in Game.GetActiveUsers()){ if (user.GetPlayer() != null){ PlayerTeam team = user.GetPlayer().GetTeam(); if (teams.ContainsKey(team)) teams[team] ++; else teams.Add(team, 1); } } // find out the team with the least amount of players and return it PlayerTeam minTeam = PlayerTeam.Independent; int minTeamAmount = 8; foreach (KeyValuePair pair in teams){ if (pair.Value < minTeamAmount){ minTeamAmount = pair.Value; minTeam = pair.Key; } } if (teams.Count < 2 && !teams.ContainsKey(PlayerTeam.Independent)) Game.SetGameOver("Round restart needed!"); return minTeam; } private void CreateTimer(int interval, int count, string method, string id){ IObjectTimerTrigger timerTrigger = (IObjectTimerTrigger)Game.CreateObject("TimerTrigger"); timerTrigger.SetIntervalTime(interval); timerTrigger.SetRepeatCount(count); timerTrigger.SetScriptMethod(method); timerTrigger.CustomId = id; timerTrigger.Trigger(); }