Back to home

Stack Deathmatch

7H2AF
click to copy
This game is archived.
If you with to unarchive it, click the "restore" button in the options menu.
This code can also be found at workshop.codes/7H2AF

Category:
Custom game mode

Author:
CuddlyFlower

Rating:
1

Version:
0.9.3

Posted:
about 1 month ago

Last updated:
20 days ago

Tags:
deathmatch stack

Project Links

Share this workshop!

Options

Killing someone in this deathmatch mode means they are added to your stack - basically, they float above your head and are temporarily added to your team.

settings
{
	main
	{
		Description: "7H2AF - Stack Deathmatch - Players who are killed are added to your stack - discord.gg/YP544CH"
	}

	lobby
	{
		Allow Players Who Are In Queue: Yes
		Map Rotation: After A Game
		Match Voice Chat: Enabled
		Max Spectators: 12
		Return To Lobby: Never
	}

	modes
	{
		Deathmatch
		{
			disabled maps
			{
				Ilios Lighthouse
				Ilios Ruins
				Ilios Well
				Lijiang Control Center
				Lijiang Control Center Lunar New Year
				Lijiang Garden
				Lijiang Garden Lunar New Year
				Lijiang Night Market
				Lijiang Night Market Lunar New Year
				Nepal Sanctum
				Nepal Shrine
				Nepal Village
				Oasis City Center
				Oasis Gardens
				Oasis University
				Workshop Expanse
				Workshop Expanse Night
			}
		}

		General
		{
			Enemy Health Bars: Off
			Game Mode Start: Immediately
			Hero Limit: Off
			Kill Cam: Off
			Score To Win: 40
		}
	}
}

variables
{
	global:
		0: Stack_Offset
		14: Option_Max_Score_Gain
		15: Option_Debug
		16: Option_Health_Gain
		17: Option_Show_Remaining_Players_At
		19: Players_Not_In_Stack
		20: UI_Players_Not_In_Stack
		22: Debug_Bots
		23: Temp_Player
		24: Temp_Index
		25: Temp_Array

	player:
		0: Stack_Parent
		1: Current_Stack_Offset
		2: Players_In_Stack
		3: Health_Gain_Percentage
		4: Score_to_be_gained
		5: Players_to_be_stacked
		6: Start_health
		12: Health_World_Text_Entity
		13: Health_UI_Text_Entity
		14: UI_Stack_Size
		25: Temp_Players
}

subroutines
{
	0: setup_player
	1: reset_stack
	2: remove_ui
	3: disable_abilities
	4: enable_abilities
	5: remove_stack
	6: setup_player_variables
	7: reset_player
}

rule("OPTIONS")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		"Determines how much each person adds towards the health pool of a stack [default: 100]"
		Global.Option_Health_Gain = 100;
		"Maximum score gain - e.g. with 2, you can get two points max for killing a stack, even if it has more people [default: 2]"
		Global.Option_Max_Score_Gain = 2;
		"When number of players not in stack is lower than this number, show icon to avoid hiding [default: 3]"
		Global.Option_Show_Remaining_Players_At = 3;
		"Enable for debugging [default: FALSE]"
		Global.Option_Debug = False;
	}
}

rule("Setup gamemode")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Disable Built-In Game Mode Scoring;
	}
}

rule("Setup globals")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Global.Stack_Offset = 1.900;
		Global.Players_Not_In_Stack = Empty Array;
		Global.UI_Players_Not_In_Stack = Empty Array;
	}
}

rule("Setup players")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	actions
	{
		Call Subroutine(setup_player);
	}
}

rule("Setup spawned players")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Has Spawned(Event Player) == True;
	}

	actions
	{
		Event Player.Health_Gain_Percentage = Global.Option_Health_Gain / Max Health(Event Player) * 100;
		Event Player.Start_health = Health(Event Player);
		Start Damage Modification(Event Player, Event Player.Players_In_Stack, 0, Receivers and Damagers);
		Start Damage Modification(Event Player.Players_In_Stack, Event Player, 0, Receivers and Damagers);
		Start Damage Modification(Event Player.Players_In_Stack, Event Player.Players_In_Stack, 0, Receivers and Damagers);
	}
}

rule("Reset killed players")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Alive(Event Player) == True;
	}

	actions
	{
		Call Subroutine(setup_player);
	}
}

rule("Remove stack if stack parent dead")
{
	event
	{
		Player Died;
		All;
		All;
	}

	actions
	{
		Call Subroutine(remove_stack);
	}
}

rule("Remove stack if stack parent disconnects")
{
	event
	{
		Player Left Match;
		All;
		All;
	}

	actions
	{
		For Global Variable(Temp_Index, 0, Count Of(All Players(All Teams)), 1);
			Global.Temp_Player = All Players(All Teams)[Global.Temp_Index];
			If(Global.Temp_Player.Stack_Parent == Event Player);
				Call Subroutine(reset_player);
			End;
			If(Array Contains(Global.Temp_Player.Players_In_Stack, Event Player) == True);
				Global.Temp_Player.Players_In_Stack = Remove From Array(Global.Temp_Player.Players_In_Stack, Event Player);
				Set Max Health(Global.Temp_Player, 100   Count Of(Global.Temp_Player.Players_In_Stack)
					* Global.Temp_Player.Health_Gain_Percentage);
			End;
		End;
	}
}

rule("Set stack parent when dead")
{
	event
	{
		Player Died;
		All;
		All;
	}

	conditions
	{
		(Array Contains(Attacker.Players_to_be_stacked, Event Player) || Array Contains(Attacker.Stack_Parent.Players_to_be_stacked,
			Event Player)) == True;
		Attacker != Event Player;
	}

	actions
	{
		If(Attacker.Stack_Parent != Null);
			Event Player.Stack_Parent = Attacker.Stack_Parent;
		Else;
			Event Player.Stack_Parent = Attacker;
		End;
		Resurrect(Event Player);
		Attacker.Players_to_be_stacked = Empty Array;
		Attacker.Stack_Parent.Players_to_be_stacked = Empty Array;
	}
}

rule("Stack on parent when respawned")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Has Spawned(Event Player) == True;
		Is Alive(Event Player) == True;
		Event Player.Stack_Parent != Null;
	}

	actions
	{
		Attach Players(Event Player, Event Player.Stack_Parent, Vector(0, Event Player.Stack_Parent.Current_Stack_Offset, 0));
		Modify Global Variable(Players_Not_In_Stack, Remove From Array By Value, Event Player);
		Event Player.Stack_Parent.Current_Stack_Offset  = 2;
		Modify Player Variable(Event Player.Stack_Parent, Players_In_Stack, Append To Array, Event Player);
		Set Max Health(Event Player.Stack_Parent, 100   Count Of(Event Player.Stack_Parent.Players_In_Stack)
			* Event Player.Stack_Parent.Health_Gain_Percentage);
		Set Status(Event Player, Null, Unkillable, 9999);
		Set Status(Event Player, Null, Rooted, 9999);
		Set Max Health(Event Player, 1000);
	}
}

rule("Set player score of attacker")
{
	event
	{
		Player Died;
		All;
		All;
	}

	conditions
	{
		Attacker != Null;
		Attacker != Event Player;
	}

	actions
	{
		Event Player.Score_to_be_gained = Min(1   Count Of(Event Player.Players_In_Stack), Global.Option_Max_Score_Gain);
		If(Attacker.Stack_Parent == Null && Count Of(Attacker.Players_In_Stack) <= 0);
			Modify Player Score(Attacker, Event Player.Score_to_be_gained);
		Else If(Attacker.Stack_Parent != Null);
			Modify Player Score(Attacker.Stack_Parent, Event Player.Score_to_be_gained);
			Modify Player Score(Attacker.Stack_Parent.Players_In_Stack, Event Player.Score_to_be_gained);
		Else;
			Modify Player Score(Attacker, Event Player.Score_to_be_gained);
			Modify Player Score(Attacker.Players_In_Stack, Event Player.Score_to_be_gained);
		End;
	}
}

rule("Redistribute damage to stack parent")
{
	event
	{
		Player Took Damage;
		All;
		All;
	}

	conditions
	{
		Event Player.Stack_Parent != Null;
		Has Status(Event Player, Unkillable) == True;
	}

	actions
	{
		Damage(Event Player.Stack_Parent, Attacker, Event Damage);
		Heal(Event Player, Null, Max Health(Event Player));
	}
}

rule("Reset if full stack achieved")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Count Of(Event Player.Players_In_Stack) >= Count Of(All Players(All Teams)) - 1;
		Count Of(All Players(All Teams)) > 1;
	}

	actions
	{
		Big Message(All Players(All Teams), Custom String("Full Stack! Reset..."));
		Wait(1, Ignore Condition);
		Small Message(All Players(All Teams), Custom String("3"));
		Wait(1, Ignore Condition);
		Small Message(All Players(All Teams), Custom String("2"));
		Wait(1, Ignore Condition);
		Small Message(All Players(All Teams), Custom String("1"));
		Wait(1, Ignore Condition);
		Kill(Event Player, Null);
		Call Subroutine(reset_stack);
	}
}

rule("Subroutine: remove stack")
{
	event
	{
		Subroutine;
		remove_stack;
	}

	actions
	{
		If(Attacker.Stack_Parent != Null);
			Modify Player Variable(Attacker.Stack_Parent, Players_to_be_stacked, Append To Array, Event Player);
		Else;
			Modify Player Variable(Attacker, Players_to_be_stacked, Append To Array, Event Player);
		End;
		Call Subroutine(reset_stack);
		Call Subroutine(setup_player_variables);
	}
}

rule("Subroutine: setup player")
{
	event
	{
		Subroutine;
		setup_player;
	}

	actions
	{
		Call Subroutine(setup_player_variables);
		Wait(1, Ignore Condition);
		If(Event Player.Stack_Parent == Null);
			If(Array Contains(Global.Players_Not_In_Stack, Event Player) == False);
				Modify Global Variable(Players_Not_In_Stack, Append To Array, Event Player);
			End;
			Set Max Health(Event Player, 100);
		End;
	}
}

rule("Subroutine: setup player variables")
{
	event
	{
		Subroutine;
		setup_player_variables;
	}

	actions
	{
		Event Player.Current_Stack_Offset = Global.Stack_Offset;
		Event Player.Players_In_Stack = Empty Array;
		disabled Event Player.Temp_Players = Empty Array;
		Event Player.Players_to_be_stacked = Empty Array;
		Call Subroutine(remove_ui);
	}
}

rule("Subroutine: reset stack")
{
	event
	{
		Subroutine;
		reset_stack;
	}

	actions
	{
		If(Count Of(Event Player.Players_In_Stack) != 0);
			Event Player.Temp_Players = Event Player.Players_In_Stack;
			Event Player.Temp_Players.Stack_Parent = Null;
			Clear Status(Event Player.Temp_Players, Unkillable);
			Clear Status(Event Player.Temp_Players, Rooted);
			Detach Players(Event Player.Temp_Players);
			Wait(0.100, Ignore Condition);
			Kill(Event Player.Temp_Players, Null);
			Damage(Event Player.Temp_Players, Attacker, 10000);
		End;
	}
}

rule("Subroutine: reset player")
{
	event
	{
		Subroutine;
		reset_player;
	}

	actions
	{
		Global.Temp_Player.Stack_Parent = Null;
		Clear Status(Global.Temp_Player, Unkillable);
		Clear Status(Global.Temp_Player, Rooted);
		Detach Players(Global.Temp_Player);
		Wait(0.100, Ignore Condition);
		Kill(Global.Temp_Player, Null);
		Damage(Global.Temp_Player, Attacker, 10000);
		Global.Temp_Player = Null;
	}
}

disabled rule("Subroutine: disable abilities")
{
	event
	{
		Subroutine;
		disable_abilities;
	}

	actions
	{
		If(Hero Of(Event Player) == Hero(Tracer));
		End;
	}
}

disabled rule("Subroutine: enable abilities")
{
	event
	{
		Subroutine;
		enable_abilities;
	}
}

rule("Test: create bots")
{
	event
	{
		Ongoing - Global;
	}

	conditions
	{
		Global.Option_Debug == True;
		Is Game In Progress == True;
	}

	actions
	{
		Create Dummy Bot(Hero(Ana), All Teams, -1, Nearest Walkable Position(Vector(5, 0, 0)), Vector(0, 0, 0));
		Create Dummy Bot(Hero(Ashe), All Teams, -1, Nearest Walkable Position(Vector(0, 0, 5)), Vector(0, 0, 0));
		Create Dummy Bot(Hero(Moira), All Teams, -1, Nearest Walkable Position(Vector(-5, 0, 0)), Vector(0, 0, 0));
		Create Dummy Bot(Hero(Genji), All Teams, -1, Nearest Walkable Position(Vector(0, 0, -5)), Vector(0, 0, 0));
		Create Dummy Bot(Hero(Torbjörn), All Teams, -1, Nearest Walkable Position(Vector(5, 0, 5)), Vector(0, 0, 0));
		Create Dummy Bot(Hero(Mercy), All Teams, -1, Nearest Walkable Position(Vector(-5, 0, -5)), Vector(0, 0, 0));
		Wait(0.250, Ignore Condition);
		Global.Debug_Bots = Filtered Array(All Players(All Teams), Is Dummy Bot(Current Array Element) == True);
	}
}

disabled rule("Test: damage stack")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Global.Option_Debug == True;
		Host Player == Event Player;
		Is Button Held(Event Player, Interact) == True;
	}

	actions
	{
		Damage(Random Value In Array(Event Player.Players_In_Stack), Random Value In Array(All Living Players(All Teams)), 200);
	}
}

disabled rule("Test: create bot stack")
{
	event
	{
		Ongoing - Global;
	}

	conditions
	{
		Global.Option_Debug == True;
		Is Button Held(Host Player, Interact) == True;
	}

	actions
	{
		Global.Temp_Array = Filtered Array(All Players(All Teams), Current Array Element != Host Player);
		Damage(Random Value In Array(Global.Temp_Array), Random Value In Array(Global.Temp_Array), 200);
	}
}

disabled rule("Test: stack damages parent")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Global.Option_Debug == True;
		Host Player == Event Player;
		Is Button Held(Event Player, Interact) == True;
	}

	actions
	{
		Damage(Host Player, Random Value In Array(Host Player.Players_In_Stack), 50);
	}
}

rule("Test: bot damages player")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Global.Option_Debug == True;
		Host Player == Event Player;
		Is Button Held(Event Player, Interact) == True;
	}

	actions
	{
		Damage(Host Player, First Of(Global.Debug_Bots), 50);
	}
}

disabled rule("Test: remove bots")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Global.Option_Debug == True;
		Host Player == Event Player;
		Is Button Held(Event Player, Reload) == True;
	}

	actions
	{
		Destroy All Dummy Bots;
	}
}

rule("UI - Global")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Create HUD Text(All Players(All Teams), Null, Custom String("discord.gg/YP544CH"), Custom String("7H2AF - Version 0.93"), Right, 0,
			White, White, White, Visible To and String, Default Visibility);
		If(Global.Option_Debug == True);
			Create HUD Text(All Players(All Teams), Icon String(Exclamation Mark), Custom String("Debug Mode On!"), Null, Left, 0, White,
				White, White, Visible To and String, Default Visibility);
		End;
	}
}

rule("UI - Each Player")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Game In Progress == True;
	}

	actions
	{
		Create HUD Text(Append To Array(Event Player.Players_In_Stack, Event Player), Icon String(Arrow: Up), Custom String("Stack Size"),
			Custom String("{0} of {1} players", Count Of(Event Player.Players_In_Stack), Count Of(All Players(All Teams)) - 1), Left, 0,
			Sky Blue, White, White, Visible To and String, Default Visibility);
		Event Player.UI_Stack_Size = Last Text ID;
	}
}

rule("UI - Player stack health on")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Count Of(Event Player.Players_In_Stack) != 0;
		Event Player.Health_UI_Text_Entity == Null;
		Is Alive(Event Player) == True;
	}

	actions
	{
		Create In-World Text(All Players(All Teams), Health(Event Player), Position Of(Event Player)   Vector(0,
			Event Player.Current_Stack_Offset   -0.500, 0), 1.500, Clip Against Surfaces, Visible To Position and String, Red,
			Visible Always);
		Event Player.Health_World_Text_Entity = Last Text ID;
		Wait(0.016, Ignore Condition);
		Create HUD Text(Append To Array(Event Player.Players_In_Stack, Event Player), Icon String(Plus), Custom String("Stack Health"),
			Health(Event Player), Left, 0, Red, White, White, Visible To and String, Default Visibility);
		Event Player.Health_UI_Text_Entity = Last Text ID;
		Wait(0.016, Ignore Condition);
		disabled Create HUD Text(Append To Array(Event Player.Players_In_Stack, Event Player), Icon String(Arrow: Up), Custom String("Stack Size"),
			Custom String("{0} of {1}", Count Of(Event Player.Players_In_Stack), Count Of(All Players(All Teams)) - 1), Left, 0, Sky Blue,
			White, White, Visible To and String, Default Visibility);
		disabled Event Player.UI_Stack_Size = Last Text ID;
	}
}

rule("UI - Show remaining players")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Count Of(Event Player.Players_In_Stack) == 0;
		Count Of(Global.Players_Not_In_Stack) < Global.Option_Show_Remaining_Players_At;
		Array Contains(Global.Players_Not_In_Stack, Event Player) == True;
	}

	actions
	{
		Create Icon(All Players(All Teams), Event Player, Skull, Visible To and Position, Red, True);
		Global.UI_Players_Not_In_Stack = Append To Array(Global.UI_Players_Not_In_Stack, Last Created Entity);
	}
}

rule("UI - Do not show remaining players")
{
	event
	{
		Ongoing - Global;
	}

	conditions
	{
		Count Of(Global.UI_Players_Not_In_Stack) > 0;
		(Count Of(Global.Players_Not_In_Stack) >= Global.Option_Show_Remaining_Players_At || Count Of(Global.Players_Not_In_Stack) <= 1)
			== True;
	}

	actions
	{
		For Global Variable(Temp_Index, 0, Count Of(Global.UI_Players_Not_In_Stack), 1);
			Destroy Icon(Global.UI_Players_Not_In_Stack[Global.Temp_Index]);
		End;
		Global.UI_Players_Not_In_Stack = Empty Array;
	}
}

rule("Subroutine: UI - Player stack health off")
{
	event
	{
		Subroutine;
		remove_ui;
	}

	actions
	{
		Destroy In-World Text(Event Player.Health_World_Text_Entity);
		Destroy HUD Text(Event Player.Health_UI_Text_Entity);
		disabled Destroy HUD Text(Event Player.UI_Stack_Size);
		Event Player.Health_World_Text_Entity = Null;
		Event Player.Health_UI_Text_Entity = Null;
		disabled Event Player.UI_Stack_Size = Null;
	}
}

rule("Have Fun! --CuddlyFlower")
{
	event
	{
		Ongoing - Global;
	}
}

Changelog

20 days ago 0.9.3

More bug fixes, added feature for detecting last players without stack

7H2AF
click to copy
21 days ago 0.9.0

This revision contains no notes

7H2AF
click to copy
about 1 month ago 0.9.0

This revision contains no notes

PRNXZ
click to copy