[SOLVED] Track how many times player enters a room?

Started by TheVolumeRemote, Fri 16/07/2021 05:19:06

Previous topic - Next topic

TheVolumeRemote

Hey mates, once again my ambition outweighs my skills. The goal is to track how many times a player has been in a room because if they have a certain inventory item and have entered said room enough times, I'd like to give them a hint, by sending a character in that room to talk to.

The code below is the idea I've been trying to get to work- mark firstEnter = true; at room first load and start a cascade of bool's with emphasis on ELSE if so that each time they enter, a new bool is marked true and the prior is marked false. I'm sure those who know better than me will not be surprised it doesn't work but I am out of knowledge to know why not.

Code: ags

//Top of Room script
bool firstEnter = false;
bool secondEnter = false;
bool thirdEnter = false;
bool fourthEnter = false;
bool fifthEnter = false;
bool sixthEnter = false;

function room_AfterFadeIn()
{ 
  if (firstEnter == true)
  {
    secondEnter = true;
    firstEnter = false;
  }
  else if (secondEnter == true)
  {
    thirdEnter = true;
    secondEnter = false;
  }
  else if (thirdEnter == true)
  {
    fourthEnter = true;
    thirdEnter = false;
  }
  else if (fourthEnter == true)
  {
    fifthEnter = true;
    thirdEnter = false;
  }
  else if (fifthEnter == true)
  {
    sixthEnter = true;
    fifthEnter = false;
  }
  else if (sixthEnter == true)
  {
    moveGirl = true;
    sixthEnter = false;
  }
  if (moveGirl == true && player.HasInventory(iKey))
  {
    cGirl.ChangeRoom(63, 160, 176, eDirectionLeft);
  }
}

function room_FirstLoad()
{
  firstEnter = true;
}


I also suspect an int might be a cleaner way to do this but alas, my brain seems to prefer bool's. Regardless any help as to how to track how many times a player has entered a room so that I can call something at X amount of times, would be greatly appreciated :)

Crimson Wizard

#1
What about simple int counter?

Code: ags

int timesEntered; // initialized as 0 by default


function room_Load()
{
    timesEntered++; // increase by 1
}

function room_AfterFadeIn()
{
    if (timesEntered == X) 
    {
        // do something
    }
}

TheVolumeRemote

Thank you so much again mate! I think you and Khris need a special thanks in the credits of my game, for real.

Looking at your clean and simple solution compared to the giant mess of my swing and miss, even I can tell I was more a Sierra player than LucasArts because of how bloody convoluted I was trying to make it  (roll)

(Disclaimer, I absolutely adore both companies and play/played both)

Khris

In general: using multiple bools is perfectly fine for situations where you need to track of multiple unrelated "is the case" / "isn't the case" flags. But here you're actually counting the number of times they've entered the room, so an int is what you'll use.
However you'll still use an int in a situation where something is either "banana" or "fish" or "graphite", as long as it cannot be more than one at the same time.

As for your code, it should more or less work in theory. The only mistake I can see is that the moveGirl check doesn't have an "else if" so that block will run right after moveGirl was set to true.
Did you put Display() commands in your code to check for which parts runs and what actual variable values are?

TheVolumeRemote

#4
Hi Khris and thank you so much. I definitely need to learn to be less shy about using integers and examples like the one you gave me help my understanding of them so I sincerely appreciate you taking the time to explain it  :)

I didn't use Display() to check the state of the bool's and I honestly planned to post this question and dig into the manual again to see how to check on them, but alas, yourself and Crimson Wizard were immediately on the case so I didn't get to it. That said, and I don't want to get greedy but since you're here, how would I go about using Display to check on the bools? I imagine I could have saved myself possibly entire days if I had begun to do this 8 months ago. That said, I rechecked my original code making moveGirl an Else If (and then again but omitting it from that function and putting just the moveGirl check in room_Load) but it didn't work. Even though Crimson's int solution works a treat, id like the closure of knowing where the bool attempt failed.

And one more question on the int solution- is there a way to tell it

    if (timesEntered == X OR MORE TIMES)

So that it happens not specially on the X time but anytime from X onwards?

regardless, thank you so much again for your time and help :)

Crimson Wizard

Quote from: TheVolumeRemote on Fri 16/07/2021 06:36:43
And one more question on the int solution- is there a way to tell it

    if (timesEntered == X OR MORE TIMES)

So that it happens not specially on the X time but anytime from X onwards?

Of course, you replace "==" with ">=", which means equal or larger.

https://adventuregamestudio.github.io/ags-manual/ScriptKeywords.html#operators

TheVolumeRemote

Thank you mate. I did that thing again where I hyper focused on an int-specific solution and somehow forgot what I already knew...

I was literally over here googling integer counters when I've used != and >= (etc) dozens of times in my game. I'm not mad at myself, just disappointed  (wrong)

TheVolumeRemote

Could you tell me where I can learn how to use Display() to check bools? In the manual under string formatting, I see plenty of examples but none for bools

https://adventuregamestudio.github.io/ags-manual/StringFormats.html

Crimson Wizard

Quote from: TheVolumeRemote on Fri 16/07/2021 07:15:04
In the manual under string formatting, I see plenty of examples but none for bools

https://adventuregamestudio.github.io/ags-manual/StringFormats.html

bool is an integer internally, so %d will work. The values will be 0 for false and 1 for true.

If you want to have explicit "true" or "false" string, then you might writing a helper function for that, like
Code: ags

String FormatBool(bool b)
{
    if (b) return "true";
    return "false";
}

and then use it like
Code: ags

Display("value = %s", FormatBool(value));

TheVolumeRemote

Thank you so much mate. Seriously, I would have never gotten as far as I am without your and Khris' help, whether it was directed at me or just from searching other's posts. Thank you.

Also, you both should have a Patreon or Ko-Fi or something, I owe you both several coffee's or pints or whatever  ;)

TheVolumeRemote

For closure or if you're here from searching the forums with a similar question:

1) Use the code Crimson Wizard kindly provided me, for the reason Khris suggested regarding Integers and Bools

2) My code in the OP would indeed work (as messy if not convoluted as it is), however in addition to what Khris pointed out, that line 49 in that code needs to be "else if", I simply overlooked an error on line 37, like, several hundred times. It should have said

Code: ags
fourthEnter = false;
and not
Code: ags
thirdEnter = false;


Thank you both again for your time and help, g'night everybody!


Khris

Right, classic duplicate code typo :-D

Also, programming is hard. Thinking in terms of data structures and binary logic is completely unnatural and has to be trained rigorously to get good at, like a sport or playing an instrument. It simply takes years, not months.

SMF spam blocked by CleanTalk