Jump to content

Photo

Anthus Asks Questions About Scripting


  • Please log in to reply
94 replies to this topic

#1 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 10 May 2016 - 12:37 PM

Parts in bold are tl;dr notes to see if you're interested but don't want to read all this.

Hello all. I want to first say that I'm not going to be requesting anything insane in here. No demanding bosses, or any other stuff that shouldn't require more than a few lines. I'm going to use this thread to ask for small scripts through out the 'engine building' of my quest I am trying to get off the ground. What I'll be asking for mostly are FFC scripts, and item scripts.

As of now, I think I'm going to need two scripts for use with a certain item(s). I have narrowed down the items I want to use, and made the list to incorporate as little scripting as possible. These should be the only items that need scripted. This post explains a bit about this project, and items in particular.

Part 1:
I have two wand items set up. The "Moon Rod" is a level 1, power 1 wand. The "Sun Rod" is a level 2, power 2 wand. They use different slots, and can both be obtained. The Moon Rod is going to work like a wand without a book, always. The Sun Rod is going to work like a Wand with the book (Fire Rod, basically). The item script I'm looking for will be attached to the Moon Rod, and disable the magic book whenever the Moon Wand is used, so no fire is made. Link will have an invisible Magic Book from the beginning. Essentially, one wand makes fire, one wand doesn't even with the book.

EDIT: I actually don't care about the level, or power of the wands, as long as they can both be used. I might give the Moon Rod a power of 0 to stun enemies, kind of like the Ice Rod.

Part 2:
The second part is a little more tricky, and I'm asking for you opinions on the best way to achieve this result, as simply as possible, while still being functional (a dream, right?). These wands will trigger separate triggers. One should not trigger the other's trigger. I did a test, as follows: I have two combos set up, one is a wand fire trigger, and one is a wand magic trigger. The problem here is the Wand with the book still triggers both, and the one that requires the book is only triggered if the flame stops on the combo, and since the wand fire wont appear unless it hits the edge of the screen, or hits an enemy, this won't work. I also thought about using dummy enemies as triggers. One is only killable by Wand Fire, and one is only killable by Wand magic. The issue is still here though, cause again, the wand with the book can still trigger both. I hope I'm still explaining this okay. So what do I need? I essentially want an FFC, or something, that only reacts to one wand, or the other. Maybe it only triggers the wand magic secrets if the item ID being used is = to a specified number (i.e., either wand).


Thanks to anyone willing to help, and I can provide an example quest with these items set up, and ready to go if you want something to work off of, instead of making it from scratch: Example


Also, anyone know why the first wand item is invisible in the player active subscreen?



#2 ywkls

ywkls

    Master

  • Members

Posted 10 May 2016 - 01:00 PM

Completed untested potential script for the moon rod. You can attach it to any item, but preferably one of the custom item classes.

import "std.zh"
import "stdExtra.zh"
import "ffcscript.zh"
import "string.zh"

const int SPR_MOON_MAGIC = 0;
const int MOON_MAGIC_TILE = 0;
const int MOON_MAGIC_CSET = 0;
const int MOON_MAGIC_DAMAGE = 0;
const int MOON_MAGIC_SPEED = 100;
const int SFX_MOON_MAGIC = 0;

item script MoonRod{
	void run(){
		lweapon Magic = CreateLWeaponAt(LW_MAGIC, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2));
		Magic->UseSprite(SPR_MOON_MAGIC);
		Magic->OriginalTile = MOON_MAGIC_TILE;
		Magic->CSet = MOON_MAGIC_CSET;
		Magic->Damage = MOON_MAGIC_DAMAGE;
		Magic->Step =  MOON_MAGIC_SPEED;
		if(Link->Dir ==DIR_LEFT || Link->Dir == DIR_RIGHT){
			if(Link->Dir == DIR_LEFT)
				Magic->Flip = FLIP_H;
			Magic->Tile = MOON_MAGIC_TILE+1;
		}	
		else{
			if(Link->Dir == DIR_DOWN)
				Magic->Flip = FLIP_V;
			Magic->Tile = MOON_MAGIC_TILE;
		} 
		//Play sound and attack.
		Game->PlaySound(SFX_MOON_MAGIC);
		Link->Action = LA_ATTACKING;
	}
}

There may be easier ways to do this. I literally copied a script from another project of mine and changed around the names of the variables to match your idea.

 

Edit: I have a script for specialized triggers that reacts to Lweapons rather than to a flag type. You could then use a script lweapon instead of a magic one and have separate triggers.


Edited by ywkls, 10 May 2016 - 01:23 PM.


#3 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 10 May 2016 - 01:08 PM

Do you have a copy of stdExtra.zh? I don't have one on my computer, for some reason. I just had to copy ffcscript from another ZC folder :P

 

Thanks though. :)

 

 

EDIT: Nevermind, found one. Testing it out now.



#4 ywkls

ywkls

    Master

  • Members

Posted 10 May 2016 - 01:13 PM

I do.  But you can also get it here- http://www.purezc.ne...=scripts&id=121

 

The stuff that script uses is minor, but there are other scripts we might use later that would probably need it.


  • Anthus likes this

#5 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 10 May 2016 - 01:16 PM

I got all the headers now, but:
 
PASS 1: PARSING
PASS 2: PREPROCESSING
PASS 3: BUILDING SYMBOL TABLES
TMP, LINE 27: ERROR S09: VARIABLE DIR_DOWN IS UNDECLARED.
 
-- PRESS A KEY --
 
Should I be defining the constants in the script before trying to import it? Cause right now it is not pointing to anything, but I dunno.
 
EDIT: This is line 27, the line in question:
 
if(Link->Dir == DIR_DOWN)

 

 

EDIT 2: Fixed it, it compiled! The N at the end of "DOWN" was lower case. I changed it, and re-compiled, and it worked.


  • ywkls likes this

#6 ywkls

ywkls

    Master

  • Members

Posted 10 May 2016 - 01:18 PM

That's from std.zh. Every script file needs it, but only once. The list of important headers is at the top of the code I posted. (Those aren't the only ones, just the ones this script needs.)

 

Edit: If the constants aren't defined, then you probably won't see or hear anything.

 

Here's what those constants should correspond to.

const int SPR_MOON_MAGIC = 0;//Sprite from the weapons sprite list.
const int MOON_MAGIC_TILE = 0;//First tile of this sprite's animation.
const int MOON_MAGIC_CSET = 0;/?Cset of that sprite.
const int MOON_MAGIC_DAMAGE = 0;//How much damage the attack does.
const int MOON_MAGIC_SPEED = 100;//How fast it moves.
const int SFX_MOON_MAGIC = 0;//What sound it makes.

Edited by ywkls, 10 May 2016 - 01:21 PM.

  • Anthus likes this

#7 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 10 May 2016 - 01:20 PM

Or you could do something incredibly simple like this:

item script SunWand{
	void run(){
		if(!Link->Item[I_BOOK])
			Link->Item[I_BOOK] = true;
	}
}

item script MoonWand{
	void run(){
		if(Link->Item[I_BOOK])
			Link->Item[I_BOOK] = false;
	}
}

Will only need std.zh.

 

For wand specific triggers, are you planning to do anything especially complex (self only triggers, tiered secrets, ect) or is just one combo that's triggered by the wand okay?


  • Anthus likes this

#8 Saffith

Saffith

    IPv7 user

  • ZC Developers

Posted 10 May 2016 - 01:26 PM

That's problematic... If you fire one wand, then quickly switch and use the other, it won't work right.
I think the best thing to do would be to launch an FFC script that tracks the magic and creates fire when it vanishes.
The triggers should be easy; just use a value in lweapon->Misc[] to distinguish them.

#9 ywkls

ywkls

    Master

  • Members

Posted 10 May 2016 - 01:30 PM

That's problematic... If you fire one wand, then quickly switch and use the other, it won't work right.
I think the best thing to do would be to launch an FFC script that tracks the magic and creates fire when it vanishes.
The triggers should be easy; just use a value in lweapon->Misc[] to distinguish them.

 

Hmm... I can see some possibilities...

 

Anyways, this is the script that lets you set off the flag of your choice by hitting a trigger with the lweapon of your choice.

 

http://www.purezc.ne...=scripts&id=207

 

It does require some fairly complex combo setup, but it also allows for a lot more triggers than normal flags do.



#10 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 10 May 2016 - 01:38 PM

Thanks Moosh, that does look pretty easy.

 

These triggers will be far and few between. Maybe.. 16-22 total? They will be the only wand trigger on their respective screens (and they trigger portals that take you to the other world, and they will be permanent). Self only would only matter if I wanted to have multiple triggers per screen, right? I won't be doing that for these. I should also mention that they should be able to be used on other non-scripted regular wand triggers, but I don't see that being an issue since wands already trigger wand triggers by default :P

 

EDIT: Ninja'd

 

That's problematic... If you fire one wand, then quickly switch and use the other, it won't work right.
I think the best thing to do would be to launch an FFC script that tracks the magic and creates fire when it vanishes.
The triggers should be easy; just use a value in lweapon->Misc[] to distinguish them.

 

If I turn off "switch items with L+R" would that prevent it? I don't want to do that though.

 

EDIT: I just compiled, and tested Moosh's, and didn't see any problem with switching really fast. I was mashing L, R, and the item button, and it seems fine to me. I think I would like to go ahead and use this script. I might be able to use it in conjunction with ywkls' script below. *testing intensifies*

 

Actually, I kind of see what you mean. If you fire magic with the Sun Rod, and switch to the Moon Rod, it will still make the fire. Not really sure what to do here, but I think I can live with it. Does disabling the book in a d-map override the script? I could just disable the book outright in the lightworld to avoid that. Dunno how this would effect triggers either. I guess I could hope that people don't try to break the game, but hey, its ZC :P

 

Hmm... I can see some possibilities...

 

Anyways, this is the script that lets you set off the flag of your choice by hitting a trigger with the lweapon of your choice.

 

http://www.purezc.ne...=scripts&id=207

 

It does require some fairly complex combo setup, but it also allows for a lot more triggers than normal flags do.

 

 
I'll look at that too, since there will likely be other cases where I'll want sounds, or items to trigger stuff. It's nice to have the option to design stuff that way, either way :)
 
I won't be used extensively, so I'm not too worried about the combo set up. 
 
EDIT: ywkls, I attached the script to the action slot on the wand item, and it generated magic that moved upwards regardless of which way I am facing. I can also spam it by mashing the button. 
 
 
EDIT 4: It seems that I can't assign two different Magic sprites to the items. They both use whichever is set to the Moon Rod's magic sprite.


#11 Moosh

Moosh

    Tiny Little Questmaker

  • ZC Developers

Posted 10 May 2016 - 02:25 PM

Okay. Let's try this again. This time you'll need both std.zh and ffcscript.zh. The item is made up of two scripts, an item script and an FFC script. The item script will call the FFC script, so just make sure both of them are there and stick the SunWand script on your Sun Wand item.

 

Set the constant TIL_SUNMAGIC to the tile used by your sun wand's magic sprite. If it's using the same as your regular wand, you can just use duplicate tiles and a duplicate sprite, but it needs to have a unique tile to work. I'm using tiles instead of proximity to locate the wand magic when it's created just on the off chance that it might conflict with another script creating wand weapons near Link, such as whatever Ywkls' script.

item script SunWand{
	void run(){
		int FFCSunWand[] = "FFCSunWand";
		int SunWandID = Game->GetFFCScript(FFCSunWand);
		if(CountFFCsRunning(SunWandID)==0)
			RunFFCScript(SunWandID, 0);
	}
}

const int TIL_SUNMAGIC = 27407; //The first tile used for the sun wand's magic sprite

ffc script FFCSunWand{
	void run(){
		Waitframes(12);
		lweapon l;
		for(int i=1; i<=Screen->NumLWeapons(); i++){
			l = Screen->LoadLWeapon(i);
			if(l->ID==LW_MAGIC&&l->OriginalTile==TIL_SUNMAGIC){
				break;
			}
		}
		if(l->ID!=LW_MAGIC||l->OriginalTile!=TIL_SUNMAGIC)
			Quit();
		int LastX = l->X;
		int LastY = l->Y;
		int Damage = l->Damage;
		int Dir = l->Dir;
		while(l->isValid()){
			LastX = l->X;
			LastY = l->Y;
			Waitframe();
		}
		Game->PlaySound(SFX_FIRE);
		lweapon fire = CreateLWeaponAt(LW_FIRE, LastX, LastY);
		fire->Damage = Damage;
		fire->Angular = false;
		fire->Dir = Dir;
		fire->Step = 0;
		fire->UseSprite(12);
	}
}

Then we have this simple tile based trigger script. It works similar to the wand script to find if you're using the right weapon on it. Any projectile that collides with the FFC and has the right original tile (D0) will be removed and trigger secrets. To have the trigger itself change when it's hit, stick a flag 16-31 on the FFC or under it.

ffc script TileBasedTrigger{
    void run(int firsttile){
        if(Screen->State[ST_SECRET])
            Quit();
        while(true){
            if(Screen->State[ST_SECRET])
                Quit();
            for(int i=1; i<=Screen->NumLWeapons(); i++){
                lweapon l = Screen->LoadLWeapon(i);
                if(l->OriginalTile==firsttile){
                    if(Collision(l, this)){
                        if(l->ID==LW_HOOKSHOT||l->ID==LW_BRANG)
                            l->DeadState = WDS_BOUNCE;
                        else if(l->ID==LW_BEAM)
                            l->DeadState = WDS_BEAMSHARDS;
                        else if(l->ID==LW_ARROW)
                            l->DeadState = WDS_ARROW;
                        else if(l->ID!=LW_FIRE&&l->ID!=LW_BOMBBLAST&&l->ID!=LW_SBOMBBLAST)
                            l->DeadState = WDS_DEAD;
                        Game->PlaySound(SFX_SECRET);
                        Screen->TriggerSecrets();
                        if(!ScreenFlag(SF_SECRETS, 1))
                            Screen->State[ST_SECRET] = true;
                        Quit();
                    }
                }
            }
            Waitframe();
        }
    }
}

  • Anthus likes this

#12 ywkls

ywkls

    Master

  • Members

Posted 10 May 2016 - 02:25 PM

 

EDIT: ywkls, I attached the script to the action slot on the wand item, and it generated magic that moved upwards regardless of which way I am facing. I can also spam it by mashing the button. 

 

 

I was afraid of that...

 

There are ways to have a lweapon's behavior determined by a script, but the only one I've ever gotten to work functions by using an ffc script to regulate it's X and Y position.

 

Moon Magic Beam Script

 

This version uses an ffc to control the movement of the magic. Again, completely untested rewrite of an existing script.

 

Edit: I'm not sure If I was ninja'd or not, since I don't have time to examine the script posted by Moosh at apparently the same second as me right now.


Edited by ywkls, 10 May 2016 - 02:27 PM.


#13 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 10 May 2016 - 02:50 PM

It might help to actually test the things you write, ywkls. The reason your first attempt always moved up is that you didn't set lwpn->Dir. Since it defaults to 0, and 0 is up, it went up.
  • Moosh and ywkls like this

#14 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 10 May 2016 - 03:18 PM

I'm in the process of testing Moosh's second round of scripts. They compiled nicely, and are in.

 

I noticed that for some reason though, if you do have the book, ZC ignores what sprite you set as the Magic Sprite in the item properties, and reverts to the "default" one. I am going to test this without any scripts loaded and see if it happens.

 

Thanks for all the help :)

 

 

Is there a way to combine the disabling of the book from the first Sunwand script with the FFC triggering of the second one? I changed the name so they could both be imported, but there is only one active item script.

 

The first one looks like this with the new names:

item script BookEnable{
	void run(){
		if(!Link->Item[I_BOOK])
			Link->Item[I_BOOK] = true;
	}
}

item script BookCancel{
	void run(){
		if(Link->Item[I_BOOK])
			Link->Item[I_BOOK] = false;
	}
}

But I was wondering if the book enabling/ disabling could be combined with this part of the other script?

const int TIL_SUNMAGIC = 27368; //The first tile used for the sun wand's magic sprite

ffc script FFCSunWand{
	void run(){
		Waitframes(12);
		lweapon l;
		for(int i=1; i<=Screen->NumLWeapons(); i++){
			l = Screen->LoadLWeapon(i);
			if(l->ID==LW_MAGIC&&l->OriginalTile==TIL_SUNMAGIC){
				break;
			}
		}
		if(l->ID!=LW_MAGIC||l->OriginalTile!=TIL_SUNMAGIC)
			Quit();
		int LastX = l->X;
		int LastY = l->Y;
		int Damage = l->Damage;
		int Dir = l->Dir;
		while(l->isValid()){
			LastX = l->X;
			LastY = l->Y;
			Waitframe();
		}
		Game->PlaySound(SFX_FIRE);
		lweapon fire = CreateLWeaponAt(LW_FIRE, LastX, LastY);
		fire->Damage = Damage;
		fire->Angular = false;
		fire->Dir = Dir;
		fire->Step = 0;
		fire->UseSprite(12);
	}
}

Appreciate all the help, again :)

 

And to clarify, the second script makes an FFC fire from the wand that can collide with, and trigger another FFC that is placed on the screen on top of a regular secret flag, right?



#15 TheLegend_njf

TheLegend_njf

    Deified

  • Members
  • Real Name:Grant

Posted 10 May 2016 - 03:48 PM

Having one of these threads is great. I made one of my own awhile back and I'll revisit it occasionally when I need to. :P


  • Anthus likes this


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users