Jump to content
MoaB

strange script behaviour

Recommended Posts

I have the following problem:

 

I have written a script that "infects" a player when he enters a trigger unless he has a certain helmet.

_targets = _this select 0;
_mask = false;

if (isdedicated) exitwith {};


{
	if (headgear _x == "H_PilotHelmetFighter_B") exitwith  {
		_mask = true;
		hint str _mask
	};
} forEach _targets;

sleep 5;

{
	if (_mask) exitWith {hint "Glück gehabt!"};
	hint "Du bist infiziert!";
	while {alive _x} do {
		_x setdammage ((getdammage _x)+0.5);
		enableCamShake true;
		addCamShake [8, 5, 10];
		sleep 10;
	};
} forEach _targets;

The sript is called in the onAct. field of the trigger with: nul = [thisList] execVM "script.sqf"

 

However when I enter the trigger everybody gets the hint and the camshake. Furthermore if any player, even outside the trigger, wears the helmet, the script terminates on all clients.

 

Could sombody help me? I'm new to scripting.

Share this post


Link to post
Share on other sites

I'd do this differently.

 

Have two variables on each player, moab_hasHelmet and moab_inTheShit.

 

As they take off or put on the helmet toggle the hasHelmet variable.

 

All the trigger should do is set inTheShit variable on the player, or just everyone in the area each time it goes off to make things simple.

 

Then separately have a script running on the player looping and every 10 seconds checking if the player has intheShit true or not.  If it's true, but the hasHelmet is true as well, we're all good, sleep some more.  If however inTheShit is true but hasHelmet is false... start choking.  

 

Might drop the 0.5 down to something that won't kill in 2 hits though. :)

Share this post


Link to post
Share on other sites

This solution is way over my head. How do I give a player a variable and how do I get the trigger to set it?

 

Edit: I'm sorry, I'm very new to scripting. The 0.5 was set only to test the script. It'll kill much slower when actually used.

Share this post


Link to post
Share on other sites

Thank you for your help!

 

Just so I understand this: This creates the two variables for every player, regardless of the name I've given that unit and changes them independently? (MP compatible?).

 

Is it possible to put something like this in the trigger onDeAct:

{ _x setVariable ["moab_inTheShit", false, true] } forEach thisList;

...so the player only get's infected as long as he is in the trigger without the helmet?

 

On second thought to do this I'd have to create a third variable "moab_infected" which get's set to true when the other variables are true and then deal the damage while "moab_infected" is true...right?

 

Thanks in advance for your reply.

Share this post


Link to post
Share on other sites

Is it possible to put something like this in the trigger onDeAct:

 

New method, even easier!  Just place down triggers or area markers wherever you want the zones and name each one. No need for settings or anything.

 

Then fill in those names in the _zones array at the top of this script:

player setVariable ["moab_hasHelmet", false];

_zones = [moab_zoneOne, moab_zoneTwo, moab_zoneThree, "moab_zoneFour"];

player addEventHandler ["InventoryClosed", {

	if (headgear player == "H_PilotHelmetFighter_B") then {
		player setVariable ["moab_hasHelmet", true];
	} else {
		player setVariable ["moab_hasHelmet", false];
	};
		
}];

while {alive player} do {
	
	if ({player inArea _x} count _zones > 0) then {
		if (player getVariable "moab_hasHelmet") then {
			// Helmet is on
			hint "Glück gehabt!"
		} else {
			// Helmet isn't on
			hint "Du bist infiziert!";
			player setDamage ((damage player) + 0.5);
			enableCamShake true;
			addCamShake [8, 5, 10];
		};
	};
	
	sleep 10;
};

In this example, moab_zoneOne, Two and Three are Triggers while "moab_zoneFour" was a Marker.  Markers need to be Strings (with " ") while Triggers are Objects so no " ".

Share this post


Link to post
Share on other sites

Thank you, I really appreciate your help and I'm learning a lot here.

 

It isn't exactly what I wanted to do though. I want the player to get infected when entering the area. Once the player is infected the damage should be dealt even if he left the area (yes I'm cruel and want to punish people for not being cautious :D )

 

I imagine this could be done with another variable "moab_isInfected" which get's set to "true" when "moab_hasHelmet" is "false" while the player is inside an area. Then another while-loop deals the damage while "moab_isInfected" is true:

player setVariable ["moab_hasHelmet", false];
player setVariable ["moab_isInfected", false];

_zones = [moab_zoneOne, moab_zoneTwo, moab_zoneThree, "moab_zoneFour"];

player addEventHandler ["InventoryClosed", {

	if (headgear player == "H_PilotHelmetFighter_B") then {
		player setVariable ["moab_hasHelmet", true];
	} else {
		player setVariable ["moab_hasHelmet", false];
	};
		
}];

while {alive player} do {
	
	if ({player inArea _x} count _zones > 0) then {
		if (player getVariable "moab_hasHelmet") then {
			// Helmet is on
			hint "Glück gehabt!"
		} else {
			// Helmet isn't on
			hint "Du bist infiziert!";
                        player setVariable ["moab_isInfected",true];
		};
	};
	while {player getVariable "moab_isInfected"} do {
			player setDamage ((damage player) + 0.1);
			enableCamShake true;
			addCamShake [8, 5, 10];
                        sleep 10;
        };
	sleep 10;
};

Share this post


Link to post
Share on other sites

Thank you for that recommendation.

Share this post


Link to post
Share on other sites

 

Thank you, I really appreciate your help and I'm learning a lot here.

 

It isn't exactly what I wanted to do though. I want the player to get infected when entering the area. Once the player is infected the damage should be dealt even if he left the area (yes I'm cruel and want to punish people for not being cautious :D )

 

I imagine this could be done with another variable "moab_isInfected" which get's set to "true" when "moab_hasHelmet" is "false" while the player is inside an area. Then another while-loop deals the damage while "moab_isInfected" is true:

player setVariable ["moab_hasHelmet", false];
player setVariable ["moab_isInfected", false];

_zones = [moab_zoneOne, moab_zoneTwo, moab_zoneThree, "moab_zoneFour"];

player addEventHandler ["InventoryClosed", {

	if (headgear player == "H_PilotHelmetFighter_B") then {
		player setVariable ["moab_hasHelmet", true];
	} else {
		player setVariable ["moab_hasHelmet", false];
	};
		
}];

while {alive player} do {
	
	if ({player inArea _x} count _zones > 0) then {
		if (player getVariable "moab_hasHelmet") then {
			// Helmet is on
			hint "Glück gehabt!"
		} else {
			// Helmet isn't on
			hint "Du bist infiziert!";
                        player setVariable ["moab_isInfected",true];
		};
	};
	while {player getVariable "moab_isInfected"} do {
			player setDamage ((damage player) + 0.1);
			enableCamShake true;
			addCamShake [8, 5, 10];
                        sleep 10;
        };
	sleep 10;
};

 

If it's once infected you're always infected you can swap your while for an if:

while {alive player} do {
		
	if (player getVariable ["moab_isInfected", false]) then {
		player setDamage ((damage player) + 0.1);
		enableCamShake true;
		addCamShake [8, 5, 10];
    } else {
		if ({player inArea _x} count _zones > 0) then {
			if (player getVariable ["moab_hasHelmet", false]) then {
				// Helmet is on
				hint "Glück gehabt!"
			} else {
				// Helmet isn't on
				hint "Du bist infiziert!";
                player setVariable ["moab_isInfected",true];
			};
		};
	};
	
	sleep 10;
};

I would recommend defining a default value when using getVariable, as it returns Any otherwise and that may lead to unexpected errors. So use player getVariable ["moab_isInfected",false] instead, same with the helmet. https://community.bistudio.com/wiki/getVariable

 

The first thing the script does is set that variable, so I skipped that defaulting since I assume it already has a value.  Mostly since seeing "false" every time you're testing for "true" is jarring. :)

Share this post


Link to post
Share on other sites

Thanks again for the help. I'll test it as soon as I get tom my computer :)

Share this post


Link to post
Share on other sites

Okay, when testing the following error occurs: _x not defined variable in expression: if ({player inArea _x} count _zones > 0) then

 

Not sure what the variable _x does

 

Edit: Never mind, I had non defined zones in the _zones array :-D

Share this post


Link to post
Share on other sites

_x is a "magic variable".  You'll see it within things like count and forEach.  It's basically the "current value" being inspected.

 

So for example with the zones:

_zones = [moab_zoneOne, moab_zoneTwo, moab_zoneThree, "moab_zoneFour"];

Here we create an array with 4 zones to check.  Three triggers and a marker.

 

Next we're going to step through that array to check if the player is in any of them by using count.  Count will ask, "Is the player in this area?" and get a true or false answer.  We're basically checking to see if the count of areas checked which were true is greater than 0.

{player inArea _x} count _zones > 0

As we step through the array the value of _x is automatically set to the current value of the index.  So first step is checking the trigger moab_zoneOne.  _x will equal that.  Next step is checking moab_zoneTwo so this time _x will equal that, and so on.

howManyTrueResults = {evaluation} count [array];

Share this post


Link to post
Share on other sites

Thank you very much for that explanation!

 

I've tested the scripts and it works great. I added the EventHandler "respawn" to set "moab_isInfected" to false, because players took damage even after dying and respawning.

 

I also set up a trigger which heals players by setting "moab_isInfected" to false.

 

Edit: I kept the "while"-loop to deal damage though so I could set the interval independently from the interval which checks for the conditions.

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

×