Variable Counter

Started by Frodo, Thu 23/05/2019 02:16:18

Previous topic - Next topic

Frodo

I'm very confused with the Variable Counter commands. 

I have a long corridor, with stairs going up to the 1st Floor. 
Now I don't want my character to climb up the stairs until he has turned on 8 radiators on the Ground Floor (the radiators are in several different rooms). 

I created a Global Variable (Type Int) in the Global Variable section.
I added int RadiatorCount; to the Global Script.
And I added the following to the Room (in this case, the hallway) script:

Code: ags

function room_LeaveTop()
{  
 if (RadiatorCount == 8) {
   player.ChangeRoom(13, 583, 400);
}
else player.Think("I can't go up there yet.  The manager won't let me.");
}



Now it doesn't seem to make any difference if I turn the radiators on, or not.
The player walks onto the stairs, and says "I can't go up there...', then the game hangs. 
I have to quit with Alt & X.

Any ideas what I'm doing wrong?

dayowlron

Are you incrementing the number when the Radiator is being turned on? Can you put a display above the if statement that displays Radiator Count to see if the value has the correct value in it?
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

Slasher

#2
You must have the character move down away from the top edge after speaking or they will hang there....

Are you using Game.DoOnceOnly to add RadiatorCount +=1 each time you turn a radiator on?  Or else Toggle On/Off...

The total must equal 8 as per RadiatorCount == 8 before player can go up the stairs....


Crimson Wizard

#3
Quote from: Frodo on Thu 23/05/2019 02:16:18
I created a Global Variable (Type Int) in the Global Variable section.
I added int RadiatorCount; to the Global Script.

Here's where I got confused. Are you saying there's two variables, one in Global Variables pane and another in global script? Note that if you create one in "Global Variables" pane then you don't have to declare them again in script.


Quote from: Frodo on Thu 23/05/2019 02:16:18
Now it doesn't seem to make any difference if I turn the radiators on, or not.

You have shown a script where you do the check, could you also show a script where you change the variable?


Quote from: Frodo on Thu 23/05/2019 02:16:18
The player walks onto the stairs, and says "I can't go up there...', then the game hangs. 

The function room_LeaveTop is called whenever game detects that your character is standing beyond the border. So when you walk your character there, it starts running endlessly, checking for your variable, and doing player.Think. Since it's a blocking command, player will never be able to move out.
Like Slasher said above, the common solution is to make player character walk away from the edge by a script command.

Khris

I suspect you have declared the variable in the Global script's header. This will create a separate variable for each room and is not what you want. To create a single global int, you need

Code: ags
// header
import int RadiatorCount;

Code: ags
// main script
int RadiatorCount;
export RadiatorCount;


Because this is tedious and somewhat difficult for beginners, the Global Variables pane was added to the Project Tree. Creating a variable in there means you can use it right away in your scripts. You don't have to use  int RadiatorCount;  (and this should throw an error anyway, if the name is the same).

Frodo

#5
I've been at this for hours, and I'm STILL confused.   :confused:

Each radiator had a "RadiatorsOnNumber ++;" code when you interact with it, which I changed to "RadiatorsOnNumber +=1;"
I took the int RadiatorCount out of the Global Script, since I think the Global Variables thing should make it work anyway. 

I changed the code to:

Code: ags

function room_LeaveTop()
{
  if (Game.DoOnceOnly("RadiatorCount"))  {
    GiveScore(1);
  
  if (RadiatorCount < 8)   
  
   
  if (RadiatorCount)      
  Display("RadiatorCount"); 

  if (RadiatorCount == 8) {
   player.ChangeRoom(13, 583, 400);
}
else player.Think("I can't go up there yet.  The manager won't let me.");
}
}


It doesn't hang anymore, which is good.  But it won't let me go up the stairs either. 

I tried adding a Hotspot, and then used the same code if you Stand On Hotspot, but that has no effect on anything. 


Any other suggestions?

Slasher

#6
What about something like this:

Code: ags

function room_LeaveTop() 
{
 if (RadiatorCount == 8) {
 player.ChangeRoom(13, 583, 400);
}
 else {
 player.Say("I can't go up there yet.  The manager won't let me until.......");
 player.Walk(player.x,player.y+40, eBlock, eWalkableAreas);
}
}


Cassiebsg

What exactly are you doing with this variable? RadiatorsOnNumber ?
I don't see you using it to check anything. And Where do you had ++ to RadiatorCount? Also, make sure you only give +1 once per Radiator, otherwise you may easily get past the 8.
There are those who believe that life here began out there...

Crimson Wizard

#8
Quote from: Frodo on Fri 24/05/2019 03:04:55
Each radiator had a "RadiatorsOnNumber ++;" code when you interact with it, which I changed to "RadiatorsOnNumber +=1;"

These two variants are equivalent, there was no need for a change really.


Quote from: Frodo on Fri 24/05/2019 03:04:55
I changed the code to:

Code: ags

function room_LeaveTop()
{
  if (Game.DoOnceOnly("RadiatorCount"))  {
    GiveScore(1);
  
  if (RadiatorCount < 8)   
  
   
  if (RadiatorCount)      
  Display("RadiatorCount"); 

  if (RadiatorCount == 8) {
   player.ChangeRoom(13, 583, 400);
}
else player.Think("I can't go up there yet.  The manager won't let me.");
}
}



Um, this code makes even less sense than your previous one. It seems like you have mismatching brackets there too, which breaks your intentions.

Game.DoOnceOnly runs only once for a given string (as name implies). The first opening curved bracket is after this condition and it only closes after all the other code. So this means that the whole code in room_LeaveTop now will be performed only once, regardless of RadiatorCount, and then nothing will happen.

You also have a random "if (RadiatorCount < 8) " in the middle. Since there are no curved brackets, this makes next single line run under that condition, and the code becomes efficiently equivalent to:
Code: ags

if (RadiatorCount < 8)
{
  if (RadiatorCount)
    Display("RadiatorCount");
}


My biggest advice is to do proper indentation in the code, then you will see how the code will execute easier.



PS. Display("RadiatorCount"); will not display the variable's value, it will display just a string "RadiatorCount". To display values, use string formatting (see it in the manual), for example:
Code: ags

Display("RadiatorCount = %d", RadiatorCount);

Vincent

I would do it in this way:

Into the Global Variables add a new variable type "int" named "RadiatorCount" default value to 0.

Create each hotspot or region for each radiator:
Code: ags

function region1_WalksOnto()
{
  if (Game.DoOnceOnly("TakeFirstRadiator"))
  {
     RadiatorCount ++;
     player.SayBackground(String.Format("%d", RadiatorCount));
  }
}

function region2_WalksOnto()
{
  if (Game.DoOnceOnly("TakeSecondRadiator"))
  {
     RadiatorCount ++;
     player.SayBackground(String.Format("%d", RadiatorCount));
  }
}

// etc



Create an hotspot or region for the stairs:
Code: ags

function region10_WalksOnto()
{
   if (RadiatorCount != 8)
   {
      player.Think("I can't go up there yet.  The manager won't let me.");
      player.Walk(player.x,player.y+40, eBlock, eWalkableAreas); // exit region
   }
   else
   {
      player.ChangeRoom(13, 583, 400);
   }
}

Frodo

Vincent, THANKYOU!  That works!

It may be easy for some, but I've been really struggling to understand the counter. 

Vincent

You are welcome. I would suggest you to spend some time to read this page carefully before doing anything else.

SMF spam blocked by CleanTalk