The "a b c things" are not script, it's just me trying to explain to you what to do on a conceptual level.
Here, I made you an example: there's a single map and a relatively short hps script - just unpack to the custom_stories folder. It demonstrates how to do a pass code. Since you said you're using script areas, I made a similar setup. For simplicity, the pass code has only 3 digits. There's a door, and a... eh... console of sorts xD, which enables you to enter the password. The password is set in the example.hps script file, and it's currently 231 - but you can change that.
Here's the most important part of the script:
const int INVALID_VALUE = -1; // represents some invalid value, just for readability...
int secretPassCode = 231;
int numPresses = 0; // the number of button presses (so far)
int userEntry = 0;
void OnEnter()
{
SetEntityPlayerInteractCallback("ScriptArea_1", "OnButtonPress", false);
SetEntityPlayerInteractCallback("ScriptArea_2", "OnButtonPress", false);
SetEntityPlayerInteractCallback("ScriptArea_3", "OnButtonPress", false);
}
void OnButtonPress(string &in sender)
{
int digit = GetDigitFromButton(sender);
if (digit == INVALID_VALUE)
return;
PlaySoundAtEntity("", "static_rock_start.snt", sender, 0.0f, false);
userEntry += digit * Pow(10, 2 - numPresses);
AddDebugMessage(sender + "; SUM: " + userEntry, false);
++numPresses; // increments numPresses by 1
if (numPresses >= 3) // all digits were entered
{
if (userEntry == secretPassCode)
{
SetSwingDoorLocked("door_1", false, false); // Unlocks the door
PlaySoundAtEntity("", "unlock_door.snt", "door_1", 0.0f, false);
}
// Otherwise, reset all the variables, so that the user can try again
userEntry = 0;
numPresses = 0;
}
}
As you can see, it's not very long. A constant and some variables are declared at the top. Then, in OnEnter(), the same interaction callback function is hooked up with each script area. It's the OnButtonPress() function, and it get's called whenever a "button" (script area) is interacted with.
The line
int digit = GetDigitFromButton(sender);
calls another function I made, which simply takes the script area name as an argument, and returns a corresponding digit.
Here's how:
int GetDigitFromButton(string &in buttonID)
{
int result = INVALID_VALUE;
if (buttonID == "ScriptArea_1")
result = 1;
else if (buttonID == "ScriptArea_2")
result = 2;
else if (buttonID == "ScriptArea_3")
result = 3;
return result;
}
Now, in the OnButtonPress() function, this is the important line - it's the line that actually implements the "a b c thing" I was talking about:
userEntry += digit * Pow(10, 2 - numPresses);
I used the += shorthand, but it can be also written like this:
userEntry = userEntry + (digit * Pow(10, 2 - numPresses));
Here, the digit obtained earlier is first multiplied by a power of 10, depending where in the sequence it should be (that's what the Pow() function does). Then it's added to the overall sum that is going to become the user entry when the final button is pressed.
After each button press, I increment the numPresses counter. The line
++numPresses;
is equivalent to
numPresses = numPresses + 1;
Then I simply check if all 3 buttons where pressed, and if so, I compare the user code to the secret code. If they are equal, I unlock the door, if not, I reset everything, so that the user can try again.
BTW, the Pow() function is another function I wrote for this script:
// Raises an integer to some power
int Pow(int number, int power) // doesn't support negative powers!
{
if (power == 0)
return 1;
for (int i = 1; i < power; ++i)
number *= number;
return number;
}
EDIT: There's a bug in the Pow() function - it gives incorrect numbers for the powers greater than 2 (which is important if there's more than 3 digits). Here's the correct version - just replace it with this in the HPL file if downloading:
// Raises an integer to some power
int Pow(int number, int power) // doesn't support negative powers!
{
if (power == 0)
return 1;
int result = number;
for (int i = 1; i < power; ++i)
result *= number;
return result;
}
That's the entire script - it's not that complicated.
P.S. If there happen to be any problems with the map, delete the map_cache file (in the "maps" dir), just in case.