PDA

View Full Version : Trying to figure out Zscript



Jigglysaint
01-06-2008, 02:03 AM
Wow, it must have been a year since I've messed arround with ZC. Just felt bored, so I decided to try my luck at scripting.

Problem is, I am not quite sure exactly what I am doing. To get the hang of things, I tried to insert two simple scripts, one of them being the display string on item pickup script. For some reason I can't have more than one script activated at at time. When I compile one, the other stops working.

The other thing is that I am attemping to make a simple weapon. I just want the wand to fire rocks instead of magic. Problem is, it seems that spawning a weapon sprite is limited to NPC actions, and I am really not knowing what's going on.

Also, as a bit of a rant, they really should organize things and allow for the option to displa and write stuff with bytes. Also a ram editor for ZC would be handy. Heck I'd code stuff in raw hex if I could.

So I just need a little help on how I would go about coding in a simple new weapon.

Russ
01-06-2008, 02:15 AM
\Problem is, I am not quite sure exactly what I am doing. To get the hang of things, I tried to insert two simple scripts, one of them being the display string on item pickup script. For some reason I can't have more than one script activated at at time. When I compile one, the other stops working.

You have to have both scripts in the same file.

Jigglysaint
01-06-2008, 02:18 AM
Ahh, I see. So basically, you need to compile everything at once for it to work. Well that will help when I figure out how to make new weapons. You would think it's as easy as just changing what projectile comes out of where.

pkmnfrk
01-06-2008, 04:45 AM
Scripting is, no offense everyone, a clusterfuck.

To make the wand fire rocks, you don't need to use Scripting, you can edit the wand directly. Go to the Action tab of the Wand item, and in the "Magic Sprite" box, choose "Rock". I'm 95% sure that changes both the sprite and the behaviour, but I haven't played around with it much.

And, making new weapons up entirely is a real pain (right now).

Jigglysaint
01-06-2008, 05:34 PM
I'm pretty sure it only changes the graphics. I tried that with the sword beam and it still acted like a sword beam. I want it to shoot reflected rocks. It's kind of like the homing wand that one alpha had as a joke item.

Joe123
01-06-2008, 05:36 PM
Scripting is, no offense everyone, a clusterfuck.

What is clusterfuck?

Jigglysaint
01-06-2008, 06:11 PM
I take it somebody's been watching the Nerd?

Anyway, so I was right. Sprites are only for the sprite. The projectile will still act like the wand magic. Perhaps if I edit the actual sprite, hmmm. If not, then I'm thinking that if I could spawn an invisible NPC that fires an object when pressed, then goes away, it could work. I just don't know how to define NPC's yet.

Gleeok
01-07-2008, 03:01 AM
What is clusterfuck?

:laughing:

clusterfuck (http://en.wiktionary.org/wiki/clusterfuck)


And, making new weapons up entirely is a real pain (right now).


I ran into all sorts of unexpected stupid shit for months trying to make a global damage script, or even a function similar to ShadowMancers that deals damage. (not recomended) I believe I'm at stage 7-Denial, or is that acceptance... ;) Anyway I take it the path to glory is paved with cussing for you too?

Jigglysaint
01-07-2008, 06:11 PM
If I understand correctly, certain weapons will only damage Link or enemies. I don't know why it's not possible to edit the sprites directly. If you can give an enemy a sprite to fire, why not a weapon? Also, how come you can only choose certain weapons for enemies to fire? BTW, when I refer to sprite, I mean the script that makes it do it's thing. Like I want to have a weapon with the wand firing attribute, but no wand stab, or arrows that don't decrease ammo.

But anyway, I know there are limitations and stuff. I just can't seem to get zcript and Zasm down. For some reason I am unsure how to work out all the variables. I know 6502c and a little Z80, but zasm seems to be a low level language aimed at programmers, not rom hackers. If I had an opcode list and a list of ram loations, I could go to town. Oh well, I'll keep trying tonight.

Joe123
01-07-2008, 06:27 PM
ZASM isn't perhaps as worth worrying about as ZScript, no-one around appears to be interested in it, so you've unlikely to get help so easily.

And basically, if you want to script items, you have to script them from scratch.
It is possible, but not very easy.

You'd be better off with something a bit less extravagent perhaps.
Try making a boss or something with FFC scripts.

Jigglysaint
01-07-2008, 07:01 PM
I could, except I still don't really understand zcript very well. I mean I understand the concept, but the big problem is syntax, and proper usage of each command. The examples and text I've read state what the variables are, but not explicitly how they are used.

pkmnfrk
01-07-2008, 07:11 PM
But anyway, I know there are limitations and stuff. I just can't seem to get zcript and Zasm down. For some reason I am unsure how to work out all the variables. I know 6502c and a little Z80, but zasm seems to be a low level language aimed at programmers, not rom hackers. If I had an opcode list and a list of ram loations, I could go to town. Oh well, I'll keep trying tonight.

Oh, sweet...

No. Although I've not looked too much at ZASM, I can only hope there are no pointers in it. Or direct memory addressing.

Honestly, stick to ZScript for most of your code, and if you have a small, but frequently called function, you could write it in ZASM.

And, I'm not sure what you mean by "I am unsure how to work out all the variables". Zscript is pseudo object oriented, revolving around the five major classes: Link, FFC, Screen, Game and NPC. So, all your magic variables are going to be members of those objects.

Link, Screen and Game are singletons (i.e. there is only one of each, and are accessed by their class name), while FFC and NPC are instances of the FFCs and enemies on the screen, respectively.

ZScript.txt outlines the members for each class, and gives you all the information you need.

And, you can create your own variables of types int, float (which is the same as int), bool, ffc and npc. The last two are pointers to FFC and NPC classes.

So, for example:


ffc Zelda = Screen->LoadFFC(1);
Zelda->X = 16;
Zelda->Y = 16;

This snippet grabs a pointer to the first FFC, and places it at (16,16) (measured in pixels). Since we use a variable to hold the results of Screen->LoadFFC, we can reference it by name.

The clusterfuck I refer to is actually the rest of the stuff, wrapping scripts in "ffc script" blocks, which have members themselves, but oh! they can't have variables, all globals are in the global namespace.

And, no, swearing is not my last course of action. It's simply the most accurate word to describe the state of scripting.

Jigglysaint
01-07-2008, 07:29 PM
Let's just use this as an example:

item script rock{
void run(int Weapon){
NPC->Weapon(18);
Game->PlaySound(51);
} // run
} // rock

The script doesn't work, which makes sense because it's wrong. The first line is fine. The second line, voidrun, I am unsure of what to do with this. After that is NPC class, which for some reason the script won't recognize. What I am trying to do is get a certain weapon value, and apparently you can only do that with the NPC class. After, I have the playsound. When most people show scripts, they use (CAPS_LOCK), but when I try to use the worded value, the script rejects it. Instead it seems to work with a number imput. Nowhere do I see any explanation to use the actual value instead of the text. That's kind of what's confusing me.

Joe123
01-07-2008, 07:39 PM
*sigh*
I'm afraid you can't just say:
Here's an Item Script ZC, I said something about NPC rock weapons, therefore you should shoot one for me!

What you've said is:

item script rock{ //start script
void run(int Weapon){ //start void run
NPC->Weapon(18);
Game->PlaySound(51);
} //end void run
}// end script

And how ZQuest reads that is:

This script is an item script, so put it in the 'item' compile menu.
Run command for the script (loading an integer called weapon)
Find the enemy that you've previously loaded called 'NPC', and set it's weapon to (18)
Play the Sound effect number 51
End the run command
End the script.

pkmnfrk
01-07-2008, 07:43 PM
A few things:

- ZScript is case sensitive.

- a function looks like this:


type function-name ( [type param1 [, ...]] ) {
contents of function
//if function requires a return value, then you must use return(...) at some point
}

The first type is the the type that the function returns.

- void is a special type, and can only be used as a return type. It means "I don't return anything"

- NPC->Weapon(18) doesn't work because zscript is looking for a variable called "NPC", and can't find one.

- npc->Weapon(18) doesn't work because you're trying to call a function using a base type. Doesn't work for the same reason "int->Weapon(18)" doesn't work.

- You should create a variable to hold the NPC in, like this:

npc myenemy;
myenemy = Screen->CreateNPC(NPC_SHOOTROCK)

- But, even if you do that, it still won't have a Weapon() function. You can't really force enemies to do anything in particular.

- Game->PlaySound(51) does work (but the compiler doesn't get that far);

- in std.zh, you'll see a lot of lines that look like this:

const int SFX_ROCK = 51; // Octorok rock is fired.
const int WPN_REFROCK = 18;
This is a constant. It means that "WPN_REFROCK" means 18, and "SFX_ROCK" means 51.

- You are strongly advised to put this line at the top of every single script file you create:

import "std.zh"
This will cause the compile to recognize all the aforementioned constants.

So, you know assembly, but not C? Odd.

Joe123
01-07-2008, 07:54 PM
Beat you to it...

Yours is much better explained though =P

Anyway, something more what it should look like to make that happen would be:

bool rock = false;

item script rock{
void run(){
rock = true;
}
}

ffc script rock{
void run(){
ffc rockshot = Screen->LoadFFC(32);
eny1 = Screen->LoadNPC(1);
eny2 = Screen->LoadNPC(2);
//...
eny10 = Screen->LoadNPC(10);
while(true){
if(Abs(eny1->X - rockshot->X) < 8 && Abs(repeat for y){
eny1->HP -= 1;
}
//repeat for other NPCs
if(rock){
rockshot->X = Link->X;
rockshot->Y = Link->Y;
if(Link->Dir == DIR_DOWN){
rockshot->Vy = 1;
}
//...
if(Link->Dir == DIR_RIGHT){
rockshot->Vx = 1;
}
Game->PlaySound(51);
rock = false;
}
Waitframe();
}
}
}

Which is an ffc weapon.
Don't try to use it as is, it's just a bit of a template.

I should explain each step actaully.
Meh.
I will do if you want in a minute.

Jigglysaint
01-07-2008, 07:55 PM
Yeah. The main reason I learned assembly is just so I can hack roms. I don't know anything about C unfortunatly.

So I hope that helps me out a bit. I'll see if I can get somthing to work.

Edit: So basically what I would eventually want to do is to make a FFC appear on a button press, which in turn also fires the weapon? Yeah, that is complicated.

Now as for spacing and stuff. I notice that each line is indented by 1 space as it goes down. Is that manditory, or is it just for organization?

Either way I am not familar with C, so I don't know how everything works. When I learned ASM, I actually didn't understand for the longest time. Then somebody explained RAM, and it's interaction with the opcodes and things fell into place. I am sure once I start understanding things, everything will fall into place.

Mega Link
01-07-2008, 08:40 PM
Now as for spacing and stuff. I notice that each line is indented by 1 space as it goes down. Is that manditory, or is it just for organization?
Organization.

Joe123
01-07-2008, 08:40 PM
Edit: So basically what I would eventually want to do is to make a FFC appear on a button press, which in turn also fires the weapon? Yeah, that is complicated.

Well, that's only the half of it.

The best part is, that you have to get the script to load every single NPC on every single f*cking screen you want the weapon to work on, and then check every frame if they're close enough to the ffc to take damage, and then damage them.

That's what this bit does:

if(Abs(eny1->X - rockshot->X) < 8 && Abs(repeat for y){
eny1->HP -= 1;
}


Now as for spacing and stuff. I notice that each line is indented by 1 space as it goes down. Is that manditory, or is it just for organization?
It isn't manditory per se, but if you don't do it then
A) your scripts will be hard for you to read and
B) noone else will have even the slightest chance.
Also, for the love of God, use 'tab' to indent and not a series of different numbers of space-bars.
Tab is so much simpler.

Anyway, indenting allows you to see what levels the script works on, which is why it's used.

The first level (in the ffc script one) is the script-wide, the second one encloses only the run command, the third one is for things only within the while loop, and then there are ifs at various levels.
It's more like a tier system than just 'every line gets indented as you go down'.
As you'll see, once you're inside the while loop, there are quite a few ifs on the same tier.

EDIT: Oh wow, you beat me to it MegaLink.
I didn't realise =P

Jigglysaint
01-07-2008, 09:20 PM
Okay so making weapons is harder than I think it should be. Sheesh, all I want is to make a wand like the one in an early pre-2:10 beta that had the wand fire reflected fireballs that homed in on it's target. I wasn't looking to make anything more complicated that to just change the behaviour of projectile weapons.

I guess ZC still isn't advanced enough yet. Still, there should still be lots to do. Right now I want to create a new itemclass, but I am not sure how to do it.

cbailey78
01-07-2008, 09:38 PM
You would have to be a rocket scientist to script! :)

Gleeok
01-08-2008, 12:00 AM
I guess ZC still isn't advanced enough yet. Still, there should still be lots to do. Right now I want to create a new itemclass, but I am not sure how to do it.

http://www.armageddongames.net/forums/showthread.php?t=97366


That should keep you busy. ;)



The best part is, that you have to get the script to load every single NPC on every single f*cking screen you want the weapon to work on, and then check every frame if they're close enough to the ffc to take damage, and then damage them.


.....now 75% more crash-free. I've almost got it....

Jigglysaint
01-08-2008, 01:53 AM
Yup, fun allright, at least untill I used my last energy tank and the game crashed.

DarkDragon
01-08-2008, 02:27 AM
The problem with ZScript is that it only translates C-like code into ZASM; what is fundamentally impossible in ZASM is thus also impossible in ZScript. For instance, ZASM has no notion of a heap; all data is stored in either one of the 8 registers, or on the stack, thus, the script-scope variables that you want are not possible without substantially redesigning ZASM - a 2.50 project at the earliest.

The main problem is that everything in ZC - enemies, weapons, items, etc - were never designed with scripting in mind. It's being retrofitted in now, as best as possible, until we have the change to redesign ZC from the bottom up with scripting in mind.

pkmnfrk
01-08-2008, 06:55 PM
The problem with ZScript is that it only translates C-like code into ZASM; what is fundamentally impossible in ZASM is thus also impossible in ZScript. For instance, ZASM has no notion of a heap; all data is stored in either one of the 8 registers, or on the stack, thus, the script-scope variables that you want are not possible without substantially redesigning ZASM - a 2.50 project at the earliest.

The main problem is that everything in ZC - enemies, weapons, items, etc - were never designed with scripting in mind. It's being retrofitted in now, as best as possible, until we have the change to redesign ZC from the bottom up with scripting in mind.

Yeah, I know, I know. But, we can wish, right?

I can't imagine that adding a heap would be too difficult. Hell, you wouldn't even have to make a real heap, per se. Use a vector, and allocate variables as indexes into that.

I'd love to take a look at the innards of the scripting system, but I know that's not possible :(

Jigglysaint
01-14-2008, 12:15 AM
Is it possible to obtain and re-insert the actual item itemclass scripts to make duplicates? Also why can't I name custom item classes?

_L_
01-14-2008, 12:47 AM
What do you mean? An item script can be instantiated by many items.

Jigglysaint
01-16-2008, 01:06 AM
Well for one thing, what if I want two arrow slots in my inventory? let's say for example that I want fire arrows and ice arrows. That's not a problem, I can just make two items. However, both will compete for space in the inventory screen as the game looks for item classes rather than the items themselves. That means the ice arrows will replace the fire ones, and vice versa. I have a way arround that which involves a weapons exchange, but being able to have multiples of the same class would be good. Also with the custom item class, I guess you insert a script for it to run, but there's no way of naming it, unlike the custom items.

Finally, and this is a rant, there should be support for editing and displaying numbers as bytes rather than numbers. This is especially good for things that store data as bits, like reflect flags. I don't know if that's feesable or not though.

_L_
01-16-2008, 10:39 AM
Certainly there's no way to duplicate the hard-coded item classes at this point. But you can give the same script to two items of a different itemclass.

For instance, you can assign my Bottled Water script (in NeoFirst) to an item of itemclass "Custom Itemclass 1", and also assign it to an item of itemclass "Custom Itemclass 2". Both of those itemclasses can each have a subscreen slot to itself.

...Bytes? Is that hexadecimal or binary?

pkmnfrk
01-16-2008, 07:07 PM
Also with the custom item class, I guess you insert a script for it to run, but there's no way of naming it, unlike the custom items.

Item classes don't actually exist. You can't point at one in game, and say "Look! That there is an item class!" Thus, there is no real need to be able to change it.

Also, items get scripts, item classes don't. Item classes are used for two things only:

- Determining where on the subscreen items go
- Figuring out if the game should add or remove the lower level items when you pick it up


Finally, and this is a rant, there should be support for editing and displaying numbers as bytes rather than numbers. This is especially good for things that store data as bits, like reflect flags. I don't know if that's feesable or not though.


int a;
a = 0x123;
a = 1101101b

That what you're looking for?

Joe123
01-16-2008, 07:16 PM
You can do that?

I was under the impression that you couldn't?

pkmnfrk
01-16-2008, 07:24 PM
No, you very much can.