Select a random hero when none is specified

Hello!

I want a random hero to be selected automatically if a player does not specify a chosen hero. I do NOT want them to spawn with a random hero and lock into them, or be random if the player has already selected a hero. Just think of it as a way to pick a random option.

I’m rather amateurish at this so I tried:
Hero of event player == Null
Is in game setup == true

Wait (1 second)
Start forcing player to be hero random value in array of all heroes
Stop forcing hero.

And other array looking stuff that didn’t work in hero of event player (!=).
I’ve at least seen that the action side works but I’m not sure how to get conditions right.

Why are you using “hero of(event player) == null” when “has spawned(event player) == false” is a thing?

2 Likes

IIRC you cannot force player select an hero if they has not spawned at least once in the game. Unless you set gamemode general settings to select automatically a random hero. Then you can create an script to open hero selection screen.

1 Like

also getting the hero value while the hero isn’t yet chosen will always return “unknown value” so unless “unknow value” counts as a form of “null” this script will never run.

Idk when but an Update at somepoint changed how the Start forcing Hero action works on players who haven’t spawned. it now spawns the player for them. Meaning the script you want is now possible.

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

	conditions
	{
		Has Spawned(Event Player) != True;
		Is In Setup == True;
	}

	actions
	{
		Wait(5, Abort When False);
		Start Forcing Player To Be Hero(Event Player, Random Value In Array(Allowed Heroes(Event Player)));
		Stop Forcing Player To Be Hero(Event Player);
	}
}

That script was tested not even 5m ago, worked perfectly fine. after not being spawned for 5 seconds during setup time, it chose a random hero that i was able to play, for me.

(i found this out by mistake while making a mode, and immediately thought of this question. So i went to verify it’ll work, and now have informed you that it does after verifying)

1 Like

I have been searching high and low for a way to simply detect an undecided player’s hero is empty. I can’t for the life for me For context, it’s for code to force-start Junkenstein’s Revenge because it won’t start unless all player slots are filled. So what i did was fill them by spawning dummy bots, but during testing, I realized that I need to destroy those dummy bots if any human player unselects their hero, so that I can let more humans join in the mean time, and then after a bit, spawn dummy bots again to fill any empty slots and force the game to start. So I have some loops and such to make it somewhat polished, but I can’t get it to detect that unslecting of a hero, and it’s super weird to me that such a simple thing is so hard.

Nothing is working. Not checking for null, or 0, or false. :frowning:

variables
{
	global:
		14: junkensteinsRevengeAssemblyTime
}

actions
{
	"We wait however many seconds for additional players to join and players to get act together."
	Wait(Global.junkensteinsRevengeAssemblyTime, Ignore Condition);
	"Need outer loop due to edge case where you get 4 human players to join, so no bots are added, but then one human leaves JUST before it exits assembly... and you're stuck"
	While(Is Assembling Heroes);
		"We do, however, insist on having at least one player present to consider starting."
		Wait Until(Number Of Players(Team 1) >= 1, 99999);
		"If any human player undecides their hero, extend the assembly period to let more humans in."
		If(Is True For Any(All Players(Team 1), !Is Dummy Bot(Current Array Element) && !Array Contains(All Heroes, Hero Of(
			Current Array Element))));
			Destroy All Dummy Bots;
			Wait(2, Ignore Condition);
		"Otherwise, force spawning of dummy bots to force start of game."
		Else;
			"Keep trying to exit out of assembly time and adding bots to force that until you do."
			While(Number Of Players(All Teams) < Number Of Slots(All Teams));
				Create Dummy Bot(Random Value In Array(Filtered Array(All Heroes, Current Array Element != Is Hero Being Played(All Heroes,
					All Teams))), Team 1, -1, Position Of(Random Value In Array(Spawn Points(Team 1))), Vector(0, 0, 0));
			End;
			Wait(0.064, Ignore Condition);
		End;
		Wait(0.250, Ignore Condition);
	End;
	Destroy All Dummy Bots;
}

Somehow, it is getting stuck in If(Is True For Any(All Players(Team 1), !Is Dummy Bot(Current Array Element) && !Array Contains(All Heroes, Hero Of(Current Array Element))));

have you checked to see whats the return value of “hero of” is, using a log? my bet is its whatever the last selected hero is still, and overwatch just keeps it the same for stuff like in elimination, when the time runs out on the assemble it auto selects either the last selected or randomly.

I’m currently in the middle of debugging this and seem to have narrowed it down to “Hero Of()” being the problem, but for the life of me can’t understand why it’s breaking. :frowning: