Copy to Clipboard Test

LttP/OoT Style Wallmaster (AutoGhost) Code

const int SFX_WALLMASTER_SHADOW = 66;
const int SFX_WALLMASTER_DROP = 63;
const int SFX_WALLMASTER_LTTP_FALL = 67;
const int SFX_WALLMASTER_GRAB = 64;
const int SFX_WALLMASTER_AWAY = 61;
const int COMBO_AUTOWARP = 889;
const int TILE_WALLMASTER = 2668;
const int COLOR_SHADOW = 0x08;

ffc script OoTWallmaster
{
	void run(int enemyID)
	{
		bool OoT; // True if Miscellaneous Attribute 1 is not 0. Makes the Wallmaster behave more like OoT and give more warning than LttP style.
		int wait;
		int xradius;
		int yradius;
		
		npc ghost = Ghost_InitAutoGhost(this, enemyID);
		Ghost_SetFlag(GHF_MOVE_OFFSCREEN);
		
		if (ghost->Attributes[0] > 0)
		{
			OoT = true;
		}
		
		while (true)
		{
			Ghost_X = -100;
			Ghost_Y = -100;
			ghost->DrawXOffset = -1000;
			ghost->DrawYOffset = -1000;
			//Ghost_Z = 0;
			ghost->CollDetection = false;
			Link->CollDetection = true;
			
			// Wallmaster waiting.
			wait = Rand(ghost->Attributes[1], ghost->Attributes[2]);
			for (int i = 0; i < wait; i++)
			{
				Ghost_Waitframe(this, ghost, true, true);
			}
			
			// Set tile to something not invisible.
			//Ghost_Data = COMBO_WALLMASTER;
			//Ghost_CSet = 10;
			ghost->OriginalTile = TILE_WALLMASTER;
			
			if (OoT)
			{
				Game->PlaySound(SFX_WALLMASTER_SHADOW);
			}
			
			// Wallmaster's shadow appears under Link.
			for (int i = 0; i < 150; i++)
			{
				Ghost_X = Link->X;
				Ghost_Y = Link->Y;
				//Ghost_Z = 256;
				if (OoT)
				{
					xradius = (Min(i + 50, 150) / 150) * 8;
					yradius = (Min(i + 50, 150) / 150) * 6;
					Screen->Ellipse(2, Ghost_X + 7, Ghost_Y + 12, xradius, yradius, COLOR_SHADOW, 1, 0, 0, 0, true, OP_OPAQUE);
				}
				Ghost_Waitframe(this, ghost, true, true);
			}
			
			// Wallmaster falls.
			//while (Ghost_Z > 0)
			//{
				//Ghost_Waitframe(this, ghost, true, true);
			//}
			if (!OoT)
			{
				Game->PlaySound(SFX_WALLMASTER_LTTP_FALL);
			}
			ghost->DrawXOffset = 0;
			for (int i = -256; i <= 0; i += 4)
			{
				ghost->DrawYOffset = i;
				if (!OoT)
				{
					xradius = (Clamp(256 + i, 50, 150) / 150) * 8;
					yradius = (Clamp(256 + i, 50, 150) / 150) * 6;
				}
				Screen->Ellipse(2, Ghost_X + 7, Ghost_Y + 12, xradius, yradius, COLOR_SHADOW, 1, 0, 0, 0, true, OP_OPAQUE);
				Ghost_Waitframe(this, ghost, true, true);
			}
			
			Game->PlaySound(SFX_WALLMASTER_DROP);
			ghost->CollDetection = true;
			
			// Wallmaster grabs Link if it touches him.
			for (int i = 0; i < 90; i++)
			{
				if (Abs(Link->X - Ghost_X) < 12 && Abs(Link->Y - Ghost_Y) < 12 && Link->Z < 4)
				{
					Game->PlaySound(SFX_WALLMASTER_GRAB);
					for (int j = 0; j < 256; j++)
					{
						Link->X = Ghost_X;
						Link->Y = Ghost_Y;
						NoAction();
						//Link->Action = LA_NONE;
						//Link->Z = j;
						//Ghost_Z = j;
						Link->DrawYOffset--;
						ghost->DrawYOffset--;
						if (j > 20 && ghost->CollDetection)
						{
							ghost->CollDetection = false;
						}
						if (j > 0 && Link->CollDetection)
						{
							Link->CollDetection = false;
						}
						xradius = (Clamp(256 - j, 50, 150) / 150) * 8;
						yradius = (Clamp(256 - j, 50, 150) / 150) * 6;
						Screen->Ellipse(2, Ghost_X + 7, Ghost_Y + 12, xradius, yradius, COLOR_SHADOW, 1, 0, 0, 0, true, OP_OPAQUE);
						Screen->FastTile(4, Ghost_X, Ghost_Y + ghost->DrawYOffset, TILE_WALLMASTER, Ghost_CSet, OP_OPAQUE);
						Ghost_Waitframe(this, ghost, true, true);
					}
					Screen->SetSideWarp(0, Game->LastEntranceScreen - Game->DMapOffset[Game->GetCurDMap()], Game->LastEntranceDMap, WT_IWARPOPENWIPE);
					this->Data = COMBO_AUTOWARP;
					//Link->Z = 0;
					Link->DrawYOffset = 0;
					Link->CollDetection = true;
					Quit();
				}
				Screen->Ellipse(2, Ghost_X + 7, Ghost_Y + 12, xradius, yradius, COLOR_SHADOW, 1, 0, 0, 0, true, OP_OPAQUE);
				Ghost_Waitframe(this, ghost, true, true);
			}
			
			Game->PlaySound(SFX_WALLMASTER_AWAY);
			
			// Wallmaster rises back to the ceiling if it fails to grab.
			ghost->CollDetection = false;
			for (int i = 0; i < 256; i += 2)
			{
				//Ghost_Z = i;
				ghost->DrawYOffset = -i;
				xradius = (Clamp(256 - i, 50, 150) / 150) * 8;
				yradius = (Clamp(256 - i, 50, 150) / 150) * 6;
				Screen->Ellipse(2, Ghost_X + 7, Ghost_Y + 12, xradius, yradius, COLOR_SHADOW, 1, 0, 0, 0, true, OP_OPAQUE);
				Ghost_Waitframe(this, ghost, true, true);
			}
		}
	}
}