Frictional Games Forum (read-only)

Full Version: Remove key after 3x uses
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I know this is possible but im not sure exactly how. I want to have a key be used on 3 different doors then once this is true the key should disappear from the inventory. Could anyone give me a hand with this please?
I cant give you any specific code since I havent touched amnesia in a while but I would imagine you need a variable that keeps track of how many times the key was used, and a function that runs everytime you use the key on a door to check and add to the variable

something like this maybe

SetLocalVarInt("KeyAmountOfTimesUsed",0);

void keyondoor()
{
AddLocalVarInt("KeyAmountOfTimesUsed",1);

if(GetLocalVarInt("KeyAmountOfTimesUsed")) == 3)
{
//script to remove key from the inventory
}

}
You can also do it by using a condition on the doors, if door 1, 2 and 3 are unlocked you remove the key.
I created a simple code snipped that hopefully resolves your problem.
Feel free to use the general UnlockDoor function for any of your keys and doors, for it will unlock them just fine without any modifications.

Bare in mind the snipped is controlled by the variables on top.
Feel free to replace variables with string entries if you feel like it.

PHP Code:
// Conrol variables for this code snippet
string yourFirstDoor "myDoor01";
string yourSecondDoor "myDoor02";
string yourThirdDoor "myDoor03";

string yourSpecialKey "myKeyItem";

void OnStart()
{
    
// Preloading Resources
    
PreloadSound("unlock_door.snt");

    
// Callbacks setup
    
AddUseItemCallback(""yourSpecialKeyyourFirstDoor"UnlockDoor"true);
    
AddUseItemCallback(""yourSpecialKeyyourSecondDoor"UnlockDoor"true);
    
AddUseItemCallback(""yourSpecialKeyyourThirdDoor"UnlockDoor"true);
}

// GENERAL DOOR UNLOCK FUNCTION
void UnlockDoor(string &in asItemstring &in asEntity)
{
    
SetSwingDoorLocked(asEntityfalsetrue);
    
PlaySoundAtEntity("""unlock_door.snt"asEntity1.0ffalse);
    
    
// If it's your special key and all doors are unlocked, remove it from the Inventory
    
if(asItem == yourSpecialKey && AllDoorsUnlocked())
    {
        
RemoveItem(asItem);
    }
    
// If it's some other normal key, just remove it without any condition
    
else if(asItem != yourSpecialKey)
    {
        
RemoveItem(asItem);
        return;
    }
}

// CHECKING IF ALL DOORS ARE UNLOCKED
bool AllDoorsUnlocked()
{
    if(
GetSwingDoorLocked(yourFirstDoor) == false && 
       
GetSwingDoorLocked(yourSecondDoor) == false && 
       
GetSwingDoorLocked(yourThirdDoor) == false)
    {
        return 
true;
    }
    return 
false;

Brilliant thanks guys Smile

Something I did want to do but I dont think is possible is have a key open multiple doors on different maps, THEN be removed when all the doors are open. But this way will work well enough Tongue
you should be able able to do that by using global variables which can be accessed across different maps. I dont have any experience using them though so you will have to look it up or ask someone else.
The only (as far as I know) difference between global and local variables is that local can be used only in one map, while global can be accessed in any map.
So, basically, each time a door is opened you need to add those scripts:
-one that adds +1 to the global variable
-one that checks if the variable is equal to 3/higher than 2 and if this condition is met, it removes the key
-and of course the one that opens the door.

I don't think it's necesseary, but you can set the variable to 0, preferably in the "global" file, using the OnGameStart function.
Ah right I never even knew you could use global variables. I will look into them Smile
First of all, there are more than just Global and Local variables.
I would say there are also SubLocal.

And there are more differences than just map scope.

1) LocalVariables are not only visible in one map, they are also visible for every function in it.

2) SubLocal Variables, like
PHP Code:
void OnStart()
{
string mySubVar "Whoa";

are visible only for the function and nothing else can reach it.

3) Don't even bother with Global.hps file. There is a difference between Global variables and Global.hps.

Just set the Global value as usual with:
PHP Code:
SetGlobalVarInt("name"0);

// Might also interest you:
// AddGlobalVarInt("name", 1); adds the integer to the value
// GetGlobalVarInt(string& asName); returns the integer value 
in your normal map file, preferably at the puzzle sequence initialization. It is redundantly unnecessary to add it OnGameStart unless it's your first puzzle.
I get you're trying to make it more digestable for not-so-advanced scripters, but calling it sublocal might be a bit misleading. (PS: I expect you to know what I'll say here Spelos, but I'll just explain it for anyone else who might be interested).

It's just the primitive version of the variable functions that FG made. Their scope is determined based on where they're initialized. So doing

PHP Code:
string mySubVar "Whoa";

void OnStart()
{


Would give it a similar scope to a LocalVarString function. From here it can be accessed by any code blocks below it. If you place it within OnStart, like the example, it would only be accessible from within that block and its sub-blocks.

Personally I prefer using the primitive versions due to simplicity, but the function versions do have their pros. For one it doesn't matter where it's initialized. Another thing is that the variable name can be dynamically changed.

PHP Code:
AddLocalVarInt("MyInt"+i1); 

Something like this wouldn't be possible with a simple
PHP Code:
int myInt+myInt+1//Errors, obviously 
Pages: 1 2