Jump to content

Photo

Learning to combine scripts


  • Please log in to reply
69 replies to this topic

#1 Cukeman

Cukeman

    "Tra la la, look for Sahasrahla. ... ... ..."

  • Banned
  • Location:Hyrule/USA

Posted 30 March 2016 - 12:50 AM

I'm very much a graphics kinda guy, then a quest maker. That's a lot, so I don't even try to script really, I mean I have a little, but when I read the scripting tutorials posted here the author would go from step 1 to step 2, and suddenly I'd be like, wait- there's 5 steps missing that I'm just supposed to understand? Clearly it was written for people with more than zero knowledge of programming...

 

Anyway scripters are generous to make scripts for me and sometimes they get mildly irritated when I ask for easy favors, so I'm going to try a little scripting here. I figure people would rather correct my attempts to help me learn instead of just doing it for me.

 

Today I'm going to try combining these two scripts. I might do it wrong, if so, I hope to be corrected so I can learn. Here goes:

 

Script 1:

ffc script CreateItem
{
    void run(int itemID)
    {
        item i = Screen->CreateItem(itemID);
        i->X = this->X;
        i->Y = this->Y;
    }
}

Script 2:

ffc script CreateHoldUpItem
{
    void run(int itemID)
    {
        item i = Screen->CreateItem(itemID);
        i->X = this->X;
        i->Y = this->Y;
        i->Pickup=IP_HOLDUP;
    }
}

My attempt to combine:

ffc script CreateItem2
{
    void run(int itemID, int Pickup)
    {
        item i = Screen->CreateItem(itemID);
        i->X = this->X;
        i->Y = this->Y;
        {
        if (Pickup > 0)
        i->Pickup=IP_HOLDUP;
        else i->Pickup=false;
        }
    }
}

I expect to be combining global scripts soon, global scripts are so freaking intimidating to me, because if something's wrong it can affect multiple scripts which can be quest-breaking. I much prefer ffc and item scripts because they affect only themselves, but sometimes ya need a global.



#2 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 30 March 2016 - 01:09 AM

Your attempt at combining them will almost work, but it'll give you an error if you try to compile it. item->Pickup isn't a boolean (a true or false value), but is instead a number. It's 0 by default for newly created items, which means Link won't hold the thing up. So you don't even need the "else" statement there.

Combining global scripts isn't too bad if you're familiar with their basic structure. Saffith made a nice post about it here. Ideally, all of your global scripts will be simple function calls you can just copy and paste into that basic skeleton from Saffith's post, but sometimes people aren't so nice and neat with how they write them.

#3 Cukeman

Cukeman

    "Tra la la, look for Sahasrahla. ... ... ..."

  • Banned
  • Location:Hyrule/USA

Posted 30 March 2016 - 01:14 AM

Your attempt at combining them will almost work, but it'll give you an error if you try to compile it. item->Pickup isn't a boolean (a true or false value), but is instead a number. It's 0 by default for newly created items, which means Link won't hold the thing up. So you don't even need the "else" statement there.

Combining global scripts isn't too bad if you're familiar with their basic structure. Saffith made a nice post about it here. Ideally, all of your global scripts will be simple function calls you can just copy and paste into that basic skeleton from Saffith's post, but sometimes people aren't so nice and neat with how they write them.

 
So cut the else line and I'm good?

ffc script CreateItem2
{
    void run(int itemID, int Pickup)
    {
        item i = Screen->CreateItem(itemID);
        i->X = this->X;
        i->Y = this->Y;
        {
        if (Pickup > 0)
        i->Pickup=IP_HOLDUP;
        }
    }
}

EDIT: Current version:

ffc script CreateItem2
{
    void run(int itemID, int Pickup)
    {
        item i = Screen->CreateItem(itemID);
        i->X = this->X;
        i->Y = this->Y;
        if (Pickup > 0)
        i->Pickup=IP_HOLDUP;
    }
}

Edited by Cukeman, 30 March 2016 - 04:47 AM.


#4 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 30 March 2016 - 01:19 AM

Yes, that will work. You've got some braces around the pickup section that apparently do nothing, but it'll still work.
  • Cukeman likes this

#5 Mani Kanina

Mani Kanina

    Rabbits!

  • Members

Posted 30 March 2016 - 04:20 AM

Shouldn't there be braces containing the code the if statement runs after being determined true though?

#6 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 30 March 2016 - 04:44 AM

If the body of the if statement is just one line, the braces are optional. But that's beside the point, because the braces are supposed to be around the block of code locked by the conditional, not the condition itself.
  • Mani Kanina likes this

#7 Mani Kanina

Mani Kanina

    Rabbits!

  • Members

Posted 30 March 2016 - 05:18 AM

Yes I know that it's formatted incorrectly here, but since you said it would still run I was confused since I had assumed you needed braces in every scenario.

#8 Cukeman

Cukeman

    "Tra la la, look for Sahasrahla. ... ... ..."

  • Banned
  • Location:Hyrule/USA

Posted 02 April 2016 - 04:11 PM

So, I've got this create item script that works great, but I want to add a feature that will prevent the item from being created if Link already has the item specified in D2

 

Original Script:

//D0: Item ID to create
//D1: Whether or not Link holds up the Item

ffc script CreateItem
{
    void run(int itemID, int Pickup)
    {
        item i = Screen->CreateItem(itemID);
        i->X = this->X;
        i->Y = this->Y;
        if (Pickup > 0)
        i->Pickup=IP_HOLDUP;
    }
}

My attempt to modify:

//D0: Item ID to create
//D1: Whether or not Link holds up the Item
//D2: Number of Item that prevents Item from being created

ffc script CreateItem
{
    void run(int itemID, int Pickup, int itemPreventItemID)
    {
        if(!Link->Item[itemPreventItemID])
            {
                item i = Screen->CreateItem(itemID);
                i->X = this->X;
                i->Y = this->Y;
                if (Pickup > 0)
                i->Pickup=IP_HOLDUP;
            }
    }
}

Edited by Cukeman, 02 April 2016 - 04:15 PM.


#9 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 02 April 2016 - 04:17 PM

That will work.


  • Cukeman likes this

#10 Cukeman

Cukeman

    "Tra la la, look for Sahasrahla. ... ... ..."

  • Banned
  • Location:Hyrule/USA

Posted 02 April 2016 - 06:03 PM

That will work.

 

Is the reason it works because you're not telling the script what to do if Link has the item so it doesn't do anything?



#11 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 02 April 2016 - 06:24 PM

Right. Having a pair of braces containing nothing is perfectly valid, so skipping all of the code with an if statement won't cause issues.


  • Cukeman likes this

#12 Cukeman

Cukeman

    "Tra la la, look for Sahasrahla. ... ... ..."

  • Banned
  • Location:Hyrule/USA

Posted 14 April 2016 - 11:03 PM

global script ActiveGlobal
{
    void run()
    {
        // Before while
        while(true)
        {
            // Before Waitdraw
            Waitdraw();
            // After Waitdraw
            Waitframe();
        }
    }
}

I'm a little confused about the term "loops". How many loops are in this example and where do they begin and end?



#13 coolgamer012345

coolgamer012345

    🔸

  • Members
  • Location:Indiana, USA

Posted 14 April 2016 - 11:35 PM

global script ActiveGlobal
{
    void run()
    {
        // Before while
        while(true)
        {
            // Before Waitdraw
            Waitdraw();
            // After Waitdraw
            Waitframe();
        }
    }
}

I'm a little confused about the term "loops". How many loops are in this example and where do they begin and end?

 

In the example, there's only one loop. It starts with while(true) and ends with the closing curly bracket (the }) on the line after Waitframe();. while(true){} will redo any code that's within the curly brackets indefinitely, though different things in place of 'true' can allow the loop to end (for example while(Link->HP > 0), which would loop as long as Link's HP was over 0. If Link's HP was/under 0 when the loop goes to restart, the loop would end and any code that was after the closing bracket of the loop would be ran).


  • Cukeman likes this

#14 Cukeman

Cukeman

    "Tra la la, look for Sahasrahla. ... ... ..."

  • Banned
  • Location:Hyrule/USA

Posted 14 April 2016 - 11:55 PM

So I've got this script to put in the while(true) loop:

for(int i = 1; i <= Screen->NumNPCs(); i++) {
    npc enem = Screen->LoadNPC(i);
 
    // If this is the death animations enemy
    if(enem->Id == NPC_BIGDEATHANIM && enem->HP == 0) {
        // Move it 8px right/down to be in the center of the 32x32 block
        enem->X += 8;
        enem->Y += 8;
        enem->HP = -1; // So this enemy won't be processed twice
    }

and this constant:

const int NPC_BIGDEATHANIM = 178;//ID of 0 HP Enemy

To combine this global... (I'm not sure if it goes before while, before waitdraw or after waitdraw) ...I would... add lines 10, 21, 22 and 33?

 

Attempt:

const int NPC_BIGDEATHANIM = 178;//ID of 0 HP Enemy

global script ActiveGlobal
{
    void run()
    {
        // Before while
        while(true)
        {
            BigDeathAnim();

            // Before Waitdraw
            Waitdraw();
            // After Waitdraw
            Waitframe();
        }
    }
}


void BigDeathAnim()
{
for(int i = 1; i <= Screen->NumNPCs(); i++) {
    npc enem = Screen->LoadNPC(i);
 
    // If this is the death animations enemy
    if(enem->Id == NPC_BIGDEATHANIM && enem->HP == 0) {
        // Move it 8px right/down to be in the center of the 32x32 block
        enem->X += 8;
        enem->Y += 8;
        enem->HP = -1; // So this enemy won't be processed twice
    }
}

 



#15 Lejes

Lejes

    Seeker of Runes

  • Members
  • Location:Flying High Above Monsteropolis

Posted 15 April 2016 - 12:05 AM

If you put it in the "// Before while" space, it will run once when you start your game, and won't run again until you hit Continue or Retry/Save/reset. Only the stuff within while (true)'s braces will run continuously while you're playing the quest. As for whether to put it before or after Waitdraw()...well, for this script it doesn't really matter. It should function either way. The global script you've got there should work.
  • Cukeman likes this


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users