I need some help with this enemy. Currently everything works as intended except that if Link is caught while in the air it appears that his shadow is knocked back; however, I manually set this Link->DrawXOffset & Link-?Z to zero, so his shadow shouldn't be being knocked back. Anybody know what's going on?
const int CMASTER_ATTR_MIN_WAIT = 0;
const int CMASTER_ATTR_MAX_WAIT = 1;
const int CMASTER_ATTR_RISE_DELAY = 2;
const int CMASTER_ATTR_RESPAWN = 3;
const int CMASTER_CMB_AUTOWARP = 888;
ffc script CeilingMaster
{
void run(int enemyID)
{
//Init
npc ghost = Ghost_InitAutoGhost(this, enemyID);
ghost->Extend = EXT_NOSHADOW; //This makes it impossible to see while in the air
//Flags
Ghost_SetFlag(GHF_NORMAL); //Set Direction, Knockback, Stun, Clock.
Ghost_SetFlag(GHF_NO_FALL); //Enemy is immune to gravity.
Ghost_SetFlag(GHF_SET_OVERLAY); // Allows it to be drawn over Layer 4.
//Position Handling
Ghost_X = Link->X;
Ghost_Y = Link->Y;
Ghost_Z = Ghost_Y + 16;
//Movement Delays
int minwait = Ghost_GetAttribute(ghost, CMASTER_ATTR_MIN_WAIT, 120); //2 seconds.
int maxwait = Ghost_GetAttribute(ghost, CMASTER_ATTR_MAX_WAIT, 210); //3.5 seconds.
float step = ghost->Step/100; //if this is zero it’will incorporate gravity.
int riseDelay = Ghost_GetAttribute(ghost, CMASTER_ATTR_RISE_DELAY, 48); //0.8 seconds.
bool respawn = (ghost->Attributes[CMASTER_ATTR_RESPAWN] != 0);
//Behavior Loop
while(Ghost_HP > 0) //Loop until Dead.
{
//Wait to drop.
for(int counter = Rand(minwait, maxwait); counter > 0; counter--)
{
Ghost_Waitframe(this, ghost, false, false); //Done before so Ghost_X and Y are up to frame with Link’s position.
Ghost_X = Link->X;
Ghost_Y = Link->Y;
Ghost_Z = Ghost_Y + 16;
}
//Fall towards the ground.
if(step == 0)
{
Ghost_UnsetFlag(GHF_NO_FALL);
}
Game->PlaySound(SFX_FALL);
Ghost_Z -= 16;
ghost->Extend = EXT_NORMAL; //This makes the shadow appear.
//Wait for a Ground Collision
do
{
//Check for Link Collisions.
if(LinkCollision(ghost)) //Grabbed Link?
{
Ghost_SetFlag(GHF_NO_FALL); //Stop Falling
break; //Exit Loop
}
if(step!=0) Ghost_Z -= step;
Ghost_Waitframe(this, ghost, false, false); //It won’t respawn if we clear and qut.
} while(Ghost_Z > 0);
//Collision Stuff
if(Link->CollDetection && LinkCollision(ghost))
{
//Move to Link's Position.
Ghost_X = Link->X;
Ghost_Y = Link->Y;
Link->Z = 0;
Link->Invisible = true;
Link->CollDetection = false;
if(Link->HP <= 0) //Quit if Link Dies;
{
Link->Invisible = false;
Link->CollDetection = true;
this->Data = 0; Quit();
}
//Change to the grab combo.
Ghost_Data++;
for(int i = 0; i < riseDelay ; i++)
{
NoAction();
Screen->DrawTile(4, Ghost_X, Ghost_Y - Ghost_Z + 10, Link->Tile, Link->TileWidth, Link->TileHeight,
6, -1, -1, 0, 0, 0, Link->Flip, true, 128);
Screen->DrawTile(4, Ghost_X, Ghost_Y - Ghost_Z - 2, Game->ComboTile(Ghost_Data), Ghost_TileWidth, Ghost_TileHeight,
Ghost_CSet, -1, -1, 0, 0, 0, 0, true, 128);
Ghost_Waitframe(this, ghost, false, false);
}
//Carry Link up into the ceiling.
int frame;
while(Ghost_Z - 32 < Ghost_Y)
{
Ghost_Z += 2;
NoAction();
Screen->DrawTile(4, Ghost_X, Ghost_Y - Ghost_Z + 10, Link->Tile, Link->TileWidth, Link->TileHeight,
6, -1, -1, 0, 0, 0, Link->Flip, true, 128);
Screen->DrawTile(4, Ghost_X, Ghost_Y - Ghost_Z - 2, Game->ComboTile(Ghost_Data), Ghost_TileWidth, Ghost_TileHeight,
Ghost_CSet, -1, -1, 0, 0, 0, 0, true, 128);
Ghost_Waitframe(this, ghost, false, false);
}
//Warp Link
int dmap = Game->LastEntranceDMap;
int screen = Game->LastEntranceScreen;
Screen->SetSideWarp(0, screen, dmap, WT_IWARPBLACKOUT);
this->Data = CMASTER_CMB_AUTOWARP;
//Reset Link
Link->Invisible = false;
Link->CollDetection = true;
Quit();
}
//Doesn’t have Link, Wait a bit and move up towards the cealing.
for(int i; i < riseDelay && Ghost_Waitframe(this, ghost, false, false); i++);
//Set GHF_NO_FALL.
Ghost_SetFlag(GHF_NO_FALL);
//Move towards the ceiling... Using the boolean && operator again.
while(Ghost_Z < Ghost_Y && Ghost_Waitframe(this, ghost, false, false))
Ghost_Z += 2.5;
//Set Ghost_Z offset
Ghost_Z += 16;
//Hide the shadow once more
ghost->Extend = EXT_NOSHADOW;
//One Last Waitframe
Ghost_Waitframe(this, ghost, false, false);
}
if(respawn)
{
Screen->CreateNPC(enemyID);
}
Ghost_Waitframe(this, ghost, true, true);
}
}

