Jump to content
grollig

JIP / Dedi compatible Bombtimer - How to?

Recommended Posts

Hi there!
Currently im struggling with a JIP compatible bomb timer on a dedicated server for my latest TvT mission. In short: A bomb can be activated by OPFOR (addAction). BLUFOR obviously has the task do disarm the bomb (addAction). Once armed, the bomtimer runs for 45 minutes until detonation sequence is initiated.

 

What I'am trying to achieve is that a bomb timer (countdown) gets displayed for all players from the moment OPFOR activates the bomb (so it is not running from missionstart). By now I was trying to sync the displayed time left for the clients using the command "serverTime", but this doesn't seem to be accurate enough (and will only work if the server is up for at least 300 seconds, btw). On a testrun last night the displayed countdown timers for each player were differing by up to 10 seconds near the end of the mission.

 

Here is what I have until now:

 

Init.sqf

bomb_timer = 2700; // 45 minutes

if (isNil "bomb_activated") then {bomb_activated = false};
if (isNil "bomb_detonationTime") then {bomb_detonationTime = 999999};



AddAction on bomb object (starts bomb_arm.sqf locally on executing players client)

arm = this addAction ["Activate bomb", "scripts\bomb_arm.sqf",[],6,true,true,"","side _this == east && alive _target && _target distance _this < 3 && (!bomb_activated)"];

 

 

bomb_arm.sqf


private ["_aktObjekt","_aktSpieler","_aktion"];
_aktObjekt = _this select 0;
_aktSpieler = _this select 1;

// play an animation for the player arming the bomb
_aktSpieler playMove "AinvPknlMstpSlayWrflDnon_medic";
sleep 7;
waitUntil {animationState _aktSpieler != "AinvPknlMstpSlayWrflDnon_medic"};

// Before arming the bomb, check if bomb hasn't already been activated and the guy activating the bomb is still alive and not unconscious
if ((!bomb_activated) && (alive _aktSpieler) && !(_aktSpieler getVariable ["ACE_isUnconscious",false])) then
{
    bomb_activated = true;
    publicVariable "bomb_activated";
};

 

 

1st Editor placed Trigger:

Serverside, once, to run script bomb_activated.sqf

Condition: (isServer) && {bomb_activated}

On Act.: if (isServer) then {act = [] execVM "scripts\bomb_activated.sqf"};

 

 

bomb_activated.sqf:

if (isServer) then
{
    // Calculate time of detonation and make it available as global variable
    bomb_detonationTime = (serverTime + bomb_timer);
    publicVariable  "bomb_detonationTime";
    
    // Inform all players that the bomb has been activated
    [["<t size='1.2' color='#ffffff'>The Bomb has been activated!</t>",0,0.3,3,0],"BIS_fnc_dynamicText",true,false,false] call BIS_fnc_MP;
};

 

 

 

2nd Editor placed Trigger:

Clientside, once, will fire for JIP players as well

Condition: (hasInterface) && {bomb_detonationTime < 999999}

On Act.:if (hasInterface) then {nul = [] execVM "scripts\countdown.sqf"}

 

 

 

countdown.sqf


if (hasInterface) then
{
    // JIP Check
    waitUntil {!isNull player && time > 0 && (local player)};

    // calculate remaining time to detonation
    _timeleft = (bomb_detonationTime - serverTime);

    // start loop for countdowndisplay
    while {true} do
    {
        if (_timeleft <= 0) exitWith {hintSilent parseText "<t size='1.8' align='center'>- Ignition! -</t>"};
        if (bomb_disarmed) exitWith {hintSilent parseText "<t size='1.8' align='center'>- Disarmed! -</t>"};
        hintSilent parsetext format ["<t size='1.8' align='center'>Bombtimer:<br/>%1</t>",[((_timeleft)/60),"HH:MM"] call bis_fnc_timetostring];
        _timeleft = _timeleft -1;
        sleep 1;
    };
};

Share this post


Link to post
Share on other sites
/*
    Author: Revo

    Description:
    Shows a global countdown.

    Parameter(s):
        0: number
    Returns:
    countDownFinished - Only available on the server
*/

if (!isServer) exitWith {};

_countdown = param [0,60];
countdownFinished = false;

for "_i" from 1 to _countDown do
{
    _timeleft = [_countdown - _i] call BIS_fnc_secondsToString;
    [[[_timeLeft],{hintSilent format ["Time left: %1",_this select 0]}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP;
    sleep 1;
};    

countdownFinished = true;

Countdown will display for all players.

  • Like 1

Share this post


Link to post
Share on other sites

Thank you very much, R3vo!

 

After reading your first answer (before the edit) I came up with the following serverside script:

 

if (isServer) then
{
    // Prevent double execution
    if (isNil "countdownStarted") then
    {
        countdownStarted = true;
                      
        _timeleft = bomb_timer; // bomb_timer defined in init.sqf

        while {true} do
        {
            // Start detonationcam script when timer reaches 0
            if (_timeleft <= 0) exitWith {[[[],{hintSilent parseText "<t size='1.8' align='center'>- Ignition! -</t>"; [] execVM "scripts\detonationcam.sqf"}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP};
                    
            // Stop timer if bomb is disarmed
            if (bomb_disarmed) exitWith {[[[],{hintSilent parseText "<t size='1.8' align='center'>- Disarmed! -</t>"}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP};
                    
            // Run timer
            [[[_timeleft],{hintSilent parsetext format ["<t size='1.8' align='center'>Bombentimer:<br/>%1</t>",[((_this select 0)/60),'HH:MM'] call BIS_fnc_timeToString];}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP;
            _timeleft = _timeleft -1;
            sleep 1;
        };
    };
};

 

This worked well while testing locally, though the countdown may skip a second from time to time, but this is not a problem for me. So basically sending the hint to the clients per BIS_fnc_MP seems to be the key solution. Wonder if this has any noticeable impact on network traffic. Will report back after testing wirh a few players online (might take a few days, until the mission is finished).

Share this post


Link to post
Share on other sites

Looks fine so far, however, one thing I changed myself after doing my first post here, is to calculate the time which is left and converting it to a string before sending it over the network. My educated guess is, that if you don't do that, every client has to calculate that value for itself, which is unecessary.

  • Like 1

Share this post


Link to post
Share on other sites

[...] calculate the time which is left and converting it to a string before sending it over the network. [...]

 

Ah, now I see... will adapt my script accordingly and test it on our dedicated server within the next couple of days. Thanks again for your effort and for pointing me in the right direction. :)

Share this post


Link to post
Share on other sites

We did a quick test on our dedicated server with 6 connected players, and the script is working fine. The displayed countdown skips or holds a second from time to time, but the overall timeprogress seems to be linear, so that's okay for me. Most importantly, the moment the timer reaches zero is in sync for all clients, even after a very long runtime.

 

Here's my latest version of the script, using the essential parts of R3vos's approach:

if (isServer) then
{
  _countdown = bomb_timer; // bomb_timer defined in init.sqf
 
  while {true} do
  {
      if (_countdown <= 0) exitWith {[[[],{hintSilent parseText "<t size='1.8' align='center'>- Ignition! -</t>"; [] execVM "scripts\detonationcam.sqf"}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP};
      if (bomb_disarmed) exitWith {[[[],{hintSilent parseText "<t size='1.8' align='center'>- Disarmed! -</t>"}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP};
      _timeleft = [(_countdown/60),'HH:MM'] call BIS_fnc_timeToString;
      [[[_timeLeft],{hintSilent parsetext format ["<t size='1.8' align='center'>Bombtimer:<br/>%1</t>",_this select 0]}],"BIS_fnc_spawn",true] spawn BIS_fnc_MP;
      _countdown = _countdown - 1;
      sleep 1;        
  };
};

Share this post


Link to post
Share on other sites

I'm glad I could help, your script looks pretty neat. Guess the skipping of the seconds is caused by a rounding error or the sleep command being inaccurate.

Share this post


Link to post
Share on other sites

HI i use those scripts for countdown timer

 

but i have some problems with it, and i'm sure will help a lot of people here if we can fix it !

 

when someone disarm the bomb, thus the countdown timer, we cannot rearm the bomb and the timer

 

also when disarming the bomb the timer stops but the nuke goes of anyway !

 

i have a trigger with say3D sound when arming the bomb no problem the sounds goes off and the timer as well, (i use invisible helipad to play and stop the sound)

but after disarming, we cannot arm again, the sound doesn't fire, even with createVehicle again the sound doesn't play and timer doesn't show up again.

 

So to be clear, everything i have to arm the bomb, start timer and play a siren, goes of only one time !

 

How to use the functions repeatably ?

 

help me out because i can not find an answer, and tried so much things since two days, even things i don't understand what i'm doing !

 

ask me for the scripts, code or i can send you the mission file, should be easier !

 

everything needs to work for a multiplayer server !

 

thanks in advance for taking your time to help me,

 

credits, and authors will be put in the mod files !

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

×