Forum Jump :

Author Message


Posts: 3
Rank:


Level: Member

Country: us
Location:
Occupation:
Age:
In-game name:

 
#1 Posted at 2017-11-30 04:48        
     
I've recently begun scripting for arma 3 in a attempt to make more immersive missions.

Unfortunately I can't get my head around why my trigger isn't doing what it's supposed to.

I was building upon the hostage script from here.

In brief I want to make OPFOR shoot their hostage only after BLUFOR was detected. I know this can be done in the 3D editor easily, but I wanted to put it into a script to have one overall hostage script (to rule them all!), and be able to attach it to any unit. This would allow for a more stealthy approach to hostage rescues, where detection means hostage death and possibly mission failure.

The way I'm going about this is: I create a trigger inside the script centered around the poor hostage, when any OPFOR in this trigger area detects BLUFOR, the captive flag for the hostage is removed (setcaptive false), thereby making them kill-able by OPFOR is BLUFOR can't save them in time.

So, I basically follow the hostage script from here, and I add a few lines to the end to make this trigger. The final script looks like this:

The first codeblock is just setup, the second codeblock is where I think the problem is (they're all part of 1 sqf in my mission).

_captive = _this select 0;
_captive setCaptive true;

... Other settings (animations, remove items) from original script

_captive disableAI "MOVE"; // Disable AI Movement
_captive disableAI "AUTOTARGET"; // Disable AI Autotarget
_captive disableAI "ANIM"; // Disable AI Behavioural Scripts
_captive allowFleeing 0; // Disable AI Fleeing
_captive setBehaviour "Careless"; // Set Behaviour to Careless because, you know, ARMA AI.

// Hold action script from original script
[
... THE SAME HOLD ACTION SCRIPT
] remoteExec ["bis_fnc_holdActionAdd"];
[/code]

These last 4 lines are where I've isolated the problem to

[highlight=sqf]
_trg = createTrigger ["EmptyDetector", getPos _captive];
_trg setTriggerArea [10, 10, 5, false];
_trg setTriggerActivation ["WEST", "EAST D", false];
_trg setTriggerStatements ["this", "_captive setCaptive false; [_captive] joinSilent (group player);", ""];


Note that this is attached to the unit by placing:
null = [this] execVM "hostageScript.sqf";
in their init line

(Also note the joinSilent statement in the setTriggerStatements is so that civilians are treated like BLUFOR)

What happens is the captive script runs flawlessly (captives are not killed and can be freed), but upon detection... nothing happens! The captive remains a captive despite the trigger supposedly being switched to true.

So I've tried religiously googling, but I still feel the problem is the setTriggerStatements. I used hints to try to debug this, and the hints show up, but the result is still the same, in that captives remain captives. I don't know why it isn't working, I've tried setting a "playerdetected=true" variable (that is initialized to false), and then running an if then statement, but it's the same result. I've tried putting an execVM statement instead, but it's still the same problem.

Am I missing something about how triggers work? Is it that I'm attaching this script to the unit, making it run repeatedly thereby setting the unit as a captive immediately after the trigger unsets them?

Any help would be greatly appreciated!

EDIT: Solved

Courtesy of F2kSel for finding the solution

Add to the bottom of the original script found here the following lines:

_trg = createTrigger ["EmptyDetector", getPos _captive];
_trg setVariable ["triggercaptive",_captive];
_trg setTriggerArea [10, 10, 5, false];
_trg setTriggerActivation ["WEST", "EAST D", true];
_trg setTriggerStatements ["this",  "captiveunit = thistrigger getvariable 'triggercaptive'; captiveunit setCaptive false;hint str captiveunit", ""];

Note that the trigger area is quite large, and can be made smaller for a less challenging mission.

This is the correct way to pass variables to trigger statements, too for other scripts.

This was built on the original script by GalacticTwinkles, and the modifications were discovered by F2kSel, the final script for hostageScript.sqf now looks like:

// Set AI Hostage Script 
// By Galactic Twinkles
// Modified by F2kSel, XianGrim, Elegarma
// Define Captive
_captive = _this select 0;
// Select random animation
_anim = selectRandom ["Acts_AidlPsitMstpSsurWnonDnon01","Acts_AidlPsitMstpSsurWnonDnon02","Acts_AidlPsitMstpSsurWnonDnon03","Acts_AidlPsitMstpSsurWnonDnon04","Acts_AidlPsitMstpSsurWnonDnon05","Acts_ExecutionVictim_Loop"];

// Set Captive Settings
_captive setCaptive true;
// Remove Items
removeAllWeapons _captive;
removeBackpack _captive;
removeVest _captive;
removeAllAssignedItems _captive;
_captive switchMove _anim; // SwitchMove to random animation
// Set unit as hurt if it's the Execution animation
if (_anim == "Acts_ExecutionVictim_Loop") then {
	_captive setDamage .5;
};
_captive disableAI "MOVE"; // Disable AI Movement
_captive disableAI "AUTOTARGET"; // Disable AI Autotarget
_captive disableAI "ANIM"; // Disable AI Behavioural Scripts
_captive allowFleeing 0; // Disable AI Fleeing
_captive setBehaviour "Careless"; // Set Behaviour to Careless because, you know, ARMA AI.

// Add Hold Action to Free Hostage
[
/* 0 object */				        _captive,
/* 1 action title */				"Free Hostage",
/* 2 idle icon */				"\a3\ui_f\data\IGUI\Cfg\HoldActions\holdAction_unbind_ca.paa",
/* 3 progress icon */				"\a3\ui_f\data\IGUI\Cfg\HoldActions\holdAction_unbind_ca.paa",
/* 4 condition to show */			"true",
/* 5 condition for action */			"true",
/* 6 code executed on start */			{},
/* 7 code executed per tick */			{},
/* 8 code executed on completion */      	{
						        if (_this select 3 select 0 == "Acts_ExecutionVictim_Loop") then {
								_this select 0 playMove "Acts_ExecutionVictim_Unbow";
							} else {
								_this select 0 switchMove "Acts_AidlPsitMstpSsurWnonDnon_out";
							};
							_complMessage = selectRandom ["I thought I was gonna die in here!","Thank you so much man.","I think I shit my pants...","Can I hug you?","I'M ALIVE.","Where the hell am I?"];
							["Hostage", _complMessage] remoteExec ["BIS_fnc_showSubtitle"];
							sleep 5.5;
							(_this select 0) enableAI "MOVE";
							(_this select 0) enableAI "AUTOTARGET";
							(_this select 0) enableAI "ANIM";
							(_this select 0) setBehaviour "SAFE";
							[(_this select 0)] joinSilent player;
							[(_this select 0),(_this select 2)] remoteExec ["bis_fnc_holdActionRemove",[0,-2] select isDedicated,true];

						},
/* 9 code executed on interruption */       {
						_intrMessage = selectRandom ["Hey! I don't wanna die here!","Don't leave me here man! Please!","THEY'RE EATING PEOPLE. GET ME OUT OF HERE.","*Mumbles* Shit shit shit..."];
						["Hostage", _intrMessage] remoteExec ["BIS_fnc_showSubtitle"];
					    },
/* 10 arguments */			    [_anim],
/* 11 action duration */		    3,
/* 12 priority */			    0,
/* 13 remove on completion */		    true,
/* 14 show unconscious */		    false
] remoteExec ["BIS_fnc_holdActionAdd",[0,-2] select isDedicated,true];

_trg = createTrigger ["EmptyDetector", getPos _captive];
_trg setVariable ["triggercaptive",_captive];
_trg setTriggerArea [10, 10, 5, false];
_trg setTriggerActivation ["WEST", "EAST D", true];
_trg setTriggerStatements ["this",  "captiveunit = thistrigger getvariable 'triggercaptive'; captiveunit setCaptive false;hint str captiveunit", ""];

To add this to a unit add this to their init line:
null = [this] execVM "hostageScript.sqf";

Credits go to GalacticTwinkles (original script), F2kSel (modifications), XianGrim (figuring out the scoping problem, and the alternative solution)

This post was edited by elegarma (2017-12-01 03:33, 382 days ago)


Author Message


Posts: 151
Rank:


Level: Member

Country: us
Location: Pennsylvania
Occupation:
Age:
In-game name: Xian

 
#2 Posted at 2017-11-30 09:33        
     
Is your trigger detecting the _captive? Maybe it's a locality issue and can't find who _captive is in the trigger? Just a wild guess as I'm not at home to test it atm.

_trg setTriggerStatements ["this", "_captive setCaptive false; [_captive] joinSilent (group player); hint format ['captive = %1',_captive];", ""];

Could be totally wrong, just a guess.


Advertisement


Author Message


Posts: 3
Rank:


Level: Member

Country: us
Location:
Occupation:
Age:
In-game name:

 
#3 Posted at 2017-11-30 15:50        
     
You're probably correct, I tried your script and the hint outputted:
captive = any (which shouldn't be the case)

I think _captive is not detected by the trigger, like you said.

I've tried 2 solutions but both didn't work:

Using setvariable, and getvariable:

_captive= _this select 0;
...
triggercaptivespace setVariable ["triggercaptive",_captive];

_trg = createTrigger ["EmptyDetector", getPos _captive];
_trg setTriggerArea [10, 10, 5, false];
_trg setTriggerActivation ["WEST", "EAST D", true];
_trg setTriggerStatements ["this",  format["captive = triggercaptivespace getvariable 'triggercaptive'; captive setCaptive False;"], ""];

Gave me the error that triggercaptivespace was an undefined variable

Trying the format route:

_captive= _this select 0;
_trg = createTrigger ["EmptyDetector", getPos _captive];
_trg setTriggerArea [10, 10, 5, false];
_trg setTriggerActivation ["WEST", "EAST D", true];
_trg setTriggerStatements ["this", format ["%1 setCaptive false;", _captive]," "];

Gives me a missing ; error (however, the captive unit name does show up in the error message, so maybe that's something!)

Any thoughts? It could be I made an error in one of the above statements, too!


Author Message


Posts: 1513
Rank:


Level: Member

Country: uk
Location:
Occupation:
Age:
In-game name:

 
#4 Posted at 2017-12-01 00:33        
     
First has a few issues issues.
triggercaptivespace is not defined it needs to be an existing object or mission space.
in this case lets use the trigger that will be created _trg.
It will need to be used after the creation of the trigger.


You won't need to use the format in setTriggerStatements and you also can't use captive as that's a command.
So it should now look like this

_captive = _this select 0;
_trg = createTrigger ["EmptyDetector", getPos _captive];
_trg setVariable ["triggercaptive",_captive];
_trg setTriggerArea [10, 10, 5, false];
_trg setTriggerActivation ["WEST", "EAST D", true];
_trg setTriggerStatements ["this",  "captiveunit = thistrigger getvariable 'triggercaptive'; captiveunit setCaptive false;hint str captiveunit", ""];

The second method is actually correct, I didn't get any errors however it may not work because the unit may not have an actual name. Try naming the unit.

This post was edited by F2kSel (2017-12-01 00:45, 382 days ago)


Author Message


Posts: 151
Rank:


Level: Member

Country: us
Location: Pennsylvania
Occupation:
Age:
In-game name: Xian

 
#5 Posted at 2017-12-01 02:50        
     
If it helps, I did it without the trigger completely. I just added it to the action itself:


// Set AI Hostage Script 
// By Galactic Twinkles
// Define Captive
_captive = _this select 0;
// Select random animation
_anim = selectRandom ["Acts_AidlPsitMstpSsurWnonDnon01","Acts_AidlPsitMstpSsurWnonDnon02","Acts_AidlPsitMstpSsurWnonDnon03","Acts_AidlPsitMstpSsurWnonDnon04","Acts_AidlPsitMstpSsurWnonDnon05","Acts_ExecutionVictim_Loop"];

// Set Captive Settings
_captive setCaptive true;
// Remove Items
removeAllWeapons _captive;
removeBackpack _captive;
removeVest _captive;
removeAllAssignedItems _captive;
_captive switchMove _anim; // SwitchMove to random animation
// Set unit as hurt if it's the Execution animation
if (_anim == "Acts_ExecutionVictim_Loop") then {
	_captive setDamage .5;
};
_captive disableAI "MOVE"; // Disable AI Movement
_captive disableAI "AUTOTARGET"; // Disable AI Autotarget
_captive disableAI "ANIM"; // Disable AI Behavioural Scripts
_captive allowFleeing 0; // Disable AI Fleeing
_captive setBehaviour "Careless"; // Set Behaviour to Careless because, you know, ARMA AI.

// Add Hold Action to Free Hostage
[
_captive,
"Free Hostage",
"\a3\ui_f\data\IGUI\Cfg\HoldActions\holdAction_unbind_ca.paa",
"\a3\ui_f\data\IGUI\Cfg\HoldActions\holdAction_unbind_ca.paa",
"true",
"true",
{},
{},
{
	if (_this select 3 select 0 == "Acts_ExecutionVictim_Loop") then {
	_this select 0 playMove "Acts_ExecutionVictim_Unbow";
	} else {
		_this select 0 switchMove "Acts_AidlPsitMstpSsurWnonDnon_out";
	};
	_complMessage = selectRandom ["I thought I was gonna die in here!","Thank you so much man.","I think I shit my pants...","Can I hug you?","I'M ALIVE.","Where the hell am I?"];
	["Hostage", _complMessage] remoteExec ["BIS_fnc_showSubtitle"];
	sleep 5.5;
	(_this select 0) enableAI "MOVE";
	(_this select 0) enableAI "AUTOTARGET";
	(_this select 0) enableAI "ANIM";
	(_this select 0) enableAI "PATH";
	(_this select 0) setBehaviour "SAFE";
	[(_this select 0)] joinSilent grpNull;
	(_this select 0) addRating -10000;
	(_this select 0) setCaptive false;
	{_x reveal (_this select 0)} forEach allUnits;
	[(_this select 0)] joinSilent group player;
	[(_this select 0),(_this select 2)] remoteExec ["bis_fnc_holdActionRemove",[0,-2] select isDedicated,true];

},
{
	_intrMessage = selectRandom ["Hey! I don't wanna die here!","Don't leave me here man! Please!","THEY'RE EATING PEOPLE. GET ME OUT OF HERE.","*Mumbles* Shit shit shit..."];
	["Hostage", _intrMessage] remoteExec ["BIS_fnc_showSubtitle"];
	},
[_anim],
3,
0,
true,
false
] remoteExec ["BIS_fnc_holdActionAdd",[0,-2] select isDedicated,true];


Author Message


Posts: 3
Rank:


Level: Member

Country: us
Location:
Occupation:
Age:
In-game name:

 
#6 Posted at 2017-12-01 03:02        
     
@F2sKel Yep, that did the trick. It makes sense in retrospect, but I never realized passing variables to triggers would be an issue.

@XianGrim, but is the action conditional on detection of BLUFOR?

Thank you very much F2kSel and XianGrim. As you could probably tell, this is one of my first scripts and I really appreciate the help.

I wanted to use this script in a mission where you have to rescue a POW, and if you do he gives you valuable intel making the rest of the mission much easier as a result. Also, it would up the stakes and make you try your best.

Strangely there doesn't seem to be any script out there that utilizes OPFOR detection of BLUFOR, so I'm glad we got one now.

Do you think I can upload the final script to the forum or to armaholic? It was mostly built off of the GalacticTwinkles script, so what's the policy on that? Is crediting GalacticTwinkles, F2kSel and XianGrim enough or should I explicitly seek GalacticTwinkles' permission first?

In any case, hopefully I can help someone on the forum like you two did.