I just wondered, so I could enhance my frog-finding system.(Like skulltullas)
I heard something like this from the developers, but I don't know if it has been implemented or anything.
Printable View
I just wondered, so I could enhance my frog-finding system.(Like skulltullas)
I heard something like this from the developers, but I don't know if it has been implemented or anything.
Yes.
Though this may change in the future, currently, to allocate a global register, just declare a variable in script scope:
Code:ffc script foo {
int thisisglobal;
}
ffc script bar {
void run() {foo.thisisglobal = 2;}
}
Hrm. I wish there was a way to differentiate variables between hardcoded non-variables in those vBulletin code tags. For example, "void" and "run" aren't variables, but I'd bet that "foo" and "thisisglobal" are. You'd imagine that such variable names would be absolutely common sense that they're user-created variables, but then again, with me seeing so many variables called "this->" (That exact variable, "this" .. yes.) it's getting hard to tell. I'm no C++ programmer, and they can get rather technical sometimes.
... Wow, that's rather off topic. Sorry. XD Just thinking out loud.
So, any FF script can refer to a global variable if it's already been created by another somewhere else. What determines if a variable will be global or not though? How would you set one up to be global vs a single-script variable?
Technically, foo is the name of the script, which is different from a variable. It is user-defined, though, if that's what you mean.Quote:
I wish there was a way to differentiate variables between hardcoded non-variables in those vBulletin code tags. For example, "void" and "run" aren't variables, but I'd bet that "foo" and "thisisglobal" are.
this isn't a variable; it's a pointer to the current FFC. Whenever you see this->anything, it's accessing the properties of the FFC that's running the script.Quote:
You'd imagine that such variable names would be absolutely common sense that they're user-created variables, but then again, with me seeing so many variables called "this->" (That exact variable, "this" .. yes.) it's getting hard to tell.
If I'm not mistaken, the way it is now, any variables declared inside run() or outside of any function are automatically global.Quote:
What determines if a variable will be global or not though? How would you set one up to be global vs a single-script variable?
Ah, yes, it is. :) Thank you Saffith, as always. ^^.Quote:
It is user-defined, though, if that's what you mean.
... Aah, so it's hardcoded. So I can never use it to refer to anything but the FFC that's running the script. Stupid question, but can we make it refer to the script too? (I told you this was a stupid question. :blah: )Quote:
this isn't a variable; it's a pointer to the current FFC. Whenever you see this->anything, it's accessing the properties of the FFC that's running the script.
... Hm. L_L' Why run() of all things though. ... I think this is one of those things where I'd have to study ZScript as a whole to understand this concept rather than asking one question at a time related to it. (Sort of like trying to put a puzzle together by randomly placing pieces on the board, hoping it'll form some semblance of a picture, rather than starting from the base piece and working off of that one. Naturally, the latter is better.)Quote:
If I'm not mistaken, the way it is now, any variables declared inside run() or outside of any function are automatically global.
So... Zscript is object oriented. Will you, in fact, be able to change a user-defined variable at any time? Where is it stored?
I'm not entirely sure what you mean. Do you mean, say, to change which script the FFC is running? Or to change the text of the script itself in some way?Quote:
Originally Posted by ShadowTiger
Yeah, pretty much.Quote:
Originally Posted by beefster09
Global variables are stored in the global registers (gd0-gd255).Quote:
Where is it stored?
... Why is it that quotes are only italicized if the quotee's name is given? That's bizarre.
Variables declared inside run() should NOT be global; if they currently are it's a bug ;)
They may not be global, but other FFCs on the screen using variables of the same name certainly like to change them.
Actually, it seems it's not quite as simple as I thought.
If you assign that to two FFCs on the same screen, it should set their X positions to the same value if temp is global. It doesn't do that.Code:ffc script foo
{
void run()
{
int temp;
temp=this->X;
Waitframe();
this->X=temp;
}
}
I'm pretty sure they're not entirely contained—that was the problem with multiple chaser traps, for example—but they're not simply global, either.
So there really are gd0-gd255?
Yeah. You can access them using precisely those names in ZASM. In ZScript, you can't access them directly; you just create a global variable, and the compiler will find a place for it. Since you don't know what it'll pick, it can be dangerous to mix ZASM and ZScript in a single quest.
So how do you declare a global variable? Will it save when you save your game? Can you access local variables directly using ZScript?
Anything declared within the script body, outside of any method, is automatically global. It can be referred to from another script using scriptName.variableName.Quote:
So how do you declare a global variable?
This may change, though.
... I think so, yeah. I'll have to check and make sure, but I think they're saved.Quote:
Will it save when you save your game?
I'm not sure I know what you mean... That's pretty much the only way you would access them.Quote:
Can you access local variables directly using ZScript?
I'm very interested in this bug. When Saffith's sample script is compiled, temp will be stored on foo's stack. Since each script SHOULD have a separate stack, that two script's local variables are interfering with each other indicates something has gone horribly wrong at runtime.
Could somebody take two scripts which are known to interfere with each other, and pare them down to a minimal set of scripts that still exhibit the bug? As soon as we get two SMALL scripts that illustrate the bug, we need to look at the ASM dumps and determine if the bug is both a compile-time and runtime bug or just runtime.
This is about as small as I can manage.
I'm fairly certain it has something to do with this. If I avoid it, there's never a problem.
I compile those, attach foo to FFC #1 and bar to FFC #2, and it prints the position of #1 twice.Code:ffc script foo
{
void run()
{
int var=this->X;
Trace(var);
}
}
ffc script bar
{
void run()
{
int var=this->X;
Trace(var);
}
}
Also, if I only use one of those and attach it to both FFCs, I get the same output.Code:foo
SETV d2,0
SETR d3,REFFFC
PUSHR d3
PUSHR d2
SETR d4,SP
PUSHR d4
SETV d2,14
PUSHR d2
SETR d6,d4
ADDV d6,0
LOADI d2,d6
PUSHR d2
GOTO 34
POP d4
SETR d6,d4
ADDV d6,1
STOREI d2,d6
PUSHR d4
SETV d2,26
PUSHR d2
SETR d6,d4
ADDV d6,1
LOADI d2,d6
PUSHR d2
GOTO 30
POP d4
SETV d3,0
POP d3
QUIT
POP d3
TRACER d3
POP d3
GOTOR d3
POP d3
SETR REFFFC,d3
SETR d2,X
POP d3
GOTOR d3
bar
SETV d2,0
SETR d3,REFFFC
PUSHR d3
PUSHR d2
SETR d4,SP
PUSHR d4
SETV d2,14
PUSHR d2
SETR d6,d4
ADDV d6,0
LOADI d2,d6
PUSHR d2
GOTO 34
POP d4
SETR d6,d4
ADDV d6,1
STOREI d2,d6
PUSHR d4
SETV d2,26
PUSHR d2
SETR d6,d4
ADDV d6,1
LOADI d2,d6
PUSHR d2
GOTO 30
POP d4
SETV d3,0
POP d3
QUIT
POP d3
TRACER d3
POP d3
GOTOR d3
POP d3
SETR REFFFC,d3
SETR d2,X
POP d3
GOTOR d3
Same ol' ASM.Code:ffc script foo
{
void run()
{
int var=this->X;
Trace(var);
}
}
Code:foo
SETV d2,0
SETR d3,REFFFC
PUSHR d3
PUSHR d2
SETR d4,SP
PUSHR d4
SETV d2,14
PUSHR d2
SETR d6,d4
ADDV d6,0
LOADI d2,d6
PUSHR d2
GOTO 34
POP d4
SETR d6,d4
ADDV d6,1
STOREI d2,d6
PUSHR d4
SETV d2,26
PUSHR d2
SETR d6,d4
ADDV d6,1
LOADI d2,d6
PUSHR d2
GOTO 30
POP d4
SETV d3,0
POP d3
QUIT
POP d3
TRACER d3
POP d3
GOTOR d3
POP d3
SETR REFFFC,d3
SETR d2,X
POP d3
GOTOR d3
Saffith, do you want to forward that quest file I emailed you on to DarkDragon? If he wanders around that quest for awhile (normal cheats enabled) he'll find some examples of the bizzare FFC behavior first hand.
I've added line numbers, some commentary, and split the subroutines off of your ASM dump; if there's a bug in the ASM I don't see it.Code:1 SETV d2,0 ; placeholder
2 SETR d3,REFFFC ; value of the this pointer
3 PUSHR d3
4 PUSHR d2
5 SETR d4,SP
6 PUSHR d4 ; stack is now: 0, this, 254
7 SETV d2,14 ; return value
8 PUSHR d2
9 SETR d6,d4
10 ADDV d6,0
11 LOADI d2,d6 ; d2 is now this
12 PUSHR d2 ; stack is now 0, this, 254, 14, this
13 GOTO 34
14 POP d4 ; SP is popped off of the stack. Stack is now 0, this. d2 holds X.
15 SETR d6,d4
16 ADDV d6,1
17 STOREI d2,d6 ; Stack is now X, this.
18 PUSHR d4 ; Stack is now X, this, 254
19 SETV d2,26 ; return value
20 PUSHR d2 ; stack is now X, this, 254, 26
21 SETR d6,d4
22 ADDV d6,1
23 LOADI d2,d6 ; d2 now holds X
24 PUSHR d2 ; stack is now X, this, 254, 26, X
25 GOTO 30
26 POP d4 ; pops SP off of the stack. Stack is now X, this
27 SETV d3,0 ; NOP
28 POP d3
29 QUIT
30 POP d3 ; pops X off of the stack
31 TRACER d3
32 POP d3 ; pops return value 26 off of the stack
33 GOTOR d3
34 POP d3 ; this is popped off of the stack
35 SETR REFFFC,d3
36 SETR d2,X ; d2 is now X
37 POP d3 ; 14 is popped off of the stack
38 GOTOR d3
What happens if you run two FFCs on the same screen with the following ZASM script:
Code:LOADR d3, REFFFC
TRACER d3
QUIT
You meant SETR, not LOADR, right?
I attached it to eight different FFCs. For the first two, the output isn't entirely predictable. One of them prints #1's X position, and the other one prints 0. It seems as if the order of those two somehow depends on their positions.
For FFCs #3-8, however, it simply prints the numbers 2-7 in order.
Yes, but how do you declare a global variable that can be acessed anywhere in the game?
And we only get a limited number of global variables, right? So if I want to make a set of global variables that mirror Link's inventory, checking for all items he could possibly have, do I even have enough space to do that? I guess I could use some creative data structure, where I use X bits to determine unique combinations of 2^X different items, but I'll be damned if that doesn't sound like a pain in the ass.
Oops, yes, yes I did.
:odd:Quote:
I attached it to eight different FFCs. For the first two, the output isn't entirely predictable. One of them prints #1's X position, and the other one prints 0.
Well, here's the bug. REFFFC should be intialized to 0 for the first FFC, 1 for the second, etc. If they are being set to unpredictable values, then yes, cross-script intereference is very possible.
Well, there are 256 item slots, of which a little over 100 are used now, so yes, you could use global variables. But since each global is a long, it would be much more efficient to use individual bits. When arrays are implemented that won't be too bad to implement; right now it's so painful that it's probably not worth doing.Quote:
So if I want to make a set of global variables that mirror Link's inventory, checking for all items he could possibly have, do I even have enough space to do that?
EDIT: Sorry beefster09, I completely missed your post.
Gobal variables are always totally global, you don't need to do anything special to access them from elsewhere in the game.
Thank you!