[Help] Gamemode Damage & Healing Tracker/Meter

viva a Heroes Select Table, Orbs pops up with Hero Icons etc… if you shot ana you get ana, if you shot bap, you get bap- etc

variables
{
	global:
		29: AllowButton
		30: Layer0_Button
		33: ControllerPlayerHeroes
		34: ControllerBotHeroes
}

subroutines
{
	11: Layer1_Button
	12: DisallowButton
}

rule("ControllerPlayerHeroes | Select")
{
	event
	{
		Ongoing - Each Player;
		Team 1;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Button(Primary Fire)) == True;
		Global.ControllerPlayerHeroes[0] == 0;
		Distance Between(Global.Layer0_Button[0], Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player)
			+ Facing Direction Of(Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True)) <= 1;
		Global.AllowButton == True;
		Global.ControllerBotHeroes == False;
	}

	actions
	{
		Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer0_Button[0], 1);
		Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
		Wait(0.250, Ignore Condition);
		Global.ControllerPlayerHeroes[0] = 1;
		Call Subroutine(Layer1_Button);
		Call Subroutine(DisallowButton);
	}
}
variables
{
	global:
		29: AllowButton
		31: List_Heroes
		33: ControllerPlayerHeroes
		38: Layer1_Button
}

subroutines
{
	12: DisallowButton
}

rule("Start Forcing Player To Be Hero [Ana]")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Button(Primary Fire)) == True;
		Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player)
			* 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[0]) <= 0.666;
		Global.ControllerPlayerHeroes == 1;
		Global.AllowButton == True;
	}

	actions
	{
		Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[0], 1);
		Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
		Wait(0.250, Ignore Condition);
		Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[0]);
		Call Subroutine(DisallowButton);
	}
}

rule("Start Forcing Player To Be Hero [Baptiste]")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		Is Button Held(Event Player, Button(Primary Fire)) == True;
		Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player)
			* 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[1]) <= 0.666;
		Global.ControllerPlayerHeroes == 1;
		Global.AllowButton == True;
	}

	actions
	{
		Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[1], 1);
		Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
		Wait(0.250, Ignore Condition);
		Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[1]);
		Call Subroutine(DisallowButton);
	}
}

is there a way how i can make one Rule for this ? and not 38 ?^^

  • Button for the hero select pop up with a subroutine
  • one button for each hero (38 total 0-37)

EDIT: Better Way to do this ?


variables
{
	global:
		29: AllowButton
		31: List_Heroes
		33: ControllerPlayerHeroes
		38: Layer1_Button
}

subroutines
{
	12: DisallowButton
}

rule("Start Forcing Player To Be Hero |")
{
	event
	{
		Ongoing - Each Player;
		All;
		All;
	}

	conditions
	{
		disabled (Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Vector(0, 0, 0), All Players(All Teams), Event Player, True),
			Vector(0, 0, 0)) ? 0 : (True ? 0 : 0)) == True;
		disabled Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player)
			* 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[0]) <= 0.666;
		Is Button Held(Event Player, Button(Primary Fire)) == True;
		Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(Event Player)
			* 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Index Of Array Value(Global.Layer1_Button,
			True)) <= 0.666;
		Global.ControllerPlayerHeroes == 1;
		Global.AllowButton == True;
	}

	actions
	{
		"0"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[0])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[0], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[0]);
			Call Subroutine(DisallowButton);
		End;
		"1"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[1])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[1], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[1]);
			Call Subroutine(DisallowButton);
		End;
		"2"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[2])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[2], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[2]);
			Call Subroutine(DisallowButton);
		End;
		"3"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[3])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[3], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[3]);
			Call Subroutine(DisallowButton);
		End;
		"4"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[4])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[4], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[4]);
			Call Subroutine(DisallowButton);
		End;
		"5"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[5])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[5], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[5]);
			Call Subroutine(DisallowButton);
		End;
		"6"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[6])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[6], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[6]);
			Call Subroutine(DisallowButton);
		End;
		"7"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[7])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[7], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[7]);
			Call Subroutine(DisallowButton);
		End;
		"8"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[8])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[8], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[8]);
			Call Subroutine(DisallowButton);
		End;
		"9"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[9])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[9], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[9]);
			Call Subroutine(DisallowButton);
		End;
		"10"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[10])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[10], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[10]);
			Call Subroutine(DisallowButton);
		End;
		"11"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[11])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[11], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[11]);
			Call Subroutine(DisallowButton);
		End;
		"12"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[12])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[12], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[12]);
			Call Subroutine(DisallowButton);
		End;
		"13"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[13])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[13], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[13]);
			Call Subroutine(DisallowButton);
		End;
		"14"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[14])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[14], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[14]);
			Call Subroutine(DisallowButton);
		End;
		"15"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[15])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[15], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[15]);
			Call Subroutine(DisallowButton);
		End;
		"16"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[16])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[16], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[16]);
			Call Subroutine(DisallowButton);
		End;
		"17"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[17])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[17], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[17]);
			Call Subroutine(DisallowButton);
		End;
		"18"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[18])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[18], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[18]);
			Call Subroutine(DisallowButton);
		End;
		"19"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[19])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[19], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[19]);
			Call Subroutine(DisallowButton);
		End;
		"20"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[20])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[20], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[20]);
			Call Subroutine(DisallowButton);
		End;
		"21"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[21])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[21], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[21]);
			Call Subroutine(DisallowButton);
		End;
		"22"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[22])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[22], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[22]);
			Call Subroutine(DisallowButton);
		End;
		"23"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[23])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[23], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[23]);
			Call Subroutine(DisallowButton);
		End;
		"24"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[24])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[24], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[24]);
			Call Subroutine(DisallowButton);
		End;
		"25"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[25])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[25], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[25]);
			Call Subroutine(DisallowButton);
		End;
		"26"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[26])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[26], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[26]);
			Call Subroutine(DisallowButton);
		End;
		"27"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[27])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[27], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[27]);
			Call Subroutine(DisallowButton);
		End;
		"28"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[28])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[28], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[28]);
			Call Subroutine(DisallowButton);
		End;
		"29"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[29])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[29], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[29]);
			Call Subroutine(DisallowButton);
		End;
		"30"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[30])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[30], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[30]);
			Call Subroutine(DisallowButton);
		End;
		"31"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[31])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[31], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[31]);
			Call Subroutine(DisallowButton);
		End;
		"32"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[32])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[32], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[32]);
			Call Subroutine(DisallowButton);
		End;
		"33"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[33])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[33], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[33]);
			Call Subroutine(DisallowButton);
		End;
		"34"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[34])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[34], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[34]);
			Call Subroutine(DisallowButton);
		End;
		"35"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[35])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[35], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[35]);
			Call Subroutine(DisallowButton);
		End;
		"36"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[36])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[36], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[36]);
			Call Subroutine(DisallowButton);
		End;
		"37"
		If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
			Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True), Global.Layer1_Button[37])
			<= 0.666);
			Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[37], 1);
			Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
			Wait(0.250, Ignore Condition);
			Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[37]);
			Call Subroutine(DisallowButton);
		End;
	}
}

You need an additional array which contains the orbs or hero selection icons in wolrd position, these position needs to be mapped with the array of allowed heroes you want to be selected. Then you need to implement the following

  1. On the supposed selection mechanism event, where you check the ray cast position if it hits an orb, you check if the ray hitted position is in the position array.
    2.Get the index value of the position the ray hitted, use that index to retrieve the hero value from the hero array which is mapped to the position.
    3.After recieving the hero someone selected apply the start forcing hero action to procced.

It sounds a bit complicated i can post an example to show what i mean, its something very few use, but its a crucial toolkit for solving problems which presents relationships, we implement something that is called a dictionary data structure, may sound familiar depending on your programming knowledge. In the end it should reduce the rule amound from 38? To maybe just 2 or 3, what it definately does is increasing the used element count in your mode due of additional array or arrays in this case. feel free to ask anything if something is unclear.

2 Likes

If I understand correctly, I need an array that contains the hero icons? Such as

actions
{
	Global.A[Array(Hero Icon String(Hero(Ana)), Hero Icon String(Hero(Ashe)))] = 0;
}

In order to recognize whether the icon contains the value or which value it contains - i.e. Index 0 becomes Index Value Ana Icon, or Ash Icon - please correct me if I’m wrong

OFFTOPIC:
Thanks to you, I was finally able to test ( for create dummy bot ) what you meant by storing a value in an index - that’s exactly the same principle, right?

variables
{
	global:
		31: List_Heroes
		35: ValueBotHero
}

actions
{
	Global.ValueBotHero[0] = Global.List_Heroes[0];
}

But what I can’t do is define the value for the team and the slot.

The problem is that unfortunately I never learned to program properly. For me it’s more learning by doing, and copy and paste, and understanding why
But as I understand it, it has a lot to do with storing a value in an index - reading it out or doing several comparisons - right?

Yes, please show me, I would be very interested :slight_smile:

1 Like

I’m sorry i meant the pure hero values or constants, but in principle it’s kind of what you suggested. A dictionary is like an array of pairs, and that pair has two distinct or similar data of information, for example a pair can hold a number and is related or paied (there comes the name) with another number, of different or same value, in your case we pair position (a vector) and a hero. In total all looks like the following below, the selection mechanism is set within one rule and works for any player, i added of course some other rules for initialization and creating the orbs with their hero icons placed in as well, and lastly a reset rule:

variables
{
	global:
		0: Positions
		1: SelectableHeroes
		2: Orbs
		3: Icons

	player:
		0: SelectedHero
		1: HasSelected
}

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

	actions
	{
		"Creating the position array, they are the keys or column/rows of the selection table, we need these to retrieve the mapped hero value from the hero array."
		Global.Positions = Array(Vector(0, 3, 10), Vector(-4, 3, 10), Vector(-8, 3, 10));
		"Creating the array of heroes, these represent the value or column/row of the selection table, they are mapped to their pairing key values in the position array."
		Global.SelectableHeroes = Array(Hero(Ana), Hero(Ramattra), Hero(Sombra));
		For Global Variable(I, 0, Count Of(Global.Positions), 1);
			"Creates the orbs we shoot at, on each defined position from the positions array above, we just choose the reevaluation option of Visibile to since we do not update their positions, and may not destroy them either."
			Create Effect(!Local Player.HasSelected ? Local Player : Null, Sphere, Color(Red), Evaluate Once(Global.Positions[Global.I]), 1,
				Visible To);
			Global.Orbs[Global.I] = Last Created Entity;
			"Creating the hero icons formatted as in-world text entities to render them into the world, here we also just reevaluate the visibility, same reasoning as with the orbs."
			Create In-World Text(!Local Player.HasSelected ? Local Player : Null, Custom String("{0}", Hero Icon String(Evaluate Once(
				Global.SelectableHeroes[Global.I]))), Evaluate Once(Global.Positions[Global.I]), 2, Do Not Clip, Visible To, Color(White),
				Default Visibility);
			Global.Icons[Global.I] = Last Text ID;
			Wait(0.016, Ignore Condition);
		End;
	}
}

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

	actions
	{
		Event Player.SelectedHero = Null;
		Event Player.HasSelected = False;
	}
}

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

	conditions
	{
		Is Alive(Event Player) == True;
		!Event Player.HasSelected == True;
		Is Button Held(Event Player, Button(Primary Fire)) == True;
	}

	actions
	{
		"We try to recieve the hero we selected as we shot at it's orb, for that we need our selection table, the mapped array of position and hero values."
		Event Player.SelectedHero = Global.SelectableHeroes[Index Of Array Value(Global.Positions, First Of(Filtered Array(
			Global.Positions, Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player)
			+ Facing Direction Of(Event Player) * 10, All Players(All Teams), Event Player, True), Current Array Element) <= 1)))];
		Abort If(Event Player.SelectedHero == Null);
		Start Forcing Player To Be Hero(Event Player, Event Player.SelectedHero);
		Wait(1, Ignore Condition);
		Event Player.HasSelected = True;
	}
}

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

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

	actions
	{
		Event Player.SelectedHero = Null;
		Stop Forcing Player To Be Hero(Event Player);
		Wait(1, Ignore Condition);
		Event Player.HasSelected = False;
	}
}

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

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

	actions
	{
		Teleport(Event Player, World Vector Of(Vector(0, 0, -10), Global.Positions[0], Rotation And Translation));
		Wait(1, Ignore Condition);
		Set Facing(Event Player, Direction Towards(Eye Position(Event Player), Global.Positions[0]), To World);
	}
}

As we shoot at an orb, we look into the pseudo table/dictionary and try first to identify if the ray cast we emit is equal or close to the one of the positions in the dictionary, it’s done with the first of filtered array… part, we take the matched position and pass that into the index of array value argument, this will give us the index of the position value within the dictionary, then we use that index we found and pass it further into the value of array function, or known as access array at index, of our hero array of the dictionary/table to obtain the hero at the previously found corresponding index number and lastly store the hero value we have looked up in the table to another variable. Here the variable is SelectedHero, we use that variable to swap to the selected hero.

Edit: make sure workshop expanse map is enabled, the vector positions goes with that map :slight_smile: .
Edit 2: The reverse is also possible meaning if we are able to get the hero value, we can use that hero value’s array index to find it’s paired position :smiley: , in theory or for some other uses cases and to complete the definition of a dictionary.
Edit 3: For everyone as a readthrough [What is a Dictionary](https://en.wikipedia.org/wiki/Associative_array)

2 Likes

Consider using “For” instead of copy pasting 38 times. Not gonna pick apart your code but here is a quick example to give you an idea:

For Global Variable(A, 0, 37, 1);
If(Distance Between(Ray Cast Hit Position(Eye Position(Event Player), Eye Position(Event Player) + Facing Direction Of(
Event Player) * 1000, All Players(Opposite Team Of(Team Of(Event Player))), Event Player, True),
Global.Layer1_Button[Global.A]) <= 0.666);
Play Effect(All Players(All Teams), Good Explosion, Color(Green), Global.Layer1_Button[Global.A], 1);
Play Effect(All Players(All Teams), Buff Explosion Sound, Color(Green), Event Player, 100);
Wait(0.250, Ignore Condition);
Start Forcing Player To Be Hero(Event Player, Global.List_Heroes[Global.A]);
Call Subroutine(DisallowButton);
End;

The For loop at this point would not make any sense, since you choose a hero once, and therefore playing the effects for each player or on a global level once, the selection interface needs to be created in a seperate rule in advance, your suggestion strips away the option of choice too tbh and when we look at the whole context and what the OP is trying to do. Maybe have a look again. Well for me OP needs to explain what DisallowButton has to do with the hero selection, why should button be disallowed after a hero got selected?

2 Likes

OP is calling this code 38 times only changing index 0, 1, 2, 3 etc…This for loop would do the exact same thing in 10 lines of code vs. 380 lines. I’m not going to pick apart OP code I just immediate seen this issue. Good luck

The OP asked for a better way to do this type of coding and that is what my post was about.

I wasn’t going to dive into this code but I wrote this out quickly in case it’s what you’re looking for. If you want the stationary flipping hero selector before spawning player you would just teleport the player in front of the vector you decide to place this selector and start a camera slightly in front of the player while locking the player down then releasing them. Both examples are in the code and they’re both “For” loops about 20 lines of code long. You can remove players from the available characters once selected if you like by setting the variable in GAMESTATE rule. Anyways, hope this helps in some way! It was fun to make. Take a look at the server load top right of video, it’s very light weight. These are very versatile with how/what you can do with them. The orbs and icons aren’t destroyed by default, instead hidden. There is a variable in GAMESTATE rule in which you can destroy them after 1 use if you like. I didn’t really take the time to debug it if needed as it functioned just fine in the time I spent with it. Man really stripped away the option of choice and it just doesn’t make sense does it?

Example 1: Individual shootable orbs you can place throughout the level.
Example 2: Press “JUMP” to toggle the example. Single stationary rotating/flipping shootable hero selector.

workshop.codes/P1KQY
Youtube: eUn3OjZ350g
Workshop Import code: P1KQY

Ah i see, well i wouldn’t call it an issue OP’s approach was a brute force, and uses branches instead of a loop, and i realized my none loop 5 liner suggestion is actually a loop on the native side or under the hood, it uses the paradigma of functional and array programming, well that’s what filtered, sorted and mapped array can provide us with as close as possible to such. Additionally when we speak of better way of coding in that it also uses less file size and element count, the for loop helps alot and can reduce it ofc, but i still see the “For” loop redundant there , cause i did not saw the loop narrow down to one selection, well a selection of the hero proceeds in the loop body, but it won’t stop and still iterates until GLobal.A just becomes 37.

2 Likes
	For Global Variable(Counter, 0, Count Of(Global.HeroList), 1);
		If(Global.MapCreationActive[Global.Counter] == True && Global.RandomizingHero == False);
			"Increase value 0.70 for a bigger hit radius on orbs."
			If(Distance Between(Event Player.LookAtPosition, Global.MapCreationCoords[Global.Counter]) <= 0.700);
				Start Forcing Player To Be Hero(Event Player, Global.HeroList[Global.Counter]);
				Global.MapCreationCoords[Global.Counter] = Vector(0, -100, 0);
				"False = REMOVE taken hero from available randomized hero pool.  True=KEEP taken hero in available random hero pool"
				Global.MapCreationActive[Global.Counter] = False;
				"TOGGLE this variable to FALSE in the GAMESTATE rule if you wish to have the orbs and hero icons destroyed and removed from the game never to be seen again!"
				If(Global.KeepOrbsActive == False);
					Destroy Effect(Global.MapCreation[Global.Counter]);
					Destroy In-World Text(Global.MapText[Global.Counter]);
				End;
				Break;
			End;
		End;
	End;

That is why you call a break and have preemptive checks from the loop doing anything on indexes it shouldn’t be. The loop completes faster than the human eye can see.

They only time it would hit index 37 is if the hero selected was the last index in the hero list array lol.

For the hero selection you wouldn’t even need that as well :slight_smile: .

2 Likes

For the hero selector it is in example 2 of the code, which is this. Anyway best of luck OP hope some information was helpful to you.

actions
{
	Call Subroutine(HideHeroOrbs);
	Global.RandomizingHero = True;
	Global.RandomINT = Random Integer(0, Count Of(Global.HeroList));
	For Global Variable(Counter, 0, Count Of(Global.HeroList), 1);
		If(Global.MapCreationActive[Global.Counter] == True);
			Global.MapCreationCoords[Global.Counter] = Vector(0, 0, 0);
			Global.MapTextCoords[Global.Counter] = Vector(0, 0, 0);
			If(Global.Counter == Global.RandomINT);
				Global.RandomizingHero = False;
				Break;
			End;
			Wait(0.100, Ignore Condition);
			Global.MapCreationCoords[Global.Counter] = Vector(0, -100, 0);
			Global.MapTextCoords[Global.Counter] = Vector(0, -100, 0);
			Wait(0.100, Ignore Condition);
		End;
	End;
}

Thank you all for putting in such effort, I’ve been experimenting with your codes for the last three days, I saved everything separately in templates.

  1. I think there’s something wrong with the codes you gave me, because unfortunately I can’t always select a hero when I shoot the orb

  2. And Thank you that you wrote some descriptions in the actions
    helped me a lot to understand

  3. But I think it will be difficult for me to implement it myself, but I think it would definitely help my problem with too many effects, icons and entities.
    Because that’s exactly what I need

4.With Create HUD Text - how i can show all value´s in a array ?
All heroes in this array should be displayed like a super massive created hud text -

variables
{
	global:
		31: List_Heroes
}

actions
{
	"Global Variable"
	Global.List_Heroes = Array(Hero(Ana), Hero(Baptiste), Hero(Brigitte), Hero(Kiriko), Hero(Lúcio), Hero(Mercy), Hero(Moira), Hero(
		Zenyatta), Hero(Lifeweaver), Hero(Illari), Hero(D.Va), Hero(Doomfist), Hero(Junker Queen), Hero(Orisa), Hero(Ramattra), Hero(
		Reinhardt), Hero(Roadhog), Hero(Sigma), Hero(Winston), Hero(Wrecking Ball), Hero(Zarya), Hero(Ashe), Hero(Bastion), Hero(
		Cassidy), Hero(Echo), Hero(Genji), Hero(Hanzo), Hero(Junkrat), Hero(Mei), Hero(Pharah), Hero(Reaper), Hero(Sojourn), Hero(
		Soldier: 76), Hero(Sombra), Hero(Symmetra), Hero(Torbjörn), Hero(Tracer), Hero(Widowmaker));
}
1 Like

Its distanced based from the position to you and the orb at exactly 10, meaning the length of the ray cast line is projected 10 meters to the direction you are looking at, if you are to far away it won’t work. I may to fix it, you could try Noel’s loop version to test for more precision in detecting hits, my attempt would be to wrap the ray cast part around the Update Every Frame value, so the loop under the hood of the filterring array function may gain more accuracy in tracking each ray cast which is natively done.

No problem the case of a dictionary is a well documented topic you’ll find references of it on any programming based and relevant sites on the internet. There was a youtube video tutorial about it used in the Overwatch workshop as well, i can’t remember excactly how it was titled there. But it was explained pretty well and easy to understand afterwards.

Thanks, also for your interest, i am happy that i could shine some light on a very useful method. Sad actually workshop has no built-in variant for dictionaries to work in tandem with the array. Setting up such scenarios would be much easier.

Yes,

  1. you need a main string variable which will contain all hero values as their string interpretation and is displayed/used in your hud text.
  2. the hero array we need to iterate over.
  3. a temporary string variable that stores the hero from the hero list as we iterate over it.
  4. in a for loop (the process of iterating) store a hero in the temporary mentioned in step 3, then we concatinate that temporary to the main string variable mentioned in step 1, repeat that process until we hit the last hero in the array.

The code snippet would look like this:

variables
{
	global:
		0: HeroList
		1: HeroListString
		26: Temporary
}

rule("Rule 1")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Wait(1, Ignore Condition);
		Global.HeroList = Allowed Heroes(Host Player);
		Create HUD Text(All Players(All Teams), Custom String("{0}", Global.HeroListString), Null, Null, Left, 0, Color(White), Color(
			White), Color(White), Visible To and String, Default Visibility);
		For Global Variable(I, 0, Count Of(Global.HeroList), 1);
			Global.Temporary = Custom String("{0}\n", Global.HeroList[Global.I]);
			Global.HeroListString = Custom String("{0}{1}", Global.HeroListString, Global.Temporary);
			Wait(0.016, Ignore Condition);
		End;
	}
}

Edit: Here is an optimized sample to cover point 1 in your statement, i apply something called LineIntersectsSphere, it removes the fixed distance of 10 entirely and dynamically uses the distance between Event Player and the potential selection orb:

settings
{
	modes
	{
		disabled Control
		{
			Limit Roles: 1 Tank 2 Offense 2 Support
		}

		disabled Escort
		{
			Limit Roles: 1 Tank 2 Offense 2 Support
		}

		disabled Flashpoint
		{
			Limit Roles: 1 Tank 2 Offense 2 Support
		}

		disabled Hybrid
		{
			Limit Roles: 1 Tank 2 Offense 2 Support
		}

		disabled Push
		{
			Limit Roles: 1 Tank 2 Offense 2 Support
		}

		Skirmish
		{
			enabled maps
			{
				Workshop Expanse 972777519512063901
			}
		}
	}
}

variables
{
	global:
		0: Positions
		1: SelectableHeroes
		2: Orbs
		3: Icons

	player:
		0: HasSelected
}

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

	actions
	{
		"Creating the position array, they are the keys or column/rows of the selection table, we need these to retrieve the mapped hero value from the hero array."
		Global.Positions = Array(Vector(Empty Array, 3, 10), Vector(-4, 3, 10), Vector(-8, 3, 10));
		"Creating the array of heroes, these represent the value or column/row of the selection table, they are mapped to their pairing key values in the position array."
		Global.SelectableHeroes = Array(Hero(Ana), Hero(Ramattra), Hero(Sombra));
		For Global Variable(i, 0, Count Of(Global.Positions), 1);
			"Creates the orbs we shoot at, on each defined position from the positions array above, we just choose the reevaluation option of Visibile to since we do not update their positions, and may not destroy them either."
			Create Effect(!Local Player.HasSelected ? Local Player : Null, Sphere, Color(Red), Evaluate Once(Global.Positions[Global.I]), 1,
				Visible To);
			Global.Orbs[Global.I] = Last Created Entity;
			"Creating the hero icons formatted as in-world text entities to render them into the world, here we also just reevaluate the visibility, same reasoning as with the orbs."
			Create In-World Text(!Local Player.HasSelected ? Local Player : Null, Custom String("{0}", Hero Icon String(Evaluate Once(
				Global.SelectableHeroes[Global.I]))), Evaluate Once(Global.Positions[Global.I]), 2, Do Not Clip, Visible To, Color(White),
				Default Visibility);
			Global.Icons[Global.I] = Last Text ID;
			Wait(0.016, Ignore Condition);
		End;
	}
}

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

	actions
	{
		Event Player.HasSelected = False;
	}
}

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

	conditions
	{
		Is Alive(Event Player) == True;
		!Event Player.HasSelected == True;
		Is Button Held(Event Player, Button(Primary Fire)) == True;
	}

	actions
	{
		"We try to recieve the hero we selected as we shot at it's orb, for that we need our selection table, the mapped array of position and hero values."
		Abort If(Global.SelectableHeroes[Index Of Array Value(Global.Positions, First Of(Filtered Array(Global.Positions, Distance Between(
			Eye Position(Event Player) + Normalize(Facing Direction Of(Event Player)) * Distance Between(Eye Position(Event Player),
			Current Array Element), Current Array Element) < 1)))] == Null);
		Start Forcing Player To Be Hero(Event Player, Global.SelectableHeroes[Index Of Array Value(Global.Positions, First Of(
			Filtered Array(Global.Positions, Distance Between(Eye Position(Event Player) + Normalize(Facing Direction Of(Event Player))
			* Distance Between(Eye Position(Event Player), Current Array Element), Current Array Element) < 1)))]);
		Wait(1, Ignore Condition);
		Event Player.HasSelected = True;
	}
}

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

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

	actions
	{
		Stop Forcing Player To Be Hero(Event Player);
		Wait(1, Ignore Condition);
		Event Player.HasSelected = False;
	}
}

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

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

	actions
	{
		Teleport(Event Player, World Vector Of(Vector(Empty Array, Empty Array, -10), First Of(Global.Positions),
			Rotation And Translation));
		Wait(1, Ignore Condition);
		Set Facing(Event Player, Direction Towards(Eye Position(Event Player), First Of(Global.Positions)), To World);
	}
}
2 Likes

I’m sorry, I’m a little overwhelmed at the moment, that’s the reason why I haven’t answered you properly so far, personal thanks to you Noel

"TOGGLE this variable to FALSE in the GAMESTATE rule if you wish to have the orbs and hero icons destroyed and removed from the game never to be seen again!"

What you mean by that when you say “from the game never to be seen again”
How can I imagine this, are the effects simply deleted from the entity list?
And is there a way to check how many entities you have already created?
Viva HUD Text

@ ArcanaXXI
When I try to paste the text I get the following:
ERROR: Expected a variable after Variable( on line 65

Is there a way to Create In-World Text to be like an array? or various in-world texts, such as “Heroes” and “Bot Heroes” with the principle of

variables
{
	global:
		2: List_HeroString
		3: Temporary
		8: Counter
		20: List_Heroes
}

actions
{
	Global.Temporary = Custom String("{0}\n", Global.List_Heroes[Global.Counter]);
	Global.List_HeroString = Custom String("{0}{1}", Global.List_HeroString, Global.Temporary);
}

Not from the entitiy list you set up with as an array, the array or list just contain the entity’s reference number, remove from game and never seen again means the entities or texts are deallocated from memory, so yes entirely from the current game instance, making the stored reference numbers of the cleared entity useless.

Text Count value returns the number of all current created HUD Texts, In-World Texts, Progress Bar HUD Texts and Progress Bar In-World Texts.

Which text do you mean? The error doesn’t appear to me, could you describe what excactly is happening when copying my snippets?

Yes it’s possible to use Create In-World Text, replace it with the HUD version and then just put the main string variable in the text argument field, but a loop is still required for concatinating the array to one string, if you prefer to let the code create it for you, you also could create a big string manually inside the UI under the custom string value, but for 38 heroes i don’t know if it is worth the fiddle time involved to do, though you would save server load, since no processing at running the mode is additionally done. The choice is yours.

I think I have to reinstall Overwatch because it doesn’t make sense to me why I can’t add it. Update/EDIT coming later/tomorrow.

Yes it’s possible to use Create In-World Text, replace it with the HUD version and then just put the main string variable in the text argument field, but a loop is still required for concatinating the array to one string, if you prefer to let the code create it for you, you also could create a big string manually inside the UI under the custom string value, but for 38 heroes i don’t know if it is worth the fiddle time involved to do, though you would save server load, since no processing at running the mode is additionally done. The choice is yours.

Okay, this is getting interesting because I just have no idea what you’re talking about :smiley: But if you have the time and feel like it, feel free to send it to me!

I mean Like a main menu with 3 times Create In-World Text with
1.“Heroes”
2.“PlaceholdB”
3.“PlaceholdC”

And how can you find out whether he’s shooting at the “Heroes”, for example?
And only with the In-World Text thing , and not with Vectors

In the Hero Orb Scenario - I have more Vectors as Heroes

variables
{
	global:
		18: List_EffectEntity
		20: List_Heroes
		23: List_Vector_Layer_2
}

actions
{
	For Global Variable(List_EffectEntity, 0, Count Of(Global.List_Heroes), 1);
		disabled For Global Variable(List_EffectEntity, 0, Count Of(Global.List_Vector_Layer_2), 1);
}

Because I have more vectors than heroes, I changed the count of so that 38 heroes are displayed with the associated orbs

And now I have the problem because I don’t want any hero icons to be displayed in the main menu and they are not yet available for selection, so I need something to define where the “I shoot at point xy” and I thought maybe your concept would also work with create in-world texts

Because if something like that worked, it would be really practical, because then I wouldn’t have to make the system/concept dependent on which icons it shoots but rather what the name of the in-world text is… so I think it would be easier for me to implement it

Because before that I made the system dependent on which button I/he clicked, and I used a lot of global variables like “ControllerPlayerHeroes”
when I shoot the orb then Global.ControllerPlayerHeroes[0] = 1;

In-World Text “Heroes” Layer 0
If the orb has Global.ControllerPlayerHeroes[0] = 0 - then it is white (not selected)

If it has Global.ControllerPlayerHeroes[0] = 1 - then it is selected and the orb turns green

Layer 1

And A Subroutine pops up with the new Vectors in the middle , and made the Hero Icons-Orbs

Do you happen to know how I should do that, purely mentally -

It’s like the code provided as such:

variables
{
	global:
		0: HeroList
		1: HeroListString
		26: Temporary
}

rule("Rule 1")
{
	event
	{
		Ongoing - Global;
	}

	actions
	{
		Wait(1, Ignore Condition);
		Global.HeroList = Allowed Heroes(Host Player);
		Create HUD Text(All Players(All Teams), Custom String("{0}", Global.HeroListString), Null, Null, Left, 0, Color(White), Color(
			White), Color(White), Visible To and String, Default Visibility);
		For Global Variable(I, 0, Count Of(Global.HeroList), 1);
			Global.Temporary = Custom String("{0}\n", Global.HeroList[Global.I]);
			Global.HeroListString = Custom String("{0}{1}", Global.HeroListString, Global.Temporary);
			Wait(0.016, Ignore Condition);
		End;
	}
}

But instead of using HUd Text you would use In-World Text. The manual part would be to chain string format place holders one by one togerther in one string for example like so:


Global.String = Custom String("{0}\n{1}\n{2}", Global.HeroList[0], Global.HeroList[1], Custom String("{0}\n{1}\n{2}", Global.HeroList[2], Global.HeroList[3], Global.HeroList[4],... and so on))

But all that would just create one string as one In-World Text or HUD Text, that’s what you also don’t want as i understand, going per vector position again just turns out to be like the variant with the icons and orbs.

That is a big hint, well i could come up with an idea of mine to maybe blend closer to your actual idea or changed conept in mind.

We can create a feedback loop, with other creators as well, giving you their ideas, if possible of course.

I start first maybe you could list down and strucutre your concept, not yet how you have tried to implementate it- we may do this together-, in what should happen when, the states of selection and how it should look like visually, maybe giving some references of what you have seen from other sources, that tried to solve similar problems.

I completely forgot that you’re not allowed to post links here, nobody wants to see my paint sketches anyway xD It’s best if you add me on battlenet Nocreeper#2484

You can paste the link in code or quote blocks if you want and use imgur :smiley: , i can copy-paste the links into my browser with no issues, so battlenet is not required from my point of view, maybe it’s better we keep it public here, so others with even more creativity or workshop tinkerring ability can help us :smiley: .