Copy to Clipboard Test

Elevator on Tracks Code

const int CF_ELEVATOR = 98; //Combo flag marking elevator tracks
const int CF_ELEVATORSTOP = 99; //Combo flag marking that you can get off an elevator

const int SFX_ELEVATOR_START = 6; //Sound that plays when an elevator starts moving
const int SFX_ELEVATOR_PERSISTENT = 17; //Sound that plays while an elevator moves

const int ELEVATOR_SFX_FREQ = 4; //How often the persistent sound plays

const int ELEVATOR_STEP = 4; //How fast elevators move along tracks

const int LM_ACTION = 0; //Link->Misc for special actions
const int LMA_ON_ELEVATOR = 1; //Link->Misc state for being on an elevator

ffc script Elevator{
	void run(int offX, int offY, int combo){
		int elevatorX = this->X+offX;
		int elevatorY = this->Y+offY;
		int elevatorDir;
		int targetX; int targetY;
		int sfxTimer;
		bool onElevator;
		int data = this->Data;
		this->Data = FFCS_INVISIBLE_COMBO;
		Waitframe();
		if(combo>0){
			if(Link->Misc[LM_ACTION]==LMA_ON_ELEVATOR){
				this->Data = combo;
			}
			else{
				Quit();
			}
		}
		else
			this->Data = data;
		if(Link->Misc[LM_ACTION]==LMA_ON_ELEVATOR&&ComboFI(Link->X+8, Link->Y+8, CF_ELEVATOR)){
			elevatorX = ComboX(ComboAt(Link->X+8, Link->Y+8));
			elevatorY = ComboY(ComboAt(Link->X+8, Link->Y+8));
			this->X = elevatorX-offX;
			this->Y = elevatorY-offY;
			
			if(elevatorX==0)
				elevatorDir = DIR_RIGHT;
			else if(elevatorX==240)
				elevatorDir = DIR_LEFT;
			else if(elevatorY==0)
				elevatorDir = DIR_DOWN;
			else if(elevatorY==160)
				elevatorDir = DIR_UP;
			
			targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
			targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
			Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
		}
		else if(Link->Misc[LM_ACTION]==LMA_ON_ELEVATOR)
			Link->Misc[LM_ACTION] = 0;
		while(true){
			while(Link->Misc[LM_ACTION]==LMA_ON_ELEVATOR){
				while(Distance(elevatorX, elevatorY, targetX, targetY)>ELEVATOR_STEP){
					if(SFX_ELEVATOR_PERSISTENT>0){
						sfxTimer++;
						if(sfxTimer>ELEVATOR_SFX_FREQ){
							sfxTimer = 0;
							Game->PlaySound(SFX_ELEVATOR_PERSISTENT);
						}
					}
					int angle = Angle(elevatorX, elevatorY, targetX, targetY);
					elevatorX += VectorX(ELEVATOR_STEP, angle);
					elevatorY += VectorY(ELEVATOR_STEP, angle);
					this->X = elevatorX-offX;
					this->Y = elevatorY-offY;
					Link->X = elevatorX;
					Link->Y = elevatorY;
					Link->Jump = 0;
					Waitframe();
				}
				elevatorX = targetX;
				elevatorY = targetY;
				this->X = elevatorX-offX;
				this->Y = elevatorY-offY;
				Link->X = elevatorX;
				Link->Y = elevatorY;
				if(ComboFI(elevatorX+8, elevatorY+8, CF_ELEVATORSTOP)){
					Link->Misc[LM_ACTION] = 0;
					if(Link->InputUp&&CheckElevator(elevatorX, elevatorY, DIR_UP)){
						elevatorDir = DIR_UP;
						targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
						targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
						Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					}
					else if(Link->InputDown&&CheckElevator(elevatorX, elevatorY, DIR_DOWN)){
						elevatorDir = DIR_DOWN;
						targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
						targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
						Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					}
					else if(Link->InputLeft&&CheckElevator(elevatorX, elevatorY, DIR_LEFT)){
						elevatorDir = DIR_LEFT;
						targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
						targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
						Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					}
					else if(Link->InputRight&&CheckElevator(elevatorX, elevatorY, DIR_RIGHT)){
						elevatorDir = DIR_RIGHT;
						targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
						targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
						Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					}
					else{
						while(!Link->PressUp&&!Link->PressDown&&!Link->PressLeft&&!Link->PressRight){
							Waitframe();
						}
						Waitframe();
					}
				}
				else{
					int oldDir = elevatorDir;
					elevatorDir = -1;
					for(int i=0; i<4&&elevatorDir==-1; i++){
						if(OppositeDir(oldDir)!=i){
							if(CheckElevator(elevatorX, elevatorY, i))
								elevatorDir = i;
						}
					}
					if(elevatorDir==-1)
						elevatorDir = oldDir;
					targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
					targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
					if(ElevatorNumBranches(elevatorX, elevatorY)>2){
						elevatorDir = -1;
						while(elevatorDir==-1){
							this->X = elevatorX-offX;
							this->Y = elevatorY-offY;
							Link->X = elevatorX;
							Link->Y = elevatorY;
							Link->Jump = 0;
							if(Link->InputUp&&CheckElevator(elevatorX, elevatorY, DIR_UP)){
								elevatorDir = DIR_UP;
								targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
								targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
								Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
							}
							else if(Link->InputDown&&CheckElevator(elevatorX, elevatorY, DIR_DOWN)){
								elevatorDir = DIR_DOWN;
								targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
								targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
								Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
							}
							else if(Link->InputLeft&&CheckElevator(elevatorX, elevatorY, DIR_LEFT)){
								elevatorDir = DIR_LEFT;
								targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
								targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
								Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
							}
							else if(Link->InputRight&&CheckElevator(elevatorX, elevatorY, DIR_RIGHT)){
								elevatorDir = DIR_RIGHT;
								targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
								targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
								Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
							}
							Waitframe();
						}
					}
				}
			}
			if(Distance(elevatorX, elevatorY, Link->X, Link->Y)<8){
				if(Link->Dir==DIR_UP&&Link->PressUp&&CheckElevator(elevatorX, elevatorY, DIR_UP)){
					elevatorDir = DIR_UP;
					targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
					targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
					Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					Game->PlaySound(SFX_ELEVATOR_START);
				}
				else if(Link->Dir==DIR_DOWN&&Link->PressDown&&CheckElevator(elevatorX, elevatorY, DIR_DOWN)){
					elevatorDir = DIR_DOWN;
					targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
					targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
					Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					Game->PlaySound(SFX_ELEVATOR_START);
				}
				else if(Link->Dir==DIR_LEFT&&Link->PressLeft&&CheckElevator(elevatorX, elevatorY, DIR_LEFT)){
					elevatorDir = DIR_LEFT;
					targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
					targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
					Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					Game->PlaySound(SFX_ELEVATOR_START);
				}
				else if(Link->Dir==DIR_RIGHT&&Link->PressRight&&CheckElevator(elevatorX, elevatorY, DIR_RIGHT)){
					elevatorDir = DIR_RIGHT;
					targetX = ElevatorTargetX(elevatorX, elevatorY, elevatorDir);
					targetY = ElevatorTargetY(elevatorX, elevatorY, elevatorDir);
					Link->Misc[LM_ACTION] = LMA_ON_ELEVATOR;
					Game->PlaySound(SFX_ELEVATOR_START);
				}
			}
			Waitframe();
		}
	}
	bool CheckElevator(int elevatorX, int elevatorY, int elevatorDir){
		int x; int y;
		if(elevatorDir==DIR_UP){
			x = elevatorX+8;
			y = elevatorY-8;
			if(ComboFI(x, y, CF_ELEVATOR)||ComboFI(x, y, CF_ELEVATORSTOP))
				return true;
		}
		else if(elevatorDir==DIR_DOWN){
			x = elevatorX+8;
			y = elevatorY+24;
			if(ComboFI(x, y, CF_ELEVATOR)||ComboFI(x, y, CF_ELEVATORSTOP))
				return true;
		}
		else if(elevatorDir==DIR_LEFT){
			x = elevatorX-8;
			y = elevatorY+8;
			if(ComboFI(x, y, CF_ELEVATOR)||ComboFI(x, y, CF_ELEVATORSTOP))
				return true;
		}
		else if(elevatorDir==DIR_RIGHT){
			x = elevatorX+24;
			y = elevatorY+8;
			if(ComboFI(x, y, CF_ELEVATOR)||ComboFI(x, y, CF_ELEVATORSTOP))
				return true;
		}
		return false;
	}
	int ElevatorNumBranches(int elevatorX, int elevatorY){
		int count;
		for(int i=0; i<4; i++){
			if(CheckElevator(elevatorX, elevatorY, i))
				count++;
		}
		return count;
	}
	int ElevatorTargetX(int elevatorX, int elevatorY, int elevatorDir){
		if(elevatorDir==DIR_LEFT)
			return elevatorX-16;
		else if(elevatorDir==DIR_RIGHT)
			return elevatorX+16;
		else
			return elevatorX;
	}
	int ElevatorTargetY(int elevatorX, int elevatorY, int elevatorDir){
		if(elevatorDir==DIR_UP)
			return elevatorY-16;
		else if(elevatorDir==DIR_DOWN)
			return elevatorY+16;
		else
			return elevatorY;
	}
}