Jump to content

Photo

?Epona Script?


  • Please log in to reply
138 replies to this topic

#16 Joe123

Joe123

    Retired

  • Members

Posted 07 January 2008 - 07:12 PM

Oh wow thanks, much better than the ones I found.

I shall have a play around with those later icon_thumbsup.gif

Probably with DoR Link on them.

#17 Russ

Russ

    Caelan, the Encouraging

  • Administrators
  • Location:Washington

Posted 07 January 2008 - 08:08 PM

Wait, so then how do you get off Eopna? Or on for that matter? I didn't see anything in the script about it. Sorry I am being so stupid as to how this script works. Oh, and you should post this on AGN. I'm sure plenty of people have been waiting for this.

Edit: And why dodn't you make flag 99 or one of the general purpose flags a "No Epona" flag?

Edited by russadwan, 07 January 2008 - 09:50 PM.


#18 LostInHyru1e

LostInHyru1e

    Can you take me as far as PureZC?

  • Members
  • Real Name:Lost
  • Location:Refer to Screename

Posted 07 January 2008 - 10:46 PM

I know nothing about scripting, but this is awesome.

Joe123, your are awesome. icon_smile.gif Is it complete now? This may wind up being the greatest script ever.

#19 Joe123

Joe123

    Retired

  • Members

Posted 08 January 2008 - 03:11 AM

QUOTE(russadwan @ Jan 8 2008, 01:08 AM) View Post

Wait, so then how do you get off Eopna? Or on for that matter? I didn't see anything in the script about it. Sorry I am being so stupid as to how this script works. Oh, and you should post this on AGN. I'm sure plenty of people have been waiting for this.

Edit: And why dodn't you make flag 99 or one of the general purpose flags a "No Epona" flag?


Use the item again. I'm sure I said earleir.

In the item script where it says 'epona = !epona;', that mean's if epona is true, set if false, if epona is false, set it true.
Not just 'epona = false;' (otherwise Id've written that =P)

It's not complete enough to post yet really.
Maybe when I've done more with it.

That's a good idea.
I was thinking about it earlier, but I was going to do it with an ffc script.
It should be global, I'll go do it.


#20 Twilight Knight

Twilight Knight

    Tell all with glee, Argon's on PureZC

  • Members
  • Real Name:Sven
  • Location:Rotterdam, NL

Posted 08 January 2008 - 02:49 PM

Yes it'll be better as a global script. Making all these ffc's will bore people. icon_razz.gif

QUOTE(LostInHyru1e @ Jan 8 2008, 04:46 AM) View Post

I know nothing about scripting, but this is awesome.

Joe123, your are awesome. icon_smile.gif Is it complete now? This may wind up being the greatest script ever.


I agree with your statement, this sure is a nifty script, I hope it works.

#21 Joe123

Joe123

    Retired

  • Members

Posted 08 January 2008 - 03:05 PM

Well, I'm definately progressing.
CODE
import "std.zh"

//I've included some setup for having Link's items disabled when he rides on Epona. All it requires is some duplication of
//code, and I've included pretty extensive instructions in the required sections, so even non-scripters should be able to
//to it. That's the idea anyway =P.
//The way it works is, when Link picks up each item, the game stores what level of the item he has in a global integer,
//therefore keeping a copy of his inventory closeby at all times. Not difficult by any means, just tedious for me to write
//out really.



bool epona = false;
bool ep1 = false;
bool ep2 = false;

//You'll have to make an integer for each itemclass you want to be disabled when Link rides Epona.
int brang = 0;

global script globalscript{
    void run(){
    int eponaLTM = 131;
    ffc epa = Screen->LoadFFC(32);
    int ecmb = 20584;

    int fdly;
    int spd;
    int i; int schk;
        while(true){
            if(epona && !ep2){
                if(ep1){
                    //item clk = Screen->CreateItem(I_CLOCK);
                    //clk->X = Link->X;
                    //clk->Y = Link->Y;
                    //Link->Item[eponaLTM] = true;
                    Link->SwordJinx = -1;
                    ep1 = false;
                    
                    //These next few lines can be used to remove Link's items while he is riding on Epona
                    //this will require some user-setup though.
                    //You'll have to find the item ID of what you want to disable, and copy one of the
                    //lines below, and then put that item ID in the [] instead.
                    Link->Item[23] = false;
                    Link->Item[24] = false;
                    Link->Item[35] = false;
            
                    //The next few lines check to make sure Link is far enough away from a solid object,
                    //move the Epona ffc onto him, and make it 2x2 instead of 1x1.
                    //epa->Data = ecmb+8;
                    epa->TileWidth = 2;
                    epa->TileHeight = 2;
                    epa->CSet = 5;
                    epa->Flags[3] = true;
                    for(i=0; i<16; i++){
                        if(isSolid(Link->X, Link->Y+16+i) == true) schk = i;
                    }
                    if(schk > 0){Link->Y -= schk; schk = 0;}
                    epa->X = Link->X-9; epa->Y = Link->Y;
                }
                //these ifs are what actually attach Epona's ffc to Link, and change her graphics and whatnot
                if(Link->Action != LA_FROZEN && Link->Action != LA_ATTACKING){
                    if(Link->Jump < 0) Link->Jump = 0;
                    if(Link->Dir == 0){
                        if(epa->TileWidth != 1) epa->TileWidth = 1;
                        if(Link->InputUp && !isSolid(Link->X,Link->Y)){
                            epa->Data = ecmb+4;
                            if(fdly == spd){Link->Y -= 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb;
                        epa->X = Link->X; epa->Y = Link->Y-8;
                    }
                    if(Link->Dir == 1){
                        if(epa->TileWidth != 1) epa->TileWidth = 1;
                        if(Link->InputDown && !isSolid(Link->X,Link->Y+8) && !isSolid(Link->X-13,Link->Y+32)){
                            epa->Data = ecmb+5;
                            if(fdly == spd){Link->Y += 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+1;
                        epa->X = Link->X; epa->Y = Link->Y-8;
                    }
                    if(Link->Dir == 2){
                        if(epa->TileWidth != 2) epa->TileWidth = 2;
                        if(Link->InputLeft && !isSolid(Link->X-13,Link->Y+8)){
                            epa->Data = ecmb+6;
                            if(fdly == spd){Link->X -= 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+2;
                        epa->X = Link->X-10; epa->Y = Link->Y;
                    }
                    if(Link->Dir == 3){
                        if(epa->TileWidth != 2) epa->TileWidth = 2;
                        if(Link->InputRight && !isSolid(Link->X+24,Link->Y+8)){
                            epa->Data = ecmb+7;
                            if(fdly == spd){Link->X += 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+3;
                        epa->X = Link->X-8; epa->Y = Link->Y;
                    }
                }
            }
            if(!epona){
                if(ep2){
                    Link->Item[I_CLOCK] = false;
                    Link->Item[eponaLTM] = false;
                    Link->SwordJinx = 0;
                    ep2 = false;

                    //To re-enable the items when Link gets off of Epona, you'll have to put an if
                    //statement here that has each level of the item (as you've set them with the item
                    //scripts) and then have that set the appropriate item ID to true.
                    if(brang == 1) Link->Item[23] = true;
                    if(brang == 2) Link->Item[24] = true;
                    if(brang == 3) Link->Item[35] = true;

                    epa->Data = 0;
                }
            }
        Waitframe();
        }
    }
    bool isSolid(int x, int y) {
        if(x<0 || x>255 || y<0 || y>175)
                        return false;
        int mask=1111b;
        if(x%16<8)
            mask&=0011b;
        else
            mask&=1100b;
        if(y%16<8)
            mask&=0101b;
        else
            mask&=1010b;
        return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
    }
}

//For disabling the items, you'll have to make item scripts like this for each item you want removed, and have them reference
//the itemclass numbers you typed above.
//Have it set the level of the item here (the first script sets the integer brang to 1), as you can see, this is 'wbrang',
//for the wooden boomerang, and so it sets the boomerang itemclass integer (brang) to 1.
item script wbrang{
    void run(){
        brang = 1;
    }
}

item script mbrang{
    void run(){
        brang = 2;
    }
}

item script fbrang{
    void run(){
        brang = 3;
    }
}

//This is the activation script for Epona. I've made it into an item that plays a SFX, so the idea is really that it's
//Epona's song on the ocarina, but that's up to you =)
item script eponassong{
    void run(){
        if(!ep2){
            epona = !epona;
            if(epona){ep1 = true;}
            if(!epona){ep2 = true;}
        }
        Game->PlaySound(33);
    }
}

//This script should make sure that Link can't get on Epona on screens that you don't want him to. He should also get off
//instantly upon entering a screen with this script applied.
ffc script gerroffthathorse{
    void run(){
        while(true){
            ep2 = true;
            epona = false;
        Waitframe();
        }
    }
}


I've started on a 32x32 sideways Epona, and a 16x32 up/down Epona.
It now sticks ffc 32 ontop of Link, and uses those tiles that ZebraStallion posted.

It's working great, apart from the solidity detection.

I think I'm going to have to add a lot more solidity checks, using a for loop that checks all down each side you want to walk down rather than just at one point, stop Link from being able to walk normally, and reference the solidity detection from the ffc, rather than Link.

I haven't added that flag 98 bit yet, although I shall do, don't fear, it'll come at the same time as the better solidity detection.

And of course it works, TK.
I wouldn't post it if it didn't work now, would I icon_wink.gif

It's just a little rough round the edges at the moment (with rather too many 'Link can walk through solid combo' bugs =P), but I'm working on it ^_^

Edited by Joe123, 08 January 2008 - 03:10 PM.


#22 Twilight Knight

Twilight Knight

    Tell all with glee, Argon's on PureZC

  • Members
  • Real Name:Sven
  • Location:Rotterdam, NL

Posted 08 January 2008 - 04:12 PM

QUOTE(Joe123 @ Jan 8 2008, 09:05 PM) View Post

Well, I'm definately progressing.
CODE
import "std.zh"

//I've included some setup for having Link's items disabled when he rides on Epona. All it requires is some duplication of
//code, and I've included pretty extensive instructions in the required sections, so even non-scripters should be able to
//to it. That's the idea anyway =P.
//The way it works is, when Link picks up each item, the game stores what level of the item he has in a global integer,
//therefore keeping a copy of his inventory closeby at all times. Not difficult by any means, just tedious for me to write
//out really.
bool epona = false;
bool ep1 = false;
bool ep2 = false;

//You'll have to make an integer for each itemclass you want to be disabled when Link rides Epona.
int brang = 0;

global script globalscript{
    void run(){
    int eponaLTM = 131;
    ffc epa = Screen->LoadFFC(32);
    int ecmb = 20584;

    int fdly;
    int spd;
    int i; int schk;
        while(true){
            if(epona && !ep2){
                if(ep1){
                    //item clk = Screen->CreateItem(I_CLOCK);
                    //clk->X = Link->X;
                    //clk->Y = Link->Y;
                    //Link->Item[eponaLTM] = true;
                    Link->SwordJinx = -1;
                    ep1 = false;
                    
                    //These next few lines can be used to remove Link's items while he is riding on Epona
                    //this will require some user-setup though.
                    //You'll have to find the item ID of what you want to disable, and copy one of the
                    //lines below, and then put that item ID in the [] instead.
                    Link->Item[23] = false;
                    Link->Item[24] = false;
                    Link->Item[35] = false;
            
                    //The next few lines check to make sure Link is far enough away from a solid object,
                    //move the Epona ffc onto him, and make it 2x2 instead of 1x1.
                    //epa->Data = ecmb+8;
                    epa->TileWidth = 2;
                    epa->TileHeight = 2;
                    epa->CSet = 5;
                    epa->Flags[3] = true;
                    for(i=0; i<16; i++){
                        if(isSolid(Link->X, Link->Y+16+i) == true) schk = i;
                    }
                    if(schk > 0){Link->Y -= schk; schk = 0;}
                    epa->X = Link->X-9; epa->Y = Link->Y;
                }
                //these ifs are what actually attach Epona's ffc to Link, and change her graphics and whatnot
                if(Link->Action != LA_FROZEN && Link->Action != LA_ATTACKING){
                    if(Link->Jump < 0) Link->Jump = 0;
                    if(Link->Dir == 0){
                        if(epa->TileWidth != 1) epa->TileWidth = 1;
                        if(Link->InputUp && !isSolid(Link->X,Link->Y)){
                            epa->Data = ecmb+4;
                            if(fdly == spd){Link->Y -= 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb;
                        epa->X = Link->X; epa->Y = Link->Y-8;
                    }
                    if(Link->Dir == 1){
                        if(epa->TileWidth != 1) epa->TileWidth = 1;
                        if(Link->InputDown && !isSolid(Link->X,Link->Y+8) && !isSolid(Link->X-13,Link->Y+32)){
                            epa->Data = ecmb+5;
                            if(fdly == spd){Link->Y += 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+1;
                        epa->X = Link->X; epa->Y = Link->Y-8;
                    }
                    if(Link->Dir == 2){
                        if(epa->TileWidth != 2) epa->TileWidth = 2;
                        if(Link->InputLeft && !isSolid(Link->X-13,Link->Y+8)){
                            epa->Data = ecmb+6;
                            if(fdly == spd){Link->X -= 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+2;
                        epa->X = Link->X-10; epa->Y = Link->Y;
                    }
                    if(Link->Dir == 3){
                        if(epa->TileWidth != 2) epa->TileWidth = 2;
                        if(Link->InputRight && !isSolid(Link->X+24,Link->Y+8)){
                            epa->Data = ecmb+7;
                            if(fdly == spd){Link->X += 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+3;
                        epa->X = Link->X-8; epa->Y = Link->Y;
                    }
                }
            }
            if(!epona){
                if(ep2){
                    Link->Item[I_CLOCK] = false;
                    Link->Item[eponaLTM] = false;
                    Link->SwordJinx = 0;
                    ep2 = false;

                    //To re-enable the items when Link gets off of Epona, you'll have to put an if
                    //statement here that has each level of the item (as you've set them with the item
                    //scripts) and then have that set the appropriate item ID to true.
                    if(brang == 1) Link->Item[23] = true;
                    if(brang == 2) Link->Item[24] = true;
                    if(brang == 3) Link->Item[35] = true;

                    epa->Data = 0;
                }
            }
        Waitframe();
        }
    }
    bool isSolid(int x, int y) {
        if(x<0 || x>255 || y<0 || y>175)
                        return false;
        int mask=1111b;
        if(x%16<8)
            mask&=0011b;
        else
            mask&=1100b;
        if(y%16<8)
            mask&=0101b;
        else
            mask&=1010b;
        return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
    }
}

//For disabling the items, you'll have to make item scripts like this for each item you want removed, and have them reference
//the itemclass numbers you typed above.
//Have it set the level of the item here (the first script sets the integer brang to 1), as you can see, this is 'wbrang',
//for the wooden boomerang, and so it sets the boomerang itemclass integer (brang) to 1.
item script wbrang{
    void run(){
        brang = 1;
    }
}

item script mbrang{
    void run(){
        brang = 2;
    }
}

item script fbrang{
    void run(){
        brang = 3;
    }
}

//This is the activation script for Epona. I've made it into an item that plays a SFX, so the idea is really that it's
//Epona's song on the ocarina, but that's up to you =)
item script eponassong{
    void run(){
        if(!ep2){
            epona = !epona;
            if(epona){ep1 = true;}
            if(!epona){ep2 = true;}
        }
        Game->PlaySound(33);
    }
}

//This script should make sure that Link can't get on Epona on screens that you don't want him to. He should also get off
//instantly upon entering a screen with this script applied.
ffc script gerroffthathorse{
    void run(){
        while(true){
            ep2 = true;
            epona = false;
        Waitframe();
        }
    }
}


I've started on a 32x32 sideways Epona, and a 16x32 up/down Epona.
It now sticks ffc 32 ontop of Link, and uses those tiles that ZebraStallion posted.

It's working great, apart from the solidity detection.

I think I'm going to have to add a lot more solidity checks, using a for loop that checks all down each side you want to walk down rather than just at one point, stop Link from being able to walk normally, and reference the solidity detection from the ffc, rather than Link.

I haven't added that flag 98 bit yet, although I shall do, don't fear, it'll come at the same time as the better solidity detection.

And of course it works, TK.
I wouldn't post it if it didn't work now, would I icon_wink.gif

It's just a little rough round the edges at the moment (with rather too many 'Link can walk through solid combo' bugs =P), but I'm working on it ^_^


Great! Is there a way to make Epona&Link unaffected by direct warps and stairs etc. Side Warps would be good but the other warps not? And also if that's possible let it be easily changed by the user?

#23 Joe123

Joe123

    Retired

  • Members

Posted 08 January 2008 - 04:39 PM

Well, that would be possible in theory, but it would involve checking all warps around Link every frame to see if he's on them and Epona, then changing them to non-warp combos, and sorting their coordinates and combo-types via lots of integers.

Without arrays, that's not a fun plan of action.

Why do you need that anyway?

#24 Zemious

Zemious

    Magicite: Bahamut

  • Members

Posted 08 January 2008 - 06:02 PM

Can you make the epona like the epona in this video?
http://www.youtube.c...h?v=waHFSZSLKFk

Its at the end.

#25 Joe123

Joe123

    Retired

  • Members

Posted 08 January 2008 - 06:13 PM

I did see that before when you posted in the thread in Developer's Exhcange.
Can you get hold of the sprites?

I can try and do it like that, perhaps, but I think it should probably wait until I have my solidity detection and a few other more essential things sorted.

It would definately be more fancy, but is Epona in Zelda Classic not fancy enough as is? =P


I'm going to do Jumps I think at some point, I'll have a loop at whips like like in that video and OoT, but I'm not sure how it'll go.

EDIT: OK, solidity detection is now down pretty damned well, aswell as flag 98 (or whatever you please, should you change the value of 'flg' icon_wink.gif), which stops Link from getting on Epona, and doesn't allow him to ride onto it, globally.
I'm getting a few problems where it's putting my 16x32 sprites into 32x32 sprite boxes, which look damned awful, and I'm really not too sure how I'm going to sort them, but I shall soldier on.

I think I might add a second ffc to be where Link would be on the horse, so that you can have it split over two CSets?
Thoughts about this anyone?

Edited by Joe123, 08 January 2008 - 07:20 PM.


#26 Russ

Russ

    Caelan, the Encouraging

  • Administrators
  • Location:Washington

Posted 08 January 2008 - 08:05 PM

QUOTE(Joe123 @ Jan 8 2008, 03:13 PM) View Post

I think I might add a second ffc to be where Link would be on the horse, so that you can have it split over two CSets?
Thoughts about this anyone?

Good idea. That way Epona wouldn't have to use cset 6. And her cset wouldn't change with Link's current ring level. I like the idea.

#27 Joe123

Joe123

    Retired

  • Members

Posted 08 January 2008 - 08:17 PM

Yeah, it allows for extra customisation of Link sprites also.
I'll do that.

Mark 4:
CODE
import "std.zh"

//I've included some setup for having Link's items disabled when he rides on Epona. All it requires is some duplication of
//code, and I've included pretty extensive instructions in the required sections, so even non-scripters should be able to
//to it. That's the idea anyway =P.
//The way it works is, when Link picks up each item, the game stores what level of the item he has in a global integer,
//therefore keeping a copy of his inventory closeby at all times. Not difficult by any means, just tedious for me to write
//out really.

bool epona = false;
bool ep1 = false;
bool ep2 = false;

//You'll have to make an integer for each itemclass you want to be disabled when Link rides Epona.
int brang = 0;

global script globalscript{
    void run(){
    int eponaLTM = 131;
    int invisLTM = 123;
    ffc epa = Screen->LoadFFC(32);
    int ecmb = 20584;
    int flg = 98;
    int gsfx = 78;
    int sfxcap = 35;
    int spd = 0;

    int fdly; int sfxfdly;
    int i; int schk;
    bool solid;
    bool wasriding;
        while(true){
            if(Screen->ComboF[ComboAt(Link->X+8,Link->Y+8)] == flg || Screen->ComboI[ComboAt(Link->X+8,Link->Y+8)] == flg){
                ep2 = true;
                epona = false;
            }
            if(epona && !ep2){
                if(ep1){
                    //item clk = Screen->CreateItem(I_CLOCK);
                    //clk->X = Link->X;
                    //clk->Y = Link->Y;
                    //Link->Item[eponaLTM] = true;
                    Link->SwordJinx = -1;
                    ep1 = false;
                    wasriding = true;
                    
                    //These next few lines can be used to remove Link's items while he is riding on Epona
                    //this will require some user-setup though.
                    //You'll have to find the item ID of what you want to disable, and copy one of the
                    //lines below, and then put that item ID in the [] instead.
                    Link->Item[23] = false;
                    Link->Item[24] = false;
                    Link->Item[35] = false;
            
                    //The next few lines check to make sure Link is far enough away from a solid object,
                    //move the Epona ffc onto him, and make it 2x2 instead of 1x1.
                    //epa->Data = ecmb+8;
                    epa->TileWidth = 2;
                    epa->TileHeight = 2;
                    epa->CSet = 5;
                    epa->Flags[3] = true;
                    for(i=0; i<16; i++){
                        if(!isSolid(Link->X, Link->Y-i) == true) schk = i;
                    }
                    if(schk > 0 && Link->Y > 20){Link->Y -= schk; schk = 0;}
                    epa->X = Link->X-9; epa->Y = Link->Y;
                }
                //these ifs are what actually attach Epona's ffc to Link, and change her graphics and whatnot
                solid = false;
                if(Link->Dir == 0){
                    if(epa->TileWidth != 1) epa->TileWidth = 1;
                    if(Link->InputUp){
                        for(i = 0; i<16; i+=2){
                        if(isSolid(epa->X+i,epa->Y) || Screen->ComboF[ComboAt(epa->X+i,epa->Y)] == flg || Screen->ComboI[ComboAt(epa->X+i,epa->Y)] == flg) solid = true;    
                        }
                        if(!solid){
                            epa->Data = ecmb+4;
                            Link->Y -= 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->Y -= 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb;
                    }else epa->Data = ecmb;
                    epa->X = Link->X; epa->Y = Link->Y;
                }
                if(Link->Dir == 1){
                    if(epa->TileWidth != 1) epa->TileWidth = 1;
                    if(Link->InputDown){
                        for(i = 0; i<16; i+=2){
                        if(isSolid(epa->X+i,epa->Y+32) || Screen->ComboF[ComboAt(epa->X+i,epa->Y+32)] == flg || Screen->ComboI[ComboAt(epa->X+i,epa->Y+32)] == flg) solid = true;    
                        }
                        if(!solid){
                            epa->Data = ecmb+5;
                            Link->Y += 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->Y += 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+1;
                    }else epa->Data = ecmb+1;
                    epa->X = Link->X; epa->Y = Link->Y;
                }
                if(Link->Dir == 2){
                    if(epa->TileWidth != 2) epa->TileWidth = 2;
                    if(Link->InputLeft){
                        for(i = 0; i<32; i+=2){
                        if(isSolid(epa->X,epa->Y+i) || Screen->ComboF[ComboAt(epa->X,epa->Y+i)] == flg || Screen->ComboI[ComboAt(epa->X,epa->Y+i)] == flg) solid = true;    
                        }
                        if(!solid){
                            epa->Data = ecmb+6;
                            Link->X -= 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->X -= 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+2;
                    }else epa->Data = ecmb+2;
                    epa->X = Link->X-8; epa->Y = Link->Y;
                }
                if(Link->Dir == 3){
                    if(epa->TileWidth != 2) epa->TileWidth = 2;
                    if(Link->InputRight){
                        for(i = 0; i<32; i+=2){
                        if(isSolid(epa->X+32,epa->Y+i) || Screen->ComboF[ComboAt(epa->X+32,epa->Y+i)] == flg || Screen->ComboI[ComboAt(epa->X+32,epa->Y+i)] == flg) solid = true;    
                        }                        
                        if(!solid){
                            epa->Data = ecmb+7;
                            Link->X += 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->X += 1; fdly = 0;}
                            else fdly++;
                        }else epa->Data = ecmb+3;
                    }else epa->Data = ecmb+3;
                    epa->X = Link->X-8; epa->Y = Link->Y;
                }
                if(Link->InputUp){Link->Dir = 0; Link->InputUp = false;}
                if(Link->InputDown){Link->Dir = 1; Link->InputDown = false;}
                if(Link->InputLeft){Link->Dir = 2; Link->InputLeft = false;}
                if(Link->InputRight){Link->Dir = 3; Link->InputRight = false;}
            }
            if(!epona){
                if(ep2){
                    Link->Item[I_CLOCK] = false;
                    Link->Item[eponaLTM] = false;
                    Link->SwordJinx = 0;
                    ep2 = false;
                    if(wasriding){
                        for(i=0; i<16; i++){
                            if(!isSolid(Link->X, Link->Y+16+i) == true) schk = i;
                        }
                        if(schk > 0 && Link->Y < 148){Link->Y += schk; schk = 0;}
                        wasriding = false;
                    }

                    //To re-enable the items when Link gets off of Epona, you'll have to put an if
                    //statement here that has each level of the item (as you've set them with the item
                    //scripts) and then have that set the appropriate item ID to true.
                    if(brang == 1) Link->Item[23] = true;
                    if(brang == 2) Link->Item[24] = true;
                    if(brang == 3) Link->Item[35] = true;

                    epa->Data = 0;
                }
            }
        Waitframe();
        }
    }
    bool isSolid(int x, int y) {
        if(x<0 || x>255 || y<0 || y>175)
                        return false;
        int mask=1111b;
        if(x%16<8)
            mask&=0011b;
        else
            mask&=1100b;
        if(y%16<8)
            mask&=0101b;
        else
            mask&=1010b;
        return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
    }
}

//For disabling the items, you'll have to make item scripts like this for each item you want removed, and have them reference
//the itemclass numbers you typed above.
//Have it set the level of the item here (the first script sets the integer brang to 1), as you can see, this is 'wbrang',
//for the wooden boomerang, and so it sets the boomerang itemclass integer (brang) to 1.
item script wbrang{
    void run(){
        brang = 1;
    }
}

item script mbrang{
    void run(){
        brang = 2;
    }
}

item script fbrang{
    void run(){
        brang = 3;
    }
}

//This is the activation script for Epona. I've made it into an item that plays a SFX, so the idea is really that it's
//Epona's song on the ocarina, but that's up to you =)
item script eponassong{
    void run(){
        if(!ep2){
            epona = !epona;
            if(epona){ep1 = true;}
            if(!epona){ep2 = true;}
        }
        Game->PlaySound(33);
    }
}

//This script should make sure that Link can't get on Epona on screens that you don't want him to. He should also get off
//instantly upon entering a screen with this script applied.
ffc script gerroffthathorse{
    void run(){
        while(true){
            ep2 = true;
            epona = false;
        Waitframe();
        }
    }
}


Large Epona is now fully implemented, solidity detection is completely un-bugged (albiet a little clumsy, but that can't be helped).
I've also added a SFX whislt galloping, and Link now 'hops' up to get onto Epona, rather than her appearing at his feet level.

So to do:
*Make Epona run onto screen and Link freeze whilst playing SFX, rather than just appearing underneath him.
I'm thinking whistle whirlwind stylee here, anything more complicated is just not worth the amount of effort required.
*Different SFX plays when Link gets off of Epona to when he gets on
I thought of this earlier, but I can't think of what the getting off SFX would be though, Epona whinneing perhaps?
*Jumps
*Link is Invicible whilst on Epona
*Link is seperate ffc
*OoT style whipping system (someday perhaps)

Damaging enemies by running into them would be very nice also, it's a shame how akward it is to damage enemies via ZScript.

Edited by Joe123, 08 January 2008 - 08:19 PM.


#28 Russ

Russ

    Caelan, the Encouraging

  • Administrators
  • Location:Washington

Posted 08 January 2008 - 08:26 PM

Oh my gosh. Joe, you are amazing! Really the only things that need to be added are Epona running on to the screen and a different sfx playing when you get off. The other ones would just make it neater. And I think it has already reached a level a the highest neatness, so something terrible could haooen if it got neater. icon_biggrin.gif .

#29 Joe123

Joe123

    Retired

  • Members

Posted 09 January 2008 - 07:30 AM

And with Mark 5:
CODE
import "std.zh"

//I've included some setup for having Link's items disabled when he rides on Epona. All it requires is some duplication of
//code, and I've included pretty extensive instructions in the required sections, so even non-scripters should be able to
//to it. That's the idea anyway =P.
//The way it works is, when Link picks up each item, the game stores what level of the item he has in a global integer,
//therefore keeping a copy of his inventory closeby at all times. Not difficult by any means, just tedious for me to write
//out really. Don't worry about doing the sword though, I've dealt with that differently.

//These are utility variables.
bool epona = false;
bool ep1 = false;
bool ep2 = false;
bool wrdg = false;


//You'll have to make an integer for each itemclass you want to be disabled when Link rides Epona.
int brang = 0;


//These next few integers deal with sound effects and other user-specific variables. You will have to set them to your own
//needs.
const int gsfx = 78; // this integer is the noise made whilst Epona gallops
const int essfx = 79; // this integer is the sound of Epona's Song, played via the scripted item
const int offsfx = 80; // this integer is the noise made by Epona when Link dismounts

const int sfxcap = 35; // this integer is the time delay, in frames, between looping the 'galloping' sound effect
const int eslng = 180; // this integer is the length, in frames, of the 'Epona's Song' sound effect
const int spd = 0; // this integer controls Epona's speed. 0 is fastest, increase the number to reduce Epona's walking speed

const int invisLTM = 131; // this integer is the Item ID number of the item with Link Tile Modification that will make Link
                          // completely invisible
const int ecmb = 20584; // this integer is the Combo ID number of the first combo of the 8 Epona combos
const int lcmb = 20596; // this integer is the Combo ID number of the first combo of the 8 Link Riding combos
const int flg = 98; // this integer is the number of the Flag used for 'No Epona' zones.


//This script basically runs all of (almost) the functions that make Epona. Load it into Global Script slot 2.
global script slot2{
    void run(){
    ffc lnk = Screen->LoadFFC(31);
    ffc epa = Screen->LoadFFC(32);
    int fdly; int sfxfdly;
    int i; int schk;
    bool solid; bool runoff;
    int hp;
        while(true){
            if(Screen->ComboF[ComboAt(Link->X+8,Link->Y+8)] == flg || Screen->ComboI[ComboAt(Link->X+8,Link->Y+8)] == flg){
                ep2 = true;
                epona = false;
                wrdg = false;
            }
            if(epona && !ep2){
                if(ep1){
                    //item clk = Screen->CreateItem(I_CLOCK);
                    //clk->X = Link->X;
                    //clk->Y = Link->Y;
                    Link->Item[invisLTM] = true;
                    Link->SwordJinx = -1;
                    ep1 = false;
                    wrdg = true;
                    
                    //These next few lines can be used to remove Link's items whilst he is riding on Epona
                    //this will require some user-setup though.
                    //You'll have to find the item ID of what you want to disable, and copy one of the
                    //lines below, and then put that item ID in the [] instead.
                    Link->Item[23] = false;
                    Link->Item[24] = false;
                    Link->Item[35] = false;

                    //Here, Link's ffc is moved over, and the whistle animation is played.
                    lnk->Data = lcmb+8; lnk->CSet = 6;
                    lnk->X = Link->X; lnk->Y = Link->Y;
                    lnk->Flags[3] = true;
                    Link->Action = LA_FROZEN; Link->Dir = 3;
                    hp = Link->HP;
                    for(i=0; i<eslng; i++){
                        Link->HP = hp;
                        Waitframe();
                    }
            
                    //The next few lines check to make sure Link is far enough away from a solid object,
                    //move the Epona ffc over to him, and make it 2x2 instead of 1x1.
                    epa->TileWidth = 2;
                    epa->TileHeight = 2;
                    epa->CSet = 5; epa->Data = ecmb+7;
                    epa->Flags[3] = true;
                    epa->X = 0; epa->Vx = 1;
                    if(Link->Y > 20) epa->Y = Link->Y-16;
                    else epa->Y = Link->Y;
                    sfxfdly = sfxcap;
                    for(i=0; i<Link->X-16; i++){
                        Link->HP = hp;
                        if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                        else sfxfdly ++;
                        Waitframe();
                    }
                    Game->PlaySound(offsfx);
                    
                    //These next lines make Link jump up onto Epona (provided he isn't at the top of
                    //the screen)
                    for(i=0; i<16; i++){
                        if(!isSolid(Link->X, Link->Y-i) == true) schk = i;
                    }
                    if(schk > 0 && Link->Y > 20){Link->Y -= schk; schk = 0;}
                    epa->X = Link->X-8; epa->Y = Link->Y;
                    lnk->X = epa->X+8; lnk->Y = epa->Y;
                    Link->Action = 0;
                }

                //these ifs are what actually attach Epona's ffc to Link, and change her graphics and whatnot
                solid = false;
                if(Link->Dir == 0){
                    if(epa->TileWidth != 1) epa->TileWidth = 1;
                    if(Link->InputUp){
                        for(i = 0; i<16; i+=2){
                        if(isSolid(epa->X+i,epa->Y) || Screen->ComboF[ComboAt(epa->X+i,epa->Y)] == flg || Screen->ComboI[ComboAt(epa->X+i,epa->Y)] == flg) solid = true;    
                        }
                        if(!solid){
                            epa->Data = ecmb+4; lnk->Data = lcmb+4;
                            Link->Y -= 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->Y -= 1; fdly = 0;}
                            else fdly++;
                        }else{epa->Data = ecmb; lnk->Data = lcmb;}
                    }else{epa->Data = ecmb; lnk->Data = lcmb;}
                    epa->X = Link->X; epa->Y = Link->Y;
                    lnk->X = epa->X; lnk->Y = epa->Y;
                }
                if(Link->Dir == 1){
                    if(epa->TileWidth != 1) epa->TileWidth = 1;
                    if(Link->InputDown){
                        for(i = 0; i<16; i+=2){
                        if(isSolid(epa->X+i,epa->Y+32) || Screen->ComboF[ComboAt(epa->X+i,epa->Y+32)] == flg || Screen->ComboI[ComboAt(epa->X+i,epa->Y+32)] == flg) solid = true;    
                        }
                        if(!solid){
                            epa->Data = ecmb+5; lnk->Data = lcmb+5;
                            Link->Y += 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->Y += 1; fdly = 0;}
                            else fdly++;
                        }else{epa->Data = ecmb+1; lnk->Data = lcmb+1;}
                    }else{epa->Data = ecmb+1; lnk->Data = lcmb+1;}
                    epa->X = Link->X; epa->Y = Link->Y;
                    lnk->X = epa->X; lnk->Y = epa->Y;
                }
                if(Link->Dir == 2){
                    if(epa->TileWidth != 2) epa->TileWidth = 2;
                    if(Link->InputLeft){
                        for(i = 0; i<32; i+=2){
                        if(isSolid(epa->X,epa->Y+i) || Screen->ComboF[ComboAt(epa->X,epa->Y+i)] == flg || Screen->ComboI[ComboAt(epa->X,epa->Y+i)] == flg) solid = true;    
                        }
                        if(!solid){
                            epa->Data = ecmb+6; lnk->Data = lcmb+6;
                            Link->X -= 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->X -= 1; fdly = 0;}
                            else fdly++;
                        }else{epa->Data = ecmb+2; lnk->Data = lcmb+2;}
                    }else{epa->Data = ecmb+2; lnk->Data = lcmb+2;}
                    epa->X = Link->X-8; epa->Y = Link->Y;
                    lnk->X = epa->X+8; lnk->Y = epa->Y;
                }
                if(Link->Dir == 3){
                    if(epa->TileWidth != 2) epa->TileWidth = 2;
                    if(Link->InputRight){
                        for(i = 0; i<32; i+=2){
                        if(isSolid(epa->X+32,epa->Y+i) || Screen->ComboF[ComboAt(epa->X+32,epa->Y+i)] == flg || Screen->ComboI[ComboAt(epa->X+32,epa->Y+i)] == flg) solid = true;    
                        }                        
                        if(!solid){
                            epa->Data = ecmb+7; lnk->Data = lcmb+7;
                            Link->X += 1;
                            if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                            else sfxfdly ++;
                            if(fdly == spd){Link->X += 1; fdly = 0;}
                            else fdly++;
                        }else{epa->Data = ecmb+3; lnk->Data = lcmb+3;}
                    }else{epa->Data = ecmb+3; lnk->Data = lcmb+3;}
                    epa->X = Link->X-8; epa->Y = Link->Y;
                    lnk->X = epa->X+8; lnk->Y = epa->Y;
                }
                if(Link->InputUp){Link->Dir = 0; Link->InputUp = false;}
                if(Link->InputDown){Link->Dir = 1; Link->InputDown = false;}
                if(Link->InputLeft){Link->Dir = 2; Link->InputLeft = false;}
                if(Link->InputRight){Link->Dir = 3; Link->InputRight = false;}
            }

            if(!epona){
                if(ep2){
                    //Link->Item[I_CLOCK] = false;
                    Link->Item[invisLTM] = false;
                    Link->SwordJinx = 0;
                    ep2 = false;
                    if(wrdg){
                        for(i=0; i<16; i++){
                            if(!isSolid(Link->X, Link->Y+16+i) == true) schk = i;
                        }
                        if(schk > 0 && Link->Y < 148){Link->Y += schk; schk = 0;}
                        epa->Vx = 2.5; epa->Data = ecmb+7;
                        epa->TileWidth = 2;
                        wrdg = false; runoff = true;
                        sfxfdly = sfxcap;        
                    }
                    if(runoff){
                        if(sfxfdly == sfxcap){Game->PlaySound(gsfx); sfxfdly = 0;}
                        else sfxfdly ++;
                        if(epa->X >256) runoff = false;
                    }
                    
                    //To re-enable the items when Link gets off of Epona, you'll have to put an if
                    //statement here that has each level of the item (as you've set them with the item
                    //scripts) and then have that set the appropriate item ID to true.
                    if(brang == 1) Link->Item[23] = true;
                    if(brang == 2){Link->Item[24] = true; Link->Item[23] = true;}
                    if(brang == 3){Link->Item[35] = true; Link->Item[24] = true; Link->Item[23] = true;}
                    
                    lnk->Data = 0;
                    if(epa->X > 256) epa->Data = 0;
                }
            }
        Waitframe();
        }
    }
    bool isSolid(int x, int y) {
        if(x<0 || x>255 || y<0 || y>175)
                        return false;
        int mask=1111b;
        if(x%16<8)
            mask&=0011b;
        else
            mask&=1100b;
        if(y%16<8)
            mask&=0101b;
        else
            mask&=1010b;
        return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
    }
}


//This script just makes sure Link gets off Epona when you save and reload the file. Add it to script slot 3.
//And DON'T think to yourself 'oh, it's ok, I'll just have the game reload with Link on Epona', beacuse that is very bad.
global script slot3{
    void run(){
        epona = false;
        wrdg = false;
        ep2 = true;
    }
}


//This is the activation script for Epona. I've made it into an item that plays a SFX, so the idea is really that it's
//Epona's song on the ocarina, but that's up to you =)
item script eponassong{
    void run(){
        if(!ep2){
            epona = !epona;
            if(epona) ep1 = true;
            if(!epona) ep2 = true;
        }
        if(epona)Game->PlaySound(essfx);
        if(!epona)Game->PlaySound(offsfx);
    }
}


//For disabling the items, you'll have to make item scripts like this for each item you want removed, and have them reference
//the itemclass numbers you typed above.
//Have it set the level of the item here (the first script sets the integer brang to 1), as you can see, this is 'wbrang',
//for the wooden boomerang, and so it sets the boomerang itemclass integer (brang) to 1.
item script wbrang{
    void run(){
        brang = 1;
    }
}

item script mbrang{
    void run(){
        brang = 2;
    }
}

item script fbrang{
    void run(){
        brang = 3;
    }
}


//This script should make sure that Link can't get on Epona on screens that you don't want him to. He should also get off
//instantly upon entering a screen with this script applied.
ffc script gerroffthathorse{
    void run(){
        while(true){
            ep2 = true;
            epona = false;
            wrdg = false;
        Waitframe();
        }
    }
}


We now have:
Link is a seperate FFC
Link is frozen and a whistle animation plays whilst the SFX for Epona's Song plays
Epona runs up to Link
When Link dismounts, Epona neighs and then runs off again

And I've just realised that I didn't really clarify how your combos would need to be set up.
IPB Image
That's a picture of:
On the left half my tilesheet
On the right half, my combopage

So what you need on the combopage is:
CODE
             1                             2                            3                            4
  Epona facing up, still;     Epona facing down, still;     Epona facing Left, still;     Epona facing right, still
             5                             6                            7                            8
Epona facing up, galloping; Epona facing down, galloping; Epona facing Left, galloping; Epona facing right, galloping

And you'll need to set the Combo ID of the first one to be the constant integer 'ecmb'.
CODE
             1                      2                         3                         4
Link facing up, still;  Link facing down, still; Link facing Left, still;  Link facing right, still
             5                      6                         7                         8
Link facing up, riding; Link facing down, riding; Link facing Left, riding; Link facing right, riding
         9
Link Playing Ocarina;

And you'll need to set the Combo ID of the first one to be the 'lcmb'

Also note that, for animated 2x2 ffcs (so for the ones of Epona running left and right), you need to set the 'ASkip.X' to be '1' instead of '0', and if you want to make any sense out of the things in 'Code' boxes, you'll want to copy them into notepad and make sure that 'word wrap' is not on.

Edited by Joe123, 09 January 2008 - 10:51 AM.


#30 Gleeok

Gleeok

    It's dangerous to dough alone, bake this.

  • Members
  • Real Name:Pillsbury
  • Location:Magical Land of Dough

Posted 09 January 2008 - 07:37 AM

Ooh, horsie. That's looking good there. My only query would be if the sideview horsie would look good in a top view, as opposed to "R"otating the top view sprites and using the side view sprites for, umm, side view...with gravity. Otherwise I can see lots of peeps using this script.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users