Jump to content
Sign in to follow this  
thetrooper

Creating a recon mission

Recommended Posts

If you cast your minds back to Arma 1 or even Operation Flashpoint, there were some recon/sniper missions.

I know how to create tasks and objectives, but, say the player conducts a recce with binos or a site, and views a certain enemy man or leader, how do you get that as an objective complete? Also is there a way you can get a count going of how many you've viewed and say after anything greater than 10 is objective complete? Maybe even display it to the player as a hint? Any ideas?

Share this post


Link to post
Share on other sites

That's promising. I know now that that exists, but can't find anything to help me set it up. For instance, I got 1 enemy and I spot him ising my binos. No idea of the Syntax or where to put it?

Share this post


Link to post
Share on other sites

I made somthing to do exactly this a very long time ago. Could find it though.

But I remember I used cursorTarget to do it. Of interest might be these two commands also:

screenToWorld

worldToScreen

You might want to try checking if the result of calling worldToScreen on a target is near to [0.5, 0.5] for some seconds. If it is then the player is most likely looking at the target.

Share this post


Link to post
Share on other sites

Actually you might want to forget about screenToWorld since I don't know how it works when an object is behind a mountain for example.

I threw this together quickly. You set which targets to spot in the top and then you execVM it. "_onSpot" will be called each time a unit is spotted. I have not tested this. You need to use a binocular and remember to "reveal" the target else cursorTarget won't work. If you want something to happen when you are done place it at the bottom.


//spawn/execVM this script

private ["_reconTargets","_lastCursorTarget","_lastCursorTime","_cTarget","_leaderA","_leaderB","_leaderC","_leaderD","_spottedTargets","_checkIsSpotting","_onSpot","_spotTime","_timeBetweenChecks","_stillSpotting"];

/* Target to spot */
_reconTargets = [_leaderA, _leaderB, _leaderC, _leaderD];

/* Custom variables */
_checkIsSpotting = {currentWeapon _this  == "Binocular"};
_onSpot = {hint format ["You spotted %1", typeOf _this];};
_spotTime = 1.8; //Watch for 1.8 seconds
_timeBetweenChecks = 0.25;

/* Loop variables */
_lastCursorTarget = objNull; //Last target in "cursorTarget"
_lastCursorTime = -100; //client time target was first spotted
_stillSpotting = true;

//Targets already spotted
_spottedTargets = [];
_spottedTargets resize (count _reconTargets);

//4 checks per scond
while {_stillSpotting} do {
   _cTarget = cursorTarget;
   //We tracking a target?
   if (!isNull _lastCursorTarget) then {
       //Same target as before and still spotting
       if (_cTarget == _lastCursorTarget && player call _checkIsSpotting) then {
           //Watched long enough?
           if (time - _lastCursorTime > _spotTime) then {
               //Spotted it
               _spottedTargets set [count _spottedTargets, _cTarget];
               _reconTargets = _reconTargets - [_cTarget];
               _lastCursorTarget = objNull;
               //Run on-spot code
               _cTarget call _onSpot;
               //No targets left?
               if (count _reconTargets == 0) then {
                   _stillSpotting = false;
               };
           };
       } else {
           //Else lost it - update with null or new target
           _lastCursorTarget = _cTarget;
           _lastCursorTime = time; //Started watching this now
       };
   } else {
       if (!isNull _cTarget) then {
           //Are we spotting. Do we have a new target to track?
           if (player call _checkIsSpotting && _cTarget in _reconTargets) then {
               _lastCursorTarget = _cTarget;
               _lastCursorTime = time; //Began watching now
           };
       };
   };
   sleep _timeBetweenChecks;
};

//All targets spotted what now?

Share this post


Link to post
Share on other sites

wow thanks for that. I'll have a play around, will let you know how it goes.

---------- Post added at 06:02 PM ---------- Previous post was at 05:34 PM ----------

It's not working at the moment. The "reveal" command is another new one for me. What I did was create my group called "recon" and in the enemy initialisation add

recon reveal this

. Also named my four bad guys as _leaderA, B, C, D. Probably haven't done that bit right.

The script produced is now in a sqf file and called on in a initialisation field. Any tips?

Share this post


Link to post
Share on other sites

I got it working by opening the editor insert a player unit give him a binocular. Then I added four units named a, b, c, d and then changed this line:

_reconTargets = [_leaderA, _leaderB, _leaderC, _leaderD];

To

_reconTargets = [a, b, c, d];

And started the script using

0 = [] execVM "recon.sqf";

When I say "reveal" I don't necessarily mean using a script command. In arma if you want to reveal a unit, the default "key" to do this is holding, not clicking, the right mouse button for at least ½ a second while the unit to reveal is in the center of the screen. Remember to do this through a binocular since the script have been configured to only allow spotting through binoculars. Also you have to look at the target for 2 seconds without losing track.

When you get it working there are other issues you might want to look into. For example add that other optics can be used:

_checkIsSpotting = {(currentWeapon _this) in ["Binocular", "Vector", "SpottingScope"]};

These classnames are not the real ones.

Another issue is MP. If you want multiple units to be able to spot in MP you need to handle this too. Eg. if player A spots unit X then player B shouldn't have to do that too.

Share this post


Link to post
Share on other sites

Good effortY yep I got it working to. That script you got there does open up the game quite a lot. I'll come back after I have a think about the mission I'm going to create.

Share this post


Link to post
Share on other sites
I got it working by opening the editor insert a player unit give him a binocular. Then I added four units named a, b, c, d and then changed this line:

_reconTargets = [_leaderA, _leaderB, _leaderC, _leaderD];

To

_reconTargets = [a, b, c, d];

And started the script using

0 = [] execVM "recon.sqf";

When I say "reveal" I don't necessarily mean using a script command. In arma if you want to reveal a unit, the default "key" to do this is holding, not clicking, the right mouse button for at least ½ a second while the unit to reveal is in the center of the screen. Remember to do this through a binocular since the script have been configured to only allow spotting through binoculars. Also you have to look at the target for 2 seconds without losing track.

When you get it working there are other issues you might want to look into. For example add that other optics can be used:

_checkIsSpotting = {(currentWeapon _this) in ["Binocular", "Vector", "SpottingScope"]};

These classnames are not the real ones.

Another issue is MP. If you want multiple units to be able to spot in MP you need to handle this too. Eg. if player A spots unit X then player B shouldn't have to do that too.

WOW this looks like this could be a great script, and add some more mission ideas for gameplay - any way you can mod this to be usable in MP as that would be awsum - a proper recce at last

Share this post


Link to post
Share on other sites

ok, I've been playing around with it for a bit. A couple of things that would be good.

1. ok lets say the player is recceing a village. He spots his first enemy (could be any of them in the list), a message in SideChat gets sent back to HQ to say

Player SideChat "hello zero, I've spotted enemy fighters within Karis Kalay, the town is hostile over";

blah blah, conversation over, carry on spotting.

2. I changed the hint so now a, b, c, d

_onSpot = {hint format ["You spotted a enemy fighter", typeOf _this];};

So now we have indicated that a, b, c, d are somekind of light riflemen. How would you go out adding d and e as "You spotted a enemy commander", but for each that opens up another sideChat to report that back to HQ then maybe get an option where to accept to take on a new task to kill him?

3. We've got a mission to recce a village/town etc, now how to incorporate a point scheme for debrief end of the mission.

Share this post


Link to post
Share on other sites

if ((typeof _this) == "RU_CommanderClassname") then {
hint "you spotted a commander";
optobj = player createsimpletask ["Eliminate the commander"];
obtobj setsimpletaskdescription ["Eliminate the commander", "Eliminate the commander", "commander:];
obtobj settaskstate "CREATED";
};

then check whether the commander is alive via alive commanderUnit (or whatever his name is), if hes not alive, settaskstate to "SUCCEEDED", also, you need to know the classname of the russian officer (i forgot what it is)

If you want to get the option of accepting/refusing a task, then i believe you want to use the bis conversation system, but be warned, this is a steep learning curve to getting it to work, and with adding choice makes it even more time consuming getting to work (you also need to know how to use fsm's)

there are some documentations on here about the conversation system and how to get it to work (pay no attention to the biki) try searching for them

Edited by Igneous01

Share this post


Link to post
Share on other sites

Tried this, it doesn't work for some reason. Been using a Takistan map so using the warlord class for it.

I'll tackle the conversation system sometime in the future. Will be a bit of a nice to have thing really.

Share this post


Link to post
Share on other sites

Will this also work for objects like buildings?

I'd like my player to recon a building. I can give it a name to place it properly in the script.

Share this post


Link to post
Share on other sites

I haven't tried it but that's what I'm keen to do also. At the moment the script runs so that all the units listed need to be recced, anyone know how I can get it so you only have to recce any two instead of all four? Something like if count == 3 then mission accomplished?

Share this post


Link to post
Share on other sites
I haven't tried it but that's what I'm keen to do also.

Perhaps an Empty marker placed near a building and given a name could work?

Inviso Helipad?

Share this post


Link to post
Share on other sites

Stuck - Ok, so this is a script to run an action after a, b, c, and d have been spotted. I'm having some problemts with how do you set it up so you only have to recce say two from these before my action at the end. Any ideas?

I'm thinking a "count" needs to be in place somewhere?

[quote name=

//spawn/execVM this script

private ["_reconTargets","_lastCursorTarget","_lastCursorTime","_cTarget","_leaderA","_leaderB","_leaderC","_leaderD","_spottedTargets","_checkIsSpotting","_onSpot","_spotTime","_timeBetweenChecks","_stillSpotting"];

/* Target to spot */

_reconTargets = [a, b, c, d];

/* Custom variables */

_checkIsSpotting = {currentWeapon _this == "Binocular"};

_onSpot = {hint format ["You spotted %1", typeOf _this];};

_spotTime = 1.8; //Watch for 1.8 seconds

_timeBetweenChecks = 0.25;

/* Loop variables */

_lastCursorTarget = objNull; //Last target in "cursorTarget"

_lastCursorTime = -100; //client time target was first spotted

_stillSpotting = true;

//Targets already spotted

_spottedTargets = [];

_spottedTargets resize (count _reconTargets);

//4 checks per scond

while {_stillSpotting} do {

_cTarget = cursorTarget;

//We tracking a target?

if (!isNull _lastCursorTarget) then {

//Same target as before and still spotting

if (_cTarget == _lastCursorTarget && player call _checkIsSpotting) then {

//Watched long enough?

if (time - _lastCursorTime > _spotTime) then {

//Spotted it

_spottedTargets set [count _spottedTargets, _cTarget];

_reconTargets = _reconTargets - [_cTarget];

_lastCursorTarget = objNull;

//Run on-spot code

_cTarget call _onSpot;

//No targets left?

if (count _reconTargets == 0) then {

_stillSpotting = false;

};

};

} else {

//Else lost it - update with null or new target

_lastCursorTarget = _cTarget;

_lastCursorTime = time; //Started watching this now

};

} else {

if (!isNull _cTarget) then {

//Are we spotting. Do we have a new target to track?

if (player call _checkIsSpotting && _cTarget in _reconTargets) then {

_lastCursorTarget = _cTarget;

_lastCursorTime = time; //Began watching now

};

};

};

sleep _timeBetweenChecks;

};

//All targets spotted what now?

Edited by TheTrooper

Share this post


Link to post
Share on other sites
Will this also work for objects like buildings?

I'd like my player to recon a building. I can give it a name to place it properly in the script.

If it is a building in the editor then turn on id's and find the number. Then you can get the building like this:

_building = [0,0,0] nearestObject 123456;

I spent a couple of minutes on a newer version that allows you to customize more. I haven't tested it and squint went down so there might be some issues!!!

You can still execVM it, however, if you need to start multiple recon missions then you should save the script and then spawn it. I recommend reading the top part of the script for how to use. Feel free to ask questions.

/*

Script for dealing with reconnaisance. Uses "hook"-like system.

Should be compiled first:
MF_Recon = compile preProcessFile "MF_Recon.sqf";
Then started like this:
[TARGETS, CHECK_INTERVAL, SPOT_TIME, IS_SPOTTING, CAN_SPOT_TARGET, ON_TARGET_SPOTTED, ON_COMPLETE] spawn "MF_Recon.sqf";

All of these except TARGETS have default. If you you want to use a default just write: nil.

Examples:

   //Spot two scuds.
       [ [scud_a, _scud_b], nil, nil, nil, nil, nil, nil] spawn MF_Recon;

   //Spot two scuds. Must spot for at least 3 seconds. Scuds will blow up when both are spotted
       _targets = [scud_a, scud_b];
       _onComplete = { {_x setDamage 1.0;} forEach (_this select 1) };
       [_targets, nil, 3, nil, nil, nil, _onComplete] spawn MF_Recon;

For more details on how to use and default values look below under: * Default variables *

By Muzzleflash
14/09/11
*/

private ["_reconTargets","_checkInterval","_spotTime","_isSpotting","_canSpotTarget","_onSpottedTarget","_onNoTargetsLeft","_spottedTargets","_lastCursorTarget","_lastCursorTime","_cleanupInterval","_cleanUpTime","_stillSpotting","_internalOnSpot","_internalOnComplete","_internalCleanUp","_cTarget","_stopRecon"];

#define IfNilThenParam(X_NAME,X_IDX) if (!isNil {_this select X_IDX}) then {X_NAME = _this select X_IDX}

/* Target to spot */
_reconTargets = _this select 0;

/*********** Defaults variables *************/

//Time between cursorTarget checks
_checkInterval = 0.5; 
//How long target must be centered in view
_spotTime = 1.8; 
//Is he currently (able to) spotting? Return true if he is. _this = player
_isSpotting = {currentWeapon _this == "Binocular"}; 
//Can he spot this particular target. Return true if he can. _this = unit (in _reconTargets).
_canSpotTarget = {player distance _this < 1200};
//Called when (just after) a target has been spotted. Return false to end recon. _this = [targetSpotted, unitsNotSpotted, unitsSpotted] 
_onSpottedTarget = {hint format ["You spotted %1", typeOf (_this select 0)]}; 
//Called when no targets left to spot. _this = [_unitsNotSpotted, _unitsSpotted]
_onNoTargetsLeft = {hint "Recon mission concluded"}; 

/* Attempt to load custom defines */
IfNilThenParam(_checkInterval,1);
IfNilThenParam(_spotTime,2);
IfNilThenParam(_isSpotting,3);
IfNilThenParam(_canSpotTarget,4);
IfNilThenParam(_onSpottedTarget,5);
IfNilThenParam(_onNoTargetsLeft,6);

//Targets already spotted
_spottedTargets = [];

/* Loop variables */
_lastCursorTarget = objNull; //Last target in "cursorTarget"
_lastCursorTime = -100; //client time target was first spotted
_cleanupInterval = 15;
_cleanUpTime = time + _cleanupInterval;
_stillSpotting = true;

/* Internal functions. Might be helpful for later MP compatibility */
_internalOnSpot = {
   _this call _onSpottedTarget;
};

_internalOnComplete = {
   _this call _onNoTargetsLeft;
};

//Remove null objects. What about dead people? Well they still need to be identied as dead right?
_internalCleanUp = {
   private ["_arr"];
   _arr = _this - [objNull];
   _arr
};

/* if's nested for performance */
while {_stillSpotting && count _reconTargets > 0} do {
   _cTarget = cursorTarget;
   //We tracking a target?
   if (!isNull _lastCursorTarget) then {
       //Same target as before and still spotting
       if (_cTarget == _lastCursorTarget && player call _isSpotting) then {
           //Watched long enough?
           if (time - _lastCursorTime > _spotTime) then {
               //Spotted it
               _spottedTargets set [count _spottedTargets, _cTarget];
               _reconTargets = _reconTargets - [_cTarget];
               _lastCursorTarget = objNull;
               //Run on-spot code
               _stopRecon = [_cTarget, _reconTargets, _spottedTargets] call _internalOnSpot;
               if (isNil "_stopRecon") then {_stopRecon = false;};
               //No targets left or stop recon?
               if (count _reconTargets == 0 || _stopRecon) then {
                   _stillSpotting = false;
               };
           };
       } else {
           //Else lost it - retry with new cursorTarget on next cycle
           _lastCursorTarget = objNull;
           _lastCursorTime = time; //Started watching this now
       };
   } else {
       //Are we spotting. Do we have a new target to track?
       if (!isNull _cTarget && _cTarget in _reconTargets) then {
           //Can we spot this?
           if (player call _isSpotting && _cTarget call _canSpotTarget) then {
               _lastCursorTarget = _cTarget;
               _lastCursorTime = time; //Began watching now
           };
       };
   };
   if (time > _cleanUpTime) then {
       _cleanUpTime = time + _cleanupInterval;
       _reconTargets = _reconTargets call _internalCleanUp;
   };
   sleep _checkInterval;
};

//All targets spotted
[_reconTargets, _spottedTargets] call _internalOnComplete;

If you want to only recon a couple of the units then you should use the onSpottedTarget hook to do it and return false if stop spotting. Example:

_myTargets = units _enemyHQGroup;
_onSpottedTarget = {
   private ["_current", "_alreadySpotted"];
   _current = _this select 0;
   _alreadySpotted = _this select 2;
   hint format ["You spotted a %1", typeOf _current];
   //Return true/end recon mission if spotted more than 2
   count _alreadySpotted >= 3
};
[_myTargets, nil, nil, nil, nil, _onSpottedTarget, nil] spawn MF_Recon;

As I said I have not tested this.

---------- Post added at 16:51 ---------- Previous post was at 16:29 ----------

I just tested it and there was some bugs. I updated the code in the post above.

These default's are meant to be changed. If you know that you need in most cases then change the defaults, and only pass in custom variables for special cases.

Example the current IsSpotting code basically just checks whether someone is using a Binocular. If you know how to check whether someone is using optics then put that into the default instead. And please tell me if you do, so I can update the default in this script version too so it will work properly in most situations.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

ok, I have a couple of questions.

reconTargets, do I need to list all the enemy guys able to recce in here

instead of this:

_reconTargets = _this select 0;

I put in:

_reconTargets = [a, b, c, d, e, f, g, h];

?

Share this post


Link to post
Share on other sites

No you should do that anymore. You should put it in when you start the script. Example of an init.sqf

MF_Recon = compile preProcessFile "recon.sqf";
[ [a,b,c,d,e,f,g,h], nil, nil, nil, nil, nil, nil] spawn MF_Recon;

The only thing you might want to edit in the file are the defaults values used when you do not specify anything - that looks like this:

/*********** Defaults variables *************/

//Time between cursorTarget checks
_checkInterval = 0.5; 
//How long target must be centered in view
_spotTime = 1.8; 
//Is he currently (able to) spotting? Return true if he is. _this = player
_isSpotting = {currentWeapon _this == "Binocular"}; 
//Can he spot this particular target. Return true if he can. _this = unit (in _reconTargets).
_canSpotTarget = {player distance _this < 1200};
//Called when (just after) a target has been spotted. Return false to end recon. _this = [targetSpotted, unitsNotSpotted, unitsSpotted] 
_onSpottedTarget = {hint format ["You spotted %1", typeOf (_this select 0)]}; 
//Called when no targets left to spot. _this = [_unitsNotSpotted, _unitsSpotted]
_onNoTargetsLeft = {hint "Recon mission concluded"}; 

Remember to read the top of the file for instructions. Let me know if something should be edited there.

Edited by Muzzleflash

Share this post


Link to post
Share on other sites

ok, yep now done that, no cigar though just yet.

bit of background

The senario I'm working on is using BAF in Takistan (Afghan type scenario).

What I'm using for spotting

_isSpotting = {currentWeapon _this == "Binocular", "Binocular_Vector", "BAF_LRR_scoped"}; 

It is mainly single units (fighters) to spot. There may be 15 of them, but you only have to find 5 for example.

_onNoTargetsLeft =
will be task completed.

However, there are a couple of things in the village if spotted, 'new task'.

At the moment though, not getting any pings with my rangefinder. Any ideas?

Share this post


Link to post
Share on other sites

_isSpotting = {currentWeapon _this == "Binocular", "Binocular_Vector", "BAF_LRR_scoped"};

Should be this:

_isSpotting = {(currentWeapon _this) in ["Binocular", "Binocular_Vector", "BAF_LRR_scoped"]};

_units = [f_1, f_2, f_3, f_4, f_5, f_6];
//This happens when a unit is spotted. If more than 5 return true which means this recon task is over.
_onTargetSpotted = {hint "You spotted af fighter"; count (_this select 2) >= 5};
//What happens when the mission is over?
_onNoTargetsLeft = {hint "Based on intel, town has been declared hostile";};
//Start this recon task
[_units, nil, nil, nil, nil, _onTargetSpotted, _onNoTargetsLeft] spawn MF_Recon;

Basically you set up settings that should apply for all/most of the missions (defaults) inside the file (recon.sqf). Then you fill in the specifics for each mission like above and start the script.

Share this post


Link to post
Share on other sites

That works a treat. Great job!

for extra bits like identifying commanders for possible tasks, is it best to run separate sqf files or keep it all within the same file?

Share this post


Link to post
Share on other sites

I would not start too many of these scripts since they each one would check what the player is looking at often. But 2 or 3 should be fine. I assume when you say run separate sqf's you mean spawn it multiple times. There's no need to copy the sqf file.

There are 2 kinds of "events". One that is run when each target is spotted and another that is run when no targets are left or you return true in the first - like you have seen now. How you use them is up to you. You can put if's and whatever into the code that runs for each spotting if you need to do something complicated.

Share this post


Link to post
Share on other sites

Sorry to ask but, is that the final coding in post #22 and where does the PHP code go?

Thanks for your kindness

KK

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
Sign in to follow this  

×