Code:
const int BD_SHUTTER=1;
const int BD_1WAYSHUTTER=2;
const int BD_LOCKED=3;
const int BD_BOSSLOCKED=4;
const int BD_BOMBABLE=5;
ffc script BasicDoors
{
// D0-D3: Door type (BD_* constant)
// D4: Combo number of switch. If the combo at this position changes,
// any 1-way shutters will open.
// D5: If nonzero, the switch is permanent.
void run(int north, int south, int west, int east, int switchPos, int switchPermanent)
{
bool playSound=false;
int switchStart=Screen->ComboD[switchPos];
bool switched=false;
bool checkNorth=north>0;
bool checkSouth=south>0;
bool checkWest=west>0;
bool checkEast=east>0;
InitDoor(DIR_UP, north, ST_DOORUP);
InitDoor(DIR_DOWN, south, ST_DOORDOWN);
InitDoor(DIR_LEFT, west, ST_DOORLEFT);
InitDoor(DIR_RIGHT, east, ST_DOORRIGHT);
// North or south
if(Link->X==120)
{
// Coming through north door
// The way positions are handled has changed since this was written, but it still seems to work well enough.
if((Game->GetCurDMap()==prevDMap && Link->Y>=160) || (Game->GetCurDMap()!=prevDMap && Link->Y<=0))
{
// Shutter - walk all the way into the room, then close the door
if(north==BD_SHUTTER || north==BD_1WAYSHUTTER)
{
while(Link->Y<32 || Link->Y>=160)
{
NoAction();
Link->InputDown=true;
Waitframe();
}
enterX=Clamp(Link->X, 0, 240);
enterY=Clamp(Link->Y, 0, 160);
}
// Locked- must have been unlocked, so open it up and be sure it's set properly
else if(north==BD_LOCKED)
{
Screen->Door[DIR_UP]=D_UNLOCKED;
Screen->State[ST_DOORUP]=true;
checkNorth=false;
}
else if(north==BD_BOSSLOCKED)
{
Screen->Door[DIR_UP]=D_BOSSUNLOCKED;
Screen->State[ST_DOORUP]=true;
checkNorth=false;
}
}
// Coming through south door
else if((Game->GetCurDMap()==prevDMap && Link->Y<=0) || (Game->GetCurDMap()!=prevDMap && Link->Y>=160))
{
if(south==BD_SHUTTER || south==BD_1WAYSHUTTER)
{
while(Link->Y>128 || Link->Y<=0)
{
NoAction();
Link->InputUp=true;
Waitframe();
}
enterX=Clamp(Link->X, 0, 240);
enterY=Clamp(Link->Y, 0, 160);
}
else if(south==BD_LOCKED)
{
Screen->Door[DIR_DOWN]=D_UNLOCKED;
Screen->State[ST_DOORDOWN]=true;
checkSouth=false;
}
else if(south==BD_BOSSLOCKED)
{
Screen->Door[DIR_DOWN]=D_BOSSUNLOCKED;
Screen->State[ST_DOORDOWN]=true;
checkSouth=false;
}
}
}
// East or west
else if(Link->Y==80)
{
// Coming through west door
if((Game->GetCurDMap()==prevDMap && Link->X>=240) || (Game->GetCurDMap()!=prevDMap && Link->X<=0))
{
if(west==BD_SHUTTER || west==BD_1WAYSHUTTER)
{
while(Link->X<32 || Link->X>=240)
{
NoAction();
Link->InputRight=true;
Waitframe();
}
enterX=Clamp(Link->X, 0, 240);
enterY=Clamp(Link->Y, 0, 160);
}
else if(west==BD_LOCKED)
{
Screen->Door[DIR_LEFT]=D_UNLOCKED;
Screen->State[ST_DOORLEFT]=true;
checkWest=false;
}
else if(west==BD_BOSSLOCKED)
{
Screen->Door[DIR_LEFT]=D_BOSSUNLOCKED;
Screen->State[ST_DOORLEFT]=true;
checkWest=false;
}
}
// Coming through east door
else if((Game->GetCurDMap()==prevDMap && Link->X<=0) || (Game->GetCurDMap()!=prevDMap && Link->X>=240))
{
if(east==BD_SHUTTER || east==BD_1WAYSHUTTER)
{
while(Link->X>208 || Link->X<=0)
{
NoAction();
Link->InputLeft=true;
Waitframe();
}
enterX=Clamp(Link->X, 0, 240);
enterY=Clamp(Link->Y, 0, 160);
}
else if(east==BD_LOCKED)
{
Screen->Door[DIR_RIGHT]=D_UNLOCKED;
Screen->State[ST_DOORRIGHT]=true;
checkEast=false;
}
else if(east==BD_BOSSLOCKED)
{
Screen->Door[DIR_RIGHT]=D_BOSSUNLOCKED;
Screen->State[ST_DOORRIGHT]=true;
checkEast=false;
}
}
}
Waitframe();
if(north==BD_SHUTTER)
{
Screen->Door[DIR_UP]=D_SHUTTER;
playSound=true;
}
else if(north==BD_1WAYSHUTTER)
{
Screen->Door[DIR_UP]=D_1WAYSHUTTER;
playSound=true;
}
if(south==BD_SHUTTER)
{
Screen->Door[DIR_DOWN]=D_SHUTTER;
playSound=true;
}
else if(south==BD_1WAYSHUTTER)
{
Screen->Door[DIR_DOWN]=D_1WAYSHUTTER;
playSound=true;
}
if(west==BD_SHUTTER)
{
Screen->Door[DIR_LEFT]=D_SHUTTER;
playSound=true;
}
else if(west==BD_1WAYSHUTTER)
{
Screen->Door[DIR_LEFT]=D_1WAYSHUTTER;
playSound=true;
}
if(east==BD_SHUTTER)
{
Screen->Door[DIR_RIGHT]=D_SHUTTER;
playSound=true;
}
else if(east==BD_1WAYSHUTTER)
{
Screen->Door[DIR_RIGHT]=D_1WAYSHUTTER;
playSound=true;
}
if(playSound)
Game->PlaySound(SFX_DOORCLOSE);
Waitframes(8);
while(true)
{
if(checkNorth)
{
if((north==BD_LOCKED || north==BD_BOSSLOCKED || north==BD_BOMBABLE) && Screen->ComboS[23]!=15)
{
Screen->State[ST_DOORUP]=true;
Game->SetScreenState(Game->GetCurMap(), Game->GetCurScreen()-16, ST_DOORDOWN, true);
checkNorth=false;
if(north==BD_BOMBABLE)
Screen->Door[DIR_UP]=D_BOMBED;
}
else if(north==BD_1WAYSHUTTER && Screen->State[ST_DOORUP])
{
Screen->Door[DIR_UP]=D_OPENSHUTTER;
Game->PlaySound(SFX_DOOROPEN);
checkNorth=false;
}
}
if(checkSouth)
{
if((south==BD_LOCKED || south==BD_BOSSLOCKED || south==BD_BOMBABLE) && Screen->ComboS[151]!=15)
{
Screen->State[ST_DOORDOWN]=true;
Game->SetScreenState(Game->GetCurMap(), Game->GetCurScreen()+16, ST_DOORUP, true);
checkSouth=false;
if(south==BD_BOMBABLE)
Screen->Door[DIR_DOWN]=D_BOMBED;
}
else if(south==BD_1WAYSHUTTER && Screen->State[ST_DOORDOWN])
{
Screen->Door[DIR_DOWN]=D_OPENSHUTTER;
Game->PlaySound(SFX_DOOROPEN);
checkSouth=false;
}
}
if(checkWest)
{
if((west==BD_LOCKED || west==BD_BOSSLOCKED || west==BD_BOMBABLE) && Screen->ComboS[81]!=15)
{
Screen->State[ST_DOORLEFT]=true;
Game->SetScreenState(Game->GetCurMap(), Game->GetCurScreen()-1, ST_DOORRIGHT, true);
checkWest=false;
if(west==BD_BOMBABLE)
Screen->Door[DIR_LEFT]=D_BOMBED;
}
else if(west==BD_1WAYSHUTTER && Screen->State[ST_DOORLEFT])
{
Screen->Door[DIR_LEFT]=D_OPENSHUTTER;
Game->PlaySound(SFX_DOOROPEN);
checkWest=false;
}
}
if(checkEast)
{
if((east==BD_LOCKED || east==BD_BOSSLOCKED || east==BD_BOMBABLE) && Screen->ComboS[94]!=15)
{
Screen->State[ST_DOORRIGHT]=true;
Game->SetScreenState(Game->GetCurMap(), Game->GetCurScreen()+1, ST_DOORLEFT, true);
checkEast=false;
if(east==BD_BOMBABLE)
Screen->Door[DIR_RIGHT]=D_BOMBED;
}
else if(east==BD_1WAYSHUTTER && Screen->State[ST_DOORRIGHT])
{
Screen->Door[DIR_RIGHT]=D_OPENSHUTTER;
Game->PlaySound(SFX_DOOROPEN);
checkEast=false;
}
}
if(switchPos>0 && !switched && Screen->ComboD[switchPos] != switchStart)
{
switched=true;
if(north==BD_1WAYSHUTTER)
OpenDoor(DIR_UP, BD_1WAYSHUTTER, switchPermanent>0);
if(south==BD_1WAYSHUTTER)
OpenDoor(DIR_DOWN, BD_1WAYSHUTTER, switchPermanent>0);
if(west==BD_1WAYSHUTTER)
OpenDoor(DIR_LEFT, BD_1WAYSHUTTER, switchPermanent>0);
if(east==BD_1WAYSHUTTER)
OpenDoor(DIR_RIGHT, BD_1WAYSHUTTER, switchPermanent>0);
Game->PlaySound(SFX_DOOROPEN);
checkNorth=false;
checkSouth=false;
checkWest=false;
checkEast=false;
}
Waitframe();
}
}
void InitDoor(int dir, int type, int state)
{
if(Screen->State[state])
{
if(type==BD_LOCKED)
Screen->Door[dir]=D_UNLOCKED;
else if(type==BD_BOSSLOCKED)
Screen->Door[dir]=D_BOSSUNLOCKED;
else if(type==BD_BOMBABLE)
Screen->Door[dir]=D_BOMBED;
}
else if(type==BD_BOMBABLE)
Screen->Door[dir]=D_BOMB;
}
void OpenDoor(int dir, int startState, bool permanent)
{
if(startState==0)
return;
if(startState==BD_LOCKED)
{
Screen->Door[dir]=D_UNLOCKED;
Screen->State[dir]=true;
Game->SetScreenState(Game->GetCurMap(), NextScreen(dir), Opposite(dir), true);
}
else if(startState==BD_BOSSLOCKED)
{
Screen->Door[dir]=D_BOSSUNLOCKED;
Screen->State[dir]=true;
Game->SetScreenState(Game->GetCurMap(), NextScreen(dir), Opposite(dir), true);
}
else if(startState==BD_BOMBABLE)
{
Screen->Door[dir]=D_BOMBED;
Screen->State[dir]=true;
Game->SetScreenState(Game->GetCurMap(), NextScreen(dir), Opposite(dir), true);
}
else // BD_SHUTTER
{
Screen->Door[dir]=D_OPENSHUTTER;
if(permanent)
Screen->State[dir]=true;
}
}
int NextScreen(int dir)
{
if(dir==DIR_UP)
return Game->GetCurScreen()-16;
else if(dir==DIR_DOWN)
return Game->GetCurScreen()+16;
else if(dir==DIR_LEFT)
return Game->GetCurScreen()-1;
else
return Game->GetCurScreen()+1;
}
}