
I don't know if anyone will use this, but maybe someday it'll come in handy for someone

It's always bugged me that countdown timers are run via map_update_proc (map_update_p_proc for Fallout 1) because this is called every 10 seconds by the game, roughly - but not an exact interval. It's unreliable and not steady and just a shitty way to display a continuous countdown.
So, using internal game timers I've made a much better one.
Originally I had it running under critter_proc but those checks run so often (every game tick) that it's a waste of cycles to put it in there. Instead, this runs roughly once a second as a timed event under timed_event_proc.
Concept:
Basically a global variable has been established with "current game time (in seconds) + X seconds" as its value.
"X" is the timer length for the bomb (or whatever), which will be set at some point during gameplay.
We take that and subtract the current game time (in seconds), resulting in a SecondsLeft amount (Y).
We check if the Y is divisible by five (" % 5 == 0"), and if so, print a "Seconds left: Y" message to the screen.
A flag keeps track of this to make sure the "Seconds left" message is only displayed once for each five-second period. (i.e. no duplicate messages)
- This could of course be very easily changed to update any other number of seconds, by changing the modulus (%) calculation. So you could do "if (Y % 1 == 0)" to have it display time left every second or "if (Y % 10 == 0)" to display every 10 seconds.
Example, Fallout 1:
Code:
THIS GOES IN OBJ_DUDE.SSL, UNDER "TIMED_EVENT_PROC"
if (fixed_param == 9) then begin
SecondsLeft := (global_var(147) - (game_time / 10));
if ((SecondsLeft % 5) == 0) and (SecondsFLAG == 0) then begin
SecondsFLAG := 1;
display_msg("Seconds left:" + SecondsLeft + " seconds.");
end
else begin
if (SecondsLeft % 5) then begin
SecondsFLAG := 0;
end
end
if ((global_var(147) - (game_time / 10)) == 0) then begin
play_gmovie(3);
metarule(13, 0);
end
add_timer_event(dude_obj, 10, 9);
end
end
fixed_param == 4 means "when a combat turn ends" and this code should go in obj_dude script under combat_p_proc
Code:
THIS GOES IN OBJ_DUDE.SSL, UNDER "COMBAT_PROC"
if (fixed_param == 4) then begin
if ((global_var(147) - (game_time / 10)) > 0) then begin // if there's still seconds left on the timer
variable LVar0 := 0;
LVar0 := (global_var(147) - (game_time / 10));
if ((SecondsLeft - LVar0) >= 5) then begin // if the current seconds left (during combat) is greater than the SecondsLeft value calculated before combat began
display_msg(message_str(443, 100) + LVar0 + message_str(443, 101)); // display current seconds left
end
end
else begin
play_gmovie(3);//------ Military Base goes boom and dies, sweet!
metarule(13, 0);
end
end
end
LINE-BY-LINE BREAKDOWN OF THE CODE:
Code:
This runs when the timer in question is triggered. For example when blowing up the Vats or blowing up the Oil Rig:
add_timer_event(dude_obj, 0, Z);
The following belongs in the obj_dude script file:
Code:
if (fixed_param == Z) then begin
Code:
SecondsLeft := (global_var(X) - (game_time / 10));
The global_var(X), as in 'Concept' above, should point to whatever variable is holding the countdown amount in seconds. For example if the bomb was set to detonate in 1 minute, global_var(X) should hold the value of 60 plus whatever the (game_time / 10) was when it was triggered.
"game_time / 10" is crucial as this converts from "ticks" to seconds. If you want to read the current time that's passed since the player was created, use "game_time / 10".
Code:
if ((SecondsLeft % DisplayThisOften) == 0) and (SecondsFLAG == 0) then begin
"(SecondsFLAG == 0)" checks the flag to make sure it's only displaying once per DisplayThisOften (i.e. no duplicate messages to user).
Code:
SecondsFLAG := 1;
Code:
display_msg("Seconds left:" + SecondsLeft + " seconds.");
end
Code:
else begin
Code:
if (SecondsLeft % DisplayThisOften) then begin
SecondsFLAG := 0;
end
end
Code:
if ((global_var(X) - (game_time / 10)) == 0) then begin
Code:
play_gmovie(3); // Military Base goes boom and dies, sweet!
metarule(13, 0); // Used for tracking if the game is over.
end
Code:
add_timer_event(dude_obj, Ticks, Z);
end