Jump to content
Lorenz94

Timer not stopping in MP

Recommended Posts

Hello, new user here!
I've been reading this forum for a while now, and I would like to thank you all for the great content and support you offer.

 

I started to edit a bomb script I found online, that works perfectly in SP, but that has problems in MP. I've researched a lot, here and on the Biki, but my current skills are not enough to solve the issue, so I'm asking for help here. The script is "Defuse the bomb" by cobra4v320. I've changed some names to better understand what's going on in the script, so refer to what you'll se here, please!

 

PROBLEM: The timer spawns, it shows correctly to each player (I think it is not jip capable), but when someone defuses the bomb, it continues to others, and if it reaches 0s, the bomb explodes, even if the poor guy that has defused can see the hint "defused". I've tried a lot of things, such as "isServer", "isDedicated", but what I think it's the problem is that the timer is NOT a publicVariable, and here is where I kindly need your help.

Trigger that calls the timer when a player is present:

_null = [bomb_name, 30] spawn COB_fnc_bombTimer;

 

fnc_bombTimer:

private ["_bomb", "_time","_detonated","_zapped","_KeyPadDefuse"];
_bomb = [_this, 0, objNull, [objNull]] call BIS_fnc_param;
_time = [_this, 1, 0, [0]] call BIS_fnc_param;
_KeyPadDefuse = 0; //Keypad ID

_detonated = parseText "Detonation in: <t color='#FF0000'>=DETONATED=</t>";
_zapped = parseText "<t color='#E5E500'>=ZAPPED=</t>";


disableSerialization;
while {alive _bomb && _time > 0 && !bombDefused} do {
	_time = _time - 1;
	hintSilent format ["Detonation in: \n %1", [((_time)/60)+.01,"HH:MM"] call BIS_fnc_timetostring];
	_bomb say3D ['timer_bomb',12,1];

	if (_time < 1) then {
		_blast = createVehicle ["HelicopterExploBig", position _bomb, [], 0, "NONE"];
        {
			if (_x distance _bomb <= 50) then {_x setDamage 1};
		} forEach allUnits;
        
		deleteVehicle _bomb;
		closeDialog _KeypadDefuse;
};

	if (bombArmed) then {
		_bomb say3D ['zapped_bomb',12,1];
		{
			if (_x distance _bomb <= 2.3) then {
			closeDialog _KeyPadDefuse && hintSilent _zapped && _x setDamage 1};
		} forEach allUnits;
        
		1.5 fadeSound 0.10;
		bombArmed = false; //This allows other people to try to defuse, without exploding the object
	};
	
	sleep 1; //Timer interval
	
};

What I'm trying to achieve is:

- Timer shows to everyone, if possible JIP capable;

- Timer stops to everyone when someone defuses.

 

secondary: hint "zapped" and "defused" show to everyone and would be very cool to display the name of the player who did the action!

Thank you in avance,

have a nice day :D

Share this post


Link to post
Share on other sites

The problem is that the bombDefused variable isn't transferred over the network, which means that the location where the script is executed still has the variable set to explode while only the client that defused the bomb has set the variable to "not explode". 

publicVariable "bombDefused";

might solve it. Put it where you are defusing the bomb:

// Code that defuses the bomb
bombDefused = true;
publicVariable "bombDefused";

bombArmed = false;
publicVariable "bombArmed";

https://community.bistudio.com/wiki/Variables#Global_Variables

Share this post


Link to post
Share on other sites
1 hour ago, 7erra said:

The problem is that the bombDefused variable isn't transferred over the network, which means that the location where the script is executed still has the variable set to explode while only the client that defused the bomb has set the variable to "not explode". 

 

Really thank you, it solved my problem. Now the actions are public, but what about the time? If a player joins in the middle of the countdown, what does he see? The timer starting from (in this case) 30s?

 

I've also managed how to display the player's name, now I'm stuck in how to assign damage to the scenery, too.

Thank you again!

Share this post


Link to post
Share on other sites

Timer and bomb diffusion should be managed on server only (trigger on server only)

Then, remoteExec hint and publicVariable defuse results.

 

If you let a standard trigger (not server only), you'll always have the script running (locally) on each client.

This could be "fine" for a big explosion in case of common activation like BLUFOR present, but totally weird with multiple explosions for some local condition like (player in thisList), and not what you need with JIP anyway.

Share this post


Link to post
Share on other sites
2 minutes ago, pierremgi said:

Timer and bomb diffusion should be managed on server only (trigger on server only) Then, remoteExec hint and publicVariable defuse results.

If you let a standard trigger, you'll always have the script running (locally) on each client (could be fine for a big explosion but not what you need).

Thank you for your reply.

 

I understand this, but I don't know how to do this. I've tried to use remoteExec, but no luck. Is there any chance you can be more precise, please?

Share this post


Link to post
Share on other sites

First of all, what is your trigger?

On server only trigger, should be something like BLUFOR present and condition this && isPlayer (thisList select 0)  // for example

or

with a standard trigger, wrap the code if (isServer) then {<code>} .

Share this post


Link to post
Share on other sites
7 minutes ago, pierremgi said:

First of all, what is your trigger?

On server only trigger, should be something like BLUFOR present and condition this && isPlayer (thisList select 0)  // for example

or

with a standard trigger, wrap the code if (isServer) then {<code>} .

 

The trigger is as big as the island in which I'm planning the mission, and it is set: "None", "Blufor", "Present". Condition is "this" and on act: _null = [name-of-bomb, 30] spawn COB_fnc_bombTimer;

And the fnc is written right above! Thank you.

Share this post


Link to post
Share on other sites

I guess your are just running a code (trigger always true). Btw, you just have to place a trigger without area and write <true> instead of <this> in condition.

Make it server only,

change:

hintSilent format ["Detonation in: \n %1", [((_time)/60)+.01,"HH:MM"] call BIS_fnc_timetostring];

for:

format ["Detonation in: \n %1", [((_time)/60)+.01,"HH:MM"] call BIS_fnc_timetostring] remoteExec ["hintSilent"]; // not JIP  test ["hintSilent",0,true] for JIP

 

Same for say3D if you want this info on all players.

 

But a remark: I don't really understand why you are scripting like this: true trigger then distance condition, then a closeDialog and no dialog; I guess there is some other code.

Your problem anyway.

 

 

 

 

 

Share this post


Link to post
Share on other sites
3 hours ago, pierremgi said:

I guess your are just running a code (trigger always true). Btw, you just have to place a trigger without area and write <true> instead of <this> in condition.

Make it server only,

change:

hintSilent format ["Detonation in: \n %1", [((_time)/60)+.01,"HH:MM"] call BIS_fnc_timetostring];

for:

format ["Detonation in: \n %1", [((_time)/60)+.01,"HH:MM"] call BIS_fnc_timetostring] remoteExec ["hintSilent"]; // not JIP  test ["hintSilent",0,true] for JIP

 

Same for say3D if you want this info on all players.

 

But a remark: I don't really understand why you are scripting like this: true trigger then distance condition, then a closeDialog and no dialog; I guess there is some other code.

Your problem anyway.

 

 

 

 

 

Here I am! I've just tested the code you suggested to be JIP capable, but now the timer doesn't start at all.

The script is this "weird" because I want the coutdown to be activated at mission start, I want that if you input the wrong code only the guy who has tried to defuse the bomb dies, while if the timer reaches 0s everybody die in that defined range. Feel free to ask more info, if you need them!

Thank you again, but still no luck ;(

Share this post


Link to post
Share on other sites
On 29/7/2017 at 5:48 PM, pierremgi said:

...

 

 

 

 

 

Hello again!
Your suggestion is working in SP, but when I try it on a server (with loopback, for instance), the timer doesn't spawn AT ALL.

I think it's an "initialization" issue, since eveything works ok out of a server.

I tried to spawn the timer from initServer (instead of using a trigger) with _null = [bomb, 30] spawn COB_fnc_bombTimer and I also tried to change the fnc to an sqf file to execVM or remoteExec it, but still no luck.

I also tried to use 2 instead of 0 in remoteExec, but no differences!!

Any help woul be appreciated, since I have finished my ideas.. Thank you!

Share this post


Link to post
Share on other sites

in init.sqf, you have to:

[bomb, 30] execVM "COB_fnc_bombTimer.sqf" ; // if this sqf exists of course

or

COB_fnc_bombTimer = { < your code here >};

[bomb, 30] spawn COB_fnc_bombTimer ;

 

Just let see what you're doing with that.

Check also.... && !bombDefused

No idea if this variable is defined so far.

Share this post


Link to post
Share on other sites
5 hours ago, pierremgi said:

in init.sqf, you have to:

[bomb, 30] execVM "COB_fnc_bombTimer.sqf" ; // if this sqf exists of course

or

COB_fnc_bombTimer = { < your code here >};

[bomb, 30] spawn COB_fnc_bombTimer ;

 

Just let see what you're doing with that.

Check also.... && !bombDefused

No idea if this variable is defined so far.

This is exactly what I'm doing. A quick resume:

initServer.sqf: (not init.sqf because the timer will start at different times for different players because of different mission loading time, correct?)
_null = [] execVM "defuse_ini.sqf"; --> defines all variables such as bombDefused, inputCode etc
_null = [bomb, 30] execVM "COB_fnc_bombTimer.sqf"; --> the timer it self

 


The sqf has been created, of course, and all variable are defined in the "defuse_ini.sqf", called at the beginning of the mission with the timerBomb sqf (before the timer, of course!)

In single player or hosted MP everything is fine, but when loaded on a dedicated, the timer doesn't activate at all. I also integrated the "add action" to the object to defuse inside the timerBomb.sqf, so that the action is available only when the timer is active and disappears when defused and I can't see even the action! Seems like the timer is not loaded at all and I can't figure out why.

Hoping to have explained it better, I thank you for your patience!

EDIT: if I put defuse_ini.sqf and bombTimer.sqf in init.sqf (so not the initServer), the timer works, but is different for players. The addaction spawns correctly with the timer, disappears when someone defuses the bomb, but the timer is still running for other people. I Can't understand why the code doesn't work if ran it from initServer.

Share this post


Link to post
Share on other sites

addAction? there is no workable addAction on dedicated server.

You need to remoteExec it also on local player or place it in init.sqf (+ hasInterface) / initPlayerLocal.sqf.

player (locally) addAction >> run a script on server (timer on server) >> broadcast the timer (every players)

Share this post


Link to post
Share on other sites
3 hours ago, pierremgi said:

addAction? there is no workable addAction on dedicated server.

You need to remoteExec it also on local player or place it in init.sqf (+ hasInterface) / initPlayerLocal.sqf.

player (locally) addAction >> run a script on server (timer on server) >> broadcast the timer (every players)

Moved add action back to the object's ini and works fine.

The timer still not work in sync between different players. I have tried both your suggestion (with and without JIP), but the timer doesn't start at all if I:

- spawn it from the trigger (both as you suggested and like I was doing before your hint);

- start it from initServer calling it with execVM;

 

It starts only if I call it from "normal" init.sqf, but then, even with your correction for MP, the timer is different for each player and global variable such as bomb status (defused or exploded) are not broadcasted. This means that the bomb is defused for the player who matches the code, he sees the hint "defused", but the timer then continues for other players, and if it reaches 0, the bomb is triggered.

I'm pasting here the updated code, that as I said previously, works perfect in hosted MP or SP:
 

Spoiler

_pcToHack = _this select 0;
_timerTime = _this select 1;
_KeyPad = 0; //ID
_triggered = parseText "Detonation in: <t color='#FF0000'>=TRIGGERED=</t>";
_zapped = parseText "You've been <t color='#E5E500'>=ZAPPED=</t>";
disableSerialization;


while {_timerTime > 0 && !bombDefused} do {
	_timerTime = _timerTime - 1;
	hintSilent format ["Detonation in: \n %1", [((_timerTime)/60)+.01, "HH:MM"] call BIS_fnc_timetostring] remoteExec ["hintSilent", 0, true];
	_pcToHack say3D ['timer_chip', 20, 0.98];

	if (_timerTime < 1) then {
		closeDialog _KeyPad;
		hintSilent _triggered;
		_blast = createVehicle ["M_NLAW_AT_F", position player, [], 0, "NONE"];
		
	};
	if (bombArmed) then {
		_pcToHack say3D ['zapped_chip',18,1.10];
		closeDialog _KeyPad;
			{
				if (_x distance _pcToHack <= 2.4) then {
					hintSilent _zapped && _x setDamage 1};
			} forEach allUnits;
		bombArmed = false; //Allows other to try
		publicVariable "bombArmed";
	};
	sleep 1;
};

 

variables are defined in a separated sqf called "defuse_ini", called from initServer.

Variables are: bombDefused = false; bombArmed = false;

Is the situation more clear now? Thank you

Share this post


Link to post
Share on other sites

Variables are: bombDefused = false; bombArmed = false

publicVariable in your defuse_ini.sqf ?

Share this post


Link to post
Share on other sites
2 minutes ago, pierremgi said:

Variables are: bombDefused = false; bombArmed = false

publicVariable in your defuse_ini.sqf ?

I have set no publicVariables in there. I set the publicVariable "bombArmed" in the timer' sqf in the last "if" sentence in the script as you can see. I set it there because my idea is to kill the player who inputs the wrong code, but to keep the bomb defusable for others.
 

The problem is in there? defuse_ini contains as follows:

inputCode = [];
defuseCode = [(round(random 9)),(round(random 9)),(round(random 9)),(round(random 9))];
bombDefused = false; //True if InputCode is equal to random defuseCode
bombArmed = false; //True at 0s (or when InputCode is wrong --> player gets zapped)

 

Share this post


Link to post
Share on other sites

If you need to broadcast (public) variables, for any reason, you need to do that from their initialization.

At this time, I don't have a clear understanding on how all your codes work, when, for what. Sorry. I can't help more.

 

 

Share this post


Link to post
Share on other sites
Just now, pierremgi said:

If you need to broadcast (public) variables, for any reason, you need to do that from their initialization.

At this time, I don't have a clear understanding on how all your codes work, when, for what. Sorry. I can't help more.

 

 

Thank you anyway!

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

×