DialogCounter, Counters in general, int counter and HasOptionBeenChosen (Solved)

Started by silverwolfpet, Sat 13/08/2011 19:25:33

Previous topic - Next topic

silverwolfpet

I swear... I'll go nuts over this one.

Short version: I've been using this.

Code: ags

@4
Kauff: &6 Look, a three-headed monkey!
  if (dialogCounter <= 0) {
  if (cGustav.x < cKauff.x) {
  cGustav.FaceLocation(cGustav.x - 1, cGustav.y);
  }
  else {
  cGustav.FaceLocation(cGustav.x + 1, cGustav.y);
  }
  Wait(40);
  cKauff.Say("&7 Ahihi, gotcha!");
  cGustav.FaceCharacter(cKauff);
  cGustav.Say("Oh haha, very funny.");
  dialogCounter++;
  }
  else {
  cGustav.Say("I'm not THAT stupid... this time.");
  }
return


All is well, it's functional. Once a character says that particular line, if the player tries it again, he'll get a different response.

I tried this in another dialogue:

Code: ags

// Dialog script file
@S  // Dialog startup entry point
  if (dialogCounter3 <= 0) {
  cGuard.Say("You do no such thing!");
  cKauff.Say("Excuse me?");
  cGuard.Say("You not escused!");
  dialogCounter3++;
  }
  else {
  cGuard.Say("I see you!");
  cKauff.Say("Uh...Nice to see you too!");
  }



It keeps telling me that dialogCounter3 is an undefined symbol.  >.<

I did NOT define dialogCounter  OR  dialogCounter2  and they work perfectly.
Ok, no worries, I go by the program's moods...

Global script, right on top, first line... I write:

Code: ags

int dialogCounter3 = 0;


Still, same error.
no worries, I try to write the same thing in every single room.
Nothing.

I then try just to define it... tried it everywhere, at the top of the script, careful not to put it anywhere else.

Code: ags

int dialogCounter3;


Nothing. Same error. no matter what I did.

Ok, trying a workaround... let's say... if you start the new dialogue (dialog5, the one which had dialogCounter3) you have to chose a dialog option, right?
what if I use this:

Code: ags

// Dialog script file
@S  // Dialog startup entry point
  if (dDialog5.HasOptionBeenChosen(1)){
  cGuard.Say("You do no such thing!");
  cKauff.Say("Excuse me?");
  cGuard.Say("You not escused!");
  }
  else {
  cGuard.Say("I see you!");
  cKauff.Say("Uh...Nice to see you too!");
  }


In theory, if you first run the dialogue, you get the first greeting from the guard. Then if you click on the first option, this will ensure that your next greeting will be different. Right? Right??

Well, no! It's not! It gives you directly the second greeting!


...I need some help here. What am I doing wrong? I really thought I learned the whole dialogCounter thing. I even tried naming it

Code: ags

int myfatbutt;


and when I use it in the dialogue, it STILL says that my fat butt is an undefined symbol!  :'( I'm taking that personally!

Jokes aside, where am I messing up?

Bogdan

Quote from: silverwolfpet on Sat 13/08/2011 19:25:33
In theory, if you first run the dialogue, you get the first greeting from the guard. Then if you click on the first option, this will ensure that your next greeting will be different. Right? Right??

I'm not sure if this will help:
In dialog when you pick one option and is written "return" at the end of the option in the dialog scripts, after option has been chosen it will return you to the dialog again, and if there is only one option left it will automatically trigger it like you chose that option. So you have probably made a mistake and out "return" instead of "stop", what is done by default. When it's "stop" it stops the dialog.

monkey0506

Quote from: silverwolfpet on Sat 13/08/2011 19:25:33I did NOT define dialogCounter  OR  dialogCounter2  and they work perfectly.

Wait a second, what? That's a lie Andrei, and you know it, I know it, and your mother knows it! AGS doesn't make variables magically appear out of thin air just coz you've referenced them (it's not PHP after all! :=).

It sounds like you probably defined dialogCounter and dialogCounter2 as global variables via the "Global variables" pane in the editor. This is actually the simplest solution to your problem, to add dialogCounter3 there.

If you want to do this from the script, then you need to look up the import and export keywords in the manual:

Code: ags
// GlobalScript.ash

import int dialogCounter3;

// GlobalScript.asc

int dialogCounter3 = 0;
export dialogCounter3;


It actually sounds though like you don't even want these variables to be integers (despite the very misleading name "Counter"), but rather just boolean values:

Code: ags
// GlobalScript.ash

import bool dialog3Used;

// GlobalScript.asc

bool dialog3Used = false;
export dialog3Used;

// inside the dialog script...
// ..instead of "dialogCounter3++;"
dialog3Used = true;


Now just to top it off, if you're doing this for every dialog, or heck, even most of them, then it might be better just to use an array (look those up in the manual too, specifically a dynamic array):

Code: ags
// GlobalScript.ash

import bool dialogUsed[];

// GlobalScript.asc

bool dialogUsed[];
export dialogUsed;

function game_start()
{
  if (Game.DialogCount) dialogUsed = new bool[Game.DialogCount]; // this is probably redundant for something you're using in DIALOG scripts, but still
}

// inside the dialog script...
// ..instead of "dialogCounter3++;"
  dialogUsed[3] = true;


The next problem I'd like to address is your indentation. It's a horrible mess. Your code is completely and utterly unreadable. You need to fix that if you're going to be asking a lot of questions. :P (Not entirely serious, but readable code is important if you're expecting other people to be able to help you)

Oh, and before distributing this game (which I know won't be for another 50 or so years ;)), please make sure you have someone proofread your Engrish. I mean, you do alright, but "escuse"...not so much something I'd want to see in your particular project. :)

silverwolfpet

Awkward... I will try these solutions (and I think they'd work)...but still, I don't remember defining anything. Awkward awkward.

Oh and the code....readable...yyyyeah, I'm trying to get the hang of it as I go. I never did this before. :D

In my defense, the Guard has an accent, so "escuuuuse" me for not telling you that.  :P

... (okay, kidding, it WAS a spelling mistake... it's a new room, I usually correct spelling at the end).

EDIT: Of course, it worked. Thank you. At least I know that, maybe one day, someone as stupid as me might come across this thread and save some time. ^.^

monkey0506

Glad that you got it working there. For the record, where did you define dialogCounter at??

Regarding the readability of the code, I was specifically talking about your indentation (or lack thereof). Look at this instead:

Code: ags
// Dialog script file
@S  // Dialog startup entry point
  if (dialogCounter3 <= 0) {
    cGuard.Say("You do no such thing!");
    cKauff.Say("Excuse me?");
    cGuard.Say("You not escused!");
    dialogCounter3++;
  }
  else {
    cGuard.Say("I see you!");
    cKauff.Say("Uh...Nice to see you too!");
  }
return


It's easier to see which commands belong to which branch of your if-else block. This is particularly important when you have nested blocks or loops. ;)

If the guard is meant to speak very broken Engrish then I'm sure your game will be fine, but it still might be worthwhile to have a native speaker look it over. ::) :D

silverwolfpet

Honestly, I swear, I cannot find the original dialogCounter and dialogCounter2 definitions.
I've searched the scripts manually and using "CTRL+F". Nothing. No idea.

I can't even remember where I read about using such a method (probably on the AGS forum).
Well, as long as they work as they should, I'm happy with it.

As far as the code indentations go... I honestly never thought of using them o.O It didn't occur to me.
I'll try to add some whenever I need help. Otherwise, I'm quite fine... I kind of..tend to...do that.  ;D

Aaaaand my English may be a bit rusty, but I DO know how to spell words, hahaha! Besides, I'll proof read everything before I launch the demo. :)

Khris

Quote from: silverwolfpet on Tue 16/08/2011 02:15:06
Honestly, I swear, I cannot find the original dialogCounter and dialogCounter2 definitions.
They have to be there, otherwise you'd get the same 'undefined token' error.

Check the Global variables pane in the project tree.

silverwolfpet

o.O

:-[

Yup... never thought of looking there actually. Yup...they are there. Heh, we're all gonna laugh about this in 4 to 5 years. Hehe. Heh... heh.  :-[

Uh, speaking of Global stuff, I want to add voices to my characters. Where do I find the default "I can't pick that up" line?
I mean the game must've set up a default line for the character to say in case you forgot to add any script related to an object. Where can I find those?

Khris

Are you using a template? Because a default game doesn't have that line.

Check the unhandled_event function in the global script.

silverwolfpet

Ah yes, it was in the verbcoin module. Bingo.

Man, I wish I was as good as you guys at this coding-thing.

monkey0506

For the record, do not modify the UnhandledEvent function inside of the Verbcoin.asc file. Don't do that. That's what I made the Verbcoin_UnhandledEventHandler macro for.

Quote from: silverwolfpet on Tue 16/08/2011 14:52:16Yup... never thought of looking there [in the Global variables pane] actually. Yup...they are there.

Quote from: monkey_05_06 on Sun 14/08/2011 06:10:57It sounds like you probably defined dialogCounter and dialogCounter2 as global variables via the "Global variables" pane in the editor.

Funny that you "never thought of looking there". ::)

silverwolfpet

Oops. must've misread it or misinterpret it. I still don't get the difference between Global functions and global script... I mean, why put them there...and what's with the asc stuff? Bah, humbug, nevermind. I'll learn them sooner or later, get to the bottom of this.
Sorry o.o

As for the handler... I just made this (before you told me not to modify anything):
Code: ags

#ifdef Verbcoin_UnhandledEventHandler
  Verbcoin_UnhandledEventHandler(mode, locType, theItem);
  #endif
  #ifndef Verbcoin_UnhandledEventHandler
  // if the macro isn't defined at all, just use some generic defaults instead
  if (mode == eVerbcoinModeInteract)
  {
    player.Say("Hm...");
  }
  else if (mode == eVerbcoinModeLookat)
  {
    player.Say("Hmmm...");
  }
  else if (mode == eVerbcoinModePickup)
  {
    player.Say("Nah...");
  }
  else if (mode == eVerbcoinModeTalkto)
  {
    player.Say("That's just silly.");
  }
  else if (mode == eVerbcoinModeUseinv)
  {
    if (player.ActiveInventory != null)
    {
      if (theItem == null) player.Say("Nope.");
      else player.Say("Not really what I had in mind.");
    }
    else player.Say("Mmno.");
  }
  #endif
}


I also plan on inserting a "if player is Kauff, say this, else say that". Is that okay? Did I mess it up  o.O ?

monkey0506

You're not going to break the Verbcoin module by putting custom interactions into it's UnhandledEvent method. The reason I said not to do it is because if, a month or a year from now, you upgrade to a higher version of the Verbcoin module, then all of your changes to the UnhandledEvent function will be lost (forever!).

If you would actually be so kind as to read the link I sent you (from the Verbcoin manual, about the Verbcoin_UnhandledEventHandler macro), all of this will be explained.

Regarding your confusion between global functions and global scripts, that's like asking the difference between a poem and a piece of paper. The scripts, by themselves, aren't really all that important. They can be used to organize things according to your need or preference, but the script could be blank or thousands of lines long, and it's still just a script. It's what's inside of the scripts that actually matters (sort of like what's printed on the page is more important than the paper itself).

A completely global function is one that you can access anywhere (well, provided it's inside a function so AGS knows when to call it) in any script. The most purely global functions are the built-in functions of AGS, such as the Character.Say function. There are lesser levels of globalness that still qualify as "global functions", such as functions that are presented by a module for the end-user to use. The Verbcoin.UnhandledEvent function is an example of one of these. It is only accessible to scripts that come after the Verbcoin module in the list of scripts, but for those scripts it works the same as any other global function. Scripts above the Verbcoin module can't access the function at all.

This brings up the topic of scope, which is a programming term that indicates when and where a function or variable exists. The UnhandledEvent function is said to be in-scope for the Verbcoin module and all subsequent scripts, but out-of-scope for prior scripts. That makes it partially global (as opposed to the built-in AGS functions which are in-scope for every script, and thereby fully global).

The opposite of a global function is a local function. A local function is only accessible within one single script. That is, it is in-scope within that script file, but out-of-scope for all other script files.

The ASH files are script headers, which are used so that you can modify the scope of functions and variables via the import keyword (variables also must be exported). When a function is imported from a script file, it moves it from that script's local scope into the global scope. So the ASH header is where you put imports for things that you need to make global.

The ASC script file is where you actually define your functions and variables. That's where the main body of your script goes. Each script only has access to its on local scope, and the global scope of the scripts before it. You can't access a lower script's scope at all (i.e., no script has access to the GlobalScript scope except room and dialog scripts).

Hopefully this isn't confusing you, and isn't oversimplifying things. I actually just posted earlier a much more in-depth and advanced lecture ::) on the scoping rules of AGS, but I fear that it would be too much for you yet. Don't worry, you'll get there, and if you don't understand this right now, it will come to you with time.

If this has all been a load of gibberish and I'm making your eyes bleed and your brain try and crawl out through your ears to escape, then just write it off as something that module writers need to know about, and don't concern yourself with it any further for now. :=

silverwolfpet

Wow, thank you! :) It did make SOME things easier to understand. I'll come back to this from time to time until I understand it fully.

So far, them game demo is on it's way and it's going swell. I'll keep you posted. I'm just trying to figure out how to GIVE something from Kauff to Gustav. Basically to use inventory item on character. And the search on the forums is disabled, for some reason.

EDIT: Nevermind, found it by myself.

SMF spam blocked by CleanTalk