Copy to Clipboard Test

Advanced Switch EX Code

const int CF_SWITCHABLE_OFF = 98;//Combo flag to define switchable combo in off state
const int CF_SWITCHABLE_ON = 99;//Combo flag to define switchable combo in on state

const int SCREEN_D_SWITCH = 0; //ScreenD to check for switch state

const int SFX_SWITCH = 16;//Sound to play on activating sewitch

//Simple 2-state switch

//Place FFC st switch location
//D0 - combo to turn flagged combos in off state
//D1 - combo to turn flagged combos in on state
//D2 - Switch type
// 0 - step -> permanent (until leaving screen)
// 1 - step - on, release - off.
// 2 - Toggle state with EX1.
// 3 - Hold EX1 on switch FFC to keep switch on, otherwise off.
// 4 - step - permanent
// 5 - toggle with EX1 - record into register
// 6 - lever - hit with weapon
// 7 - same as above, but registers.
//D3 - Switch only combos with came CSet, as FFC.
//D4 - Quake timer on turning on.
//D5 - trap settings - -1 - fire drop, >0 enemy ID spawn
//D6 - if D5>0 - number of enemies to spawn, else - damage caused by fire eweapons.  
//D7 - if (D5<0) - number of fire eweapons to spawn.

//As for switchable FFCs, you can read switch state by passing FFC pointer into SwitchState function that eith returns switch state (true - on, false - off), or generate error and terminates the script.

ffc script Switch{
	void run (int cmboff, int cmbon, int type, int color, int quake, int trap, int trap2, int trap3){
		int cmb=-1;
		int origcmb = ComboAt (CenterX(this), CenterY(this));
		int origdata = this->Data;
		this->InitD[7]=0;
		int offset=0;
		int cd=0;
		if (Screen->isSolid(CenterX(this), CenterY(this))) offset=-2;
		while(true){
			cmb = ComboAt (CenterLinkX(), CenterLinkY()+offset);
			if (cmb==origcmb){
				if (type==0 || type==1 || type==4){
					if (this->InitD[7]==0){
						Game->PlaySound(SFX_SWITCH);
						if (quake>0)Screen->Quake= quake;
					}
					if (this->InitD[7]==0){
						if (trap>0){
							for (int i=1;i<=trap2*16;i++){
								if ((i%16)==0){
									Game->PlaySound(SFX_FALL);
									npc n= SpawnNPC(trap);
									n->Z=128;
								}
								cmb = ComboAt (CenterLinkX(), CenterLinkY()+offset);
								if (cmb==origcmb)this->InitD[7]=1;
								if (type==4)SetScreenDBit(SCREEN_D_SWITCH, this->CSet, this->InitD[7]>0);
								if ((type==1 || type==3) && Screen->ComboS[origcmb]==0 && cmb!=origcmb) this->InitD[7]=0;
								if (type==4||type==5)this->InitD[7]=Cond(GetScreenDBit(SCREEN_D_SWITCH, this->CSet), 1,0);
								if (this->InitD[7]==1){
									this->Data=origdata+1;
									for (int i=0;i<176;i++){
										if (ComboFI(i, CF_SWITCHABLE_OFF) && (color==0 ||Screen->ComboC[i]==this->CSet)){
											Screen->ComboD[i]=cmbon;
											Screen->ComboF[i]=CF_SWITCHABLE_ON;
										}
									}
								}
								else{
									this->Data=origdata;
									for (int i=0;i<176;i++){
										if (ComboFI(i, CF_SWITCHABLE_ON)&& (color==0 ||Screen->ComboC[i]==this->CSet)){
											Screen->ComboD[i]=cmboff;
											Screen->ComboF[i]=CF_SWITCHABLE_OFF;
										}
									}
								}
								Waitframe();
							}
						}
						if (trap<0){
							for (int i=1;i<=trap3*16;i++){
								if ((i%16)==0){
									Game->PlaySound(SFX_FIRE);
									int fcmb = FindSpawnPoint(true, false, false, false);
									eweapon fire = CreateEWeaponAt(EW_FIRE, ComboX(fcmb), ComboY(fcmb));
									fire->Damage = trap2;
									fire->Z=128;
								}
								cmb = ComboAt (CenterLinkX(), CenterLinkY());
								if (cmb==origcmb)this->InitD[7]=1;
								if (type==4)SetScreenDBit(SCREEN_D_SWITCH, this->CSet, this->InitD[7]>0);
								if ((type==1 || type==3) && Screen->ComboS[origcmb]==0 && cmb!=origcmb) this->InitD[7]=0;
								if (type==4||type==5)this->InitD[7]=Cond(GetScreenDBit(SCREEN_D_SWITCH, this->CSet), 1,0);
								if (this->InitD[7]==1){
									this->Data=origdata+1;
									for (int i=0;i<176;i++){
										if (ComboFI(i, CF_SWITCHABLE_OFF) && (color==0 ||Screen->ComboC[i]==this->CSet)){
											Screen->ComboD[i]=cmbon;
											Screen->ComboF[i]=CF_SWITCHABLE_ON;
										}
									}
								}
								else{
									this->Data=origdata;
									for (int i=0;i<176;i++){
										if (ComboFI(i, CF_SWITCHABLE_ON)&& (color==0 ||Screen->ComboC[i]==this->CSet)){
											Screen->ComboD[i]=cmboff;
											Screen->ComboF[i]=CF_SWITCHABLE_OFF;
										}
									}
								}
								Waitframe();
							}
						}
					}
					if (cmb==origcmb){
						this->InitD[7]=1;
						if (type==4)SetScreenDBit(SCREEN_D_SWITCH, this->CSet, this->InitD[7]>0);
					}
				}
				else if (type==2 || type==5){
					if (Link->PressEx1){
						Game->PlaySound(SFX_SWITCH);
						if (quake>0)Screen->Quake= quake;
						if (this->InitD[7]==1)this->InitD[7]=0;
						else this->InitD[7]=1;
						if (type==5)SetScreenDBit(SCREEN_D_SWITCH, this->CSet, this->InitD[7]>0);
					}
				}
				else if (type==3){
					if (Link->InputEx1){
						if (this->InitD[7]==0){
							Game->PlaySound(SFX_SWITCH);
							if (quake>0)Screen->Quake= quake;
						}
						this->InitD[7]=1;
					}
					else this->InitD[7]=0;
				}
			}
			else{
				if ((type==1 || type==3) && Screen->ComboS[origcmb]==0) this->InitD[7]=0;
			}
			if (type==6 || type==7){
				if (cd>0)cd--;
				else{
					for (int i=1; i<=Screen->NumLWeapons();i++){
						lweapon l = Screen->LoadLWeapon(i);
						if (l->ID==LW_WHISTLE)continue;
						if (l->ID==LW_BOMB)continue;
						if (l->ID==LW_SBOMB)continue;
						if (!Collision(l,this)) continue;
						Game->PlaySound(SFX_SWITCH);
						if (quake>0)Screen->Quake= quake;
						if (this->InitD[7]==1)this->InitD[7]=0;
						else this->InitD[7]=1;
						if (type==7)SetScreenDBit(SCREEN_D_SWITCH, this->CSet, this->InitD[7]>0);
						// Trace(this->InitD[7]);
						cd=30;
						break;
					}
				}
			}
			if (Screen->ComboS[origcmb]>0 && this->InitD[7]==0 && (type==0||type==1||type==4)){
				if (quake>0)Screen->Quake= quake;
				Game->PlaySound(SFX_SWITCH);
				this->InitD[7]=1;
				if (type==4||type==5)SetScreenDBit(SCREEN_D_SWITCH, this->CSet, this->InitD[7]>0);
			}
			if (type==4||type==5)this->InitD[7]=Cond(GetScreenDBit(SCREEN_D_SWITCH, this->CSet), 1,0);
			if (this->InitD[7]==1){
				this->Data=origdata+1;
				for (int i=0;i<176;i++){
					if (ComboFI(i, CF_SWITCHABLE_OFF) && (color==0 ||Screen->ComboC[i]==this->CSet)){
						Screen->ComboD[i]=cmbon;
						Screen->ComboF[i]=CF_SWITCHABLE_ON;
					}
				}
			}
			else{
				this->Data=origdata;
				for (int i=0;i<176;i++){
					if (ComboFI(i, CF_SWITCHABLE_ON)&& (color==0 ||Screen->ComboC[i]==this->CSet)){
						Screen->ComboD[i]=cmboff;
						Screen->ComboF[i]=CF_SWITCHABLE_OFF;
					}
				}
			}
			//debugValue(1, Screen->D[SCREEN_D_SWITCH]);
			Waitframe();
		}
	}
}

//Returns True, if the given FFC runs Switch script and his state is ON. If FFC is not a switch FFC, the script terminates with error message in log.
bool SwitchState(ffc f, ffc n){
	int str[]="Switch";
	int scr = Game->GetFFCScript(str);
	if (f->Script!=scr){
		int err[]="Error: this FFC is not a Switch FFC.";
		Trace(FFCNum(n));
		TraceS(err);
		Quit();
	}
	return f->InitD[7]==1;
}	

//Switch operated FFC
//D0 - ID of FFC running Switch script
//D1 - Vx when switch is set to On
//D2 - Vy when switch is set to On
//D3 - Vx when switch is set to Off
//D4 - Vy when switch is set to Off
//D5 - X position, when switch is set On
//D6 - Y position, when switch is set On
//Use FFC changers to limit FFC movements.
ffc script SwitchableFFC{
	void run(int SwitchID, int VxOn, int VyOn, int VxOff, int VyOff, int locXOn, int locYOn){
		ffc f = Screen->LoadFFC(SwitchID);
		bool s = SwitchState(f, this);
		if (GetScreenDBit(SCREEN_D_SWITCH, f->CSet)){
			this->X = locXOn;
			this->Y = locYOn;
		}
		while(true){
			//SolidObjects_Add(FFCNum(this), this->X, this->Y, this->TileWidth*16, this->TileHeight*16, this->Vx, this->Vy, 2); //Set up SolidFFCs.zh and all it`s dependencies, then uncomment this line to enable FFC solidity.
			Waitframe();
			for (int i=1; i<=MAX_FFC; i++){
				ffc c = Screen->LoadFFC(i);
				if (c==this)continue;
				if (!c->Flags[FFCF_CHANGER])continue;
				if (c->X!=this->X)continue;
				if (c->Y!=this->Y)continue;
				this->Vx=c->Vx;
				this->Vy=c->Vy;
			}
			if (SwitchState(f, this)==s)continue;
			s=SwitchState(f, this);
			if (s){
				this->Vx=VxOn;
				this->Vy=VyOn;
			}
			else{
				this->Vx=VxOff;
				this->Vy=VyOff;
			}
		}
	}
}