(Double-posting due to scripts exceeding maximum post length.)
Here is my working script (without ghost.zh, file GoldenCenotaph47.z)
CODE
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;
global script hpmpcounters{
void run(){
while(true)
{
Game->Counter[CR_SCRIPT2] = Link->HP;
Game->Counter[CR_SCRIPT3] = Link->MP;
Game->Counter[CR_SCRIPT4] = Link->MaxHP;
Game->Counter[CR_SCRIPT5] = Link->MaxMP;
{
if (Link->Item[231] == true) //If Link has the fake item designated in D0
{
Link->Item[230] = false; //Removes the fake item user selects in D0
Link->Item[231] = 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[230] == true); //Gives Link the specified item in D4.{
Waitframe();
}
float angle;
{
if (usebombodo == 1)
{
slower ++;
if (slower == 5)
{
rad++;
slower = 0;
}
angle = (angle + ORBIT_SPEED) % 360;
f1 = 100 + rad * Cos(angle);
f2 = 100 + rad * Sin(angle);
Screen->FastCombo(6, f1, f2, 80, 2, 128);
r1 = 40+Rand(150);
r2 = 40+Rand(100);
slowera++;
if (slowera == 20)
{
slowera = 0;
if (bombs < 30)
{
bombs ++;
lweapon bomb = CreateLWeaponAt(LW_BOMBBLAST, r1, r2);
Game->PlaySound(SFX_BOMB);
if (bombs == 30) usebombodo = 0;
}
}
}
Waitframe();
}
if ( ringOn && Link->MP ){
//Decrement magic
ringTimer = (ringTimer+1) % ringTimePerMP;
if ( !ringTimer ) Link->MP--;
if ( Link->MP <= 0 //If magic ran out
|| Link->Action == LA_SCROLLING //Or left screen
){ //Take off ring
ringOn = false;
Link->CollDetection = true;
Link->Invisible = false;
}
}
else if ( !ringOn ){ //Disable ring
Link->CollDetection = true;
Link->Invisible = false;
}
}
}
}
//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);
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;
Screen->Wavy = 10;
Waitframes(4);
npc enemys;
for(int i = 1; i<=Screen->NumNPCs(); i++)
{
enemys = Screen->LoadNPC(i);
enemys->HP-=10;
}
}
}
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-=1;
}
}
}
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, 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->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;
}
}