Jump to content

Photo

Lantern Script!


  • Please log in to reply
5 replies to this topic

#1 Xiion

Xiion

    Senior

  • Members

Posted 06 July 2008 - 03:25 PM

I've been working on this off an on for a while now, but here it is! A fully functioning script to mimic the lantern glow from LttP!

CODE
ffc script lanterncombo

//Script for simulating a lanterns glow around link
//this script works! Note: It's possible to cheat by going to subscreen(it cancels the effect while bringing down the subscreen (if anyone can fix this, let me know))
//also, there maybe some flicker along the top tile, especially if link is moving fast, so best to limit motion to below those tiles.
//
//The way the script is setup, If you scroll onto the screen, theres a brief bit of darkness (60 frames).
//After that, if link has no item, the screen remains dark. If link has the "required item" he gets a small glow around him.
//Unless of course, he has the "Over rule item" in which case theres a small animation illuminating the entire screen.
//If you have one, and pick up the other while on screen, it will update your vision accordingly!
//Hence if you have the required, and pick up the over rule, the screen lights up!
//

//For some reason, it doesn't like text, or rather, text doesn't like it, because the text goes overwrites the script.
//Might have to do with what layer the darkness is on (currently layer 6)
//
//For this script, the TILES should be laid out like this:
//glow is currently a 3x3 square, but this can be altered to be bigger, but then you'll have to account for the Tdistance of the glow
//shadowtile=    TL    TC        TR    next animation frame...
//                CL    empty    CR    next animation frame...
//                BL    BC        BR    next animation frame...
//shadowtile2 = an 18x13 block of solid dark tiles, with an empty 3x3 spot missing from the bottom right corner WHICH MUST BE LEFT BLANK!
//lightup = a 1 x 4 row that is used to animate the light up gradient.
//It is important to note that these tiles must be placed before tile 32768, or, you need to edit the script to take that into account.
//Zquest will find the tile if its higher in value, but the inputs are signed floats which limits it to this value.
//
//Script by Xiion

{
    void run(int shadowtile, int shadowtile2, int lightup, int item_req, int item_overrule, int cset, int torch_combo)  
    //shadowtile    is the TILE number of the upper left tile of the 3x3 glow animation (see above)
    //shadowtile2     is the TILE number of the upper left tile of the darkness block
    //lightup         is the left TILE of the light up animation
    //item_req         is the value of the item required to get a glow
    //item_overrule is the value of the item required to null the darkness completely  
    //cset             denotes    which cset to use for the darkness
    //torch_combo    denotes the combo that represents a lit torch
    {            
        int Tdistance = 0; //running value of the distance between link and the top of the screen
        int initial_delay = 0;
        if (initial_delay <= 60) //gives an inital darkness animation for the first 60 frames, while link scrolls across the screen
        {
            Tdistance = Ceiling(Div(Link->Y,16));//distance from link to subscreen in tiles
            Screen->DrawTile(6, Link->X-1*16,  Link->Y-1*16,  shadowtile2,  3,  3,  cset,1,0,0,0,0,1,128);
            Screen->DrawTile(6, Link->X-16*16, Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 18, Tdistance+3, cset,1,0,0,0,0,1,128); //Top left overlap
            Screen->DrawTile(6, Link->X+2*16,  Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 15, Tdistance+3, cset,1,0,0,0,0,1,128); //Top right overlap
            Screen->DrawTile(6, Link->X-16*16, Link->Y+2*16,  shadowtile2, 18, 9,  cset,1,0,0,0,0,1,128); //Bottom left overlap
            Screen->DrawTile(6, Link->X+2*16,  Link->Y+2*16,  shadowtile2, 15, 9,  cset,1,0,0,0,0,1,128); //Bottom right overlap
            Screen->DrawTile(6, 0,0, shadowtile2, 16,1, cset,1,0,0,0,0,1,128); //top of screen overlap
            initial_delay += 1;
            Waitframe();
        }
        
        int max = lightup + 3; //gradient spans 4 tiles from lightup to lightup+3
        int tile = 0;
        int alreadylit = 0;
        int x = -16;
        int y = 0;

        
        while(true)
        {
            //look for lit torches first
            int torchnum =0;
            int frames =0;
            for (tile=0; tile<=175; tile++)
            {
                if (Screen->ComboD[tile] == torch_combo)
                {
                    torchnum ++;
                }
            }
            if (torchnum == 0)
            {
                alreadylit = 0;
            }
            if (torchnum >4)
            {
                torchnum=4;
            }
            if(Link->Item [item_overrule]) //if you have the overrule item, the screen lights up automatically
            {
                if (lightup <= max)
                {    
                    for(frames=0; frames<=4; frames++)
                    {
                        for (x=-16;x <= 256; x+=16)
                        {
                            for(y=0; y <= 176; y+=16)
                            {
                            Screen->DrawTile(6,x,y,lightup,1,1, cset,1,0,0,0,0,1,64);
                            }
                        }
                        Waitframe();
                    }
                    lightup++;
                }
                else
                {
                    Waitframe();
                }
            }
            
            else if(torchnum > 0 ) //if torches are lit, the screen will light up
            {
                for (x=-16;x <= 256; x+=16)
                {
                    for(y=0; y <= 176; y+=16)
                    {
                        Screen->DrawTile(6,x,y,lightup+torchnum-1,1,1, cset,1,0,0,0,0,1,64);
                    }
                }
                Waitframe();    
            }
            else if(Link->Item [item_req] && alreadylit==0) //if link only has the required item, and no torches are lit he gets a small animated glow around him
            {
                Tdistance = Ceiling(Div(Link->Y,16));//distance from link to subscreen in tiles
    
                for(frames=0; frames<=4; frames++)
                {
                    Screen->DrawTile(6, Link->X-1*16,  Link->Y-1*16,  shadowtile,  3,  3,  cset,1,0,0,0,0,1,128);
                    Screen->DrawTile(6, Link->X-16*16, Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 18, Tdistance+3, cset,1,0,0,0,0,1,128); //Top left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 15, Tdistance+3, cset,1,0,0,0,0,1,128); //Top right overlap
                    Screen->DrawTile(6, Link->X-16*16, Link->Y+2*16,  shadowtile2, 18, 9,  cset,1,0,0,0,0,1,128); //Bottom left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y+2*16,  shadowtile2, 15, 9,  cset,1,0,0,0,0,1,128); //Bottom right overlap
                    Screen->DrawTile(6, 0,0, shadowtile2, 16,1, cset,1,0,0,0,0,1,128); //top of screen overlap
                    Waitframe();
                }
                
                for(frames=0; frames<=4; frames++)
                {
                    Tdistance = Ceiling(Div(Link->Y,16));//distance from link to subscreen in tiles
                    Screen->DrawTile(6, Link->X-1*16,  Link->Y-1*16,  shadowtile+3,  3,  3,  cset,1,0,0,0,0,1,128);
                    Screen->DrawTile(6, Link->X-16*16, Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 18, Tdistance+3, cset,1,0,0,0,0,1,128); //Top left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 15, Tdistance+3, cset,1,0,0,0,0,1,128); //Top right overlap
                    Screen->DrawTile(6, Link->X-16*16, Link->Y+2*16,  shadowtile2, 18, 9,  cset,1,0,0,0,0,1,128); //Bottom left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y+2*16,  shadowtile2, 15, 9,  cset,1,0,0,0,0,1,128); //Bottom right overlap
                    Screen->DrawTile(6, 0,0, shadowtile2, 16,1, cset,1,0,0,0,0,1,128); //top of screen overlap
                    Waitframe();
                }
                
                for(frames=0; frames<=4; frames++)
                {
                    Tdistance = Ceiling(Div(Link->Y,16));//distance from link to subscreen in tiles
                    Screen->DrawTile(6, Link->X-1*16,  Link->Y-1*16,  shadowtile+6,  3,  3,  cset,1,0,0,0,0,1,128);
                    Screen->DrawTile(6, Link->X-16*16, Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 18, Tdistance+3, cset,1,0,0,0,0,1,128); //Top left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 15, Tdistance+3, cset,1,0,0,0,0,1,128); //Top right overlap
                    Screen->DrawTile(6, Link->X-16*16, Link->Y+2*16,  shadowtile2, 18, 9,  cset,1,0,0,0,0,1,128); //Bottom left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y+2*16,  shadowtile2, 15, 9,  cset,1,0,0,0,0,1,128); //Bottom right overlap
                    Screen->DrawTile(6, 0,0, shadowtile2, 16,1, cset,1,0,0,0,0,1,128); //top of screen overlap
                    Waitframe();
                }

                for(frames=0; frames<=4; frames++)
                {
                    Tdistance = Ceiling(Div(Link->Y,16));//distance from link to subscreen in tiles            
                    Screen->DrawTile(6, Link->X-1*16,  Link->Y-1*16,  shadowtile+3,  3,  3,  cset,1,0,0,0,0,1,128);
                    Screen->DrawTile(6, Link->X-16*16, Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 18, Tdistance+3, cset,1,0,0,0,0,1,128); //Top left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 15, Tdistance+3, cset,1,0,0,0,0,1,128); //Top right overlap
                    Screen->DrawTile(6, Link->X-16*16, Link->Y+2*16,  shadowtile2, 18, 9,  cset,1,0,0,0,0,1,128); //Bottom left overlap
                    Screen->DrawTile(6, Link->X+2*16,  Link->Y+2*16,  shadowtile2, 15, 9,  cset,1,0,0,0,0,1,128); //Bottom right overlap
                    Screen->DrawTile(6, 0,0, shadowtile2, 16,1, cset,1,0,0,0,0,1,128); //top of screen overlap
                    Waitframe();
                }
            }
            else //if link has neither item and torches aren't lit, the screen remains blank
            {
                Tdistance = Ceiling(Div(Link->Y,16));//distance from link to subscreen in tiles
                Screen->DrawTile(6, Link->X-1*16,  Link->Y-1*16,  shadowtile2,  3,  3,  cset,1,0,0,0,0,1,128);
                Screen->DrawTile(6, Link->X-16*16, Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 18, Tdistance+3, cset,1,0,0,0,0,1,128); //Top left overlap
                Screen->DrawTile(6, Link->X+2*16,  Link->Y-Tdistance*16, shadowtile2+(11-Tdistance)*20, 15, Tdistance+3, cset,1,0,0,0,0,1,128); //Top right overlap
                Screen->DrawTile(6, Link->X-16*16, Link->Y+2*16,  shadowtile2, 18, 9,  cset,1,0,0,0,0,1,128); //Bottom left overlap
                Screen->DrawTile(6, Link->X+2*16,  Link->Y+2*16,  shadowtile2, 15, 9,  cset,1,0,0,0,0,1,128); //Bottom right overlap
                Screen->DrawTile(6, 0,0, shadowtile2, 16,1, cset,1,0,0,0,0,1,128); //top of screen overlap
                Waitframe();
            }
        }
    }
}



If you find a bug, let me know I'll see what I can do to fix it.
Yeah... its a bit lengthy (not as much now!), but it works. But if you can simplify it... by all means, please let me know....

Edit: Now with Torch compatibility icon_wink.gif
Unfortunately... when the torches are lit, it does slow down zquest noticeably. My best guess as to why this is, it's because of the drawtiles translucency. I don't see anything else that could be doing it. Maybe someone smarter than me can see some other problem.

To setup the tiles for this combo:
IPB Image IPB Image

*Note: For convenience, I used a full color scheme to show all the tiles. In the images, Black is the transparent color.

On the images, I've pointed out the tiles that are referenced by the ffc arguments. Order and placement of the groups of tiles aren't important, but it is important that they stay as a group. (You can ignore the "rain" tiles to the left of the "lightup" tile, they were/are for something else, i just wanted to use the gradient there)

Shadowtile is the top left of the 1st of a 4 frame animation (1-2-3-2) with the sequential frames adjacent to the right.

Lightup is the darkest portion of 4* color gradient. *The code says its 4, my math says its 4, but for some reason, it likes 5 there. Yeah, I don't get it either icon_sweat.gif These tiles are used for when you light up torches. The first torch will cover the screen with the "lightup" tile. The next torch you light, will move change the screen to the next tile to the right, and so forth up to the 4th torch. No more changes after the 4th torch is lit. This gradient is also used when you enter/pickup the "overrule" item. It will cycle through the gradient fast before going completely transparent.

Shadowtile 2 is the top left tile of the big patch of darkness. This is an 18x13 block of tiles. It is very important that the bottom right block of 3x3 remains transparent! That block MUST REMAIN EMPTY! Otherwise you'll cover up your animation! I'm serious! Only cause I've made that mistake a dozen times, and its annoyed me everytime icon_evil.gif

Edited by Xiion, 06 July 2008 - 09:38 PM.


#2 ZebraStallion

ZebraStallion

    Follower of Destiny

  • Members

Posted 06 July 2008 - 03:28 PM

I have a question: Can you light torches?

#3 Xiion

Xiion

    Senior

  • Members

Posted 06 July 2008 - 04:21 PM

Torches.... no...

Although... maybe having it check for a particular combo might be possible, and alter the darkness based on the state of that combo...

I might go add in that functionality, because that would be useful.
Thanks for the idea!


Okay, torch functionality wont be so bad, I might have it done by later tonight, depending on bugs.
Also, wow, I just realized how I could streamline my code a bit... gonna try and do that too... I feel stupid for not noticing it earlier... for loops ftw!

Torches are a YES!
See edits to first post.

Edited by Xiion, 06 July 2008 - 07:03 PM.


#4 Russ

Russ

    Caelan, the Encouraging

  • Administrators
  • Location:Washington

Posted 06 July 2008 - 07:50 PM

Wow, this looks neat. If this is as good as it sounds, you are very good at scripting.

#5 Radien

Radien

    Courage

  • Members
  • Real Name:Steve
  • Location:Oregon

Posted 06 July 2008 - 08:27 PM

So, let me get this straight:

1. You need to set up a bunch of translucent FFCs on the screen to make the room dark before Link enters it.

2. The use of the lantern overrides those FFCs around Link, creating a "glow."

3. Pausing the game makes the whole screen visible as though it were daylight (for the moment, at least). Is this because the FFCs temporarily disappear?...

4. The darkness appears on top of text due to layering issues.


Is all of this correct? Also, how about lighting torches that trigger something other than for the room to be lit up?

#6 Xiion

Xiion

    Senior

  • Members

Posted 06 July 2008 - 08:51 PM

QUOTE
So, let me get this straight:

1. You need to set up a bunch of translucent FFCs on the screen to make the room dark before Link enters it.

2. The use of the lantern overrides those FFCs around Link, creating a "glow."

3. Pausing the game makes the whole screen visible as though it were daylight (for the moment, at least). Is this because the FFCs temporarily disappear?...

4. The darkness appears on top of text due to layering issues.


Is all of this correct? Also, how about lighting torches that trigger something other than for the room to be lit up?


1. No, its one FFC set to a blank tile (so yes, I suppose it would be translucent... err transparent really). The darkness is generated by a page and a half or so of un-comboed tiles. I should get a picture of how thats setup...
2. There are 2 items you can define. One gives a short 3x3 tile glow centered on link. The other overrides the darkness completely. They can be defined under the FFC's arguments. If they are not set(ie. set to 0), their respective actions don't occur.
3. Yeah... if theres a fix for that.... it would be awesome... you could just disable subscreens on that screen... but...
4. No. the darkness disappears when text appears. So you walk along, get to a spot that triggers some text, the darkness goes away while the text is on screen, then comes back when the text vanishes. You can still read the text. I haven't checked if putting this on a different layers helps with this... yet. Well, I've tried having the darkness on layers 4 and 5, and my text still clears the ffc. Granted, my text is being generated via an item script, so maybe thats it, I don't know.
5. You can choose which combo you want to act as your lit torch (also via FFC argument). That way yes, you could trigger other secrets without lighting the torches, you'd just need a copy of your lit torch combo, or something similar.

Gonna add a bit more info to the 1st post...

Edit: Concerning the text bug: This only seems to happen if you have the "messages freeze action" rule checked. If the rule is unchecked, the messages will play normally, and the script will continue to function.

Edited by Xiion, 07 July 2008 - 04:02 PM.



0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users