import "std.zh" import "ffcscript.zh" import "string.zh" //import "ghost.zh" int Drinks_Left; const int SFX_DRINK = 52; const int LW_EFFECT = 31; //const int SFX_ERROR = 0; //In case you want an error SFX const int SFX_MAGICCHARGE = 53; const int SFX_LIGHTARROW = 1; const int lightColor = 134; //Color of the charging ring: CSet# * 16 + color# (from 0 to 15) const int WPS_NONE = 101; //Weapon sprite with an empty tile (for superlight arrow) const float ORBIT_SPEED = 2.5; const float ORBIT_RADIUS = 48; int f1 = 0; int f2 = 0; int rad = 0; int slower = 0; int bombs = 0; int r1 = 0; int r2 = 0; int slowera = 0; int ffcslot = 1; int usebombodo = 0; const int ringTimePerMP = 15; //How many frames 1 unit of MP lasts with the One Ring const int ringShadowTile = 0; //Shadow tile for invisble Link const int ringShadowCSet = 7; //CSet of this tile bool ringOn; int ringTimer; const int DRAW_OPAQUE = 128; const int DRAW_TRANSPARENT = 64; import "gc_global_working.z" //Enemies thqat break the hpmpcountrs script are Green Dragon Moldorm 10 Moldorm 20 digdogger Kid and BS Dodongo //Item power: Same scale as any other item's damage stat //D0: Time (in frames) to charge the arrow (Recommended: 25) //D1: Weap/Misc sprite to use (34 is golden arrow sprite) //D2: Magic required (expended as you start charging) (8) //D3: Speed of the arrow (same scale as enemy step speed) (500 for normal; 2500 for super) //D4: # of the FFC script (check as you assign it to a slot) item script lightArrow{ void run(int chargeTime, int arrowSprite, int magicCost, int speed, int ffcScriptNum){ if ( Game->Counter[CR_MAGIC] < magicCost || !Game->Counter[CR_ARROWS] ){ Game->PlaySound(SFX_ERROR); //Comment out to remove error SFX return; } if(CountFFCsRunning(ffcScriptNum) == 0){ int args[4] = {this->Power*2, chargeTime, arrowSprite, speed}; Game->Counter[CR_MAGIC] -= magicCost; RunFFCScript(ffcScriptNum, args); } } } ffc script lightArrowFFC{ void run(int power, int chargeTime, int arrowSprite, int speed){ int startHP = Link->HP; lweapon lArrow; Game->PlaySound(SFX_MAGICCHARGE); for(int i = chargeTime; i > 0; i--){ //Charge duration NoAction(); //Freeze Link //Display charging animation: gold circle (non-filled) appears and shrinks (radius) Screen->Circle ( 7, Link->X+8, Link->Y+8, 20*i/chargeTime, lightColor, 1, 0, 0, 0, false, 64 ); if ( Link->HP < startHP ) return; //If Link is hurt, quit Waitframe(); } //Charging done! Shoot that arrow! Link->Action = LA_ATTACKING; Game->Counter[CR_ARROWS]--; Game->PlaySound(SFX_LIGHTARROW); lArrow = NextToLink(LW_ARROW, 8); //Create in front of Link lArrow->UseSprite(arrowSprite); //Graphics lArrow->Damage = power; //Damage lArrow->Step = speed; //Speed if ( Link->Dir == DIR_DOWN ){ //Sprite selection/rotation lArrow->Flip = 3; } else if ( Link->Dir == DIR_LEFT ){ lArrow->Tile++; lArrow->Flip = 1; } else if ( Link->Dir == DIR_RIGHT ){ lArrow->Tile++; } } } ffc script superLightArrowFFC{ void run(int power, int chargeTime, int arrowSprite, int speed){ int startX; int startY; int startHP = Link->HP; lweapon lArrow; Game->PlaySound(SFX_MAGICCHARGE); Screen->Wavy = 10; for(int i = chargeTime; i > 0; i--){ //Charge duration NoAction(); //Freeze Link //Display charging animation: random lines from Link of random length for ( int j = 0; j < 5; j++ ){ int angle = Rand(360); Screen->Arc(7, Link->X+8, Link->Y+8, Rand(50)+1, angle, angle+1, lightColor, 1, 0, 0, 0, true, false, 128); } if ( Link->HP < startHP ) return; //If Link is hurt, quit Waitframe(); } //Charging done! Shoot that arrow! startX = Link->X+8; startY = Link->Y+8; Link->Action = LA_ATTACKING; Game->Counter[CR_ARROWS]--; Game->PlaySound(SFX_LIGHTARROW); lArrow = NextToLink(LW_ARROW, 8); //Create in front of Link lArrow->UseSprite(WPS_NONE); //Graphics (invisible) lArrow->Damage = power; //Damage lArrow->Step = speed; //Speed for ( int i = 0; i < 30; i++ ){ //For 30 frames Screen->Line(4, startX, startY, lArrow->X+8, lArrow->Y+8, lightColor, 1, 0, 0, 0, 128); //Draw a line from Link to the arrow lArrow->DeadState = WDS_ALIVE; //Keep it alive at all times Waitframe(); } lArrow->DeadState = WDS_DEAD; } } //Usable Clock (Or other things??) //D0 - Item to use for clock.(or whatever) If doing clock, this needs to be a clock item with duration set. //Note: The default clock item is 4. //D1 - Amount of time to Jinx link. (0 for no Jinx) //Note: The Jinx can be used to create a small pause before the item //can be used again. You can also make it the clock duration, but this //is only recommended in quests that aren't using the B+A item setting //configuration. item script usedclock{ void run(int clockitem, int jinxtime){ item givenclock = Screen->CreateItem(4); givenclock->X = Link->X; givenclock->Y = Link->Y; givenclock->Z = Link->Z; Link->ItemJinx = 2; } } //Timestop Scroll item script timestopscroll{ void run(int clockitem, int jinxtime){ if (Game->Counter[CR_SCRIPT1] >= 1){ Game->Counter[CR_SCRIPT1] -= 1; item givenclock = Screen->CreateItem(4); givenclock->X = Link->X; givenclock->Y = Link->Y; givenclock->Z = Link->Z; Link->ItemJinx = 2; } else{ Game->PlaySound(errorsfx); } } } //Script above works, but item vanishes from in entory on 1st use; counter remains intact. How do I keep it in inventory? //Magical Key //D0 - Item to use for clock.(or whatever) If doing clock, this needs to be a clock item with duration set. //Note: The default clock item is 4. //D1 - Amount of time to Jinx link. (0 for no Jinx) //Note: The Jinx can be used to create a small pause before the item //can be used again. You can also make it the clock duration, but this //is only recommended in quests that aren't using the B+A item setting //configuration. item script magicalkey{ void run(int keyitem, int jinxtime){ item givenkey = Screen->CreateItem(9); givenkey->X = Link->X; givenkey->Y = Link->Y; givenkey->Z = Link->Z; Link->ItemJinx = 0; } } int healsfx = 39; //Sound effect to play when Link is healed int errorsfx = 65; //Sound effect to play when Link's HP is full or MP is empty item script heal6heart{ void run(int m, int h){ if(Link->MP >= m && Link->HP < Link->MaxHP){ Link->HP += 96; Link->MP -= 64; Game->PlaySound(39); } else{ Game->PlaySound(errorsfx); } } } item script heal12heart{ void run(int m, int h){ if(Link->MP >= m && Link->HP < Link->MaxHP){ Link->HP += 196; Link->MP -= 200; Game->PlaySound(39); } else{ Game->PlaySound(errorsfx); } } } item script restoremagic{ void run(int m, int h){ if(Link->HP >= m && Link->MP < Link->MaxMP){ Link->HP += 0; Link->MP += 200; Game->PlaySound(healsfx); } else{ Game->PlaySound(errorsfx); } } } //D0 = Rupeegain ffc script GetRupees{ void run(int rup){ Game->Counter[CR_RUPEES]+rup; } } //Rupee Loss - Jinx ffc script LoseRupees{ void run(int rup){ Game->Counter[CR_RUPEES]-rup; } } //Mirror Teleporter Script const int SFX_MIRROR = 62; //Sound on successful warp const int SFX_ERROR = 61; //SFX number of an error sound const int CMB_AUTOWARPA = 0; //Transparent combo with "Auto Side Warp A" combo type item script mirror{ void run (){ int targetDMap; //DMap to warp to int targetMap; //Map (not DMap) to warp to if (Game->GetCurDMap() == 1){ //First possible DMap targetDMap = 1; //Sample origin/destination DMap change targetMap = 2; } else if (Game->GetCurDMap() == 2){ //Second DMap targetDMap = 0; //All other ones start with "else" targetMap = 1; } else{ //Invalid DMap Game->PlaySound(SFX_ERROR); return; } if ( Game->GetComboSolid(targetMap, Game->GetCurScreen(), ComboAt(Link->X+8,Link->Y+8)) ){ Game->PlaySound(SFX_ERROR); return; } Game->PlaySound(SFX_MIRROR); Screen->SetSideWarp(0, Game->GetCurDMapScreen(), targetDMap, WT_IWARPWAVE); Screen->ComboD[0] = CMB_AUTOWARPA; //Trigger the warp } } // //Timestop Scroll Item //const int CR_TSCROLL = 0; //Game->Counter(CR_TSCROLL) == 0; //bool CanPickupTScroll //{ // return(Game->Counter(CR_TSCROLL) = < 255) //} item script pickupsernaran{ void run(int m){ item givenitem = Screen->CreateItem(143); givenitem->X = Link->X; givenitem->Y = Link->Y; givenitem->Z = Link->Z; } } //item script increaseMaximumDCounterCount //{ //void run(int increaseitem1, int increaseItemAmount1, int valueid, int increaseItemAmount2) //{ //if (Link->Item[(increaseitem1)] == 1) //{ // Game->MCounter[valueid] = increaseItemAmount1; //Game->Counter[valueid] += 1; //Adds +1 to the same counter. Avoids need to setup counter info for item. //} //} //} item script increaseMaximumDCounterCount { void run(int increaseitem1, int increaseItemAmount1, int valueid, int increaseItemAmount2) { if (Link->Item[(increaseitem1)] == 1) { Game->MCounter[valueid] = increaseItemAmount1; } } } item script mcp2{ void run(int m){ Link->Item[230] = false; item givenitem = Screen->CreateItem(58); givenitem->X = Link->X; givenitem->Y = Link->Y; givenitem->Z = Link->Z; } } ////D0:Is the fake item you pick up ////D1:Is the item that will disapear ////D2:Is the amount of Max MP gained ////D3:Is the amount of MP refill ////D4:Is item given if D0 is not in inventory. //ffc script MCP3{ // void run(int i, int j, int k, int mg, int mx) // { // while(true) // { // if (Link->Item[i] == true) //If Link has the fake item designated in D0 // { // Link->Item[i] = false; //Removes the fake item user selects in D0 // Link->Item[j] = false; //Removes the item the user selects in in D1 // Link->MP[mg]; //Increases MP by value of D3 // Link->MaxMP[mx]; //Increases Max MP by value of D2 // } // else (Link->Item[k] == true); //Gives Link the specified item in D4.{ // Waitframe(); // } // } //} //D0:Is the fake item you pick up //D1:Is the item that will disapear //D2:Is the amount of Max MP gained //D3:Is the amount of MP refill //D4:Is item given if D0 is not in inventory. ffc script MCP4{ void run(int i, int j, int k, int mg, int mx) { while(true) { if (Link->Item[i] == true) //If Link has the fake item designated in D0 { Link->Item[i] = false; //Removes the fake item user selects in D0 Link->Item[j] = false; //Removes the item the user selects in in D1 Link->MP += 256; //Increases MP by value of D3 Link->MaxMP += 256; //Increases Max MP by value of D2 } else (Link->Item[k] == true); //Gives Link the specified item in D4.{ Waitframe(); } } } //D0:Is the fake item you pick up //D1:Is the item that will disapear //D2:Is the amount of Max MP gained //D3:Is the amount of MP refill //D4:Is item given if D0 is not in inventory. item script MCP4I{ void run(int i, int j, int k, int mg, int mx) { while(true) { if (Link->Item[i] == true) //If Link has the fake item designated in D0 { Link->Item[i] = false; //Removes the fake item user selects in D0 Link->Item[j] = false; //Removes the item the user selects in in D1 Link->MP += 256; //Increases MP by value of D3 Link->MaxMP += 256; //Increases Max MP by value of D2 } else (Link->Item[k] == true); //Gives Link the specified item in D4.{ Waitframe(); } } } item script lon_lon_milk_pickup { void run() { Drinks_Left = 3; } } item script lon_lon_milk { void run() { Link->HP += 80; //Link regains 5 hearts Game->PlaySound(56); //Play SFX when used. if(Link->HP >= Link->MaxHP) //If Link has too much HP { Link->HP = Link->MaxHP; //It's brought down to the maximum } Drinks_Left -= 1; //Link loses 1 serving of milk if(Drinks_Left == 0) //If Link is out of milk { Link->Item[123] = false; //The item is gone } } } item script Bombos_Item{ void run(int ffcScriptNum, int comboNum, int flameNum, float speed, float radius, int explosionNum, int explosionSpread, int explosionDamage){ float args[8] = {comboNum, flameNum, speed, radius, explosionNum, explosionSpread, explosionDamage}; RunFFCScript(ffcScriptNum, args); } } ffc script Bombos_Action{ void run(int comboNum, int flameNum, float speed, float radius, int explosionNum, int explosionSpread, int explosionDamage){ Link->CollDetection = false; Link->Invisible = true; this->X = Link->X - 16; this->Y = Link->Y - 16; this->TileWidth = 3; this->TileHeight = 3; this->CSet = 6; this->Data = comboNum; //Wait till the animation finishes before starting while(this->Data == comboNum){ WaitNoAction(); } lweapon flame[16]; float angle[16]; float radiusInternal = radius; for(int i; i < flameNum; i++){ flame[i] = Screen->CreateLWeapon(LW_EFFECT); angle[i] = (360/flameNum)*i; flame[i]->UseSprite(35); flame[i]->CollDetection = false; flame[i]->X = Link->X + radiusInternal*Cos(angle[i]*speed); flame[i]->Y = Link->Y + radiusInternal*Sin(angle[i]*speed); } int timer = 120; while(timer > 0){ for(int i; i < flameNum; i++){ flame[i]->X = Link->X + radiusInternal*Cos(angle[i]*speed); flame[i]->Y = Link->Y + radiusInternal*Sin(angle[i]*speed); angle[i] %= 360; angle[i]++; } timer--; radiusInternal = radius*(timer/120); WaitNoAction(); } for(int i; i < flameNum; i++) flame[i]->DeadState = WDS_DEAD; while(explosionNum > 0){ explosionNum--; int x; int y; while(true){ x = Rand(Link->X - radius, Link->X + radius); y = Rand(Link->Y - radius, Link->Y + radius); if(Distance(Link->X, Link->Y, x, y) <= radius) break; } lweapon l = CreateLWeaponAt(LW_BOMBBLAST, x, y); l->Damage = explosionDamage; Game->PlaySound(SFX_BOMB); WaitNoAction(explosionSpread); } this->Data = 0; timer = 16; while(timer > 0){ timer--; WaitNoAction(); } this->TileWidth = 1; this->TileHeight = 1; Link->CollDetection = false; Link->Invisible = false; } } item script tremor { void run() { Screen->Quake = 20; //Weapon->HitWidth = 255; //Weapon->HitHeight = 255; //Weapon->Damage = 20; npc enemys; for(int i = 1; i<=Screen->NumNPCs(); i++) { enemys = Screen->LoadNPC(i); enemys->HP-=100; Waitframes(4); } } } item script bombodositem { void run() { bombs = 0; slower = 0; slowera = 0; rad = 0; usebombodo = 1; npc enemys; for(int i = 1; i<=Screen->NumNPCs(); i++) { enemys = Screen->LoadNPC(i); enemys->HP-=3; } } } item script theOneRing{ void run(int onSFX, int offSFX){ if ( !ringOn && Link->MP > 0 ){ ringOn = true; Game->PlaySound(56); Link->CollDetection = false; Link->Invisible = true; } else if ( ringOn ){ ringOn = false; Game->PlaySound(offSFX); } } } item script cane{ void run(int onSFX, int offSFX){ if ( !ringOn && Link->MP > 0 ){ ringOn = true; Game->PlaySound(onSFX); Link->CollDetection = true; Link->Invisible = false; } else if ( ringOn ){ ringOn = false; Game->PlaySound(offSFX); } } } //Beamos Script //fires a laser at Link when he comes within a certain range. //Only the burning tip will hurt link. //D0: the radius, in pixels, of the beamos's range //D1: the time, in frames, it takes for the beamos to activate its laser before it fires //D2: how far, in pixels, the beam tip can travel in a frame //D3: the color of the beam //D4: the weapon used for the beam's tip //D5: the amount of damage the tip does //D6: sound to be played when it detects Link //D7: beam sound effect. looped every 4 frames. ffc script Beamos{ void run(int range, int delay, float beamspeed, int beamcolor, int beamwpn, int damage, int alert_sfx, int beam_sfx) { float sx; float sy; int counter; eweapon wpn; while(true) { if(Distance(this->X, this->Y, Link->X, Link->Y) <= range) { sx = Link->X; sy = Link->Y; if(alert_sfx) Game->PlaySound(alert_sfx); Waitframes(delay); wpn = Screen->CreateEWeapon(EW_SCRIPT1); wpn->X = sx; wpn->Y = sy; wpn->UseSprite(beamwpn); wpn->Damage = damage; while(Distance(this->X, this->Y, Link->X, Link->Y) <= range && wpn->isValid()) { float angle = ArcTan(Link->X - wpn->X, Link->Y - wpn->Y); wpn->Dir = AngleToDir(ArcTan(wpn->X - this->X, this->Y - wpn->Y)); sx += beamspeed * RadianCos(angle); sy += beamspeed * RadianSin(angle); wpn->X = sx; wpn->Y = sy; Screen->Line(3, wpn->X+7, wpn->Y+7, this->X+7, this->Y+7, beamcolor, 1, 0, 0, 0, 128); if(beam_sfx && counter == 0) Game->PlaySound(beam_sfx); counter = (counter + 1) % 4; Waitframe(); } wpn->DeadState = WDS_DEAD; } Waitframe(); } } } int AngleToDir(float angle) { float deg = angle * 180 / PI; if(deg >= 0) { if(deg < 90) { if(deg < 45) return DIR_RIGHT; else return DIR_RIGHTUP; } else { if(deg < 135) return DIR_UP; else return DIR_LEFTUP; } } else { if(deg >= -90) { if(deg >= -45) return DIR_RIGHTDOWN; else return DIR_DOWN; } else { if(deg >= -135) return DIR_LEFTDOWN; else if(deg < -180) return DIR_LEFT; else return DIR_LEFTUP; } } } //// //D0: Time (in frames) to charge the arrow (Recommended: 25) //D1: Weap/Misc sprite to use (34 is golden arrow sprite) //D2: Magic required (expended as you start charging) (8) //D3: Speed of the arrow (same scale as enemy step speed) (500 for normal; 2500 for super) //D4: # of the FFC script (check as you assign it to a slot) item script bolt{ void run(int chargeTime, int arrowSprite, int magicCost, int speed, int ffcScriptNum){ Screen->Wavy = 10; Waitframes(4); npc enemys; for(int i = 1; i<=Screen->NumNPCs(); i++) { enemys = Screen->LoadNPC(i); enemys->HP-=10; } if ( Game->Counter[CR_MAGIC] < magicCost || !Game->Counter[CR_ARROWS] ){ Game->PlaySound(SFX_ERROR); //Comment out to remove error SFX return; } if(CountFFCsRunning(ffcScriptNum) == 0){ int args[4] = {this->Power*2, chargeTime, arrowSprite, speed}; Game->Counter[CR_MAGIC] -= magicCost; RunFFCScript(ffcScriptNum, args); } } } ///// ffc script boltFFC{ void run(int power, int chargeTime, int arrowSprite, int speed){ int startX; int startY; int startHP = Link->HP; lweapon lArrow; Game->PlaySound(SFX_MAGICCHARGE); for(int i = chargeTime; i > 0; i--){ //Charge duration NoAction(); //Freeze Link //Display charging animation: random lines from Link of random length for ( int j = 0; j < 5; j++ ){ int angle = Rand(360); Screen->Arc(7, Link->X+8, Link->Y+8, Rand(50)+1, angle, angle+1, 182, 1, 0, 0, 0, true, false, 20); } if ( Link->HP < startHP ) return; //If Link is hurt, quit Waitframe(); } //Charging done! Shoot that arrow! startX = Link->X+8; startY = Link->Y+8; Link->Action = LA_ATTACKING; Game->PlaySound(SFX_LIGHTARROW); lArrow = NextToLink(LW_ARROW, 8); //Create in front of Link lArrow->UseSprite(121); //Graphics (invisible) lArrow->Damage = 32; //Damage lArrow->Step = speed; //Speed for ( int i = 0; i < 30; i++ ){ //For 30 frames Screen->Line(4, startX, startY, lArrow->X+8, lArrow->Y+8, 182, 1, 0, 0, 0, 90); //Draw a line from Link to the arrow lArrow->DeadState = WDS_ALIVE; //Keep it alive at all times Waitframe(); } lArrow->DeadState = WDS_DEAD; } }