Holelava + Moving Platforms
So there's been some talk about how to combine these scripts over on pure. It's really not that hard. "I actually found a typo in the platforms script that had to be resolved."
Here's how to do it.
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.
I had to only insert two lines of code into the active script to get this working, so don't edit my scripts without my permission. Chances are you would break something anyways.