Code:
//Include these lines once at the top of your script file.
import "std.zh"
import "ffcscript.zh"
//Common Constants, only need to define once per quest.
const int DIAGONAL_MOVEMENT = 1; //Change this to 0 for nes movement.
const int BIG_LINK = 0; //Set this constant to 1 if using the Large Link Hit Box feature
//Constants used by Bottomless Pits & Lava.
const int CT_HOLELAVA = 142; //Combo type to use for pit holes and lava. "Scripted Combo 1, you can use no ground enemies if you don't use ghost.zh"
const int CF_PIT = 98; //The combo flag to register combos as pits.
const int CF_LAVA = 99; //The combo flag to register combos as lava.
const int WPS_LINK_FALL = 88; //The weapon sprite to display when Link falls into a pit. "Sprite 88 by default"
const int WPS_LINK_LAVA = 89; //The weapon sprite to display when Link drowns in lava. "Sprite 89 by default"
const int SFX_LINK_FALL = 38; //The sound to play when Link falls into a pit. "SFX_FALL by default"
const int SFX_LINK_LAVA = 55; //The sound to play when Link drowns in Lava. "SFX_SPLASH by default.
const int CMB_AUTOWARP = 0; //The first of your four transparent autowarp combos.
const int HOLELAVA_DAMAGE = 8; //Damage in hit points to inflict on link. "One Heart Container is worth 16 hit points"
//Global variables used by Bottomless Pits & Lava.
int Falling;
bool Warping;
///Constants and Variables used by platform script;
int onplatform; //Global variable use this to check if Link is on a platform for other scripts.
// MOVE this function to the one in ghost.zh if you us 2.8 or above.
// Pits and Lava are currently treated the same. Sorry folks.
bool __IsPit(int comboLoc)
{
if(Screen->ComboT[comboLoc] == CT_HOLELAVA)
{
return
(Screen->ComboF[comboLoc] == CF_PIT || Screen->ComboF[comboLoc] == CF_LAVA || Screen->ComboI[comboLoc] == CF_PIT || Screen->ComboI[comboLoc] == CF_LAVA);
}
else return false;
}
global script Active
{
void run()
{
//Initialize variables used to store Link's starting position on Screen Init.
int returndmap = Game->GetCurDMap();
int returnscreen = Game->GetCurDMapScreen();
int returnx = Link->X;
int returny = Link->Y;
int returndir = Link->Dir;
//Clear global variables used by Bottomless pits.
Falling = 0;
Warping = false;
//Main Loop
while(true)
{
NesMovementFix();
Waitdraw();
MovingPlatforms(); //Insert this here
if(Link->Action != LA_SCROLLING)
{
if(Link->Z==0 && !Falling && (returnscreen != Game->GetCurDMapScreen() || returndmap != Game->GetCurDMap()))
{
if(OnPitCombo()==0) //Not having this check was causing a terrible death trap.
{
returndmap = Game->GetCurDMap();
returnscreen = Game->GetCurDMapScreen();
returnx = Link->X;
returny = Link->Y;
returndir = Link->Dir;
}
}
if(onplatform==0) //insert this here
Update_HoleLava(returnx, returny, returndmap, returnscreen, returndir);
}
Waitframe();
}
}
}
//That's all
//This function is shared by other scripts need only once per quest.
void NesMovementFix()
{
if(DIAGONAL_MOVEMENT==0 && (Link->InputUp || Link->InputDown))
{
Link->InputLeft = false;
Link->InputRight = false;
}
}
//Handles Pit Combo Functionality.
void Update_HoleLava(int x, int y, int dmap, int scr, int dir)
{
lweapon hookshot = LoadLWeaponOf(LW_HOOKSHOT);
if(hookshot->isValid()) return;
if(Falling)
{
if(IsSideview()) Link->Jump=0;
Falling--;
if(Falling == 1)
{
int buffer[] = "Holelava";
if(CountFFCsRunning(Game->GetFFCScript(buffer))>0)
{
ffc f = Screen->LoadFFC(FindFFCRunning(Game->GetFFCScript(buffer)));
Warping = true;
if(f->InitD[1]==0)
{
f->InitD[6] = x;
f->InitD[7] = y;
}
}
else
{
if(Game->GetCurDMap()!=dmap || Game->GetCurDMapScreen()!=scr)
Link->PitWarp(dmap, scr);
Link->X = x;
Link->Y = y;
Link->Dir = dir;
Link->DrawXOffset -= Cond(Link->DrawXOffset < 0, -1000, 1000);
Link->HitXOffset -= Cond(Link->HitXOffset < 0, -1000, 1000);
Link->HP -= HOLELAVA_DAMAGE;
Link->Action = LA_GOTHURTLAND;
Link->HitDir = -1;
Game->PlaySound(SFX_OUCH);
}
NoAction();
Link->Action = LA_NONE;
}
}
else if(Link->Z==0 && OnPitCombo() && !Warping)
{
Link->DrawXOffset += Cond(Link->DrawXOffset < 0, -1000, 1000);
Link->HitXOffset += Cond(Link->HitXOffset < 0, -1000, 1000);
int comboflag = OnPitCombo();
SnaptoGrid();
Game->PlaySound(Cond(comboflag == CF_PIT, SFX_LINK_FALL, SFX_LINK_LAVA));
lweapon dummy = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
dummy->UseSprite(Cond(comboflag == CF_PIT, WPS_LINK_FALL, WPS_LINK_LAVA));
dummy->DeadState = dummy->NumFrames*dummy->ASpeed;
dummy->DrawXOffset = 0;
dummy->DrawYOffset = 0;
Falling = dummy->DeadState;
NoAction();
Link->Action = LA_NONE;
}
}
ffc script Holelava
{
void run(int warp, bool position, int damage)
{
while(true)
{
while(!Warping) Waitframe();
if(warp > 0)
{
this->Data = CMB_AUTOWARP+warp-1;
this->Flags[FFCF_CARRYOVER] = true;
Waitframe();
this->Data = FFCS_INVISIBLE_COMBO;
this->Flags[FFCF_CARRYOVER] = false;
Link->Z = Link->Y;
Warping = false;
Link->DrawXOffset -= Cond(Link->DrawXOffset < 0, -1000, 1000);
Link->HitXOffset -= Cond(Link->HitXOffset < 0, -1000, 1000);
Quit();
}
if(position)
{
Link->X = this->X;
Link->Y = this->Y;
}
else
{
Link->X = this->InitD[6];
Link->Y = this->InitD[7];
}
if(damage)
{
Link->HP -= damage;
Link->Action = LA_GOTHURTLAND;
Link->HitDir = -1;
Game->PlaySound(SFX_OUCH);
}
Link->DrawXOffset -= Cond(Link->DrawXOffset < 0, -1000, 1000);
Link->HitXOffset -= Cond(Link->HitXOffset < 0, -1000, 1000);
Warping = false;
Waitframe();
}
}
}
//Used to determine if Link is on a Pit or Lava combo.
int OnPitCombo()
{
int comboLoc = ComboAt(Link->X+8, Link->Y + Cond(BIG_LINK==0, 12, 8));
if(Screen->ComboT[comboLoc] != CT_HOLELAVA)
return 0;
else if(Screen->ComboI[comboLoc] == CF_PIT || Screen->ComboI[comboLoc] == CF_LAVA)
return Screen->ComboI[comboLoc];
else if(Screen->ComboF[comboLoc] == CF_PIT || Screen->ComboF[comboLoc] == CF_LAVA)
return Screen->ComboF[comboLoc];
else
return 0;
}
//Snaps Link to the combo so he appears completely over pit and lava combos.
void SnaptoGrid()
{
int x = Link->X;
int y = Link->Y + Cond(BIG_LINK==0, 8, 0);
int comboLoc = ComboAt(x, y);
//X Axis
if(Screen->ComboT[comboLoc] == CT_HOLELAVA && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc+1] != CT_HOLELAVA))
Link->X = ComboX(comboLoc);
else if(Screen->ComboT[comboLoc+1] == CT_HOLELAVA && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc] != CT_HOLELAVA))
Link->X = ComboX(comboLoc+1);
if(Cond(y % 16 == 0, false, Screen->ComboT[comboLoc+16] == CT_HOLELAVA) && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc+17] != CT_HOLELAVA))
Link->X = ComboX(comboLoc+16);
else if(Cond(y % 16 == 0, false, Screen->ComboT[comboLoc+17] == CT_HOLELAVA) && Cond(x % 16 == 0, true, Screen->ComboT[comboLoc+16] != CT_HOLELAVA))
Link->X = ComboX(comboLoc+17);
//Y Axis
if(Screen->ComboT[comboLoc] == CT_HOLELAVA && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc+16] != CT_HOLELAVA))
Link->Y = ComboY(comboLoc);
else if(Screen->ComboT[comboLoc+16] == CT_HOLELAVA && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc] != CT_HOLELAVA))
Link->Y = ComboY(comboLoc+16);
if(Cond(x % 16 == 0, false, Screen->ComboT[comboLoc+1] == CT_HOLELAVA) && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc+17] != CT_HOLELAVA))
Link->Y = ComboY(comboLoc+1);
else if(Cond(x % 16 == 0, false, Screen->ComboT[comboLoc+17] == CT_HOLELAVA) && Cond(y % 16 == 0, true, Screen->ComboT[comboLoc+1] != CT_HOLELAVA))
Link->Y = ComboY(comboLoc+17);
}
void MovingPlatforms()
{
onplatform = 0;
if(Link->Z == 0)
{
int buffer[] = "MovingPlatform";
for(int i = 1; i <= 32; i++)
{
ffc f = Screen->LoadFFC(i);
if(f->Script != Game->GetFFCScript(buffer)) continue;
if(Abs(Link->X + 8 - CenterX(f)) >= f->TileWidth*8) continue;
if(Abs(Link->Y + 12 - CenterY(f)) >= f->TileHeight*8) continue;
onplatform = FFCNum(f);
break;
}
}
}
ffc script MovingPlatform
{
void run()
{
float oldx = this->X;
float oldy = this->Y;
float linkx;
float linky;
while(true)
{
if(onplatform == FFCNum(this))
{
linkx += this->X - oldx;
linky += this->Y - oldy;
if(linkx << 0 != 0)
{
Link->X += linkx << 0;
linkx -= linkx << 0;
}
if(linky << 0 != 0)
{
Link->Y += linky << 0;
linky -= linky << 0;
}
}
else
{
linkx = 0;
linky = 0;
}
oldx = this->X;
oldy = this->Y;
Waitframe();
}
}
}
You're very welcome.