Frictional Games Forum (read-only)
Global Variables and Local Variables. - Printable Version

+- Frictional Games Forum (read-only) (https://www.frictionalgames.com/forum)
+-- Forum: Amnesia: The Dark Descent (https://www.frictionalgames.com/forum/forum-6.html)
+--- Forum: Custom Stories, TCs & Mods - Development (https://www.frictionalgames.com/forum/forum-38.html)
+---- Forum: Development Support (https://www.frictionalgames.com/forum/forum-39.html)
+---- Thread: Global Variables and Local Variables. (/thread-9325.html)

Pages: 1 2


Global Variables and Local Variables. - JoeBradleyUK - 07-23-2011

First off all I'd like to say sorry as I have asked about variables before, but I just don't get variables still! I've looked on the wiki, the forum posts, and the games actual script aswell, but I still don't understand.Undecided

I have also asked a lot of questions on the forums lately so I'm sorry for asking so much aswell.

If you could explain, in as much detail as possible, and apply it to a situation such as walking into an area making an other area active now, or (this is an idea I have for my custom story) having 4 chemicals, 2 in 2 different maps. Which when brought to a different map can be used to make an acid (like the puzzle in the main story, with the four glasses and the valves and chemical jar). Which can be used to corrode a lock in, yet again, a different map. That is a big puzzle, but if I could master this I can master anything!

Thanks in advance Heart


RE: Variables, God Damn! (sorry) - xtron - 07-23-2011

The different map thing is a globalvar. you could change the title of this thread to how to use Globalvar because it looks like the only problem you got is to bring stuff from one map to another.


RE: Variables, God Damn! (sorry) - JoeBradleyUK - 07-23-2011

(07-23-2011, 08:59 PM)xtron Wrote: The different map thing is a globalvar. you could change the title of this thread to how to use Globalvar because it looks like the only problem you got is to bring stuff from one map to another.

Well I actually need help in both, as I don't understand local ones either!


RE: Global Variables and Local Variables, God Damn! (sorry) - Kyle - 07-23-2011

What is there to not understand? They're very simple. Normal variables like "int x = 1" and "float i = 5.12" can only be used in a function that it is created in unless being transfered to another one with it's data. Local variables are variables that can be used within an entire script without it having to be transfered from one function to another. Global variables can be used like local variables except that they can be used in all the scripts in the folder it is created in with a "global.hps". In this "global.hps" file, it needs to have this:

Code:
void OnGameStart()
{
    
}

In the "OnGameStart" function global variables can be set up when the custom story starts and not a specific level. I don't exactly know the limits of this "global.hps", but I know that it can do this.

I hope this helps. :/

I also want to say that, for example, a SetLocalVarInt command sets the number for the indicated variable name's value. It can also work in different ways from integers, strings, and floats. And, for example, a AddLocalVarInt command adds the number to the variable's value, also as I said it works differently even in global variables.


RE: Global Variables and Local Variables, God Damn! (sorry) - Dizturbed - 07-23-2011

I dont know none of those functions.. I only know the simple ones :l


RE: Global Variables and Local Variables, God Damn! (sorry) - Apjjm - 07-23-2011

First, an overview:

Scripted Global variables:
  • Are stored in the save file, and carry between ALL maps.
  • Are used by using GetGlobalVar<Type> and SetGlobalVar<Type>
  • Names are passed into the above functions as a string
  • Default to 0 (or ""), and are created dynamically so can be used without an initialisation.
Scripted local vars
  • Are stored in the save file, but only apply to one map.
  • Are used by using GetLocalVar<Type> and SetLocalVar<Type>
  • Names are passed into the above functions as a string
  • Default to 0 (or ""), and are created dynamically so can be used without an initialisation.
Angelscript vars
  • Defined by placing the type (e.g: int, string, float, uint) followed by an identifier.
  • Are the stuff which can be passed into functions and the like
  • Are not saved, or transferred between maps.
  • The scope (I.e: how many {'s in it is) determines what can access it
  • Must be defined before use.

So, how can we use each one?
Code:
//Local vars
void RandomRoutine1()
{
   //Assignment
   SetLocalVarInt("variable_name",1234);
   SetLocalVarString("RandomVaraible_1","Yo dawg!");
  
   //Appending / adding
   AddLocalVarInt("variable_name",1);
   AddLocalVarString("RandomVaraible_1","I heard you like strings!");

   //Retreving
   int x = GetLocalVarInt("variable_name");
   string y = GetLocalVarString("RandomVaraible_1");

   //X now has the value 1235 (1234 + 1)
   //Y now has the value "Yo dawg!I heard you like strings!"
}

//Global vars work similarly. Take for example, using a score variable
//to chose which ending the player gets

void OnGameStart()
{
   SetGlobalVarInt("PlayerScore",1); //Initialise global score
  }

void somewhereOnAnylevel()
{
  AddGlobalVarInt("PlayerScore",1); //Add 1 to global score var
}

void somewhereAtEndOfGame()
{
   switch(GetGlobalVarInt("PlayerScore"))
     {
       case 0: {badEnding(); break;}
       case 1: {mediumEnding(); break;}
       case 2: {goodEnding(); break;}
       default: {hackerEnding();}
     }
}



RE: Global Variables and Local Variables, God Damn! (sorry) - JoeBradleyUK - 07-23-2011

Ok, the responses have made it a little better to understand, I don't know why but I can't seem to understand them fully! I understand the concept, it's just the actual scripting, say if I wanted a script area to only work once I have done something, would I make it so the set variable is 1 and when you go into the area it adds 1 which would activate that area? Is it kind of like that? Or am I wrong?


RE: Global Variables and Local Variables, God Damn! (sorry) - Apjjm - 07-24-2011

(07-23-2011, 11:50 PM)JoeBradleyUK Wrote: Ok, the responses have made it a little better to understand, I don't know why but I can't seem to understand them fully! I understand the concept, it's just the actual scripting, say if I wanted a script area to only work once I have done something, would I make it so the set variable is 1 and when you go into the area it adds 1 which would activate that area? Is it kind of like that? Or am I wrong?

In that case, variables would be surplus to requirements. You would set up your first action to activate the area, which triggers something.

Variables would be required, if, say, you wanted to track the state of multiple things. To put it less abstractly, lets say your map is just a big long staircase. At the foot of the staircase is the entrance & exit door. At the top is a room with one table, on which is say, a golden relic item. You want it so that when you grab the relic a giant boulder is activated when you go halfway down the stairs. We don't want the relic in the inventory though, because we won't be jamming it into some cogs to solve a puzzle.

Obviously, this can be achieved by activating a script area placed over the stairs after getting the relic, and that is all that needs to be done.

However, lets say that this time, at the top of the stairs there is a slightly larger room instead. This room has 3 relics (or 4, or 5, or whatever relics). You only want the ball the trigger after 3 have been collected. Now is when you want to use variables. Furthermore, we shall assume that this "relic count" is stored for use later (say, in appeasing a deity so that he opens a door to his church for you).

From this problem we can decide one global variable, counting how many relics we currently have, is required. As scripted variables default to 0, we do not need to initialise this variable - 0 seems the best place to start counting. Our solution, then, would look as follows:

Code:
//The staircase & room map\\
void OnStart()
{

  //Step #1: Add an interact callback for each of our relics & trigger
  //Our relics are called relic_1, relic_2, relic_3.
  for(int i =1; i<=3; i++) SetEntityPlayerInteractCallback("relic_"+i,"cbRelicGrab",false);

AddEntityCollideCallback("Player","ChaseTrigger","cbChaseBegin",true,1);
}

void cbRelicGrab(string &in asEntity)
{
   //Step #2: The player has grabbed a relic. Increment the relic count!
   AddGlobalVarInt("RelicsTaken",1);
   //Stop the player grabbing the same relic over and over - deactivate this on.
   SetEntityActive(asEntity,false);
   //Are all the relics grabbed? Yes: Activate the chase trigger.
   if(GetGlobalVarInt("RelicsTaken") >= 3) SetEntityActive("ChaseTrigger",true);
}

void cbChaseBegin(string &in asParent, string &in asChild, int alState)
{
   //Step #3: GIANT ENEMY BOULDER!
   SetEntityActive("GiantBallOfDoom",true);
}

//Church of Deity Map:\\

void OnStart()
{
//Add a collision to a script area before the door to unlock if
//The deity is pleased with our offering of relics.
AddEntityCollideCallback("Player","DeityDoorTrigger","cbUnlockDoor",false,1);
}

void cbUnlockDoor(string &in asParent, string &in asChild, int alState)
{
//Has the player got all 3 relics?
if(GetGlobalVarInt("RelicsTaken") >= 3) SetSwingDoorLocked("BigSwingDoor",false,true);
}



RE: Global Variables and Local Variables, God Damn! (sorry) - JoeBradleyUK - 07-24-2011

(07-24-2011, 12:53 AM)Apjjm Wrote:
(07-23-2011, 11:50 PM)JoeBradleyUK Wrote: Ok, the responses have made it a little better to understand, I don't know why but I can't seem to understand them fully! I understand the concept, it's just the actual scripting, say if I wanted a script area to only work once I have done something, would I make it so the set variable is 1 and when you go into the area it adds 1 which would activate that area? Is it kind of like that? Or am I wrong?

In that case, variables would be surplus to requirements. You would set up your first action to activate the area, which triggers something.

Variables would be required, if, say, you wanted to track the state of multiple things. To put it less abstractly, lets say your map is just a big long staircase. At the foot of the staircase is the entrance & exit door. At the top is a room with one table, on which is say, a golden relic item. You want it so that when you grab the relic a giant boulder is activated when you go halfway down the stairs. We don't want the relic in the inventory though, because we won't be jamming it into some cogs to solve a puzzle.

Obviously, this can be achieved by activating a script area placed over the stairs after getting the relic, and that is all that needs to be done.

However, lets say that this time, at the top of the stairs there is a slightly larger room instead. This room has 3 relics (or 4, or 5, or whatever relics). You only want the ball the trigger after 3 have been collected. Now is when you want to use variables. Furthermore, we shall assume that this "relic count" is stored for use later (say, in appeasing a deity so that he opens a door to his church for you).

From this problem we can decide one global variable, counting how many relics we currently have, is required. As scripted variables default to 0, we do not need to initialise this variable - 0 seems the best place to start counting. Our solution, then, would look as follows:

Code:
//The staircase & room map\\
void OnStart()
{

  //Step #1: Add an interact callback for each of our relics & trigger
  //Our relics are called relic_1, relic_2, relic_3.
  for(int i =1; i<=3; i++) SetEntityPlayerInteractCallback("relic_"+i,"cbRelicGrab",false);

AddEntityCollideCallback("Player","ChaseTrigger","cbChaseBegin",true,1);
}

void cbRelicGrab(string &in asEntity)
{
   //Step #2: The player has grabbed a relic. Increment the relic count!
   AddGlobalVarInt("RelicsTaken",1);
   //Stop the player grabbing the same relic over and over - deactivate this on.
   SetEntityActive(asEntity,false);
   //Are all the relics grabbed? Yes: Activate the chase trigger.
   if(GetGlobalVarInt("RelicsTaken") >= 3) SetEntityActive("ChaseTrigger",true);
}

void cbChaseBegin(string &in asParent, string &in asChild, int alState)
{
   //Step #3: GIANT ENEMY BOULDER!
   SetEntityActive("GiantBallOfDoom",true);
}

//Church of Deity Map:\\

void OnStart()
{
//Add a collision to a script area before the door to unlock if
//The deity is pleased with our offering of relics.
AddEntityCollideCallback("Player","DeityDoorTrigger","cbUnlockDoor",false,1);
}

void cbUnlockDoor(string &in asParent, string &in asChild, int alState)
{
//Has the player got all 3 relics?
if(GetGlobalVarInt("RelicsTaken") >= 3) SetSwingDoorLocked("BigSwingDoor",false,true);
}

Ok, i get it now, but the only thing i don't understand is this bit of the script Huh
Code:
//The staircase & room map\\
void OnStart()
{

  //Step #1: Add an interact callback for each of our relics & trigger
  //Our relics are called relic_1, relic_2, relic_3.
  for(int i =1; i<=3; i++) SetEntityPlayerInteractCallback("relic_"+i,"cbRelicGrab",false);

AddEntityCollideCallback("Player","ChaseTrigger","cbChaseBegin",true,1);
}



RE: Global Variables and Local Variables, God Damn! (sorry) - Apjjm - 07-24-2011

Code:
//The staircase & room map\\
void OnStart()
{

  //Step #1: Add an interact callback for each of our relics & trigger
  //Our relics are called relic_1, relic_2, relic_3.
  for(int i =1; i<=3; i++) SetEntityPlayerInteractCallback("relic_"+i,"cbRelicGrab",false);

AddEntityCollideCallback("Player","ChaseTrigger","cbChaseBegin",true,1);
}

What the for loop is doing, is it is executing the instruction "SetEntityPlayerInteractCallback("relic_"+i,"cbRelicGrab",false);" multiple times. What is happening is a counting variable called "i" is created, and set to 1. Whilst the counting variable is <=3, the above instruction is executed. At the end of doing the above instruction, "i" is increased. "i" is not a "scripted" variable.

As our relics are called "relic_1", "relic_2", "relic_3", and "i" has the values, 1, 2 and 3 in each iteration of the loop. The prefix "relic_" is common between all our relics - Hopefully you can see how this pieces together.

This is all the same as executing the following instructions.
SetEntityPlayerInteractCallback("relic_"+1,"cbRelicGrab",false);
SetEntityPlayerInteractCallback("relic_"+2,"cbRelicGrab",false);
SetEntityPlayerInteractCallback("relic_"+3,"cbRelicGrab",false);