Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Ionias on Tue 10/04/2007 05:59:08

Title: Passing a pointer to my function compiling error. (SOLVED!)
Post by: Ionias on Tue 10/04/2007 05:59:08
Ok, I have a custom function:


function Speech(Character *who, String msg) {
  // custom display speech on the screen function
  }

Now that works. However, I would like to pass this to my function:


// global script
struct ExtendedCharacter {
  int mad_loop;
  int happy_loop;
  Character* Char;
  };

ExtendedCharacter ecFatman;

function Speech(ExtendedCharacter *who, String msg) {
  // custom display speech on the screen function
  }


So this way I keep my function all nice and neat. However, whenever I try to compile the script I get this error:

There was an error compiling your script. The problem was:

In: 'Global script'

Error (line 43): Cannot declare pointer to non-managed type

I just can't wrap my brain around what I'm doing wrong.  :(
Title: Re: Passing a pointer to my function compiling error.
Post by: Gilbert on Tue 10/04/2007 06:14:55
I think you just can't declare a pointer object in a struct, it's a limitation to the script system at the moment.

Edit: Maybe I'm wrong, let me check further.
Edit2: Alright, checked the wiki:
QuoteStructs can only have pointers as members in AGS 2.71 and later.
What version of AGS are you using?
Edit3: Checked again with your codes, the problem is with putting ExtendedCharacter* as parameter of a function, seems that there's a limititation of not letting (user-defined) non-managed types to pass as parameter.
In your case, instead declare Speech() as member function of ExtendedCharacter() and it should work. So:


// global script
struct ExtendedCharacter {
  int mad_loop;
  int happy_loop;
  Character* Char;
  import int Speech(String msg);
  };

ExtendedCharacter ecFatman;

function ExtendedCharacter::Speech(String msg) {
  // custom display speech on the screen function
  }



So you can use this.Char in the body of Speech() to refer to the actual character pointer, and just use the function like
ecFatman.Speech("haha");
Title: Re: Passing a pointer to my function compiling error.
Post by: Ionias on Tue 10/04/2007 13:44:06
Excellent work around sir! I shall give it a try.

Edit1: That will work, thanks. :)

Edit2: Ok doing that for every character was getting a bit complicated so in case anyone is reading this I solved the problem a litle more simply by using this instead:


function Speech(String msg, int who = 99) {
  // custom display speech on the screen function
  if (who == 99) {
    who = player.ID;  // defaults to player character
    }
   mad_loop = character[who].GetProperty(“MadLoop”);

etc… 
}


Now my function can display speech based on the default of the player character and have all the custom stuff I need. Not sure why I didn't think of that in first place. :)
Title: Re: Passing a pointer to my function compiling error. (SOLVED!)
Post by: monkey0506 on Tue 10/04/2007 21:31:21
Although using custom properties instead of a new struct is a reasonable workaround for your problem (and probably more sensible so long as your properties don't need to change), you could still use a pointer in your function:

function Speech(Character* who, String msg) {
  if ((msg == null) || (msg == "")) return; // don't use empty Strings
  if (who == null) who = player;
  int mad_loop = who.GetProperty("MadLoop");
  // etc.
  }


Or if you really want to use the Character's ID you should consider something like this:

function Speech(String msg, int who) {
  if ((msg == null) || (msg == "")) return; // don't use empty Strings
  if ((who < 0) || (who >= 300)) who = player.ID;
  int mad_loop = character[who].GetProperty("MadLoop");
  // etc.
  }


Seeing as you can have up to 300 characters (http://americangirlscouts.org/agswiki/Reference_%28manual%29#System_limits) in your game. This version would convert any invalid Character IDs into the player character's ID whereas yours converts 99 (which is a VALID character ID) into the player's ID.

If you do decide you need to change the value of your properties during the game you will need to use a struct like you were doing, but might I suggest a different approach?

// script header
struct ExtendedCharacter {
  int mad_loop;
  int happy_loop;
  Character* Char;
  import int Speech(String msg);
  }

import ExtendedCharacter excharacter[AGS_MAX_CHARACTERS];

// global script
ExtendedCharacter excharacter[AGS_MAX_CHARACTERS];
export excharacter;

function ExtendedCharacter::Speech(String msg) {
  // custom display function
  // use this.mad_loop, this.happy_loop etc.
  }

// put this inside game_start
int i = 0;
while (i < Game.CharacterCount) {
  excharacter[i].Char = character[i];
  i++;
  }


Then you can use the excharacter array the same way you use the character array (except to use built-in functions you have to use the Char member).