Code: Select all
import "std.zh"
import "ffcscript.zh"
import "shutterControl.z"
//Constants used by the HoleLava script.
const int WPS_FALLING = 88; //The misc sprite to use for Link's graphic when he falls in a pit.
const int WPS_LAVA = 89; //The misc sprite to use for Link's graphic when he drowns in lava.
const int SFX_FALLING = 38; //The sound effect to play when Link falls in la pit.
const int SFX_LAVA = 55; //The sound effect to play when Link drowns in lava.
const int CF_LAVA = 98; //The combo FLAG to grant lava functionality to. Used for lava only.
const int CT_HOLELAVA = 142; //The combo TYPE to grant holelava functionality to. Used for both
const int SCRIPT_HOLELAVA = 1; //The ffc script slot number that has the HoleLava2 script.
const int HOLELAVA_DAMAGE = 0; //The amount of damage to deal to link in 16ths of a heart.
const int CMB_AUTOWARP = 892; //This should be a transparent autowarp combo.
//Global Variables used by the HoleLava script.
int Falling; //Determines whether Link is falling or not, and how long long the animation last.
bool Warping; //Determines if Link is being warped by a pit combo.
//Combine this global script with any others.
global script Slot2{
void run(){
//Initialize variables to be used to store Link's Position.
int oldmap = Game->GetCurMap();
int oldscreen = Game->GetCurScreen();
int startx = Link->X;
int starty = Link->Y;
//Clear the Global Variables used by the HoleLava script.
Falling = 0;
Warping = false;
//Loop indefinitely.
while(true){
//If the current map or screen changed and Link is not scrolling then set the local variables used by the HoleLava script.
if((oldscreen != Game->GetCurScreen() || oldmap != Game->GetCurMap()) && Link->Action != LA_SCROLLING){
startx = Link->X;
starty = Link->Y;
oldscreen = Game->GetCurScreen();
oldmap = Game->GetCurMap();
}
//If Link is on a pit combo and not warping or scrolling execute the holelava stuff.
if(Link->Action != LA_SCROLLING && OnPitCombo() && Link->Z <= 0 && !Warping){
//If Falling = 0...
if(Falling == 0){
//Set Link's position to the Grid position of where he is centered.
Link->X = GridX(CenterLinkX());
Link->Y = GridY(CenterLinkY());
//Initialize sprite and sound variables as if he was on a pit.
int sprite = WPS_FALLING;
int sfx = SFX_FALLING;
//If on lava change the sprite and sound variables to the ones for lava.
if(OnPitCombo() == 2){
sprite = WPS_LAVA;
sfx = SFX_LAVA;
}
//Set Falling, create the sprite, and play the sound.
Falling = CreateGraphic(sprite);
Game->PlaySound(sfx);
//Offset Link's drawx and hitx by 1000.
if(Link->DrawXOffset >= 0) Link->DrawXOffset += 1000;
else Link->DrawXOffset -= 1000;
if(Link->HitXOffset >= 0) Link->HitXOffset += 1000;
else Link->HitXOffset -= 1000;
//Set Link's action to none.
Link->Action = LA_NONE;
}
//Otherwise...
else{
//Decrement falling.
Falling--;
//If Falling = 0...
if(Falling == 0){
//If the holelava script is running...
if(CountFFCsRunning(SCRIPT_HOLELAVA) != 0){
//Load that ffc.
ffc f = Screen->LoadFFC(FindFFCRunning(SCRIPT_HOLELAVA));
//If it's second argument isn't set set the last two arguments to Link's starting position.
if(f->InitD[1] == 0){
f->InitD[6] = startx;
f->InitD[7] = starty;
}
}
//Otherwise...
else{
//Set Link's Position.
Link->X = startx;
Link->Y = starty;
//Remove the 1000 pixel offset from Link.
if(Link->DrawXOffset >= 0) Link->DrawXOffset -= 1000;
else Link->DrawXOffset += 1000;
if(Link->HitXOffset >= 0) Link->HitXOffset -= 1000;
else Link->HitXOffset += 1000;
//Damage Link.
Link->HP -= HOLELAVA_DAMAGE;
Link->Action = LA_GOTHURTLAND;
Link->HitDir = -1;
Game->PlaySound(SFX_OUCH);
}
}
}
//Null Link's input.
NoAction();
}
//Waitframe to allow the game's code to run.
Waitframe();
}
}
//This function simply returns true if Link is on a pit/lava combo.
int OnPitCombo(){
int returnnum;
int comboLoc = ComboAt(CenterLinkX(), CenterLinkY());
if(Screen->ComboT[comboLoc] == CT_HOLELAVA){
returnnum++;
if(ComboFI(comboLoc, CF_LAVA)) returnnum++;
}
return returnnum;
}
//This function creates a graphic and returns the lifespan of the graphic.
int CreateGraphic(int sprite){
lweapon l = Screen->CreateLWeapon(LW_SPARKLE);
l->CollDetection = false;
l->UseSprite(sprite);
l->X = Link->X;
l->Y = Link->Y;
l->DrawXOffset = 0;
l->DrawYOffset = 0;
return l->NumFrames*l->ASpeed;
}
}
//This script adds warp and damage functionality to the script.
ffc script HoleLava2{
//D0 is the warp type. 0 for no warp, 1-4 = sidewarps A-D.
//D1 is a boolean and is used to determine whether or not to move Link to the ffcs position. 0 false, 1 true.
//D2 is the amount of damage to do to Link when he falls.
void run(int warp, bool position, int damage){
//Loop idefinitely.
while(true){
//Wait until Falling changes to 0, regardless if it's already at 0 or not.
while(Falling == 0) Waitframe();
while(Falling != 0) Waitframe();
//If this is a warping pit...
if(warp > 0){
//Set warping to true.
Warping = true;
//Warp Link according to the warp variable.
this->Data = CMB_AUTOWARP + warp - 1;
this->Flags[FFCF_CARRYOVER] = true;
//Wait a frame.
Waitframe();
//Return Link's Draw and Hit Offsets back to normal.
if(Link->DrawXOffset >= 0) Link->DrawXOffset -= 1000;
else Link->DrawXOffset += 1000;
if(Link->HitXOffset >= 0) Link->HitXOffset -= 1000;
else Link->HitXOffset += 1000;
//Clear this data to prevent a consecutive warp.
this->Data = FFCS_INVISIBLE_COMBO;
this->Flags[FFCF_CARRYOVER] = false;
//Set Link's Z position to his Y position to give the illusion of him falling.
Link->Z = Link->Y;
//Set Warping to false and then quit.
Warping = false;
Quit();
}
//If position is true then set Link's position to the position of the FFC.
if(position){
Link->X = this->X;
Link->Y = this->Y;
}
else{
Link->X = this->InitD[6];
Link->Y = this->InitD[7];
}
//Set Link's draw and hit Offsets back to normal.
if(Link->DrawXOffset >= 0) Link->DrawXOffset -= 1000;
else Link->DrawXOffset += 1000;
if(Link->HitXOffset >= 0) Link->HitXOffset -= 1000;
else Link->HitXOffset += 1000;
//If damage is greater than 0...
if(damage > 0){
//Damage link.
Link->HP -= damage;
Link->Action = LA_GOTHURTLAND;
Link->HitDir = -1;
Game->PlaySound(SFX_OUCH);
}
shutterControl();
updatePrev();
//Waitframe to prevent freezing.
Waitframe();
}
}
}
ffc script permitem{
void run(int itemid, int killall, int temp, int sfx){
if(killall==1)Waitframes(5);
while(Screen->NumNPCs()>0&&killall==1){
Waitframe();
}
Game->PlaySound(sfx);
item i=Screen->CreateItem(itemid);
i->X=this->X;
i->Y=this->Y;
if(temp==1)i->Pickup=IP_TIMEOUT;
}
}
//Sideview Ladder Script 2.0
//D0: Set this to the flag that marks ladder combos
ffc script Sideview_Ladders{
//This detects whether Link is in the middle of an action that would prevent him from moving while on ladders
bool LinkBusy(){
return !(Link->Action<LA_ATTACKING||Link->Action==LA_CHARGING||Link->Action==LA_GOTHURTLAND);
}
//This is a modified version of CanWalk() that determines if Link can walk up or down while on a ladder
bool LadderCheck(int x, int y, int dir, int step, bool full_tile) {
int c=8;
int xx = x+15;
int yy = y+15;
if(full_tile) c=0;
if(Link->Y<=0) return true;
else if(Link->Y>=160) return true;
else if(dir==0) return !(y-step<0||Screen->isSolid(x,y+c-step)||Screen->isSolid(x+8,y+c-step)||Screen->isSolid(xx,y+c-step));
else if(dir==1) return !(yy+step>=176||Screen->isSolid(x,yy+step)||Screen->isSolid(x+8,yy+step)||Screen->isSolid(xx,yy+step));
return false; //invalid direction
}
void run(int flag){
bool cling=true;
itemdata feather=Game->LoadItemData(I_ROCSFEATHER);
if(flag==0)flag=98; //This sets the flag to 98 if you're feeling too lazy to set D0
while(true){
if(ComboFI(Link->X+8, Link->Y+8, flag)||ComboFI(Link->X+8, Link->Y+16, flag)){
if(cling)Link->Jump=0;//This makes link float when he's clinging to a ladder
//This allows Link to jump while on ladders by recreating the effect of the Roc's Feather item
if(((GetEquipmentA()==I_ROCSFEATHER&&Link->PressA)||(GetEquipmentB()==I_ROCSFEATHER&&Link->PressB))&&cling){
Game->PlaySound(SFX_JUMP);
Link->Jump=(feather->Power+2)*0.8;
cling=false;
}
//This moves Link up or down on the ladders and keeps him from falling through them if he walks on top of one
if(ComboFI(Link->X+8, Link->Y+16, flag)&&!ComboFI(Link->X+8, Link->Y+15, flag)){
cling=true;
}
else if(Link->InputUp&&LadderCheck(Link->X, Link->Y, DIR_UP, 1, true)){
if(!LinkBusy())Link->Y--;
cling=true;
}
if(Link->InputDown&&LadderCheck(Link->X, Link->Y, DIR_DOWN, 1, true)){
if(!LinkBusy())Link->Y++;
cling=true;
}
}
else if(cling)cling=false; //This makes Link stop floating when he steps off the ladder flag
Waitframe();
}
}
}
//Sideview Platform Script 1.0
//Put this script on any FFC in sideview you want Link to be able to stand on.
//Link's interaction with platforms won't work as well with accelerating platforms or non-integer velocity values.
ffc script Moving_Platform{
//This detects if Link is performing an action that should prevent him from moving while on a platform
bool LinkBusy(){
return !(Link->Action<LA_ATTACKING||Link->Action==LA_CHARGING||Link->Action==LA_GOTHURTLAND);
}
//This detects if Link is using the hookshot, an item that bugs out horribly if Link is moved while using it
bool Hookshotting(){
for(int i=1; i<=Screen->NumLWeapons(); i++){
lweapon l=Screen->LoadLWeapon(i);
if(l->ID==LW_HOOKSHOT)return true;
}
return false;
}
void run(){
itemdata feather=Game->LoadItemData(I_ROCSFEATHER);
while(true){
//This detects when Link gets on the platform
if(Link->X>this->X-12&&Link->X<this->X+12+(this->TileWidth-1)*16){
if(Link->Y>this->Y-16&&Link->Y<this->Y-8){
int savedx=this->X;
while(Link->Y>this->Y-17-Abs(this->Vy)&&Link->Y<this->Y-8&&Link->X>this->X-12&&Link->X<this->X+12+(this->TileWidth-1)*16){
//This snaps Link to the platform when he isn't hookshotting
if(!Hookshotting()){
Link->Y=this->Y-16;
Link->X+=this->X-savedx;
}
savedx=this->X;
Link->Jump=0;
//This allows Link to jump while on sideview platforms by recreating the effect of the Roc's feather item
if(((GetEquipmentA()==I_ROCSFEATHER&&Link->PressA)||(GetEquipmentB()==I_ROCSFEATHER&&Link->PressB))){
Game->PlaySound(SFX_JUMP);
Link->Jump=(feather->Power+2)*0.8;
}
if(LinkBusy())NoAction();
Waitframe();
}
}
}
Waitframe();
}
}
}