It will require my modified Tango.zh set-up, and it is untested, but if anyone wishes to look at it, here is the script in its raw state:
King Zora v0.3
/////////////////////////
/// Zelda 3 King Zora ///
/// v0.3 ///
/// 18-Nov-2016 ///
/// By: ZoriaRPG ///
/////////////////////////
///Graphics
const int TILE_KINGZORA_BASE = 0;
const int TILE_KINGZORA_OPENMOUTHBASE = 6;
const int SPRITE_KING_ZORA_SPLASH = 100;
//Sounds
const int SFX_KING_ZORA_RISES = 63;
const int SFX_KINGZORA_POST_RISE_SPLASH = 64;
const int SFX_KINGZORA_OPEN_MOUTH = 65;
//Splash Sprite Random Distance
const int KINGZORA_SPLASH_X_WAVER = 32;
const int KINGZORA_SPLASH_Y_WAVER = 48;
//Script Settings
const int KINGZORA_SPLASH_ANIM_REPEAT = 12; //The number of times that the splash sprites repeat.
const int KIGZORA_RISE_LOOP_DUR = 200; //The total duration of the animation, in frames.
const int KINGZORA_INITIAL_RISE_TIME = 20; //Delays with water splashes before King Zora begins to rise.
const int KINGZORA_RISE_CYCLE_MODULUS = 60; //The divsor that determines hor many frames to wait before drawing the
//next row of tiles, and moving King Zora up a bit.
const int KINGZORA_WAIT_OPEN_MOUTH = 40; //Frames after rising animation ends, before mouth opens.
const int KINGZORA_ITEM_JUMP = 10;
//Tango Window Styles
const int TANGO_SIZE_TINY = 4;
const int WINDOW_STYLE_KINGZORA_MAIN = 4;
const int WINDOW_STYLE_KINGZORA_TINY = 5;
const int WINDOW_STYLE_KINGZORA_ERROR= 6;
ffc script KingZora{ //zora npc id, initial distance minimum to run, item to sell, item cost, message, min distance for dialogue, Screen->D[reg] (-1 to repeat sale)
void run(int npctype, int initdist, int giveitem, int cost, int msg, int distance, int reg){
if ( reg > -1 && Screen->D[reg] ) { this->Data = 0; this->Script = 0; Quit(): }
npc kingzora[20]; int buffer[256];
int cost_str[5];
itoa(cost_str,cost); //Store the cost of the item as text.
int msg1[]="I will sell you something good, for ";
int msg2[]="rupees. What do you say?";
strcpy(buffer,msg1);
strcat(buffer,cost_str);
strcat(buffer,msg2);
//The string is now in the buffer.
//Spawn King Zora
//Init animation
//screen rumbles
//water ripples
//King zora rises
kingzora[1] = Screen->CreateNPC(npctype);
kingzora[1]->X = this->X;
kingzora[1]->Y = this->Y;
kingzora[1]->HitXOffset = -200;
kingzora[1]->HitYOffset = -200;
kingzora[1]->DrawYOffset = -200; //We'll move him in afterthe animation.
kingzora[1]->Extend = 3;
kingzora[1]->TileWidth = 3;
kingzora[1]->TileHeight = 1; //We will make this 2, then 3, gradually.
eweapon splash[12]; //the size of this array should match the constant 'KINGZORA_SPLASH_ANIM_REPEAT'.
int q[4];
while(true){
while( DistXY(this) < initdist ) Waitframe(); //Wait until Link is close enugh.
//shake screen, do ripples
if ( !q[3] ) { //Don't do this more than one time.
if ( SFX_KING_ZORA_RISES ) Game->PlaySound(SFX_KING_ZORA_RISES);
for q[0] = 1, q[0] < KIGZORA_RISE_LOOP_DUR; q++ ) {
Screen->Quake = 2;
for ( q[1] = 0; q[1] < KINGZORA_SPLASH_ANIM_REPEAT; q[1]++ ){
//draw splashes
splash[ q[1] ] = Screen->CreateLWeapon(LW_SPARKLE);
splash[ q[1] ]->CollDetection = false;
splash[ q[1] ]->UseSprite = SPRITE_KING_ZORA_SPLASH;
splash[ q[1] ]->X = this->X + Rand(-KINGZORA_SPLASH_X_WAVER, KINGZORA_SPLASH_X_WAVER);
` splash[ q[1] ]->Y = this->Y + Rand(-KINGZORA_SPLASH_Y_WAVER, KINGZORA_SPLASH_Y_WAVER);
}
//King Zora Rises from the Deep
kingzora[1]->DrawYOffset = this->Y + 32;
if ( (q[0]-KINGZORA_INITIAL_RISE_TIME) % KINGZORA_RISE_CYCLE_MODULUS == 0 && q[0] != 0 ) {
if ( kingzora[1]->TileHeight != 3 ) kingzora[1]->TileHeight++; //add a row of tiles
if ( kingzora[1]->DrawYOffset != kingzora[1]->Y ) kingzora[1]->DrawYOffset += 16; //and move him upward
//to simulate rising from the water.
}
Waitframe();
}
//Play the post-rise splash sound.
if ( SFX_KINGZORA_POST_RISE_SPLASH ) Game->PlaySound(SFX_KINGZORA_POST_RISE_SPLASH);
//Wait a few rames after rising
Waitframes(KINGZORA_WAIT_OPEN_MOUTH);
//!!King Zora Opens his mouth, here.
//Play open mouth sound
if ( SFX_KINGZORA_OPEN_MOUTH ) Game->PlaySound(SFX_KINGZORA_OPEN_MOUTH);
q[3] = 1; // Mark that the animation sequence is complete.
}
if ( ( reg > -1 && !Screen->D[reg] ) && DistXY(this) < distance && ( Link->PressA || Link->PressB ) ) {
//Open his mouth
kingzora[1]->OriginalTile = TILE_KINGZORA_OPENMOUTHBASE;
//Display the buffer string in a menu.
if ( KingZoraMenu(cost,buffer) {
//Opens the menu and dialogues/
//if it returns true, create the item.
item it = Screen->CreateItem(giveitem);
it->X = -200;
it->Y = this->Y;
it->Jump = KINGZORA_ITEM_JUMP;
it->Pickup = IP_HOLDUP;
WaitNoAction();
it->X = Link->X; //Fall in a pseudo-3d arc, to Link
while( !LinkCollision(it) ) {
it->Y--;
WaitNoAction();
}
if ( reg > -1 ) Screen->D[reg] = 1; //Stop the player from buying the item twice, unless 'reg' is set to a neative value.
}
else error();
}
Waitframe();
}
}
bool KingZoraMenu(int cost, int str){
int buffer[300];
strcpy(buffer, str);
//Display the buffer string in a menu.
ShowString(buffer, WINDOW_SLOT_1, WINDOW_STYLE_KINGZORA_MAIN, 48, 48);
//Give a yes/no choice.
if ( yesno() ) {
if ( cost <= Game->Counter[CR_RUPEES] ) {
Game->DCounter[CR_RUPEES] -= cost;
return true;
//Compare cost to Game->Counter[CR_RUPEES]
//if item sold, return true.
}
else return false;
}
bool yesno(){
//the yes no menu.
//Opens a submenu over the dialogue display.
int y[]="@choice(1)Yes@26";
int n[]="@choice(2)No@domenu(1)@suspend()";
SetUpWindow(WINDOW_SLOT_2, WINDOW_STYLE_KINGZORA_TINY, 32, 32, TANGO_SIZE_TINY);
Tango_LoadString(WINDOW_SLOT_2, y);
Tango_AppendString(WINDOW_SLOT_2, n);
while( !Tango_MenuIsActive() ) Waitframe();
int slotState[278];
int menuState[960];
int cursorPos;
Tango_SaveSlotState(WINDOW_SLOT_2, slotState);
Tango_SaveMenuState(menuState);
int done = 0;
int choice;
while(true){
while( Tango_MenuIsActive() ) {
cursorPos=Tango_GetMenuCursorPosition();
Waitframe();
}
choice = Tango_GetLastMenuChoice();
if ( choice == 1 ) { // yes
done = choice;
menuArg = choice;
}
else if ( choice == 2 ) { //no
done = choice;
menuArg = choice;
}
if ( done ) {
break;
// return choice;
}
else {
Tango_RestoreSlotState(WINDOW_SLOT_1, slotState);
Tango_RestoreMenuState(menuState);
Tango_SetMenuCursorPosition(cursorPos);
}
}
Tango_ClearSlot(WINDOW_SLOT_2);
if ( done == 1 ) return true; //if yes, return true
else return false;
}
void error(){
//a dialogue that gives an error message.
int err[]="Sorry, you seem to lack the funds to buy my marvelous goodies.";
//clear slot 2 (the yes/no menu)
Tango_ClearSlot(WINDOW_SLOT_1);
Tango_ClearSlot(WINDOW_SLOT_2);
//ShowMessage(err); //show the message in the slot used by the initial dialogue
ShowString(err, WINDOW_SLOT_1, WINDOW_STYLE_KINGZORA_ERROR, 48, 48);
}
}
Edited by ZoriaRPG, 18 November 2016 - 04:44 AM.

