Page 1 of 1

ACS Looping Woes

Posted: Tue Jan 14, 2025 9:46 pm
by Doominer441
Hello

I'm working on a script thats meant to monitor the players sanity (which is measured by an invisible dummy inventory item), and cause effects as it gets lower and lower. Unfortunately, this has turned into a nightmare as the loops I'm using will not behave in the way I intend, no matter what I do.

In short, it consists of a "While" loop that checks the sanity item against a set of 6 "If" statements, then if it meets any of those statements, checks a random variable to determine which effect will be played.

The main "While" loop seems to work fine, its the inner loops that check the SanityEffectWeight variable that are the (current) problem. I set up test messages to play to ensure its cycling through the different effects correctly, but the only problem is it never cycles through them. It only iterates through the first "If" statement, despite my test message showing the SanityEffectWeight should make the other effects play, none of them ever do.

I'm at a complete loss of how to fix this, since it worked before I started adding effects, but the loops should be no different no compared to how they were previously. Could anyone please advise me?

Code: Select all

script "SanityLoop" ENTER
{
	While(TRUE)
		{
			int Sanity = CheckInventory("Sanity");
			int SanityEffectWeight = Random(1, 6);
			Delay(35);
			If(Sanity >= 80)
				{
					Restart;
				}
			If(Sanity < 80 && Sanity >= 60)
				{
					//Delay(35 * 1);
					Print(i:SanityEffectWeight);
					If(SanityEffectWeight == 1 || 2)
						{
							//AmbientSound("sanity/effect/randomsound/minor", 48);
							HudMessage(s:"Baa Baa"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
							Restart;
						}
					If(SanityEffectWeight == 3 || 4)
						{
							HudMessage(s:"Black Sheep"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
							Restart;
						}
					If(SanityEffectWeight == 5 || 6)
						{
							HudMessage(s:"I aint payed to do this"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
							FadeTo(0, 0, 0, 0.25, 1.50);
							Delay(35 * 1.5);
							FadeTo(0, 0, 0, 0.0, 1.50);
							Restart;
						}
				}
			If(Sanity < 60 && Sanity >= 40)
				{
					HudMessage(s:"you have moderate sanity loss"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
					AmbientSound("sanity/effect/flicker", 63);
					Restart;
				}
			If(CheckInventory("Sanity") < 40 && CheckInventory("Sanity") >= 20)
				{
					HudMessage(s:"you have major sanity loss"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
					AmbientSound("sanity/effect/flicker", 63);
					Restart;
				}
			If(CheckInventory("Sanity") < 20 && CheckInventory("Sanity") >= 1)
				{
					HudMessage(s:"you have severe sanity loss"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
					AmbientSound("sanity/effect/flicker", 63);
					Restart;
				}
			If(CheckInventory("Sanity") == 0)
				{
					HudMessage(s:"you have gone insane"; HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GREEN, 0.5, 0.5, 3.0);
					AmbientSound("sanity/effect/flicker", 63);
					Restart;
				}
		}
}

Re: ACS Looping Woes

Posted: Wed Jan 15, 2025 1:55 am
by Player701
First of all, you are mixing two loop concepts here: the while loop and a loop implemented via restart statements. While it is most likely going to work, I still suggest that you use either one or the other to avoid potential bugs in the future.

I consider while to be a "cleaner" approach, but in your case restart might actually provide better readability due to less indentation. Note that you only need one restart statement at the end of your script. You can also make use of the else if construct for more clarity and brevity:

Code: Select all

int Sanity = CheckInventory("Sanity");
int SanityEffectWeight = Random(1, 6);
Delay(35);

if (Sanity < 80 && Sanity >= 60)
{
    ...
}
else if (Sanity >= 40)
{
    ...
}
else if (Sanity >= 20)
{
    ...
}
else if (Sanity >= 1)
{
    ...
}
else
{
    ...
}

Restart;
As for why your inner ifs don't work properly, the problem is with your expression syntax:

Code: Select all

If(SanityEffectWeight == 1 || 2)
This will evaluate to "true" if either SanityEffectWeight == 1 or 2 evaluates to true. Since 2 is considered to be a truthy value, this expression always evaluates to "true".

The correct syntax is: If(SanityEffectWeight == 1 || SanityEffectWeight == 2).

Alternatively, use a chain of else ifs like in the previous example, and compare with <=:

Code: Select all

if (SanityEffectWeight <= 2) // 1 or 2
{
    ...
}
else if (SanityEffectWeight <= 4) // 3 or 4
{
    ...
}
else // 5 or 6
{
    ...
}

Re: ACS Looping Woes

Posted: Tue Jan 21, 2025 10:27 pm
by Doominer441
I'm sorry for how long it took me to get back over this, but thank you, I really appreciated the help! My sanity script is fully functional now!