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](http://i146.photobucket.com/albums/r260/Joe123ZC/Eponasheet.gif)
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.