PDA

View Full Version : Script Help



Nimono
01-13-2007, 07:26 PM
Sigh... I'm just going to put the rest of my questions here.

1: Okay, I want to make a script that spawns another FFC at a location 2 tiles away from Link in the direction he's facing. Would "ffc LoadFFC()" work for this? Or is there a different script I must use?
2: How can I make the aforementioned FFC stick to the tile grid (meaning it can only be on one individual tile, not anywhere inbetween two or more of them)? The effect I want is for the FFC to immediately spawn on the nearest tile to its top-left corner. How can I do this? (I want the FFC to be a pushable block, so it HAS to be on a single tile space!)
3: Can a script actually spawn a combo (not an FFC using the combo) at a location?
4: When using Item Scripts, is there a way to make the custom item take on a few select characteristics of other items, like, say, the Sword Slashing?


Before you answer any of those, let me just tell you what I need these for. I'm attempting a basic Cane of Somaria item. I want the Cane to do the following:

1: Spawn a Combo/FFC 2 tiles away from Link, which should be pushable, and react to all combo types. (Not a problem if it's an actual combo it spawns instead of an FFC.)
2: If you use the Cane again, it checks for this Combo/FFC (It's one of the first things it does, actually). If it's present, it removes it from the screen and respawns it at the new point (2 tiles away from Link in the direction he's facing). If it's not there, it creates it without trying to remove it.
3: If possible AT ALL, when the first block is destroyed, the second isn't created, but instead the first block explodes with magic shoting in 4 directions (Like LttP).

The third thing is optional, but nice. By the way, if we can't currently spawn combos with a script, why not add that to ZC? It'd be nice to be able to do.

C-Dawg
01-13-2007, 07:34 PM
1. No. There is no command to create an FFC. YOu need to have an FFC to use on the screen already. What I do is make sure that, on every screen, there is an FFC #1 that is invisible by default. Then, to "make an FFC appear" you use Screen->FFC(0); and then change the properties of that FFC. Switch it's combo, make it simulate walkability, whatever.

2. Just find out which direction Link is facing, then send the FFC to the nearest X,Y ordered pair in front of Link, such that both X and Y are divisible by 16. (i.e. x/16 = 0, y/16 = 0). So all you have to do is figure out how far X and Y are from being both divisible by 16, and move the FFC accordingly. For instance, when it spawns, divide its X and Y by 16 and see what the remainders are. Move it up or down, left or right, based on those remainders to zero them out. That is, if the FFC finds itself at (34,16), a division will show that X leaves a remainder of 2 and Y leaves a remainder of 0. So you need the FFC to move X-2 to put it on the grid. If the remainder is greater than 8, add to its coordinates rather than subtract from it.

3. No. Have one set up to use. When it's done being a block, set it back to invisible and clear it's abilities.

4. No idea, I havn't messed with item scripts yet.

EDIT: We DO have access to the modulous function % for remainders, don't we?

Nimono
01-13-2007, 07:43 PM
1. No. There is no command to create an FFC. YOu need to have an FFC to use on the screen already. What I do is make sure that, on every screen, there is an FFC #1 that is invisible by default. Then, to "make an FFC appear" you use Screen->FFC(0); and then change the properties of that FFC. Switch it's combo, make it simulate walkability, whatever.

Why did that simple and obvious idea escape me? XD All I'd really have to do is move it. XD

2. Just find out which direction Link is facing, then send the FFC to the nearest X,Y ordered pair in front of Link, such that both X and Y are divisible by 16. (i.e. x/16 = 0, y/16 = 0). So all you have to do is figure out how far X and Y are from being both divisible by 16, and move the FFC accordingly. For instance, when it spawns, divide its X and Y by 16 and see what the remainders are. Move it up or down, left or right, based on those remainders to zero them out. That is, if the FFC finds itself at (34,16), a division will show that X leaves a remainder of 2 and Y leaves a remainder of 0. So you need the FFC to move X-2 to put it on the grid. If the remainder is greater than 8, add to its coordinates rather than subtract from it.

Whoa, hold up now. I barely know how to script, so I'm going to need to be brought step-by-step on how to work something like that. Please note that I learn quickly, and telling me that I should have more scripting experience isn't going to make me give up. :p

3. No. Have one set up to use. When it's done being a block, set it back to invisible and clear it's abilities.
???

4. No idea, I havn't messed with item scripts yet.

EDIT: We DO have access to the modulous function % for remainders, don't we?

My responses are in bold. I didn't feel like breaking down your post into many little quotes. :laughing:

C-Dawg
01-13-2007, 09:22 PM
It's just math. Go check the Documentation thread for the commands, but here's a snippet of the algorithm.

1. Link activates his item.
2. Checks what direction Link is facing.
3. Move the FFC to a location 16 pixels in front of Link, based on what direction he is facing, and set it to whatever attributes you want it to have.
4. Get the FFC's X and Y coordinates. Then, you need to move the FFC to the nearest 16x16 tile. Do this:



remainder = ffc_block->X % 16;
if ( remainder <= 8 ) { ffc_block->X = ffc_block->X - remainder; }
else { ffc_block->X = ffc_block->X + 16 - remainder; }


Do the same thing for Y. What this snippet does is checks the remainder of division by 16, which tells you how far away from the 16x16 grid your FFC is. It them adjusts the value to be divisible by 16.

Nimono
01-14-2007, 04:00 PM
Okay, so exactly how would I go about putting an FFC x pixels in front of Link, depending on the direction he's facing? I know I'd first have to check for the direction Link is facing, the activate code depending on that, but... It's the part for moving the FFC that confuses me.

C-Dawg
01-14-2007, 04:25 PM
Yeah, you didn't read the documentation, huh.

First, you need the create an "ffc" data type that points to the ffc you want to move. You need to know what number ffc it is. I'll assume you're using FFC #1.

This command creates a pointer to FFC #1.



ffc your_ffc= Screen->LoadFFC(1);


Think of this step as giving FFC1 a name in your code. You need to name the FFC before you can tell the script to move it. After all, without a name, the script has no idea which FFC you want to move.

Now you've got a pointer the ffc you want, so you can move it just by changing it's x and y coordinates. For instance, if you discover Link is facing north, then you'd do this:



your_ffc->X = Link->X;
your_ffc->Y = Link->Y - 16;


Get it? The FFC gets moved to Link's X-coordinate, and Link's Y-coordinate minus 16 pixels. That will put it exactly 16 pixels north of Link's position.

You need to change the combo, too, in order to make it "appear." Say that the combo you want to use is combo 30.



your_ffc->Data = 30;


And then, as I said earlier, you do the fancy remainder checking to get it centered on the 16x16 grid. Remember, the player won't see any of this adjusting until you hit a Waitframe(); or the end of the script.

Nimono
01-14-2007, 04:35 PM
Thanks. Now, another question. When I check for Link's direction facing north, would I use this code:



if int Link->Dir = 0

Or do I use something else? Plus, I might be wrong about the "1". XD (See? I'm getting the hang of this! And by the way, I've BEEN checking the documentation. It doesn't exactly tell what stuff you can do with each command. Like, the description for "Screen->LoadFFC(x)" sounds more like it simply returns what every variable for that FFC is set to, and nothing more.)

C-Dawg
01-14-2007, 05:01 PM
The documentation makes sense if you read it correctly. It defines "Screen->LoadFFC(x)" as an "ffc" data type. That means it provides you with a pointer to an ffc, not the "variable for that ffc" or whatever.

If statements are written like this:


if(Link->Dir == 0 ){

// insert your code here

}


If the conditional statement inside the () is true, the script will execute all of the code inside the {}s.

Take notice of the fact that = and == mean different things in ZScript. = does NOT mean "equals." It is an "assignment" statment. Use it when you're changing the value of variables. For instance:



x = x + 4;


Think of it as saying: "The value is x is now assigned to be the previous value of x plus four."

== means something different. "x == y" is true if and only if x is equal to y. So, when you use if statements and you want to check if two things are equal, use ==, not =.

Finally, you don't need to say "int Link->Dir." The phrases "int," "ffc," "bool," "npc," and others are data types. If you are making up your own names for things, you need to use them to tell the code what sort of thing you're making. So, for example, if you want to make a integer variable named "counter," you need to tell the script what kind of variable you're making when you first mention it.



int counter = 0;


It's also good practice to put an assignment statement there with the declaration (that's the = 0 part) so that you know what's in the variable. Look back at how we set up a pointer to an ffc; we did the same thing. We gave an ffc a "name," and we preceded that statement with the data type "ffc" to tell the code what sort of data the name was.

Once you've declared your variable, you don't have to tell the script what kind of data type it is again. I don't have to say "int counter" anymore. I just use "counter." So, for instance, if I want to change counter to 6 later in the code, I just do this.



counter = 6;


Now, the pre-defined variables, like Link->Dir, npc->HP, ffc->X, etc, are already pre-defined by the script. They are already there for you to work with. You don't have to tell the code that Link->Dir is an int; it already knows that.

Nimono
01-14-2007, 05:07 PM
Sorry, I got mixed up there. I knew that = and == were two different things and that == meant "equals" in ZScript, but... Well, people don't always think straight, do they? ;)

Thank you. Now I'm one step closer to finishing this code. So, mimicing solidity... Are there any scripts released (That is, as exported code) that have code for pseudo-solidity? I don't think you're going to want to help me figure that out any other way...

Edit: I'm almost done! Just need to find that darn code for pseudo-solidity... Anyways, can ComboF() be used on a FFC? See, I need my "Somaria Block" FFC to be able to be pushed, so I need to place Flag 61 on it. I already put the code in, but I still want to know if ComboF (or anything that would normally relate to plain combos) will work on FFCs without problems. Oh, and can I place your "tile=snapping" code-piece wherever I want into my script as long as it's before it ends and I mention the pointer to it?

C-Dawg
01-14-2007, 05:45 PM
Yes. Check my multiblock_trigger script in the showcase forum. There's a bit there that mimics unwalkability.

Nimono
01-14-2007, 06:10 PM
Yes. Check my multiblock_trigger script in the showcase forum. There's a bit there that mimics unwalkability.

Thanks! :D Before I take ANY piece of code out of it, I'm going to check it out in the player first to see how it works. Once I have that code.... That's IT. The code will be done. I'm excited. I'll have made my first true script (And possibly the very first Item script, too!)!

Edit: Forget playing the script. Is this the part that simulates unwalkability?


// Simulate unwalkability
if(walkable == 1){

if( (Link->InputUp) && (Link->Y < this->Y + 16) &&
(Abs(Link->X - this->X) < 16) &&
(Link->Y > this->Y)){Link->InputUp = false;}

if( (Link->InputDown) && (Link->Y > this->Y - 16) &&
(Abs(Link->X - this->X) < 16) &&
(Link->Y < this->Y)){Link->InputDown = false;}


if( (Link->InputLeft) && (Link->X < this->X + 16) &&
(Abs(Link->Y - this->Y) < 16) &&
(Link->X > this->X)){Link->InputLeft = false;}

if( (Link->InputRight) && (Link->X > this->X - 16) &&
(Abs(Link->Y - this->Y) < 16) &&
(Link->X < this->X)){Link->InputRight = false;}
}

Or is it the "int walkable = 1"?

C-Dawg
01-14-2007, 06:41 PM
"walkable" is a variable I defined just to keep track of whether the block is solid or not. In the multiblock trigger script, the FFC is only solid SOMETIMES. If you want yours solid all the time, you can just use what's inside the if statement.

Remember that you'll have to move the FFC out of the player's way when the block isn't there anymore, or else it will remain unwalkable even after it graphically goes away. A good safe place to move it is -16,-16

HOWEVER! The simulation of walkability you are using only applies to Link. If you want it to apply to enemies too, you'll need to do more work.

Nimono
01-14-2007, 06:48 PM
So, it'd be something like this:


(Link->InputUp) && (Link->Y < this->Y + 16) &&
(Abs(Link->X - this->X) < 16) &&
(Link->Y > this->Y)){Link->InputUp = false;}

(Link->InputDown) && (Link->Y > this->Y - 16) &&
(Abs(Link->X - this->X) < 16) &&
(Link->Y < this->Y)){Link->InputDown = false;}


(Link->InputLeft) && (Link->X < this->X + 16) &&
(Abs(Link->Y - this->Y) < 16) &&
(Link->X > this->X)){Link->InputLeft = false;}

(Link->InputRight) && (Link->X > this->X - 16) &&
(Abs(Link->Y - this->Y) < 16) &&
(Link->X < this->X)){Link->InputRight = false;}

Right? And the whole enemy thing can wait until AFTER I get this code working. But yeah, I want it to be solid to both Link and foe alike. But it SHOULD be pushable as long as it has a Push flag on it, right?

Oooh... I just thought of something. What if I wanted the player to be able to jump on top of the block in sideview areas to get around? How would I make it unwalkable then? Would falling count as "InputDown"?

C-Dawg
01-14-2007, 07:01 PM
None of that would work. An FFC can't currently be solid in the same sense that combos can be. All that the mimic code you have there will do is stop Link from walking into the block if he's close to it.

More complete mimicing of walkability hasn't been coded yet, that I know of.

However, you SHOULD be able to set the combo under the centered FFC to be solid, at least temporarily. That'd require:

1. AFTER you move the FFC to be centered on the 16x16 grid...
2. Check the walkability of the combo the ffc is on top of. Save all four corners of the walkability to a variable, so that when the ffc goes away, normal walkability is restored.
3. Change the walkability of the combo under the FFC. (In the four corners).

Nimono
01-14-2007, 07:06 PM
None of that would work. An FFC can't currently be solid in the same sense that combos can be. All that the mimic code you have there will do is stop Link from walking into the block if he's close to it.

More complete mimicing of walkability hasn't been coded yet, that I know of.

However, you SHOULD be able to set the combo under the centered FFC to be solid, at least temporarily. That'd require:

1. AFTER you move the FFC to be centered on the 16x16 grid...
2. Check the walkability of the combo the ffc is on top of. Save all four corners of the walkability to a variable, so that when the ffc goes away, normal walkability is restored.
3. Change the walkability of the combo under the FFC. (In the four corners).
How would I do that? Do I save the walkability in d0-3 and load walkability from d4-7? Or what? You're kinda confusing me a bit on what I have to do.

Also, how would I return walkability to normal? Do I do an if/else statement to check to see if FFC 1 is on the combo?

Edit: Hmmm... But then I'd have to do an if/else to check for original walkability first, so I don't end up making an unwalkable combo walkable. Plus, if I DID make the combo below the FFC solid, once I pushed it, it'd stillbe solid. Remember, this script is an item script, not an FFC script, so I'd actually have to modify the FFC, not the combo. Or the only way to restore walkability to normal is to use the item AGAIN.