Using a counter within dialogs

Started by Severian, Sun 24/08/2014 03:13:57

Previous topic - Next topic

Severian

I learned about the use of using a Counter from the tutorials, and had it all set up and working within the room. But then I realised that I needed to be able to add and substract from the Counter from within dialogs, and then I needed the subsequent actions to occur in the room the player is in.

This is what I have - basically from what I took from the room itself, when it was all working. I'm not sure how to make it work - or if this will work like this.

I moved this to the GlobalScript.ash

Code: ags
  int myCounter;


In the dialog script for the character, I tabbed it in under the dialog:

Code: ags
@1 
Shak: Don't call me ma'am!
  myCounter +=3;


And then in room1.asc

Code: ags
function repeatedly_execute_always()
{

    if (myCounter == 3) 
  {
     object[2].Visible = true;
  }
}


Now all of this worked when I had it all in the one room script file (of course then, I wasn't trying to add to the counter from the dialog). I figured that since the int myCounter was in Global.ASH that the dialog would be able to add to it, and then the room would be able to determine things based upon that number. Either I'm completely wrong - or I've done something wrong, or am going about it the wrong way, or maybe what I want can't be done?

Little help please?

Dadalus

#1
Quote
Code: ags
function repeatedly_execute_always()
{

    if (myCounter == 3) 
  {
     object[2].Visible = true;
  }
}



Your setting object[2].visible every time repeatedly_execute_always() and mycounter=3 this would lead to setting the object to visible 1000s of times. You only need to do it
Code: ags
if (myCounter == 3 && !object[2].Visible) 
.

But do you need to do it that way? couldnt you do
Code: ags
@1 

Shak: Don't call me ma'am!

  myCounter +=3;

  if (myCounter == 3) 
  {
     object[2].Visible = true;
  }


EDIT: I am assuming that you want to change various things each time the counter changes, but using repeatedly execute is not an approach I would use. I would write a function  .
Code: ags
function fTestMyCounter()
{
  if (myCounter == 3 && !object[2].Visible) 
  {
     object[2].Visible = true;
  }
  else if ...(put your other tests and actions here)
  
  
}


then call that function every time you change myCounter.


This has been a 'Mouse fetishist' approved message.

Severian

Hi, and thanks so much for your help Dadalus.

Yes, what I want to do is have different actions add or subtract from the counter - and then each time the counter hits a specific number, a specific thing happens. I'm completely new to all of this, so apologies if some of what I try and do with scripting doesn't seem to make sense.

The reason I thought it would need to go in repeatedly_execute_always is that I thought I would always need the game checking to see what the counter is, and then if the counter is a specific number, then it can perform the action (ie - showing object 2 when the counter is at 3).

If I use the function you suggested - do I put it in the GlobalScript, or the room script? And how do I call it from within the dialog? (Not all the times I want to call the script will be from within dialog).

Dadalus

"A thousand mile journey begins with a single step".

I'm new to AGS myself, though I have a lot of experience in 'Visual Basic'.

You can place your function in the global script, or in a new script. In the script header 'under edit header' you would need to write a line
Code: ags
import function fTestMyCounter();

then it will be available to rooms dialogs etc.

This has been a 'Mouse fetishist' approved message.

Gurok

#4
In order to make an int globally accessible, you need to do a little bit of gymnastics:

In GlobalScript.ash
Code: ags
import int myCounter;


In GlobalScript.asc
Code: ags
int myCounter;

export myCounter;


If you want an easier way to do this, use the Global Variables section in the Explore Project sidebar. It's designed to make this very thing easier.

The problem is that for the variable to shared, the 'instance' of the int needs to exist in a .asc script somewhere. With your current definition, I believe every script gets its own "myCounter".
[img]http://7d4iqnx.gif;rWRLUuw.gi

Dadalus

#5
I hadn't considered that.

I would do it this way.

1. set up a new script called 'MyCounter'

2. in MyCounter.asc

Code: ags
int MyCounter=0;

function fTestMyCounter()
{
  if (MyCounter == 3 && !object[2].Visible)
  {
     object[2].Visible = true;
  }

  //else if ...(put your other tests and actions here)

}

function fAddtoMycounter(int Value)
{
  MyCounter=MyCounter+Value;
  //test and perform actions
  fTestMyCounter();
}
function SetMyCounterValue(int Value)
{
  MyCounter=Value;
  //test and perform actions
  fTestMyCounter();  
}
function GetMycounterValue()
{
  return MyCounter;
}


in MyCounter.ash

Code: ags
import function GetMycounterValue();
import function SetMyCounterValue(int Value);
import function fAddtoMycounter(int Value);
import function fTestMyCounter();


then in the example you have already given

Code: ags
@1 
Shak: Don't call me ma'am!
  fAddToMyCounter(3);



But thats my way of doing things (probably from using VB). Gurok has a lot more experience in AGS than I do, so hopefully he will let us know if thats the correct approach.

EDIT: you would never have access to the MyCounter variable from outside the MyCounter script. You would use fAddtoMycounter, GetMycounterValue and SetMyCounterValue instead. You would have to remove any existing MyCounter variables, and replace adding etc with the functions.
This has been a 'Mouse fetishist' approved message.

Severian

Wowee. This is getting way beyond how I even understood any of this to work! 8-0:) I had no idea it even worked like this, or that I could add new scripts to the 'Scripts' section. :) It looks like it all makes sense to me, though. I just wouldn't have been able to put it together myself.

If I put it all in exactly as you suggested, I get this error in the dialog:

Error (line 6): Undefined token 'fAddToMyCounter'

Dadalus

Could you post the dialog script? I have tested this and it works, so im not sure why your getting that error (have you added the imports?).
This has been a 'Mouse fetishist' approved message.

Severian

The dialog script is basically all that we have here.

Code: ags
// Dialog script file
@S  // Dialog startup entry point
return
@1
Char1: Don't call me ma'am!
  fAddToMyCounter(3);


Do I need to put something in the dialog file that tells it where to pull fAddToMyCounter from?  I feel like this is what the error is telling me, but I thought that's what MyCounter.ash was for.

Dadalus

#9
That seems OK, not sure why your having a problem. Is the new Script above the global script? have you removed all your previous MyCounter variables (including any global ones?).

I have tested this in a small test game I'm building for something else, and it works just fine. If you can't fix it, then zip up a copy of your game folder (winrar or 7zip) and upload it to MediaFire (or some other filehosting site) then PM me with a link and I will look at it.
This has been a 'Mouse fetishist' approved message.

Severian

I just made a whole new game, and have added nothing except for your script and am getting the same error.

I figure there's something obvious I am missing. I'll have a bit more of a play around, and send it to you if I don't figure it out.

Khris

If you have a script with
Code: ags
import function fAddtoMycounter(int Value);

in its header and saved it, typing fAd into any script below that, including a room script should make the entire function's name pop us as auto-complete suggestion, even without a function body. if that doesn't happen, you simply didn't put the import line in the header. And unless it gets suggested, it won't compile.

Dadalus

#12
I think I've figured figured it out there is a capital 'T' and 'C' in fAddToMyCounter in the dialog script, whilst the main script its 'fAddtoMycounter" (lower case 't' & 'c'). Function names are case sensitive, change the names so they match will fix the error your getting.

My error I typed in the Dialog script in the post and put in the 'T' & 'C', I should have copied it straight from my test code. Basic schoolboy error.

EDIT: the code was written in a rush so I didn't capitalize the beginning of each new word in each of the function names, I usually name functions with a small f followed by a brief description eg 'fThisIsMyFunctionNameExample'. It doesnt have to be done this way, you can name a function anyway you want as long as when you call it the name is exactly the same.
This has been a 'Mouse fetishist' approved message.

SMF spam blocked by CleanTalk