Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Atelier on Fri 29/05/2009 10:18:36

Title: Creating a Struct [SOLVED]
Post by: Atelier on Fri 29/05/2009 10:18:36
Hullo.

I'm using a list box GUI at the bottom to display everything the player looks at. It works fine, but the code that you have to write for it is long and will slow up the game if I have to do it for every hotspot. Here's the code I use at the moment:

function hHotspotX_Look ()
{
  int ran=Random(4);
  if (ran==0) {
     DisplayBox.ScrollDown();
     DisplayBox.AddItem ("You got the first phrase.");
}
  else if (ran==1){
     DisplayBox.ScrollDown();
     DisplayBox.AddItem ("You got the second phrase.");
}
  else if (ran==2){
     DisplayBox.ScrollDown();
     DisplayBox.AddItem ("You got the third phrase.");
}
  else if (ran==3){
     DisplayBox.ScrollDown();
     DisplayBox.AddItem ("You got the fourth phrase.");
}
  else if (ran==4){
     DisplayBox.ScrollDown();
     DisplayBox.AddItem ("You got the fifth phrase.");
  }
}


Like so. Now if I had to do this I'd need to enter all this (or copy and paste) for every single hotspot. Is there a way I can simplify it by making my own custom code? I've looked into structs but I don't know where to start.

Thanks.


Title: Re: Creating a Struct
Post by: Khris on Fri 29/05/2009 11:19:33
It wouldn't slow down the game, only developing it, but nevermind that ;)

What you do is use a custom function. It doesn't need to return anything hence the "void".

//  directly above on_mouse_click

void hs_look() {
  int ran = Random(4);
  String s;
  if (ran == 0) s = "first";
  ...
  if (ran == 4) s = "fifth";
  DisplayBox.ScrollDown();
  DisplayBox.AddItem(String.Format("You got the %s phrase.", s));
}

Note how I considerably shortened your code by taking out duplicate lines.

Call this in the global script / on_mouse_click:

// eMouseLeft
  if (button == eMouseLeft) {
    if (mouse.Mode == eModeLookat && GetLocationType(mouse.x, mouse.y) == eLocationHotspot)) hs_look();
    ProcessClick(...); as before
  }
  ...


Note that this can and will add identical items to your list box.
If you want each of the five items to be added only once, you need additional checks.
Title: Re: Creating a Struct
Post by: Atelier on Sat 30/05/2009 19:14:05
I've added in both of the codes into the global script, but I'm a little confused. Is the 'hs' just used as an example, or does it have an important function to it? I'm guessing I enter the first block into the global script, under repeatedly execute or something. Sorry about this, but I need just a little more explanation for it to register with me. Thanks for helping me.
Title: Re: Creating a Struct
Post by: Trent R on Sat 30/05/2009 20:05:51
The first block is above the on_mouse_click, the second is inside of it. It is called for every single hotspot you click on.


~Trent
Title: Re: Creating a Struct
Post by: Atelier on Sat 30/05/2009 20:39:49
Success!

I entered the first block into my room script, changed the hs for the hotspot name, and it worked perfectly. This meant I could take out the coding from the global script. The script may be longer in the room script, but it frees up space in the global script and it's not too complicated for me.  :)

Thank you Khris, thank you Trent; that seems to be the only problem left for the basis of my game.
Title: Re: Creating a Struct
Post by: Khris on Sat 30/05/2009 23:57:39
I called it hs_look, short for hotspot_look.

You're not supposed to use its contents as a hotspot's look function because that destroys the whole of purpose of having it made a function and you'll end up with lots and lots of duplicate code again...

Leave the first block as it is, inside the global script, above on_mouse_click, then add this line to the global header:

import void hs_look();

Now you could use a look function like this:

function hTree_Look() {
  hs_look();
}


Calling hs_look() will in effect call all the code inside the function's body. Still, using this method, you'd have to put that line into every single hotspot's look function.
Thus I suggested calling it whenever the player looks at a hotspot by adding the second piece of code to the on_mouse_click.

On a side note, "freeing up space" in the global script is completely pointless (and not necessary anyway) if it leads you to having long room scripts with lots of duplicate code.
Title: Re: Creating a Struct
Post by: Atelier on Sun 31/05/2009 11:03:56
Ahh, that makes sense now. Admittedly, I only did what I said in the last post because I didn't understand and didn't want to be a further pain, but I ended up being more of a pain. :) I've done what you said and it works nicely. The 21 lines of code I used to have are now 1. Hopefully the last question on this though: How would I change the value of 's' for each hotspot? At the moment every hotspot either says first, second etc, so how is it done?

Thanks for your help.
Title: Re: Creating a Struct
Post by: Khris on Sun 31/05/2009 12:23:38
If you want a specific value for each hotspot, you can use a parameter.

void hs_look(int ran) {
  String s;
  if (ran == 0) s = "first";
  ...
  if (ran == 4) s = "fifth";
  DisplayBox.ScrollDown();
  DisplayBox.AddItem(String.Format("You got the %s phrase.", s));
}


Now you call it like this:
  hs_look(3);   // adds "You got the fourth phrase."

I'm still not sure which line is supposed to get added when though. Do you want looking at the first five hotspots to add the five lines in order?
Title: Re: Creating a Struct
Post by: Atelier on Sun 31/05/2009 13:19:58
I'm using this as a random phrase generator, so looking at an item/hotspot could produce one of five outcomes, in no particular order, making everything much more interesting. My very first post might explain it a little better. I was wondering whether there's a way to change the value of s for each individual outcome for looking at a particular hotspot?
Title: Re: Creating a Struct
Post by: Khris on Sun 31/05/2009 14:55:29
Quote from: Atelier on Sun 31/05/2009 13:19:58I was wondering whether there's a way to change the value of s for each individual outcome for looking at a particular hotspot?
I'm sorry but I still don't quite get it. Currently, you're using the Random() function to add one of five phrases to the listbox. If you want to add a random line for some hotspots and a specific line for others, you can use this version of the function:

void hs_look(int ran) {
  if (ran == -1) ran = Random(4);
  String s;
  if (ran == 0) s = "first";
  ...
  if (ran == 4) s = "fifth";
  DisplayBox.ScrollDown();
  DisplayBox.AddItem(String.Format("You got the %s phrase.", s));
}


Now call hs_look(-1); to add a random line, or pass a value from 0 to 4 to add a specific one.
Title: Re: Creating a Struct
Post by: Atelier on Sun 31/05/2009 15:54:50
Maybe this might explain it better:

function hGrass_Look()
{
   int ran = Random(4);
   String s;
   if (ran == 0) s = "A herbacious plant counting for most of the vegatation on the world!";
   if (ran == 1) s = "Flattened by stampeding spectators.";
   if (ran == 2) s = "Trodden, withered, and sad...";
   if (ran == 3) s = "A member of the grass family Poaceae.";
   if (ran == 4) s = "Trampled, yellowed, and dying...";
   DisplayBox.AddItem(String.Format("%s", s));
   DisplayBox.ScrollDown();
}

Rather than having all this for one hotspot, I've used your code in the global script and just imported it instead. BUT the code in the global script has outcomes like "first" "second" etc. So, I was wondering how to change these outcomes to suit the hotspot looked at. I hope that makes it clearer.  :) I admire you perseverance, I have to say. Thanks!
Title: Re: Creating a Struct
Post by: Khris on Sun 31/05/2009 18:05:56
Right, now it makes sense.

The most straightforward way is to pass the strings as parameters:

// header
import void hs_look(String s0, String s1, String s2, String s3, String s4);

// global script
void hs_look(String s0, String s1, String s2, String s3, String s4) {
  String s[5];
  s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; s[4] = s4;  // put strings in an array
  int i, c = 4;
  while (i < 5) {
    if (s[i].Length == 0) c--;  // count strings not == ""
    i++;
  }
  int ran = Random(c);  // select a random string
  DisplayBox.AddItem(s[ran]);
  DisplayBox.ScrollDown();
}

Tested, working.

This will result in pretty long lines, so alternatively you can use a global string array and assign the values beforehand:
// header
import hs_look();
import String s[5];

// global script
String s[5];
export s;

void hs_look() {
  int i, c = 4;
  while (i < 5) {
    if (s[i].Length == 0) c--;
    i++;
  }
  int ran = Random(c);
  DisplayBox.AddItem(s[ran]);
  DisplayBox.ScrollDown();
}


Then do e.g.
function hGrass_Look() {
  s[0] = "A herbacious plant counting for most of the vegatation on the world!";
  s[1] = "Flattened by stampeding spectators.";
  s[2] = "Trodden, withered, and sad...";
  s[3] = "A member of the grass family Poaceae.";
  s[4] = "Trampled, yellowed, and dying...";
  hs_look();
}
Title: Re: Creating a Struct
Post by: Atelier on Sun 31/05/2009 19:47:24
I've copied the first block of code into the global script, and that seems fine. But when it gets to the room script, it claims that 's' is an undefined token. Does it need a global variable?
Title: Re: Creating a Struct
Post by: Khris on Sun 31/05/2009 19:53:42
If you use the first method, you have to include the lines in the function call:

...
  hs_look("bla", "bleh", "blih", "", "");


Like I said, this will result in pretty long lines of code.
If you want to set the lines beforehand, like in the example at the bottom of my previous post, you have to use the second way.

Don't just copy and paste, try to understand how the code works and what it does. I also believe you're rushing things; read my posts carefully, I explained all about this already.
Title: Re: Creating a Struct
Post by: Atelier on Mon 01/06/2009 19:13:17
Good! Now that my brain's in gear today I was able to successfully do it using the second method. It works really well; cuts down on code; and I don't get that annoying thing where it adds two versions of it and does really weird stuff.

Thanks for helping me all the way on this, I really appreciate it - and I've learnt quite a bit too.  :)
Title: Re: Creating a Struct
Post by: monkey0506 on Mon 01/06/2009 19:23:18
Just to clarify one thing that I saw:

DisplayBox.AddItem(String.Format("%s", s));

It is completely unnecessary to use String.Format here because in the code snippet this was taken from you've defined s as:

String s;

So s is already a String. There's no need to format it into a String. If you were perhaps getting null pointer errors, that could be corrected by doing:

String s = "";

Although it doesn't crash, using String.Format with null Strings is still bad practice. I'm not sure if that's why you were doing it this way, but again the line could be simplified as:

DisplayBox.AddItem(s);
Title: Re: Creating a Struct
Post by: Atelier on Mon 01/06/2009 19:29:35
That probably might explain why it was acting really strangely and adding duplicate items into the display box. If that wasn't the reason then :-\
Thanks, I'll know what to do next time I deal with strings.