Well, this is getting silly, but it might fix the remaining issues:
const int __LA_HOLDUP_HANDS = 1; //The number of hands to use for the default hold-up animation.
//D0 Integer: Number of Message String to display if Link is near the bottom of the screen
//D0 Decimal: Number of Message String to display if Link is near the top of the screen
//D1 Integer: ID of Item that prevents Message String from being displayed
//D1 Decimal: ID of item to hold up. Set to '0' for no hold-up animation.
item script AdvPickUpMessage
{
void run(int stringA_stringB, int stringPreventItemID_this_item_id)
{
bool foundff;
int stringA = stringA_stringB << 0;
int stringB = ( stringA_stringB - stringA ) * 10000;
int stringPreventItemID = stringPreventItemID_this_item_id << 0;
int this_item_id = ( stringPreventItemID_this_item_id - stringPreventItemID ) * 10000;
if ( !Link->Item[stringPreventItemID] )
{
if ( this_item_id > 0 && this_item_id < 256 )
{
if ( Link->Action == LA_SWIMMING || Link->Action == LA_DIVING )
{
int ff[]="swimHoldUp";
for ( int q = 32; q > 0; q-- )
{
ffc f = Screen->LoadFFC(q);
if ( f->Data == 0 )
{
if ( f->Script == 0 )
{
foundff = true;
f->Data = 1;
f->Script = Game->GetFFCScript(ff);
f->InitD[0] = this_item_id;
f->InitD[1] = stringA;
f->InitD[2] = stringB;
break;
}
}
}
if ( !foundff )
{
int ferr[]="Cound not find a free ffc slot to run the ffc script for item script AdvPickupMessage";
TraceS(ferr);
}
Quit();
}
else
{
Link->Action = LA_HOLD1LAND + (__LA_HOLDUP_HANDS-1);
Link->HeldItem = this_item_id;
if(Link->Y > 88)
{
Screen->Message(stringA);
}
else
{
Screen->Message(stringB);
}
}
}
}
}
}
ffc script swimHoldUp{
void run(int itm, int stringA, int stringB){
do {
Waitframe();
} while(Link->Action == LA_DIVING);
Link->Action = LA_HOLD1WATER + (__LA_HOLDUP_HANDS-1);
Link->HeldItem = itm;
while( Link->Action == ( LA_HOLD1WATER + (__LA_HOLDUP_HANDS-1) ) ) { Waitframe(); }
Waitframes(2);
if(Link->Y > 88)
{
Screen->Message(stringA);
}
else
{
Screen->Message(stringB);
}
this->Data = 0;
this->Script = 0;
}
}
A function is "text ( )" or "text [ ]" and the part in the parentheses or brackets is a "call" that references another part of the script.
Err, no. That is probably my fault for using braces to indicate mutable components to the identification of a function in the buffer string. :/
In my examples earlier, stuff between the braces was either optional, or widely variable in context.
I will re-clarify this for you:
A function is a series of instructions that you define, using an identifier, that has a return type; noting that 'void' is a null return type.
So;
int do_x(){ Link->X = Linjk->X +1; return Link->X; }
void do_x(int amt) { Link->X += amt; }
These are both functions. You can identify them in a declaration, by this series of tokens:
TYPE IDENTIFIER LPAREN params RPAREN LCURLYBRACE instructions or return RCURLYBRACE
int do_x ( ) { Link->X+= 1; return Link->X; }
void do_x ( int amt ) { Link->X += amt; }
In these declarations, which define how a function works, or what it does, you can see that a function will always have an identifier (in these examples, the identifier is do_x, followed by left and right parens, with or without parameters (inputs) between them; followed by an opening curly brace, and instructions, closed by a right curly brace.
A function call occurs when you instruct code to use a function. This can occur in a script:
ffc script f{
void run(int a) { //note that run() is a function call, and the args are its parameters.
int x;
x = do_x(); //A function /call/ for the function do_x() that is /defined/ below.
Trace(x); //A function /call/ to Trace(int value), which is an /internal/ ZScript function.
}
int do_x() { x = Link->X +1; return Link->X; } //A function definition at the script scope. This is /called/ in the script.
}
...or inside another function:
int foo(){
int x = Link->X;
x = bar(x); //a call to the function 'bar(int n)' inside the function 'foo()'
return x;
}
int bar(int n){ return n*2; }
In this case the function is "HeldItem(itm)", so the "itm" is referencing another part of the script which is... in this case... the argument "(int itm)" in the second line of the ffc script swimHoldUp, correct? ...If I'm right then yes, I could have fixed that, but I would expect the error message to say that a function had an argument missing. The error message said the pointer type does not have a function, but (to my limited knowledge) the pointer has a function following it, but the referenced argument was missing... do I have that right?
The error that you saw, would have been;
That pointer does not have a function HeldItem.
This indicates an issue trying to access the pointer 'Link', which is an internal ZScript object pointer. My code error, was that I tried to use the variable HeldItem in the syntax of a function.
If Helditem was a function, it would work like this:
Link->HeldItem(value); //Set the value of the item held, as a function.
Note, that you could self-define this, with:
void HeldItem(int itm){ Link->HeldItem = itm; }
From this point, you can just call HeldItem(itm), without using the Link-> pointer, because the function automates that.
The Link pointer though, has a raw HeldItem variable, int HeldItem, not void HeldItem(int n), so the correct syntax is Link->HeldItem = itm.
Can you see the syntax difference? If the identifier has parens () immediately after it, then it is a function.
I've been writing a section for the ZScript Technical Manual that explains all of this at length, so we'll hope that it proves useful to the userbase.
Any identifier that is followed by two braces [] (with or without a numeric literal between the braces) is an array. Arrays are data nodes that hold a number of values, all connected via an identifier as a set. I will remember not to use them to indicate mutable syntax in the manual, as clearly that added to your confusion. I'll skip array syntax here, as I have a set of three tutorial files for them if you want to read those.
Pointers are more important.
The internal ZScript pointers are:
Link
Game
Screen
npc
ffc, this
lweapon
eweapon
item
itemdata, this
Each of these has its own functions, or variables. To reference the function, or variable of an internal pointer, you use the dereference arrow: ->
Thus, the variable HeldItem belongs to the Link pointer, and to access it, you use the dereference arrow:
Link->HeldItem
This instructs the compiler to find the variable in the pointer that you specify to the left of the arrow.
When you declare an npc, or an item, or one of the pointers that you are allowed to declare, the identifier that you assign it, is its pointer.
Thus for:
ffc f;
npc meanguy;
item bigsword;
The pointers are f, meanguy and bigsword.
If you are working with an ffc script, or an item script, you can use the this pointer to reference the ffc structure, or the itemdata structure for the object to which that script is attached.
So, for an item script attached to item 31, the this pointer always references itemdata for item 31, and would be identical to the id pointer below, as if you did:
itemdata id = Game->LoadItemData(31);
This applies equally to pick-up, and action item scripts.
For an ffc script, the this pointer references the ffc structure that is running the script. If the script is attached to ffc ID 2 on a screen, using the this pointer in that script is equivalent to the f pointer in this LoadFFC(int index) function call:
ffc f = Screen->LoadFFC(2);
Scripts are also effective pointers, treated similar to classes, or structs in C++, for the purpose of function calls. You are permitted to define a function at a scope that is local to a script, and to call it using the script identifier and the dot dereference:
ffc script fff{
void run(){
//instructions
}
void ding(){ Trace( Link->Y; }
}
ffc script derefexample{
void run(){
fff.ding(); // A function call, to the function ding(), defined in the script 'fff'.
// The dot ( . ) between fff and ding() indicates that we are using a function defined
// in / the script before the dot /, much like a struct function in C++.
}
}
I bet all of you thought that this section on pointers, and dereferencing was wholly off-topic; eh?
If you have questions about pointers, I can continue this, but those are the essentials.
I don't know if all of that will overwhelm you, but you can try to digest it in morsels, and see what you retain.