Jump to content

Photo

Custom Holding Up An Item Request


  • Please log in to reply
12 replies to this topic

#1 Cukeman

Cukeman

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

  • Banned
  • Location:Hyrule/USA

Posted 10 March 2016 - 03:13 AM

I just realized that since I'm using 32x32 Link, the Hold Up Item animation isn't going to work properly; the Item will appear at Link's chest level, not above his head.

 

I've been told you can't change the Y height of the Item in the Hold Up Item animation. But what if you don't use the Hold Up Item animation at all?

 

Can you make an Item Pickup Script that brings up a Message String, draws a Tile at the specified X and Y values relative to Link's position, and changes Link's Sprite to the Sprite specified for as long as the Message String is onscreen? That would be excellent.

 

D0: Message String to bring up

D1: Tile to display

D2: X value of Tile relative to Link's position

D3: Y value of Tile relative to Link's position

D4: Link Sprite to use

• 1=Land, Hold, One Hand

• 2=Land, Hold, Two Hands

• 3=Water, Hold, One Hand

• 4=Water, Hold, Two Hands


Edited by Cukeman, 10 March 2016 - 03:21 AM.


#2 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 10 March 2016 - 04:09 AM

Use the existing pickup script that I gave you. Set the item to hold up to 0, so that it draws a blank item, but does the animation; then use the drawing code to draw the real item where you want it. You may need to modify the X value, which is extremely easy.

 

If you need me to modify it for you, let me know, but you might want to give it a trial run on your own first, as that's how you'll learn.


Edited by ZoriaRPG, 10 March 2016 - 04:10 AM.


#3 Cukeman

Cukeman

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

  • Banned
  • Location:Hyrule/USA

Posted 10 March 2016 - 04:27 AM

I didn't realize that your script did this. Let me take another look at it.



#4 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 10 March 2016 - 05:36 AM

I didn't realize that your script did this. Let me take another look at it.

 
Note that this is untested,and may have errors, or problems that I would need to resolve., but you are welcome to play with it:
//import ffcscript.zh

const int DRAW_ITEM_DURATION = 100; //Should be an even number, and evenly divisible by DRAW_ITEM_FLICKER.
const int DRAW_ITEM_32X32_HOLDUP_DURATION = 100; //Special duration for 32x32 hold-up animation drawing.
const int DRAW_ITEM_LAYER = 6;
const int DRAW_ITEM_FLICKER = 20;

ffc script FFC_DrawItemoverLink{
    void run(int item_id, int y_offset, int x_offset, int flicker){
        item i = Screen->CreateItem(item_id);
        i->Z = 214747;
        i->X = 1;
        i->Y = 1;
        i->HitXOffset = -32;
        i->HitYOffset = -32;
        i->DrawXOffset = -32;
        i->DrawYOffset = -32;
        i->CollDetection = false;
        int timer;
        if ( !flicker ) timer = DRAW_ITEM_DURATION;
        if ( !flicker ) timer = DRAW_ITEM_32X32_HOLDUP_DURATION;
        while( --timer > 0 && flicker ) {
            if ( timer > ( DRAW_ITEM_DURATION / 2 ) && timer % DRAW_ITEM_FLICKER == 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,64);
            if ( timer > ( DRAW_ITEM_DURATION / 2 ) && timer % DRAW_ITEM_FLICKER != 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,128);
            if ( timer < ( DRAW_ITEM_DURATION / 2 ) && timer > ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/2) == 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,64);
            if ( timer < ( DRAW_ITEM_DURATION / 2 ) && timer > ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/2) != 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,128);
            if ( timer < ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/4) == 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,64);
            if ( timer < ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/4) != 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,128);
            Waitframe();
        }
        while ( --timer && !flicker ) {
            Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,i->Tile,i->TileWidth,i->TileHeight,i->CSet,-1,-1,0,0,0,0,true,128);
            Waitframe();
        }
        Remove(i);
        this->Data = 0;
        this->Script = 0;
        Quit();
    }
}

item script AllItemPickupDrawOverLink{
    void run(int stringA, int stringB, int invisible_holdup, int item_id, int forcedraw_item_ID, int draw_Y_offset, int draw_X_offset, int holdupType){
        int drawitem;
        int args[4]={drawitem, draw_Y_offset, draw_X_offset,NULL};
        int buffer[]="FFC_DrawItemoverLink";
        if( !Link->Item[item_id] ) {
			if(Link->Y > 96){
				if ( stringA ) Screen->Message(stringA);
			}
			else {
                if ( stringB ) Screen->Message(stringB);
            }
        }
        
        if ( !invisible_holdup ){
            if ( !Link->Item[item_id] && !forcedraw_item_ID ) drawitem = item_id;
            if ( Link->Item[item_id] && !forcedraw_item_ID ) drawnitem = -1; //Not sure on this one. Might throw an error.
            if ( forcedraw_item_ID ) drawnitem = forcedraw_item_ID;
            if ( drawnitem > 0 && !holdupType ) RunFFCScript(GetFFCScript(buffer),args);
            if ( drawnitem > 0 && holdupType ) {
                int holdtype = holdupType += 3;
                if ( Link->Action == LA_SWIMMING ) holdtype += 10;
                Link->Action = holdtype;
                Link->HeldItem = drawnitem;
            }
        }
        if ( invisible_holdup ){
            int holdtype = holdupType += 3;
            if ( Link->Action = LA_SWIMMING ) holdtype += 10;
            Link->Action = holdtype;
            Link->HeldItem = -1;
            RunFFCScript(GetFFCScript(buffer),args);
        }
            
    }
}
I added a minor feature, to allow X-axis placement, and more control over forced hold-up animations.

Edited by ZoriaRPG, 10 March 2016 - 11:13 AM.


#5 Cukeman

Cukeman

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

  • Banned
  • Location:Hyrule/USA

Posted 10 March 2016 - 05:38 AM

Do I have to input the ffc script as a Freeform Combo on each screen?


Edited by Cukeman, 10 March 2016 - 07:40 AM.


#6 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 10 March 2016 - 08:07 AM

Do I have to input the ffc script as a Freeform Combo on each screen?

 
No, this requires, and uses ffcscript.zh, and automatically launches the ffc when needed, and terminates its usage when it completes its task. You do need to ensure that one ffc is free on any screen on which you want this to work. It's usually best to reserve at least four ffcs per screen in any event, as ghosted enemies and other effects need free ffc 'slots'.
 
If you wish an explanation on how this works:
 
The command RunFFCScript() in the item pickup script is used to launch the ffc: This searches for a free ffc slot, and runs the script in that slot.
 
The ffc script itself calls:

Remove(i); //Removes the temporary item pointer, freeing it for use.
this->Data = 0; //Clears the combo of the ffc. This allows it to be used again, later.
this->Script = 0; //Clears the script of the ffc. This frees it.
Quit(); //Quits the script cleanly.

...once it reaches its termination point.
 
Edit: I just realised that the way that I handled flickering wouldn't be useful for this. I'll need to modify that for you, to establish a 'no flicker' mode.

Edited above.

I primarily fear having some typos, or other minor errors in there, caused by working on this tiny tablet, compounded with lack of sleep, so if it throws any, don;t be too shocked.

Note: The holdup animation is a simple 0, 1, or 2 value.

  • 0 is no hold-up.
  • 1 is one-handed.
  • 2 is two-handed.
  • Land/Water versions are automated.

Edited by ZoriaRPG, 10 March 2016 - 11:24 AM.

  • Cukeman and Lightwulf like this

#7 Cukeman

Cukeman

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

  • Banned
  • Location:Hyrule/USA

Posted 10 March 2016 - 12:00 PM

item script AllItemPickupDrawOverLink{
    void run(int stringA, int stringB, int invisible_holdup, int item_id, int forcedraw_item_ID, int draw_Y_offset, int draw_X_offset, int holdupType){
        int drawitem;

 

When an item is drawn above Link, I actually want to draw a Tile and not the actual Item itself (sometimes I will use an image that is different from the item, and I noticed the arguments specify an Item not a Tile).

 

There should be four different sets of X and Y values for where the Tile is drawn, depending on which of the four Hold Up Item Animations is being used.


Edited by Cukeman, 10 March 2016 - 01:28 PM.


#8 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 11 March 2016 - 07:01 AM

When an item is drawn above Link, I actually want to draw a Tile and not the actual Item itself (sometimes I will use an image that is different from the item, and I noticed the arguments specify an Item not a Tile).
 
There should be four different sets of X and Y values for where the Tile is drawn, depending on which of the four Hold Up Item Animations is being used.

//import ffcscript.zh

const int DRAW_ITEM_DURATION                = 100; //Should be an even number, and evenly divisible by DRAW_ITEM_FLICKER.
const int DRAW_ITEM_32X32_HOLDUP_DURATION   = 100; //Special duration for 32x32 hold-up animation drawing.
const int DRAW_ITEM_LAYER                   = 6;
const int DRAW_ITEM_FLICKER                 = 20;
const int DRAW_ITEM_CSET                    = 0;
const int DRAW_ITEM_TILEHEIGHT              = 16;
const int DRAW_ITEM_TILEWIDTH               = 16;

ffc script FFC_DrawItemoverLink{
    void run(int item_id, int y_offset, int x_offset, int flicker){
        item i = Screen->CreateItem(item_id);
        i->Z                = 214747;
        i->X                = 1;
        i->Y                = 1;
        i->HitXOffset       = -320;
        i->HitYOffset       = -320;
        i->DrawXOffset      = -320;
        i->DrawYOffset      = -320;
        i->CollDetection    = false;
        int timer;
        int gfx[10];
        
        if ( !flicker ) timer = DRAW_ITEM_DURATION;
        if ( !flicker ) timer = DRAW_ITEM_32X32_HOLDUP_DURATION;
        
        if ( item_id > 0 ) {     //Using an item ID for the tile.
            gfx[0] = i->Tile;       //The graphic value
            gfx[1] = i->TileWidth;
            gfx[2] = i->TileHeight;
            gfx[3] = i->CSet;
        }
        if ( item_id < 0 ) {     //A specific tile.
            gfx[0] = item_id * -1;          //Convert the negative value to positve.
            gfx[1] = DRAW_ITEM_TILEWIDTH;   //Tileheight
            gfx[2] = DRAW_ITEM_TILEHEIGHT;  //Tilewidth
            gfx[3] = DRAW_ITEM_CSET;        //CSet
        }
        
        while( --timer > 0 && flicker ) { //If we're flickering
            //Do the drawing based on script inputs.
            if ( timer > ( DRAW_ITEM_DURATION / 2 ) && timer % DRAW_ITEM_FLICKER == 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],gfx[3],-1,-1,0,0,0,0,true,64);
            if ( timer > ( DRAW_ITEM_DURATION / 2 ) && timer % DRAW_ITEM_FLICKER != 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],gfx[3],-1,-1,0,0,0,0,true,128);
            if ( timer < ( DRAW_ITEM_DURATION / 2 ) && timer > ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/2) == 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],v,-1,-1,0,0,0,0,true,64);
            if ( timer < ( DRAW_ITEM_DURATION / 2 ) && timer > ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/2) != 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],gfx[3],-1,-1,0,0,0,0,true,128);
            if ( timer < ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/4) == 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],gfx[3],-1,-1,0,0,0,0,true,64);
            if ( timer < ( DRAW_ITEM_DURATION / 4 ) && timer % (DRAW_ITEM_FLICKER/4) != 0 ) Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],gfx[3],-1,-1,0,0,0,0,true,128);
            Waitframe();
        }
        while ( --timer && !flicker ) { //If not flickering
            Screen->DrawTile(DRAW_ITEM_LAYER,Link->X+x_offset,Link->Y+y_offset,gfx[0],gfx[1],gfx[2],gfx[3],-1,-1,0,0,0,0,true,128);
            Waitframe();
        }
        Remove(i);          // Cleanup the item pointer...
        this->Data = 0;     //...clear the ffc combo...
        this->Script = 0;   //...clear the ffc script...
        Quit();             //..and cleanly exit.
    }
}

item script AllItemPickupDrawOverLink{
    void run(int stringA, int stringB, int invisible_holdup, int item_id, int forcedraw_item_ID, int draw_Y_offset, int draw_X_offset, int holdupType){
        int drawitem;
        int args[4]={drawitem, draw_Y_offset, draw_X_offset,NULL};
        int buffer[]="FFC_DrawItemoverLink";
        if( !Link->Item[item_id] ) {
			if(Link->Y > 96){
				if ( stringA ) Screen->Message(stringA);
			}
			else {
                if ( stringB ) Screen->Message(stringB);
            }
        }
        
        if ( !invisible_holdup ){
            if ( !Link->Item[item_id] && !forcedraw_item_ID ) drawitem = item_id;
            if ( Link->Item[item_id] && !forcedraw_item_ID ) drawnitem = -1; //Not sure on this one. Might throw an error.
            if ( forcedraw_item_ID ) drawnitem = forcedraw_item_ID;
            if ( drawnitem > 0 && !holdupType ) RunFFCScript(GetFFCScript(buffer),args);
            if ( drawnitem > 0 && holdupType ) {
                int holdtype = holdupType += 3;
                if ( Link->Action == LA_SWIMMING ) holdtype += 10;
                Link->Action = holdtype;
                Link->HeldItem = drawnitem;
            }
        }
        if ( invisible_holdup ){
            int holdtype = holdupType += 3;
            if ( Link->Action = LA_SWIMMING ) holdtype += 10;
            Link->Action = holdtype;
            Link->HeldItem = -1;
            RunFFCScript(GetFFCScript(buffer),args);
        }
            
    }
}
Added using a specific tile, by passing a negative value for the arg to the item_id param of the ffc script.
 
I've no idea why you need multiple x/y positions: If you set up an item script to hold up the item, with the animation, just assign the values as needed based on the hold-up type that you specify.
 
If you want x/y positions hardcoded based on the hold-up type, that wouldn't be too terrible to add. They'd be defaults, overridden by the offset args.
 
Still entirely untested. Apparently, this is 'the way we roll' now.

Edited by ZoriaRPG, 11 March 2016 - 09:15 AM.

  • Cukeman likes this

#9 Cukeman

Cukeman

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

  • Banned
  • Location:Hyrule/USA

Posted 11 March 2016 - 07:33 AM

Added using a specific tile, by passing a negative value for the arg to the item_id param of the ffc script.

 

 

Sweet! :D
 

I've no idea why you need multiple x/y positions: If you set up an item script to hold up the item, with the animation, just assign the values as needed based on the hold-up type that you specify.

If you want x/y positions hardcoded based on the hold-up type, that wouldn't be too terrible to add. They'd be defaults, overridden by the offset args.

 

 

Well, with the Land based Hold-Up animations, in the one-handed version the item would be left of center, while in the two-handed version the item would be centered. And for the Water based Hold-Up animations, they would have the same X values, but the Y values would be lower since Link is something like half as short, since he's submerged in water. That makes sense.... doesn't it?
 

Still entirely untested. Apparently, this is 'the way we roll' now.

 

 

Sorry- I'm still in the middle of setting up my Big Link sprites, so it's hard to judge if all parts of the script are working when I can't line things up. I'm working on it. Maybe I can at least test the tile display if not the X/Y positioning.


Edited by Cukeman, 11 March 2016 - 07:42 AM.


#10 Avaro

Avaro

    o_o

  • Members
  • Real Name:Robin
  • Location:Germany

Posted 11 March 2016 - 08:40 AM

 

Well, with the Land based Hold-Up animations, in the one-handed version the item would be left of center, while in the two-handed version the item would be centered. And for the Water based Hold-Up animations, they would have the same X values, but the Y values would be lower since Link is something like half as short, since he's submerged in water. That makes sense.... doesn't it?

 

The X and Y positions and the holdup type are variables you can change per item. But yeah, the Y difference based on water or land is not in the script yet.


Edited by Avataro, 11 March 2016 - 08:41 AM.


#11 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 11 March 2016 - 09:10 AM

The X and Y positions and the holdup type are variables you can change per item. But yeah, the Y difference based on water or land is not in the script yet.

 
That should be a fixed offset, so I'd need to know the pixel difference the OP requires, given the tiles that he is using. It would be very basic to add it in, if I'm given the specific value.

Link's X/Y value is always based on his upper-left corner, with no regard to if he is swimming, and I do not believe this changes; which is why this shouldn't matter. It uses Link->Y as the baseline for the offset.


Edited by ZoriaRPG, 11 March 2016 - 09:16 AM.


#12 Cukeman

Cukeman

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

  • Banned
  • Location:Hyrule/USA

Posted 27 April 2016 - 07:34 PM

 
That should be a fixed offset, so I'd need to know the pixel difference the OP requires, given the tiles that he is using. It would be very basic to add it in, if I'm given the specific value.

Link's X/Y value is always based on his upper-left corner, with no regard to if he is swimming, and I do not believe this changes; which is why this shouldn't matter. It uses Link->Y as the baseline for the offset.

 

Sorry it's taken this long to gather my Link sprites together and import them. Here are the offsets:

 

Hold up Item on Land (1 Hand) = 2 pixels up and 11 pixels right from default location

Hold up Item on Land (2 Hands) = 6 pixels up from default location

Hold up Item in Water (1 Hand) = 4 pixels up and 11 pixels right from default location

Hold up Item in Water (2 Hands) = 1 pixel down from default location


Edited by Cukeman, 28 April 2016 - 01:11 AM.


#13 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 28 April 2016 - 12:55 AM

l'll see about adding this into the code on Monday. I barely recall making this now, and forgot entirely until i saw your update, so don't fret about tardiness. :D

P.S.I advise sending me a reminder on Sunday.

Edited by ZoriaRPG, 28 April 2016 - 12:57 AM.

  • Cukeman likes this


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users