Multiply Functioned Functions [SOLVED]

Started by Atelier, Mon 10/08/2009 15:16:54

Previous topic - Next topic

Atelier

Hullo.

So I've begun programming my project, and everything was going fine, until I realised that my scripts would soon become illegible. So I've partioned the global script up into nice chunks, with no problems.

However, I'm having to change my method of getting the player's input (it's a text game) and giving them the response in the text box. Here's my old code for doing that...

Code: ags

function InputBox_OnActivate(GUIControl *control)
{
   if (player.Room == 1)
      {
         if (InputBox.Text == "Leave - East")
         {
            DisplayBox.AddItem("Leave - East: You walk away from the church and reach the meadow, where you steal a view of the castle.");
            player.Changeroom(5);
         }
      }
}


This is a pain, bearing in mind that there could easily be over fifty interactions in a single room, and dozens of rooms. So, I need a shorter and sharper way of doing the exact same things in ideally one line. Here's what I've started on below, but I've hit a snag and so would be grateful for help.

(This is what I've got in the global script).

Code: ags

function InputBox_OnActivate(GUIControl *control)
{
    InputBox.Text = Input; //I've created a global variable called Input to make things simpler.
    Scene_One_Inputs(); //This is a custom function which I have created in a separate script and imported.
    Scene_Two_Inputs(); //Another custom function in a different script.
    Scene_Three_Inputs(); //And another.
    //You get the idea.
}


Here's the driving force behind giving the response:

Code: ags

function On_Input([string TEST]) //This is the part I need help with.
{
   Input = "";
   DisplayBox.AddItem(TEST);
}


Then I link the three functions together: Scene_One_Inputs; On_Input; and InputBox_OnActivate, like so:

(In Room 1.asc. It's not the normal room script, I've just created one to hold the Input codes so my global script isn't so messy).
Code: ags

function Scene_One_Inputs() //This is the custom function which I put under InputBox_OnActivate.
{
   if (Input == "Leave - East") On_Input(["Leave - East: You walk away from the church and reach the meadow, where you steal a view of the castle."]);
}


This has condensed all of my old method down. But I should probably get to the problem :-\ I thought that I should explain how everything works, as it is all connected.

I need help with the On_Input function, namely the last part, ([string TEST]) . How could I enter the text, whatever it may be, into this parameter, and have the line inside the function (DisplayBox.AddItem) recognise it and then add it.

It tells me there's a parse error near the "[", in this line:

Code: ags

if (Input == "Leave - East") On_Input(["Leave - East: You walk away from the church and reach the meadow, where you steal a view of the castle."]);


I've tried fiddling around with the order of everything, but nothing seems to work. My query has been poorly explained, and I went a bit crazy with the code tags, but I would be very grateful for some help and/or alternatives. Thanks. :)

Khris

First of all, there seems to be a mistake in the new InputBox_OnActivate:
Code: ags
InputBox.Text = Input;

You have to turn this around, I guess.

On to the problem: what's with the square brackets?
To pass a String to a function (note the capital S), use:

Code: ags
function On_Input(String TEST)
{
   Input = "";
   DisplayBox.AddItem(TEST);
}


Then call it like this:

Code: ags
  On_Input("Blah.");

Atelier

#2
Thankfully I don't get an error message at the bottom any more when I try to run the game, but I get a message just before: Script link failed: Runtime error: unresolved import 'On_Input'

I was sure everything was in the right header, but evidently not. I've got this in the header of the script I want to use the function in:

Code: ags

import function On_Input(String TEST);


What's wrong here? Thanks.

Khris

The header with the import line has to be below the script the function is declared in. Right-click scripts and select "Move up/down" to change their order.

Atelier

The function is within the global script, which is glued to the bottom, so what I've done is create a super script at the top for all of my custom functions, and placed it in there. Now I can get working!

You've saved the day again, thanks Khris. :)

monkey0506

Quote from: KhrisMUC on Tue 11/08/2009 18:52:49The header with the import line has to be below the script the function is declared in.

Or the same script...or one above it...or whatever. The point is that the variable/function must be defined before it's used. So if you have a script called "SuperScript" in which you define this function "On_Input", then the function cannot be used in any script that appears above "SuperScript" in the list of scripts...no matter what you do. You would have to either reorder the scripts, or actually move the function. This is just like how you can't define the function at the bottom of the script and then call it from the very top.

Within "SuperScript" of course the function is defined. As we know, you can't call the function until it has been defined. So if the function gets defined on line 148, you can't call it on any line prior to that.

If you want the function to become available to another script, that's when you need the import. You actually do have options here. The most common method is just to make the function global to every subsequent script (that is every script that comes after the script that actually defines the function). We do that by just putting the import line into the script header.

Here's another important point. The import can appear anywhere you want it to. It can be in a header file 5 scripts up from where the function is defined. It can be in a room script. It can even be in the same script body as the function itself!

However, no matter where you import it, that doesn't change the rules about where it can be used (it must first be defined). So you must keep that in mind.

What it does effect though is the scope of the variable. If you put it into a script header (whether before, the same, or the one immediately after the script that defines the function) then every subsequent script will have access to the function. If you put the import into a script 5 scripts later than the one that defines the function, then none of the scripts in-between will have access. If you only import it into a room script, then only that room has access.

So where you import it is important ultimately as it determines the scope, but the most important thing to note is that it must always be defined before you call the function.

Khris

Of course, my mistake.

What causes the unresolved import message again?

monkey0506

"unresolved import" indicates that you are referencing an imported function or variable which has not yet been defined. Essentially it means what it says, that the import is unresolved. The import resolves when the function/variable is defined.

It's actually interesting to note that the engine only seems to attempt to resolve imports when they are actually referenced. For example, if you put into a script header "import int undefinedintvar;" but never again make reference to "undefinedintvar" then you won't encounter any errors.

So realistically what we can learn from this is that AGS will only give an "unresolved import" if you're referencing an imported function/variable before the actual definition.

This actually ties into the post above. As long as the import is resolved before it's referenced, then you won't have any problems.

And Khris just so you know I wasn't trying to call you out, rather just trying to help clarify how "import" works. ;)

SMF spam blocked by CleanTalk