Jump to content
Sign in to follow this  
resistance-rat

Simple CountDown script

Recommended Posts

Hi.

I have made a new (as usual) simple script that countdowning the time.

Script is included in the example mission. Mission include two scripts.

countdown.sqs main script and hint.sqs showing the time in hint.

CountDown script v1.00

Screenshot

countdownpic.th.jpg

countdown.sqs

[] exec "hint.sqs"
time_0 = 9
time_1 = 5
time_2 = 1


#timeloop
time_0 = time_0 - 1
? time_0 == -1 : time_1 = time_1 - 1; time_0 = 9 
? (time_1 == 0) and (time_0 == 0) : time_2 = time_2 - 1; time_1 = 5; time_0 = 9 
~1
goto "timeloop"

hint.sqs

#loop
hintSilent format ["Reinforcements arrive: %1:%2%3", time_2, time_1, time_0]
? (time_2 < 0) : goto "end"
~0.1
goto "loop"

#end
hintSilent "Reinforcements arriving..."
exit

Edited by resistance-rat

Share this post


Link to post
Share on other sites

maybe you can just copy and paste the script?

I think you'll get more answers that way:)

Share this post


Link to post
Share on other sites

MP compatible now (at least i hope)

//nul = [951, "Reinforcements arrive:", "Reinforcements arriving..."] execVM "timer.sqf"

private ["_remaining", "_ref", "_timer", "_msg1", "_msg2"];
_timer = _this select 0;
_msg1 = _this select 1;
_msg2 = _this select 2;
_ref = time;
"glt_timerMsg" addPublicVariableEventHandler {[] call glt_showCountdown};
if (isnil "glt_timeFormat") then {
glt_timeFormat = {
	private ["_hours", "_minutes", "_seconds"];
	_hours = 0;
	_minutes = 0;
	_seconds = 0;
	_seconds = _this;
	if (_seconds > 59) then {
		_minutes = floor (_seconds / 60);
		_seconds = _seconds - (_minutes * 60);
	};
	if (_minutes > 59) then {
		_hours = floor (_minutes / 60);
		_minutes = _minutes - (_hours * 60);
	};
	if (_seconds < 10) then {
		_seconds = format ["0%1", _seconds];
	};
	if (_minutes < 10) then {
		_minutes = format ["0%1", _minutes];
	};
	[_hours, _minutes, _seconds]
};
};

if (isnil "glt_showCountdown") then {
glt_showCountdown = {
	hintsilent glt_TimerMsg;
};
};

if (isServer) then {
while {_timer > 0} do {
	_remaining = _timer call glt_timeFormat;
	glt_timerMsg = format ["%1\n\n%2:%3:%4",_msg1, (_remaining select 0), (_remaining select 1), (_remaining select 2)];
	publicVariable "glt_timerMsg";
	if (local player) then {[] call glt_showCountdown};
	_timer = _timer - 1;
	sleep 1;
};
};
glt_timerMsg = _msg2;
publicVariable "glt_timerMsg";
if (local player) then {[] call glt_showCountdown};

Some thoughts about your version, if you don't mind.

Don't use sqs anymore. It is outdated, sqf is better for the prformance and a few other reasons. Just don't use it anymore.

Your countdown.sqs has no exit condition, it will run forever, even if the time has elapsed. This is an absolutely no-go. There shouldn't be any scripts runnin without reason.

Why making 2 scripts? Would fit into one perfectly.

MP compatibility is...well...bad. Although they run on all clients, depending on client machines they might go out of sync. Better to have the timer runnin on server only and broadcasting the elapsed time to the clients.

Do not "hardcode" variables into the script if they're meant to be user-editable. In your script, mainly the countdown time but also the text. Compare with my version.

Oh, and please, do not use sqs anymore.

Edited by [FRL]Myke

Share this post


Link to post
Share on other sites

@resistance-rat

You should have reworked your scripts according to the points i've listed before submitting it to armaholic.

Share this post


Link to post
Share on other sites
Myke;1647722']MP compatible now (at least i hope)

//nul = [951, "Reinforcements arrive:", "Reinforcements arriving..."] execVM "timer.sqf"

private ["_remaining", "_ref", "_timer", "_msg1", "_msg2"];
_timer = _this select 0;
_msg1 = _this select 1;
_msg2 = _this select 2;
_ref = time;
"glt_timerMsg" addPublicVariableEventHandler {[] call glt_showCountdown};
if (isnil "glt_timeFormat") then {
glt_timeFormat = {
	private ["_hours", "_minutes", "_seconds"];
	_hours = 0;
	_minutes = 0;
	_seconds = 0;
	_seconds = _this;
	if (_seconds > 59) then {
		_minutes = floor (_seconds / 60);
		_seconds = _seconds - (_minutes * 60);
	};
	if (_minutes > 59) then {
		_hours = floor (_minutes / 60);
		_minutes = _minutes - (_hours * 60);
	};
	if (_seconds < 10) then {
		_seconds = format ["0%1", _seconds];
	};
	if (_minutes < 10) then {
		_minutes = format ["0%1", _minutes];
	};
	[_hours, _minutes, _seconds]
};
};

if (isnil "glt_showCountdown") then {
glt_showCountdown = {
	hintsilent glt_TimerMsg;
};
};

if (isServer) then {
while {_timer > 0} do {
	_remaining = _timer call glt_timeFormat;
	glt_timerMsg = format ["%1\n\n%2:%3:%4",_msg1, (_remaining select 0), (_remaining select 1), (_remaining select 2)];
	publicVariable "glt_timerMsg";
	if (local player) then {[] call glt_showCountdown};
	_timer = _timer - 1;
	sleep 1;
};
};
glt_timerMsg = _msg2;
publicVariable "glt_timerMsg";
if (local player) then {[] call glt_showCountdown};

Some thoughts about your version' date=' if you don't mind.

Don't use sqs anymore. It is outdated, sqf is better for the prformance and a few other reasons. Just don't use it anymore.

Your countdown.sqs has no exit condition, it will run forever, even if the time has elapsed. This is an absolutely no-go. There shouldn't be any scripts runnin without reason.

Why making 2 scripts? Would fit into one perfectly.

MP compatibility is...well...bad. Although they run on all clients, depending on client machines they might go out of sync. Better to have the timer runnin on server only and broadcasting the elapsed time to the clients.

Do not "hardcode" variables into the script if they're meant to be user-editable. In your script, mainly the countdown time but also the text. Compare with my version.

Oh, and please, do not use sqs anymore.[/quote']

Thanks Myke, just what I was looking for.

But how do I have it output how much time is left? I'd like to be able to say things like "cutText ["One Minute Remaining","PLAIN",2];" when obviously only one minute remains on the countdown, etc.

Or at least change variables at certain amounts of time left, such as "OneMinute = 1;" which I could use to script the pre-countdown-finish commands.

Cheers.

Share this post


Link to post
Share on other sites

Anyone got any ideas? Is there a way to extract the time left on the countdown for use in other scripts at the same time, triggers, etc?

Cheers.

Share this post


Link to post
Share on other sites

I've tried this to solve my issue, with the selection in bold being my addition to Myke's script:

In Trigger:

xhandler = [30, "Extraction:", "Extraction imminent..."] execVM "Timer_Modified.sqf"

Timer_Modified.sqf:

private ["_remaining", "_ref", "_timer", "_msg1", "_msg2"];

_timer = _this select 0;

_msg1 = _this select 1;

_msg2 = _this select 2;

_ref = time;

"glt_timerMsg" addPublicVariableEventHandler {[] call glt_showCountdown};

if (isnil "glt_timeFormat") then {

glt_timeFormat = {

private ["_hours", "_minutes", "_seconds"];

_hours = 0;

_minutes = 0;

_seconds = 0;

_seconds = _this;

if (_seconds > 59) then {

_minutes = floor (_seconds / 60);

_seconds = _seconds - (_minutes * 60);

};

if (_minutes > 59) then {

_hours = floor (_minutes / 60);

_minutes = _minutes - (_hours * 60);

};

if (_seconds < 10) then {

_seconds = format ["0%1", _seconds];

};

if (_minutes < 10) then {

_minutes = format ["0%1", _minutes];

};

[_hours, _minutes, _seconds]

};

};

if (isnil "glt_showCountdown") then {

glt_showCountdown = {

hintsilent glt_TimerMsg;

};

};

if (isServer) then {

while {_timer > 0} do {

_remaining = _timer call glt_timeFormat;

if (_timer == 25) then hint "25 seconds remaining";

glt_timerMsg = format ["%1\n\n%2:%3:%4",_msg1, (_remaining select 0), (_remaining select 1), (_remaining select 2)];

publicVariable "glt_timerMsg";

if (local player) then {[] call glt_showCountdown};

_timer = _timer - 1;

sleep 1;

};

};

glt_timerMsg = _msg2;

publicVariable "glt_timerMsg";

if (local player) then {[] call glt_showCountdown};

It's meant to be able to throw out hints, or, instead of one, a variable change (such as 25secvar = 1, which I can use to launch other scripts).

Nothing happens at the 25 second mark, though?

Share this post


Link to post
Share on other sites

Wouldnt it be simpler to do something similar to this:

Gamelogic "timer1", init: [this,20,"Shit happens!"] execVM "timer.sqf"

_timerlogic = _this select 0;
_timer = _this select 1;
_alarmtext = _this select 2;
_alarm = time + _timer;
_timerlogic setVariable ["timer",_timer];

if (local player) then {
   while (time <= _alarm) do {
      _timerlogic setVariable ["timer",(_alarm - time)];
      hintSilent format ["timer: %1",_timerlogic getVariable "timer"];
      sleep 1;
     }
    hintSilent _alarmtext;
  }
}

Does not take into account minutes and hours. Setvariable means that any script can get the timer. Completely untested, just wrote it up in a couple of mins so I have no idea if it really works, lol. If one want functions only for the server (spawning units, whatnot) then of course it can run on the server instead and simply spit out the timer to the client by setting setVariable network send to true.

Edited by Murklor

Share this post


Link to post
Share on other sites
Wouldnt it be simpler to do something similar to this:

Gamelogic "timer1", init: [this,20,"Shit happens!"] execVM "timer.sqf"

_timerlogic = _this select 0;
_timer = _this select 1;
_alarmtext = _this select 2;
_alarm = time + _timer;
_timerlogic setVariable ["timer",_timer];

if (local player) then {
   while (time <= _alarm) do {
      _timerlogic setVariable ["timer",(_alarm - time)];
      hintSilent format ["timer: %1",_timerlogic getVariable "timer"];
      sleep 1;
     }
    hintSilent _alarmtext;
  }
}

Does not take into account minutes and hours. Setvariable means that any script can get the timer. Completely untested, just wrote it up in a couple of mins so I have no idea if it really works, lol. If one want functions only for the server (spawning units, whatnot) then of course it can run on the server instead and simply spit out the timer to the client by setting setVariable network send to true.

How does one run this only on the server, where I can run functions (such as spawning units), but spit out the actual time left to clients? I know you sorta instructed how but I'm not 100%.

Cheers.

Share this post


Link to post
Share on other sites

[b]if !isserver exitwith {};[/b]
_timerlogic = _this select 0;
_timer = _this select 1;
_alarmtext = _this select 2;
_alarm = time + _timer;
_timerlogic setVariable ["timer",_timer[b],true[/b]];

if (local player) then {
   while (time <= _alarm) do {
      _timerlogic setVariable ["timer",(_alarm - time)[b],true[/b]];
      hintSilent format ["timer: %1",_timerlogic getVariable "timer"];
      sleep 1;
     }
    hintSilent _alarmtext;
  }
}

On clients:

timer1 getvariable "timer"

Share this post


Link to post
Share on other sites

Says missing ';' on line 14.

Anyway, how do I implement "timer1 getvariable "timer"" for a client?

Cheers.

EDIT: And line 13 too.

Share this post


Link to post
Share on other sites

Oh, blame Murklor, he used while () instead of while {}. :P

currentTime = timer1 getvariable "timer";

Then you can do whatever you want with the time.

For example, something like this:

[] spawn {
 while {sleep 1; _curTime = timer1 getvariable "timer"; _curTime > 0} do {
   hintsilent format ["Time left: %1",_curTime];
 };
};

Share this post


Link to post
Share on other sites

Cheers so far, mate!

There were a few issues; the ending of the script blocks were missing semi-colons, and there was an extra '};' at the end. Final looks like:

_timerlogic = _this select 0;

_timer = _this select 1;

_alarmtext = _this select 2;

_alarm = time + _timer;

_timerlogic setVariable ["timer",_timer];

if (local player) then {

while {time <= _alarm} do {

_timerlogic setVariable ["timer",(_alarm - time)];

hintSilent format ["timer: %1",_timerlogic getVariable "timer"];

sleep 1;

};

hintSilent _alarmtext;

};

I was wondering a few things; your example doesn't make sense to me, for one... but also, how could I influence the timer count via a parameter? Ie. the countdown controls mission time; at the end of the countdown mission ends.

And one more thing - how do I change it so it doesn't give xx.xx seconds? The decimal point looks weird. Just a whole number would be better I thought...

Share this post


Link to post
Share on other sites

BTW: You guys might be interested in BIS_fnc_timeToString function ;)

Share this post


Link to post
Share on other sites

Ooh, might be interesting for future reference, thanks Gaia...

Also, to add to my list of earlier questions, here;

I was wondering a few things; your example doesn't make sense to me, for one... but also, how could I influence the timer count via a parameter? Ie. the countdown controls mission time; at the end of the countdown mission ends.

And one more thing - how do I change it so it doesn't give xx.xx seconds? The decimal point looks weird. Just a whole number would be better I thought...

How do I correctly display the timer for clients? Shk, I'm trying with your code "currentTime = timer1 getvariable "timer";" but I don't understand how to use it.

Cheers.

Share this post


Link to post
Share on other sites

Hi,

i currently use this small timer script in SP:

timer.sqs:

_timer = _this select 0;
#Start
if  (out==0) then {goto "exit1"};
~1
_timer = _timer -1;
HintSilent format["%1 Seconds remaining", _timer];
if (_timer >= 1) then {goto "Start"} else {};
#exit1
HintSilent "";
exit;

It works well but is not MP compatible. What do i need to do to make it Mp compatible ?

The hint showing the time left should be visible for all human players in a Team vs. Team mission.

Share this post


Link to post
Share on other sites

I need one and I used the scripts from post 1 and 17. But both give me error 7. Anyone knows whats up with that?

Need one for SP...

Share this post


Link to post
Share on other sites

Need one for SP...

Just use Mykes script from post 3....it works fine in SP as well.

Share this post


Link to post
Share on other sites

Yes that script works fine on SP and MP but not on a dedi :( so if anyone can get a timer working on a dedi that would be good have tried a lot but none work :(

Share this post


Link to post
Share on other sites

Hmm, so you just want a simple hint with a timer counting down from a given number? Works anywhere you start it, but of course it's kind of silly to show hints on dedi.

// Usage: nul = 20 execvm "timer.sqf"

private ["_t","_min","_sec","_msec"];

_t = _this * 60;

while {_t > 0} do {
 _min = floor (_t / 60);
 _sec = floor (_t mod 60);

 _min = (if (_min <= 9) then {"0"} else {""}) + str _min;
 _sec = (if (_sec <= 9) then {"0"} else {""}) + str _sec;

 hintsilent format["%1:%2",_min,_sec];

 _t = _t - 1;
 sleep 1;
};

Share this post


Link to post
Share on other sites

I just need a timmer that starts about 30 sec after bluefor enter a trigger and counts down from 25 Min and that to be displayed to all players on a Dedi so we all get the same time as it is part of a mission - not worried about JIP.

Have tride a lot but for some reason they do not seem to work on a dedi in MP no problem it allways works.

I was using this but does not work on dedi in MP works evey time when i test and even if i play on a dedi on my own but as soon as i get a squad it never works !

//nul = [951, "Reinforcements arrive:", "Reinforcements arriving..."] execVM "timerhold.sqf"
private ["_remaining", "_ref", "_timer", "_msg1", "_msg2"];
_timer = _this select 0;
_msg1 = _this select 1;
_msg2 = _this select 2;
_ref = time;
"glt_timerMsg" addPublicVariableEventHandler {[] call glt_showCountdown};
if (isnil "glt_timeFormat") then {
glt_timeFormat = {
	private ["_hours", "_minutes", "_seconds"];
	_hours = 0;
	_minutes = 0;
	_seconds = 0;
	_seconds = _this;
	if (_seconds > 59) then {
		_minutes = floor (_seconds / 60);
		_seconds = _seconds - (_minutes * 60);
	};
	if (_minutes > 59) then {
		_hours = floor (_minutes / 60);
		_minutes = _minutes - (_hours * 60);
	};
	if (_seconds < 10) then {
		_seconds = format ["0%1", _seconds];
	};
	if (_minutes < 10) then {
		_minutes = format ["0%1", _minutes];
	};
	[_hours, _minutes, _seconds]
};
};

if (isnil "glt_showCountdown") then {
glt_showCountdown = {
	hintsilent glt_TimerMsg;
};
};

if (isServer) then {
while {_timer > 0 && psholdtimer } do {
	_remaining = _timer call glt_timeFormat;
	glt_timerMsg = format ["%1\n\n%2:%3:%4",_msg1, (_remaining select 0), (_remaining select 1), (_remaining select 2)];
	publicVariable "glt_timerMsg";
	if (local player) then {[] call glt_showCountdown};
	_timer = _timer - 1;
	sleep 1;
};
};
glt_timerMsg = _msg2;
publicVariable "glt_timerMsg";
if (local player) then {[] call glt_showCountdown};
timerholdDone = true;

Ill give your one a go let you know how i get on

Share this post


Link to post
Share on other sites

To make sure it's started for everyone, you could do a double trigger like this (didnt test):

Trigger 1:

cond: west present

onact: if isserver then {TimerStartTime = time;publicvariable "TimerStartTime"}

Trigger 2:

cond: time > (TimerStartTime + 30)

onact: if !isdedicated then {nul = 25 execvm "timer.sqf"}

Of course, it should work with just one blufor present trigger.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×