Copy to Clipboard Test

alttimers.zh Code

///////////////////////////////////
//Alternative Timers Library v1.1//
///////////////////////////////////

//import "std.zh"
//import "string.zh"

//These constants determine timer states. Don`t change them.
const int TIMER_STATE_STOPPED = 0; //Timer is stopped
const int TIMER_STATE_COUNTING_UP = 1; //Timer is counting up
const int TIMER_STATE_COUNTING_DOWN = 2; //Timer is counting down
const int TIMER_STATE_PAUSED_COUNTUP = 3; //The timer counting up is paused
const int TIMER_STATE_HIT_ZERO = 4; //The countdown timer has just recently hit 0
const int TIMER_STATE_PAUSED_COUNTDOWN = 5; //The timer counting down is paused

//Main timer global arrays. Expand as you want. But make sure, that all 4 arrays have the same size.
int TimerSeconds[5];
int TimerFrames[5];
int TimerState[5];
//You can set any of booleans of this array to "FALSE" to prevent UpdateTimers() command from affecting specific timers.
bool GlobalTimer[5];

//Example of how the global script should be combined with other global scripts.
global script Timers{
	void run(){
		while (true){
			UpdateTimers();
			Waitdraw();
			Waitframe();
		}
	}
}

//Timers initialization routine. Put this into your "init" global script. 
void InitTimers(){
	int numtimers = SizeOfArray(TimerSeconds);
	for (int i=0; i<=numtimers; i++){
		TimerSeconds[i]=0;
		TimerFrames[i]=0;
		TimerState[i]=0;
		GlobalTimer[i]=true;
	}
}

//Main timer update function. Must be placed in before Waitdraw() command in the main loop
//of global script.
void UpdateTimers(){
	int NumTimers = SizeOfArray(TimerState);
	for (int i=0; i<NumTimers; i++){
		if (!GlobalTimer[i]) continue;
		if (TimerState[i]==TIMER_STATE_STOPPED) continue;
		if (TimerState[i]==TIMER_STATE_PAUSED_COUNTUP) continue;
		if (TimerState[i]==TIMER_STATE_PAUSED_COUNTDOWN) continue;
		if (TimerState[i]==TIMER_STATE_HIT_ZERO){
			TimerSeconds[i]=0;
			TimerFrames[i]=0;
			TimerState[i]=TIMER_STATE_STOPPED;
		}
		if (TimerState[i]==TIMER_STATE_COUNTING_UP){
			TimerFrames[i]++;
			if (TimerFrames[i]>=60){
				TimerSeconds[i]++;
				TimerFrames[i]=0;
			}
		}
		if (TimerState[i]==TIMER_STATE_COUNTING_DOWN){
			TimerFrames[i]--;
			if (TimerFrames[i]<0){
					TimerSeconds[i]--;
					TimerFrames[i]=59;
			}
			if (TimerSeconds[i]<0){
					TimerFrames[i] = 0;
					TimerSeconds[i] = 0;
					TimerState[i]=TIMER_STATE_HIT_ZERO;
			}
		}
	}
}

//Local version of timer updating. Best used in FFC scripts, if you don`t want to combine global scripts.
void UpdateTimer(int timer, int speed){
	if (TimerState[timer]==TIMER_STATE_STOPPED) return;
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTUP) return;
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTDOWN) return;
	if (TimerState[timer]==TIMER_STATE_HIT_ZERO){
		TimerSeconds[timer]=0;
		TimerFrames[timer]=0;
		TimerState[timer]=TIMER_STATE_STOPPED;
	}
	if (TimerState[timer]==TIMER_STATE_COUNTING_UP){
		TimerFrames[timer]+=speed;
		if (TimerFrames[timer]>=60){
			TimerSeconds[timer]++;
			TimerFrames[timer]=0;
		}
	}
	if (TimerState[timer]==TIMER_STATE_COUNTING_DOWN){
		TimerFrames[timer]-=speed;
		if (TimerFrames[timer]<0){
				TimerSeconds[timer]--;
				TimerFrames[timer]=59;
		}
		if (TimerSeconds[timer]<0){
				TimerFrames[timer] = 0;
				TimerSeconds[timer] = 0;
				TimerState[timer]=TIMER_STATE_HIT_ZERO;
		}
	}
}

//Sets the timer, regardless of it`s previous state.
void SetTimer (int timer, int Seconds, int Frames){
	TimerFrames[timer] = Frames;
	TimerSeconds[timer] = Seconds;
}

//Adds or removes value (seconds and fractions of seconds) from timer.
//Use negative values to reduce time. "AllowNegative" boolean, when
//set to "false" prevents timer from going into negative value.
void AddToTimer(int timer, int Seconds, int Frames, bool AllowNegatives){
	TimerFrames[timer] += Frames;
	TimerSeconds[timer] += Seconds;
	if (TimerFrames[timer]>= 60){
		while (TimerFrames[timer]>= 60){
			TimerSeconds[timer] ++;
			TimerFrames[timer] -= 60; 
		}
	}
	if (TimerFrames[timer]<= 0){
		while (TimerFrames[timer]<= 60){
			TimerSeconds[timer] --;
			TimerFrames[timer] += 60; 
		}
	}
	if (!AllowNegatives){
			if (TimerSeconds[timer]<= 0)TimerSeconds[timer] = 0;
	}
}

//Fast-forwards timer by adding or removing value/s, depending on timer state.
void FastForwardTimer(int timer, int Seconds, int Frames){
	if (TimerState[timer]==TIMER_STATE_COUNTING_UP) AddToTimer(timer, Seconds, Frames, false);
	if (TimerState[timer]==TIMER_STATE_COUNTING_DOWN) AddToTimer(timer, (-(Seconds)),(-(Frames)), false);
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTUP) AddToTimer(timer, Seconds, Frames, false);
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTDOWN) AddToTimer(timer, (-(Seconds)),(-(Frames)), false);
}

//Rewinds timer by adding or removing value/s, depending on timer state.
void RewindTimer(int timer, int Seconds, int Frames){
	if (TimerState[timer]==TIMER_STATE_COUNTING_UP) AddToTimer(timer, (-(Seconds)),(-(Frames)), false);
	if (TimerState[timer]==TIMER_STATE_COUNTING_DOWN) AddToTimer(timer, Seconds, Frames, false);
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTUP) AddToTimer(timer, (-(Seconds)),(-(Frames)), false);
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTDOWN) AddToTimer(timer, Seconds, Frames, false);
}

//Launch timer counting up. 
void StartCountingUp(int timer){
	TimerState[timer] = TIMER_STATE_COUNTING_UP;
}

//Launch timer countdown.
void StartCountingDown(int timer){
	TimerState[timer] = TIMER_STATE_COUNTING_DOWN;
}

//Pauses the given timer.
void PauseTimer(int timer){
	if (TimerState[timer]==TIMER_STATE_COUNTING_UP) TimerState[timer] = TIMER_STATE_PAUSED_COUNTUP;
	if (TimerState[timer]==TIMER_STATE_COUNTING_DOWN) TimerState[timer] = TIMER_STATE_PAUSED_COUNTDOWN;
}

//Resumes the paused timer.
void ResumeTimer(int timer){
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTUP) TimerState[timer] = TIMER_STATE_COUNTING_UP;
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTDOWN) TimerState[timer] = TIMER_STATE_COUNTING_DOWN;
}

//Stops and resets the given timer.
void StopTimer(int timer){
	TimerFrames[timer] = 0;
	TimerSeconds[timer] = 0;
	TimerState[timer] = TIMER_STATE_STOPPED;
}

//Sets countdown timer, so the desired events will be triggered instantly, as if timer hits 0.
//Just like cutting wrong wire on time bomb causing it to explode immediately.
//"detonatepaused", if set to TRUE, also allow detonation of paused timer.
void DetonateInstantly(int timer, bool detonatepaused){
	if ((TimerState[timer]==TIMER_STATE_PAUSED_COUNTDOWN)&&(!detonatepaused)) return;
	if (TimerState[timer] != TIMER_STATE_COUNTING_DOWN) return;
	TimerFrames[timer] = 0;
	TimerSeconds[timer] = 0;
}

//Use this function to prevent countdown timer from going beyond desired value.
//Just like preventing fuel tank from overfilling with added fuel.
void SetMaxCountdowntimer(int timer, int Seconds, int Frames){
	if ((TimerState[timer] != TIMER_STATE_COUNTING_DOWN)&&
		(TimerState[timer]!=TIMER_STATE_PAUSED_COUNTDOWN)) return;
	if(TimerSeconds[timer] > Seconds){
		TimerSeconds[timer] = Seconds;
		TimerFrames [timer] = Frames;
	}
	else if (TimerSeconds[timer] == Seconds){
		if (TimerFrames [timer] > Frames) TimerFrames [timer] = Frames;
	}
}

//Returns TRUE if the timer is still active (either running or paused).
bool TimerIsActive(int timer){
	if (TimerState[timer]==TIMER_STATE_STOPPED) return false;
	return true;
}

//Returns TRUE if the timer is running.
bool TimerIsRunning (int timer){
	if (TimerState[timer]==TIMER_STATE_COUNTING_UP) return true;
	if (TimerState[timer]==TIMER_STATE_COUNTING_DOWN) return true;
	return false;
}

//Returns TRUE if the timer is paused.
bool TimerIsPaused (int timer){
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTUP) return true;
	if (TimerState[timer]==TIMER_STATE_PAUSED_COUNTDOWN) return true;
	return false;
}

//Returns TRUE if timer has reached specific threshold, depending on it`s state.
bool TimerReachValue(int timer, int Seconds, int Frames){
	if (TimerState[timer]==TIMER_STATE_COUNTING_UP){
		if(TimerSeconds[timer] > Seconds) return true;
		if(TimerSeconds[timer] < Seconds) return false;
		if(TimerFrames [timer] >= Frames) return true;
		return false;
	}
	if (TimerState[timer]==TIMER_STATE_COUNTING_DOWN){
		if(TimerSeconds[timer] < Seconds) return true;
		if(TimerSeconds[timer] > Seconds) return false;
		if(TimerFrames [timer] <= Frames) return true;
		return false;
	}
	return false;
}

//Draws the given timer onto screen. Format is similar to Draw functions.
//"layer", "x", "y", "font", "color", & "opacity" arguments are similar to other drawing functions.
//"DrawFrames" boolean draws fractions of second, if TRUE
//"DrawMinutes" boolean converts timer into "mmm:ss:(ff)" format from "ssssss:(ff)".
void DrawTimer(int layer, int x, int y, int font, int color, int timer, bool drawframes, bool drawminutes, int opacity){
	int frames = TimerFrames[timer];
	int seconds = TimerSeconds[timer];
	int curseconds = seconds%60;
	int minutes = Floor(seconds/60);
	int source[24] = "%d:0%d:0%d";
	int string[256];
	if (drawframes){
		if (drawminutes){
			if (curseconds>9) remnchr(source, 3, 1);
			if (frames>9){
				int remchar = 7;
				if (curseconds>9) remchar = 6;
				remnchr(source, remchar, 1);
			}
			sprintf(string, source, minutes, curseconds, frames);
		}
		else{
			int newstr[] ="%d:0%d";
			if (frames>9) remnchr(newstr, 3, 1); 
			strcpy(source, newstr);
			sprintf(string, source, seconds, frames);
		}
	}
	else {
		if (drawminutes){
			int newstr[] ="%d:0%d";
			if (curseconds>9) remnchr(newstr, 3, 1); 
			strcpy(source, newstr);
			sprintf(string, source, minutes, curseconds);
		}
		else{
			int newstr[] ="%d"; 
			strcpy(source, newstr);
			sprintf(string, source, seconds);
		}
	}
	Screen->DrawString(layer, x, y, font, color, -1, TF_NORMAL, string, opacity);
}

//Test script. Creates generic time bomb. When timer expires, bomb explodes.
//Stepping on bomb results in an instant explosion. 
//Set the combo to look like bomb.
// D0: "Seconds" part of init timer.
// D1: "Frames" part of init timer.
// D2: Damage dealt to Link if he was too close to bomb, when it goes boom.
ffc script TimerTest{
	void run(int seconds, int frames, int damage){
		if (!TimerIsActive(0))SetTimer (0, seconds, frames);
		StartCountingDown(0);
		while (true){
			if (LinkCollision(this)) DetonateInstantly(0, true);
			if(TimerState[0]==TIMER_STATE_HIT_ZERO){ //KA-BOOM!!
				eweapon explosion = Screen->CreateEWeapon(EW_BOMBBLAST);
				explosion->X=this->X;
				explosion->Y=this->Y;
				explosion->Damage = damage;
				if (damage==0) explosion->CollDetection=false;
				this->Data=0;
				Quit();
			}
			int drawx = this->X - 16;
			int drawy = this->Y - 16;
			DrawTimer(0, drawx, drawy, 0, 1, 0, true, true, OP_OPAQUE);
			Waitframe();
		}
	}
}