[script] Enemies detecting players only within some range

Workshop for all Mission Engineer Comrades. Home of the FA Mission Making Template.
EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

[script] Enemies detecting players only within some range

Post by EsotericReverie »

I want to allow players to move freely until they come within a certain distance of enemy troops, a distance at which the enemy might reasonably be able to see that the players are armed. Once the enemy realises this, they should be alerted and start treating players as a threat.

My general plan is this:

- Mission setup:
On init:

Code: Select all

{_x setCaptive true} forEach units group player;
EnemyWeaponSpottingDistance = 100;
(possibly, this distance should differ between different players, depending on what weapons they're using/carrying? That AT tube is pretty conspicuous...)

- Detection trigger (one per player):
Condition:

Code: Select all

({side _x == guer} count ((position player1) nearEntities EnemyWeaponSpottingDistance)) > 0
OnAct:

Code: Select all

player1 setVariable ["PlayerWeaponsSpotted", true, true];
- Global hostility trigger:
Condition:

Code: Select all

PlayerWeaponsSpotted
OnAct:

Code: Select all

{_x setCaptive false} forEach units group player;
Effects: Some text alerting the players that they've been identified as insurgents.


This should do the trick, as far as I can tell, even in MP (with the setVariable thing, right?). The problem is, I never seem to trigger the Detection trigger, unless I remove the {side _x == guer} part. Any idea why?


Edit:
Also, is there a way to use knowsAbout without having to have the AI actually fire at me or acting as if I'm the enemy? When I've got setCaptive, knowsAbout for all enemies seems to be 0, the same goes for when I've got the two sides friendly to each other. It would be good to have the ability to check whether the AI patrols and sentries actually see and know about the players too...

User avatar
wolfenswan
Posts: 1209
Joined: Wed May 25, 2011 4:59 pm

Re: [script] Enemies detecting players only within some rang

Post by wolfenswan »

have you tried nearestObjects/nearObjects instead of nearEntities?

EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

Re: [script] Enemies detecting players only within some rang

Post by EsotericReverie »

Well, I've tried typing some information about the entities, and that works, I get a list of AAF soldiers with this:

Code: Select all

{player globalchat format ["%1: %2, knowsAbout: %3", _x, side _x, _x knowsAbout player1]} forEach ((position player1) nearEntities EnemyWeaponSpottingDistance);
It even says what side they're on properly (GUER)! I am totally stumped by why side _x works in the format string, but not in my condition. I've tried conditions like {side _x == guer}, {side _x == GUER} and {side _X == "GUER"}, none of which seem to work... I'll try nearestObject(s) too.

Edit:
nearObjects makes no difference, there's something with the count condition... :(

EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

Re: [script] Enemies detecting players only within some rang

Post by EsotericReverie »

Okay, next question: so far I have the following trigger condition, which actually seems to work:

Code: Select all

({side _x == side Patrol} count ((position player) nearEntities (player getVariable ["EnemyWeaponSpottingDistance", 100]) )) > 0
"Patrol" is an enemy group. This new count condition seems to act as a workaround to whatever was stopping that from working before.
And I also managed to turn the spotting distance into a player variable. Now, each player is responsible for letting the others know when it has been spotted.

Now, I want to force the sentries to actually be aware of the presence of the player before triggering, so that sneaking past them becomes possible if you use cover or move behind them etc. turning the count condition into this, does not give any hits, however:

Code: Select all

{side _x == side Patrol and (_x knowsAbout player) > 0}
Any idea why?

User avatar
wolfenswan
Posts: 1209
Joined: Wed May 25, 2011 4:59 pm

Re: [script] Enemies detecting players only within some rang

Post by wolfenswan »

It even says what side they're on properly (GUER)! I am totally stumped by why side _x works in the format string, but not in my condition. I've tried conditions like {side _x == guer}, {side _x == GUER} and {side _X == "GUER"}, none of which seem to work... I'll try nearestObject(s) too.
You're confusing side as a variable and side formatted as a string.

To compare the side variable it would have to be side _x == resistance or side _x == independent.
Or str (side _x) == "GUER"
If you use str side resistance you get "GUER"

That's why your second example works as you're comparing two side variables.

See
http://community.bistudio.com/wiki/side

EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

Re: [script] Enemies detecting players only within some rang

Post by EsotericReverie »

Yeah, I found out about the "faction" command, and using that works splendidly! I've got it workin properly, locally, now. I'll post the solution here in a bit, just testing it out with LaKroy in MP, first.

EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

Re: [script] Enemies detecting players only within some rang

Post by EsotericReverie »

So, this is how I got it working decently, at last:

Game start:
Set all player units "captive", so AAF won't shoot them. Set a default "spotting distance", the range at which the enemy will see that these dudes are armed:

Code: Select all

{_x setCaptive true; _x setVariable ["SpottingDistance", 150];} forEach units group player;
PlayerWeaponsSpotted  = false;
(The spotting distance can theoretically be changed with things like fishy behaviour, equipping bigger guns, etc.)

Detection trigger:
There is only one, and it's activated by the player. This scenario is strictly for coop play, so having AI friends trigger the alarm is a non-issue as it stands.
Condition:

Code: Select all

({faction _x == "IND_F" and (_x knowsAbout player) > 0} count ((position player) nearEntities (player getVariable ["SpottingDistance", 100]) )) > 0
For each entity that is within spotting distance of the player, check whether it is AAF and if it knows about the player. If the number of such entities is greater than 0, sound the alarm. I'd be interested in exploring using a threshold value for the knowsAbout condition that could be determined by equipment or behaviour, requiring a larger value for someone in civilian clothes without visible weapons, for instance.

On Act:

Code: Select all

PlayerWeaponsSpotted = true;
publicVariable "PlayerWeaponsSpotted";
SpotPosition = position player;
publicVariable "SpotPosition";
Set two global variables, PlayerWeaponsSpotted to indicate players have been spotted, and SpotPosition, to indicate where. The position is later used to call in reinforcements to that location.

Alert trigger:
A trigger that goes off when players have been spotted and takes care of making them eligible targets.

Condition:

Code: Select all

PlayerWeaponsSpotted
On Act:

Code: Select all

{_x setCaptive false} forEach units group player;
Makes all player's group members targets.


This, coupled with some informative text, an alarm noise and a little script to call reinforcements to the SpotPosition, has proven rather effective!


Any thoughts on this procedure?

Black Mamba
Posts: 335
Joined: Sun May 27, 2012 12:11 pm

Re: [script] Enemies detecting players only within some rang

Post by Black Mamba »

Although it globally looks sound to me, I don't see the point in having that second trigger, given that it will fire basically at the same time as the first. Why no stick the setCaptive business in the first trigger? Did I miss something?
Plus it would allow you to easily convert your two PV in one single array. The less PV the better.

EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

Re: [script] Enemies detecting players only within some rang

Post by EsotericReverie »

Thanks for the feedback! 'PV', though? Not familiar with that term.
Edit: oh: public variables, of course!

What I want to make sure is that all players get the alert signal, hence the two triggers, one to set the flag and publish it to all clients, one to trigger the alert. If that is not necessary for whatever reason, that's nice. I also use the PlayerWeaponsSpotted flag in a number of other places, so I still need that, or the trigger OnAct would become totally unwieldy.

EsotericReverie
Posts: 84
Joined: Thu Sep 05, 2013 8:30 am

Re: [script] Enemies detecting players only within some rang

Post by EsotericReverie »

A follow-up question:

Can I get the AI to destroy a civilian vehicle without passengers and without having them be hostile to CIV? "Destroy" waypoints only work on enemy targets, apparently, but I want the AI to try to destroy the pickup truck with the improvised bomb on the back, whether or not there's anyone sitting in it...

Post Reply