int32 USoundNodeRandom::ChooseNodeIndex(FActiveSound& ActiveSound)
{
	int32 NodeIndex = 0;
	float WeightSum = 0.0f;

#if WITH_EDITOR
	bool bIsPIESound = (GEditor != nullptr) && ((GEditor->bIsSimulatingInEditor || GEditor->PlayWorld != nullptr) && ActiveSound.GetWorldID() > 0);

	if (bIsPIESound)
	{
		// Find the first available index - needed if there is only one
		while (PIEHiddenNodes.Contains(NodeIndex))
		{
			NodeIndex++;
		}
	}
#endif //WITH_EDITOR


	// only calculate the weights that have not been used and use that set for the random choice
	for (int32 i = 0; i < Weights.Num(); ++i)
	{
#if WITH_EDITOR
		if (!bIsPIESound || !PIEHiddenNodes.Contains(i))
#endif //WITH_EDITOR
		{
			if (!bRandomizeWithoutReplacement || !HasBeenUsed[i])
			{
				WeightSum += Weights[i];
			}
		}
	}

	float Choice = FMath::FRand() * WeightSum;
	WeightSum = 0.0f;
	for (int32 i = 0; i < ChildNodes.Num() && i < Weights.Num(); ++i)
	{
#if WITH_EDITOR
		if (!bIsPIESound || !PIEHiddenNodes.Contains(i))
#endif //WITH_EDITOR
		{
			if (bRandomizeWithoutReplacement && HasBeenUsed[i])
			{
				continue;
			}
			WeightSum += Weights[i];
			if (Choice < WeightSum)
			{
				NodeIndex = i;
				HasBeenUsed[i] = true;
				NumRandomUsed++;
				break;
			}
		}
	}

	return NodeIndex;
}
void USoundNodeRandom::ParseNodes( FAudioDevice* AudioDevice, const UPTRINT NodeWaveInstanceHash, FActiveSound& ActiveSound, const FSoundParseParameters& ParseParams, TArray<FWaveInstance*>& WaveInstances )
{
	RETRIEVE_SOUNDNODE_PAYLOAD(sizeof(int32));
	DECLARE_SOUNDNODE_ELEMENT(int32, NodeIndex);

	// Pick a random child node and save the index.
	if (*RequiresInitialization)
	{
		NodeIndex = ChooseNodeIndex(ActiveSound);
		*RequiresInitialization = 0;
	}

#if WITH_EDITOR
	bool bIsPIESound = (GEditor != nullptr) && ((GEditor->bIsSimulatingInEditor || GEditor->PlayWorld != nullptr) && ActiveSound.GetWorldID() > 0);
#endif //WITH_EDITOR

	// check to see if we have used up our random sounds
	if (bRandomizeWithoutReplacement && (HasBeenUsed.Num() > 0) && (NumRandomUsed >= HasBeenUsed.Num()
#if WITH_EDITOR
		|| (bIsPIESound && NumRandomUsed >= (HasBeenUsed.Num() - PIEHiddenNodes.Num()))
#endif //WITH_EDITOR
		))
	{
		// reset all of the children nodes
		for (int32 i = 0; i < HasBeenUsed.Num(); ++i)
		{
			if (HasBeenUsed.Num() > NodeIndex)
			{
				HasBeenUsed[i] = false;
			}
		}

		// set the node that has JUST played to be true so we don't repeat it
		HasBeenUsed[NodeIndex] = true;
		NumRandomUsed = 1;
	}

	if (NodeIndex < ChildNodes.Num() && ChildNodes[NodeIndex])
	{
		ChildNodes[NodeIndex]->ParseNodes(AudioDevice, GetNodeWaveInstanceHash(NodeWaveInstanceHash, ChildNodes[NodeIndex], NodeIndex), ActiveSound, ParseParams, WaveInstances);
	}
}