Code:
//Fairy Partner
int fairy_r = 0;
int fairy_x = 0;
int fairy_y = 0;
int fairy_tx = 0;
int fairy_ty = 0;
int fairy_timer = 0;
bool fairy_hidden = false;
int prev_screen = 0;
const int fairy_tile = 940;
const int fairy_cset = 7;
const int fairy_timer_cnt = 240;//60 * 4; //four seconds, or so
int curScreen() {
return Game->GetCurDMapScreen()/1000 + Game->GetCurDMap();
}
global script slot2 {
void run() {
fairy_x = Link->X;
fairy_y = Link->Y;
fairy_tx = Link->X;
fairy_ty = Link->Y;
fairy_timer = fairy_timer_cnt;
while(true) {
if(Link->Item[129]) fairy();
prev_screen = curScreen();
Waitframe();
}
}
void fairy() {
//what is the fairy following?
bool yes = false;
int draw_cset = fairy_cset;
if(curScreen() != prev_screen) {
//we've warped or scrolled or something
//jump to position
fairy_x = Link->X + 8;
fairy_y = Link->Y + 8;
}
//is there an enemy close by?
if(!yes) {
int lowest_id = -1;
int lowest_dist = 1024;
for(int i = 1; i <= Screen->NumNPCs(); i++) {
npc nme = Screen->LoadNPC(i);
//all this is basically "everything that isn't *really* a monster to be killed"
if( !(nme->ID <= NPC_ABEI2 || nme->ID == NPC_ENEMYFIRE || (nme->ID >= NPC_GLEEOK1FIRE && nme->ID <= NPC_GLEEOK4FIRE) || nme->ID == NPC_GOHMAFIRE || nme->ID == NPC_ITEMFAIRY || nme->ID == NPC_SHOOTFBALL || (nme->ID >= NPC_SHOOTMAGIC && nme->ID <= NPC_SHOOTFLAME2) || nme->ID == NPC_TRAP || (nme->ID >= NPC_TRAPHORIZLOS && nme->ID <= NPC_TRAPVERTC) || (nme->ID >= NPC_TRAP8WAY && nme->ID <= NPC_TRAPCCLOCKWISELOS))) {
int d = Distance(Link->X, Link->Y, nme->X, nme->Y);
if(d < 96 && d < lowest_dist) {
lowest_dist = d;
lowest_id = i;
}
}
}
if(lowest_id != -1) {
npc nme = Screen->LoadNPC(lowest_id);
fairy_tx = nme->X + 8;
fairy_ty = nme->Y + 8;
yes = true;
draw_cset = fairy_cset + 1;
fairy_timer = fairy_timer_cnt;
}
}
//what about an item?
if(!yes) {
int lowest_id = -1;
int lowest_dist = 1024;
for(int i = 1; i <= Screen->NumItems(); i++) {
item itm = Screen->LoadItem(i);
int d = Distance(Link->X, Link->Y, itm->X, itm->Y);
if(d < 96 && d < lowest_dist) {
lowest_dist = d;
lowest_id = i;
}
}
if(lowest_id != -1) {
item itm = Screen->LoadItem(lowest_id);
fairy_tx = itm->X + 8;
fairy_ty = itm->Y + 8;
fairy_timer = fairy_timer_cnt;
yes = true;
}
}
//perhaps there's a secret flag?
if(!yes) {
int lowest_id = -1;
int lowest_dist = 1024;
for(int i = 0; i < 160; i++) {
int f;
if(Screen->ComboF[i] != 0) {
f = Screen->ComboF[i];
if((f >= 1 && f <= 6) || (f >= 9 && f <= 11) || f == 13 || (f >= 47 && f <= 51) || (f >= 68 && f <= 90)) {
int d = Distance(Link->X, Link->Y, (i % 16) * 16, Floor(i / 16) * 16);
if(d < lowest_dist) {
lowest_dist = d;
lowest_id = i;
}
}
}
if(Screen->ComboI[i] != 0) {
f = Screen->ComboI[i];
if((f >= 3 && f <= 6) || f == 11 || f == 13 || (f >= 68 && f <= 90)) {
int d = Distance(Link->X, Link->Y, (i % 16) * 16, Floor(i / 16) * 16);
if(d < lowest_dist) {
lowest_dist = d;
lowest_id = i;
}
}
}
}
if(lowest_id != -1) {
fairy_tx = (lowest_id % 16) * 16 + 8;
fairy_ty = Floor(lowest_id / 16) * 16 + 8;
draw_cset = fairy_cset + (fairy_r % 3);
fairy_timer = fairy_timer_cnt;
yes = true;
}
}
//dungeon door?
if(!yes) {
//I COULD do it closest, but I'd rather do this instead...
int side = Rand(3);
for(int i = 0; i < 4; i++) {
if(Screen->Door[side] == D_BOMB || Screen->Door[side] == D_WALKTHRU) {
yes = true;
fairy_timer = fairy_timer_cnt;
draw_cset = fairy_cset + (fairy_r % 3);
break;
}
side++;
if(side == 4) {
side = 0;
}
}
if(yes) {
if(side == DIR_UP) {
fairy_tx = 120; fairy_ty = 16;
} else if(side == DIR_DOWN) {
fairy_tx = 120; fairy_ty = 144;
} else if(side == DIR_LEFT) {
fairy_tx = 16; fairy_ty = 80;
} else if(side == DIR_RIGHT) {
fairy_tx = 224; fairy_ty = 80;
}
}
}
if(!yes) { //default to Link
fairy_tx = Link->X + 8;
fairy_ty = Link->Y + 8;
}
if(!yes) {
if(fairy_timer > 0) {
fairy_timer--;
}
}
if(fairy_timer > 0 && fairy_hidden) {
fairy_hidden = false;
}
if(fairy_x < fairy_tx) {
fairy_x++;
} else if(fairy_x > fairy_tx){
fairy_x--;
}
if(fairy_y < fairy_ty) {
fairy_y++;
} else if(fairy_y > fairy_ty){
fairy_y--;
}
int fx = 0;fairy_x;
int fy = 0;fairy_y;
fx = Sin(fairy_r * 4) * 16;
fy = Cos((fairy_r * 3)) * 16;
if(fairy_timer < 60) {
float mod = fairy_timer;
mod /= 60;
fx *= mod;
fy *= mod;
}
fairy_r += 1;
if(fairy_timer == 0 && fx == 0 && fy == 0) { //(fx == 45 || fairy_r == 225)) {
fairy_hidden = true;
}
if(!fairy_hidden) {
if(fairy_r >= 360) fairy_r = 0;
//Screen->DrawTile(4, fairy_x + fx - 8, fairy_x + fx - 8, fairy_tile + (fairy_r % 2), 1, 1, draw_cset, 1, 0, 0, 0, 0, true, 64);
Screen->DrawTile(4, fairy_x + fx - 8, fairy_x + fx - 8, fairy_tile + (fairy_r % 2), 1, 1, draw_cset, 1, 0, 0, 0, 0, 0, true, 64);
}
}
}