Back to home

Quick-Swap OW - No Role Lock

S4GRQ
click to copy
This game is archived.
If you with to unarchive it, click the "restore" button in the options menu.

Category:
Other

Author:
TehCupcakes

Rating:
2

Version:
1.0.0

Posted:
6 months ago

Last updated:
6 months ago

Tags:
swap hero

Share this workshop!

Options

Standard Overwatch, with a twist: you can swap heroes outside of spawn! To make this manageable within the workshop's limitations, however, you can only select 3 heroes for your quick swap rotation. Each hero retains their own ultimate charge, so you can even bank up to three ultimates and use them in rapid succession.

The goal of this mode is to provide opportunities to synergize hero abilities spontaneously and creatively. Use a high-mobility hero to get a low-mobility hero in a position they could not, or back to the point much faster than usual. Swap to a hero with self-healing if you're low on health. Counter your opponents' picks in a rapid back-and-forth swap battle! The possibilities are nearly endless. :)

Swapping has a few limitations to prevent abuse and escaping certain death:

  • Your health after swapping will be the same percentage as it was before you swapped.
  • After swapping, your previously used hero will be unavailable to swap for 5 seconds. This prevents cooldown abuse where you cycle all three heroes instantly to get a cooldown back. You can still use swaps to reduce cooldown for some of the longer cooldown abilities, but I thought 5 seconds was a good trade-off that still allows you to switch back and forth freely without too much abuse.
  • You cannot swap while you are impacted by negative status effects. (Stun, sleep, freeze, etc.)
  • D.va is unavailable. There is currently no way in the workshop to identify if D.va is in her mech, and it didn't seem fair to allow swapping to a full health hero after being demeched.

Like most Overwatch modes, this plays best with a full lobby. It is essentially an add-on that introduces a new feature, rather than trying to change existing Overwatch modes.

This version has no role lock, so you can add any combination of damage, support, and tank to your quick swap queue. This can create some real interesting combinations, like switching to a healer when your team needs more healing and back to damage when the time is right. If you prefer a more structured style, search the listings for a version of this with role lock.

variables
{
	player:
		0: QuickSwapHeroes
		1: CurrentSwapIndex
		2: NormalizedHealthBeforeSwap
		3: UltimateChargeArray
		4: SwapCooldownArray
		5: SwapToIndex
		24: HUDHeaderId
		25: HelpTextId
}

rule("Set Player Variables")
{
	event
	{
		Player Joined Match;
		All;
		All;
	}

	actions
	{
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 0, 0);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 1, 0);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 2, 0);
		Set Player Variable(Event Player, CurrentSwapIndex, 0);
		Set Player Variable(Event Player, NormalizedHealthBeforeSwap, Normalized Health(Event Player));
		Set Player Variable At Index(Event Player, UltimateChargeArray, 0, 0);
		Set Player Variable At Index(Event Player, UltimateChargeArray, 1, 0);
		Set Player Variable At Index(Event Player, UltimateChargeArray, 2, 0);
	}
}

rule("Reset On Game Start & Between Rounds")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Or(Is Assembling Heroes, Is Between Rounds) == True;
	}

	actions
	{
		Set Player Allowed Heroes(Event Player, Filtered Array(All Heroes, Compare(Current Array Element, !=, Hero(D.Va))));
		Destroy All HUD Text;
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 0, 0);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 1, 0);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 2, 0);
		Set Player Variable(Event Player, CurrentSwapIndex, 0);
		Set Player Variable(Event Player, NormalizedHealthBeforeSwap, Normalized Health(Event Player));
		Set Player Variable At Index(Event Player, UltimateChargeArray, 0, 0);
		Set Player Variable At Index(Event Player, UltimateChargeArray, 1, 0);
		Set Player Variable At Index(Event Player, UltimateChargeArray, 2, 0);
	}
}

rule("Set Quick Swap")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Interact) == True;
		Is Button Held(Event Player, Crouch) == False;
		Array Contains(Player Variable(Event Player, QuickSwapHeroes), Hero Of(Event Player)) != True;
		Is In Spawn Room(Event Player) == True;
	}

	actions
	{
		disabled Skip If(Compare(Array Contains(All Damage Heroes, Hero Of(Event Player)), ==, False), 1);
		disabled Set Player Allowed Heroes(Event Player, Filtered Array(All Damage Heroes, Array Contains(Allowed Heroes(Event Player),
			Current Array Element)));
		disabled Skip If(Compare(Array Contains(All Tank Heroes, Hero Of(Event Player)), ==, False), 1);
		disabled Set Player Allowed Heroes(Event Player, Filtered Array(All Tank Heroes, Array Contains(Allowed Heroes(Event Player),
			Current Array Element)));
		disabled Skip If(Compare(Array Contains(All Support Heroes, Hero Of(Event Player)), ==, False), 1);
		disabled Set Player Allowed Heroes(Event Player, Filtered Array(All Support Heroes, Array Contains(Allowed Heroes(Event Player),
			Current Array Element)));
		Skip If(Compare(Value In Array(Player Variable(Event Player, QuickSwapHeroes), 0), !=, 0), 3);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 0, Hero Of(Event Player));
		Set Player Variable(Event Player, CurrentSwapIndex, 0);
		Abort;
		Skip If(Compare(Value In Array(Player Variable(Event Player, QuickSwapHeroes), 1), !=, 0), 3);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 1, Hero Of(Event Player));
		Set Player Variable(Event Player, CurrentSwapIndex, 1);
		Abort;
		Skip If(Compare(Value In Array(Player Variable(Event Player, QuickSwapHeroes), 2), !=, 0), 3);
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 2, Hero Of(Event Player));
		Set Player Variable(Event Player, CurrentSwapIndex, 2);
		Abort;
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 0, Value In Array(Player Variable(Event Player, QuickSwapHeroes), 1));
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 1, Value In Array(Player Variable(Event Player, QuickSwapHeroes), 2));
		Set Player Variable At Index(Event Player, QuickSwapHeroes, 2, Hero Of(Event Player));
		Set Player Variable(Event Player, CurrentSwapIndex, 2);
	}
}

rule("Update Saved Ultimate Charge -- Must be BEFORE rule that does swap")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, QuickSwapHeroes), Player Variable(Event Player, CurrentSwapIndex)) == Hero Of(
			Event Player);
		Value In Array(Player Variable(Event Player, UltimateChargeArray), Player Variable(Event Player, CurrentSwapIndex))
			!= Ultimate Charge Percent(Event Player);
	}

	actions
	{
		Set Player Variable At Index(Event Player, UltimateChargeArray, Player Variable(Event Player, CurrentSwapIndex),
			Ultimate Charge Percent(Event Player));
	}
}

rule("Swap With Crouch Interact")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Crouch) == True;
		Is Button Held(Event Player, Interact) == True;
		Has Spawned(Event Player) == True;
		Health(Event Player) > 0;
		Value In Array(Player Variable(Event Player, QuickSwapHeroes), 1) != 0;
		Or(Has Status(Event Player, Hacked), Or(Has Status(Event Player, Knocked Down), Or(Has Status(Event Player, Asleep), Or(Has Status(
			Event Player, Frozen), Or(Has Status(Event Player, Rooted), Or(Has Status(Event Player, Stunned), Or(Has Status(Event Player,
			Burning), Compare(Health(Event Player), <=, 0)))))))) == False;
	}

	actions
	{
		Set Player Variable(Event Player, SwapToIndex, Add(Player Variable(Event Player, CurrentSwapIndex), 1));
		Skip If(Compare(Value In Array(Player Variable(Event Player, QuickSwapHeroes), Player Variable(Event Player, SwapToIndex)), !=, 0),
			1);
		Modify Player Variable(Event Player, SwapToIndex, Add, 1);
		Skip If(Compare(Player Variable(Event Player, SwapToIndex), <, 3), 1);
		Set Player Variable(Event Player, SwapToIndex, 0);
		Skip If(Compare(Value In Array(Player Variable(Event Player, SwapCooldownArray), Player Variable(Event Player, SwapToIndex)), <=,
			0), 3);
		Small Message(Event Player, Custom String("Swap to {0} on cooldown.", Value In Array(Player Variable(Event Player,
			QuickSwapHeroes), Player Variable(Event Player, SwapToIndex)), Null, Null));
		Play Effect(Event Player, Buff Explosion Sound, White, Event Player, 1);
		Abort;
		Skip If(Compare(Value In Array(Player Variable(Event Player, QuickSwapHeroes), Player Variable(Event Player, CurrentSwapIndex)),
			!=, Hero Of(Event Player)), 1);
		Set Player Variable At Index(Event Player, SwapCooldownArray, Player Variable(Event Player, CurrentSwapIndex), 5);
		Set Player Variable(Event Player, NormalizedHealthBeforeSwap, Normalized Health(Event Player));
		Start Forcing Player To Be Hero(Event Player, Value In Array(Player Variable(Event Player, QuickSwapHeroes), Player Variable(
			Event Player, SwapToIndex)));
		Stop Forcing Player To Be Hero(Event Player);
		Set Player Variable(Event Player, CurrentSwapIndex, Player Variable(Event Player, SwapToIndex));
		Set Ultimate Charge(Event Player, Value In Array(Player Variable(Event Player, UltimateChargeArray), Player Variable(Event Player,
			CurrentSwapIndex)));
		Wait(0.016, Ignore Condition);
		Damage(Event Player, Null, Multiply(Max Health(Event Player), Subtract(1, Player Variable(Event Player,
			NormalizedHealthBeforeSwap))));
	}
}

rule("Show Message When Swap Prevented")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Crouch) == True;
		Is Button Held(Event Player, Interact) == True;
		Or(Has Status(Event Player, Hacked), Or(Has Status(Event Player, Knocked Down), Or(Has Status(Event Player, Asleep), Or(Has Status(
			Event Player, Frozen), Or(Has Status(Event Player, Rooted), Or(Has Status(Event Player, Stunned), Or(Has Status(Event Player,
			Burning), Compare(Health(Event Player), <=, 0)))))))) == True;
	}

	actions
	{
		Small Message(Event Player, Custom String("Cannot swap because of status effect.", Null, Null, Null));
	}
}

rule("Update Slot 1 Cooldown")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, SwapCooldownArray), 0) > 0;
	}

	actions
	{
		Wait(1, Abort When False);
		Modify Player Variable At Index(Event Player, SwapCooldownArray, 0, Subtract, 1);
		Loop If Condition Is True;
	}
}

rule("Update Slot 2 Cooldown")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, SwapCooldownArray), 1) > 0;
	}

	actions
	{
		Wait(1, Abort When False);
		Modify Player Variable At Index(Event Player, SwapCooldownArray, 1, Subtract, 1);
		Loop If Condition Is True;
	}
}

rule("Update Slot 3 Cooldown")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, SwapCooldownArray), 2) > 0;
	}

	actions
	{
		Wait(1, Abort When False);
		Modify Player Variable At Index(Event Player, SwapCooldownArray, 2, Subtract, 1);
		Loop If Condition Is True;
	}
}

rule("Draw Quick Swap Hero #1")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, QuickSwapHeroes), 0) != 0;
	}

	actions
	{
		Create HUD Text(Event Player, Hero Icon String(Value In Array(Player Variable(Event Player, QuickSwapHeroes), 0)), String(
			"{0}: {1}", String("Cooldown", Null, Null, Null), String("{0} sec", Value In Array(Player Variable(Event Player,
			SwapCooldownArray), 0), Null, Null), Null), Custom String("ULTIMATE: {0}%", Value In Array(Player Variable(Event Player,
			UltimateChargeArray), 0), Null, Null), Left, 1, White, Orange, Green, Visible To and String, Default Visibility);
	}
}

rule("Draw Quick Swap Hero #2")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, QuickSwapHeroes), 1) != 0;
	}

	actions
	{
		Create HUD Text(Event Player, Hero Icon String(Value In Array(Player Variable(Event Player, QuickSwapHeroes), 1)), String(
			"{0}: {1}", String("Cooldown", Null, Null, Null), String("{0} sec", Value In Array(Player Variable(Event Player,
			SwapCooldownArray), 1), Null, Null), Null), Custom String("ULTIMATE: {0}%", Value In Array(Player Variable(Event Player,
			UltimateChargeArray), 1), Null, Null), Left, 2, White, Orange, Green, Visible To and String, Default Visibility);
	}
}

rule("Draw Quick Swap Hero #3")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Value In Array(Player Variable(Event Player, QuickSwapHeroes), 2) != 0;
	}

	actions
	{
		Create HUD Text(Event Player, Hero Icon String(Value In Array(Player Variable(Event Player, QuickSwapHeroes), 2)), String(
			"{0}: {1}", String("Cooldown", Null, Null, Null), String("{0} sec", Value In Array(Player Variable(Event Player,
			SwapCooldownArray), 2), Null, Null), Null), Custom String("ULTIMATE: {0}%", Value In Array(Player Variable(Event Player,
			UltimateChargeArray), 2), Null, Null), Left, 3, White, Orange, Green, Visible To and String, Default Visibility);
	}
}

rule("Create Help Text In Spawn")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is In Spawn Room(Event Player) == True;
		Player Variable(Event Player, HelpTextId) == Null;
	}

	actions
	{
		Create HUD Text(Event Player, Custom String("Press interact in spawn room to set heroes.", Null, Null, Null), Null, Null, Top, 0,
			Yellow, White, White, Visible To and String, Default Visibility);
		Set Player Variable(Event Player, HelpTextId, Last Text ID);
		Create HUD Text(Event Player, Custom String("Quick Swap", Null, Null, Null), Custom String("Press crouch interact to swap.", Null,
			Null, Null), Custom String("Select 3 heroes.", Null, Null, Null), Left, 0, White, White, White, Visible To and String,
			Default Visibility);
		Set Player Variable(Event Player, HUDHeaderId, Last Text ID);
	}
}

rule("Destroy Help Text Outside Spawn")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is In Spawn Room(Event Player) == False;
	}

	actions
	{
		Destroy HUD Text(Player Variable(Event Player, HelpTextId));
		Set Player Variable(Event Player, HelpTextId, Null);
		Destroy HUD Text(Player Variable(Event Player, HUDHeaderId));
		Set Player Variable(Event Player, HUDHeaderId, Null);
	}
}