Advertisement

Author Topic: LAGGY Detect Dead Bodies script (ACCEPTED)  (Read 2485 times)

0 Members and 1 Guest are viewing this topic.

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
LAGGY Detect Dead Bodies script (ACCEPTED)
« on: 10 Feb 2009, 22:17:57 »
Detect Dead Bodies script by LAGGY v 0.9

Actually gives the "Hide Body" action a reason to exist.
In my opinion a must in any infiltration or stealth mission.

This is a script that can recognize when a dead unit from a certain side or with a certain unitName is found by someone from a certain side, group or with a certain name.
The parameters are important. Through those you can customize the script for your mission purposes and set global effects if the conditions are met. Read the init.sqf and its instructions.

Based on eventhandler "killed"
Should be MP compatible - tested on dedi.
JIP behaviour still unknown.

Unless someone spots bugs or can suggest improvements, I concider this to be ready for submission.


IMPORTANT CHANGES in this version:

-Works also on vehicles like cars etc.
-Included an array called "LAGGY_FoundBodiesList" that contains all units (having the EH) that have been killed AND found under the set script conditions.
-Included the possibility of "Crucial Bodies", which means that you can check if specified units have been killed and found (based on unitName).
-Included the possibility of "Crucial Finders", which means that you can check if specified units have found any of the bodies (based on side,group and unitName).
-Included the possibility of "Crucial Bodies found by Crucial Finders", which means that you can check if the two are combined... defined Body found by defind Finder.
-Structured the init.sqf a little better.
-Updated example mission to be more informative and pedagogical.


Implementation: unit addEventHandler ["killed",{_this execVM "FindBody.sqf"}]


Options and Parameters:

All EH units are when killed and found put in an array that can be called.
An array to include specified units to be killed and found with specified effects.
An array to include specified units that might find bodies and with specified effects.
Check if the specified bodies are found by specified finders and with specified effects.
Check for different combinations of "corpse side" and "finder side".
Possibility to change the "searched" radius around the corpses.
Possibility to choose "awareness level" of the searchers (based on knowsAbout command).
Possibility to limit the search to bodies that are killed by enemy fire, not by collisions or friendly fire.


KNOWN ISSUES:

The dead units side still has to be checked through config, since all dead units become CIVILIAN. Not much I can do about that.
This means that if you change the side somehow on a unit having this eventhandler, when it dies the "original config side" will be active as side of dead unit.
This is a minor issue I think. In those rare occasions, just name the unit and include his name in the array LAGGY_CrucialBodies. He will then be treated as special (see init.sqf).
The array LAGGY_CrucialFinders can help too, as well as putting LAGGY_FindBody_checkaccidents to true.
Just make sure his "side change" doesn't conflict with other interests in your mission.


DISCLAIMER: Use at your own risk, you know the drill.

Hope you find it useful.

Laggy

OFPEC DOWNLOAD
« Last Edit: 19 Sep 2011, 11:19:26 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Dead Body reaction script (BETA).
« Reply #1 on: 10 Feb 2009, 22:30:45 »
You might try to improve that a bit, as that way (bodyDetected = true) there is no way to know outside that script which unit or side detected a dead body.

You may also add more parameters to allow destroyed vehicles detection.

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
Re: Dead Body reaction script (BETA).
« Reply #2 on: 10 Feb 2009, 22:35:00 »
Will do for sure,

Was mainly concerned if this script would be "tough" to run on many units in heavily populated areas.
Read somewhere that checking nearestObjects was quite demanding for your PC.
The possibility to check side of killed unit would also be great.
Do dead units have a side, for a short while before they join grpNull?

Another question is if checking for i.e "soldierWB" would work for any BLUFOR soldier models.
Just like "Man" checks for any man model.

Thanks,

Laggy
« Last Edit: 10 Feb 2009, 22:44:51 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Dead Body reaction script (BETA).
« Reply #3 on: 11 Feb 2009, 00:00:16 »
dead units are civilian side. Anyway I was meaning to know the side of the unit that detected the dead one. For example, in a MP game you publish the variable indicating that someone detected a dead unit, but then nobody knows which side detected the dead one, for example, to trigger the corresponding alarm, etc. Just as an example, you are in a group which infiltrating an enemy base, your group leader and the leaders of enemy groups use your script, then one of your AI mates detects the corpse of your last victim and the enemy triggers an alarm because everything is depending on a single global variable.

And nearobjects is not quite demanding as long as the selected scanning radious is short.

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
Re: Dead Body reaction script (BETA).
« Reply #4 on: 11 Feb 2009, 17:15:54 »
Thanks again.

Edit:

Just tried my new failing eventhandler + trigger solution.
Don't think the above nearestObjects solution is good, since it will care about units that got killed by "accidents", like a car hitting them... not uncommon in ArmA.
With an eventhandler you can exit the script if the unit was not killed by enemies.

In this early draft script I probably made a stupid mistake (or more) but...

Okay, I tried this:

INIT.SQF
Code: [Select]
LAGGY_deadCount = 0;

In units init:
this addEventHandler ["killed",{_this execVM "LAGGY_Friend_Kill_Det.sqf"}]
Code: [Select]
_unit = _this select 0;

LAGGY_deadCount = LAGGY_deadCount + 1;
publicVariable "LAGGY_deadCount";

_unit SetVehicleVarName format ["LAGGY_deadGuy%1", LAGGY_deadCount];
LAGGY_deadGuysName = vehicleVarName _unit;
publicVariable "LAGGY_deadGuysName";

_trigger = createTrigger ["EmptyDetector", position _unit];
_trigger setTriggerActivation ["ANY", "EAST D", false];
_trigger setTriggerArea [50, 50, 0, false];
_trigger setTriggerStatements ["LAGGY_deadGuysName in thislist", "LAGGY_eastAlarm = true; publicVariable ""LAGGY_eastAlarm""", ""];
_trigger setTriggerText "";

LAGGY_deadGuysName = Null;
publicVariable "LAGGY_deadGuysName";


It doesn't work, even though I get no error message.

Mu humble guess is that I don't understand how to put the "unitname" of the detected unit in the trigger correctly. Don't even know if this is a dead end solution.

The eventhandler is executed correctly, cause I have checked it with other solutions. An editor placed trigger now reacts to: LAGGY_eastAlarm and an OPFOR unit is "finding" the dead body.

Laggy
« Last Edit: 12 Feb 2009, 00:02:34 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Dead Body reaction script (BETA).
« Reply #5 on: 12 Feb 2009, 00:05:02 »
Well, if a patrol discovers a corpse, might be the death cause would be of little importance (they will not proceed with an on-the-fly autopsy  :P ).

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
Re: Dead Body reaction script (BETA).
« Reply #6 on: 12 Feb 2009, 00:15:05 »
HaHa!!!  :)

I guess you are right... Hm...
So do you think the nearestObjects solution would be better?
What I really was after with the trigger workaround was to detect the "side" of the unit before it was killed.
The eventhandler + trigger could possibly do that, if you dynamically change the triggers "detected by" depending on which eventhandler type you put in the init + the chance to exit if killed by friendlyFire.
« Last Edit: 12 Feb 2009, 00:19:05 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Dead Body reaction script (BETA).
« Reply #7 on: 12 Feb 2009, 00:40:39 »
For standard BIS missions probably you can detect the side of the corpse checking the typeOf, might be even with isKindOf:
Code: [Select]
if (_corpse isKindOf "SoldierWB") then {WEST SIDE};

Offline i0n0s

  • Moderator
  • *****
Re: Dead Body reaction script (BETA).
« Reply #8 on: 12 Feb 2009, 01:00:57 »
You can read the side from the config:
Code: [Select]
getNumber(configFile >> "CfgVehicles" >> typeOf _unit  >> "side")1 = west, 0 = east, 2 = resistance
« Last Edit: 12 Feb 2009, 02:09:20 by i0n0s »

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
Re: Dead Body reaction script (BETA).
« Reply #9 on: 12 Feb 2009, 01:45:35 »
Thanks all,

Think I might have found another good and "PC powersaving" solution.  :D :D :D
Looks very promising in editor.

Back tomorrow with update.

Laggy

EDIT:

Okay here it goes...

To save your PC some headache, I decided to go with an eventhandler "killed" to avoid running the script on all units that "might" find the body.

Instead I switched the role of _x so that the dead units body now checks for "finders" nearby.
The script checks for "same sided" units finding the dead body. BLUFOR looking for dead BLUFOR etc.

I also tried to avoid the script kicking in if the unit was not killed by enemy fire. I know this can be enhanced with maybe different parameters... checking sides finding other sides etc. This script is really easy to use though. My main worry is if it will have problems in Multiplayer.

In any units init or other wanted way:

this addEventHandler ["killed",{_this execVM "DetectFriendlyBody.sqf"}]

Code: [Select]
_deadguy = _this select 0;
_killer = _this select 1;
_deadguyside = getNumber (configFile >> "CfgVehicles" >> typeOf _deadguy  >> "side");
_killerside = getNumber (configFile >> "CfgVehicles" >> typeOf _killer  >> "side");

while { _deadguyside != _killerside } do
{
_finders = nearestObjects [vehicle _deadguy, ["AllVehicles"], 100];
   if (count _finders > 1) then
   {
      {
         if (_x != vehicle _deadguy) then
         {
            if ((_x knowsAbout vehicle _deadguy > 1) AND (getNumber (configFile >> "CfgVehicles" >> typeOf _x  >> "side") == _deadguyside)) then
            {
               FriendlyBodyDetected = true; publicVariable "FriendlyBodyDetected"
            };
         };
      } forEach _finders;
   };
sleep 2;
};


What do you think?

Laggy
« Last Edit: 12 Feb 2009, 11:41:36 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Dead Body reaction script (BETA).
« Reply #10 on: 12 Feb 2009, 11:30:40 »
The script is still not indicating detecting side or detected side.
Code: [Select]
call compile format ["FriendlyBodyDetected%1 = true", _deadguyside];
publicVariable format ["FriendlyBodyDetected%1", _deadguyside];

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
Re: Dead Body reaction script (BETA).
« Reply #11 on: 12 Feb 2009, 11:46:51 »
Okay guys... I think I have something special. Either I'm ignorant or clever  :P

I have this eventhandler "killed".

Code: [Select]
_deadguy = _this select 0;
_killer = _this select 1;
_deadguyside = getNumber (configFile >> "CfgVehicles" >> typeOf _deadguy  >> "side");
_killerside = getNumber (configFile >> "CfgVehicles" >> typeOf _killer  >> "side");

while { _deadguyside != _killerside } do
{
_finders = nearestObjects [vehicle _deadguy, ["AllVehicles"], LAGGY_FindBody_searchradius];
   if (count _finders > 1) then
   {
      {
         if (_x != vehicle _deadguy AND (alive _x)) then
         {
            if ((_x knowsAbout vehicle _deadguy > 0) AND (_x knowsAbout vehicle _deadguy > LAGGY_FindBody_awareness)) then
            {
               _searcherside = getNumber (configFile >> "CfgVehicles" >> typeOf _x  >> "side"); call compile format ["LAGGY_BodySide%1 = true", _deadguyside]; call compile format ["LAGGY_FinderSide%1 = true", _searcherside]; LAGGY_BodyAndFinderCombo = call compile format ["[LAGGY_BodySide%1,LAGGY_FinderSide%2]",_deadguyside,_searcherside]; publicVariable "LAGGY_BodyAndFinderCombo";
            };
         };
      } forEach _finders;
   };
sleep 2;
};

I then have this quite extensive init.sqf to check ALL possible bodySide/finderSide combinations.
You can also set parameters regarding radius and awareness.

Code: [Select]
// Set LAGGY_BodyAndFinderCombo as Nil.
LAGGY_BodyAndFinderCombo = Nil;

// Set the wanted search area radius around the units that you want to be found after being killed.
LAGGY_FindBody_searchradius = 50;

// Set awareness level of the "searchers". Number can be 0-4. The lower number the HIGHER awareness.
LAGGY_FindBody_awareness = 0;

// Set the combinations of "bodyside" and "finderside", and the desired effect.


while { true } do
{
            if (LAGGY_BodySide0 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide0 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An OPFOR body was found by OPFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide0 = false; LAGGY_FinderSide0 = false
    };
            if (LAGGY_BodySide0 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide1 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An OPFOR body was found by BLUFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide0 = false; LAGGY_FinderSide1 = false
    };
            if (LAGGY_BodySide0 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide2 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An OPFOR body was found by INDEPENDENT"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide0 = false; LAGGY_FinderSide2 = false
    };
            if (LAGGY_BodySide0 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide3 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An OPFOR body was found by CIVILIAN"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide0 = false; LAGGY_FinderSide3 = false
    };
            if (LAGGY_BodySide1 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide0 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A BLUFOR body was found by OPFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide1 = false; LAGGY_FinderSide0 = false
    };
            if (LAGGY_BodySide1 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide1 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A BLUFOR body was found by BLUFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide1 = false; LAGGY_FinderSide1 = false
    };
            if (LAGGY_BodySide1 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide2 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A BLUFOR body was found by INDEPENDENT"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide1 = false; LAGGY_FinderSide2 = false
    };
            if (LAGGY_BodySide1 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide3 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A BLUFOR body was found by CIVILIAN"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide1 = false; LAGGY_FinderSide3 = false
    };
            if (LAGGY_BodySide2 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide0 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An INDEPENDENT body was found by OPFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide2 = false; LAGGY_FinderSide0 = false
    };
            if (LAGGY_BodySide2 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide1 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An INDEPENDENT body was found by BLUFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide2 = false; LAGGY_FinderSide1 = false
    };
            if (LAGGY_BodySide2 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide2 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An INDEPENDENT body was found by INDEPENDENT"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide2 = false; LAGGY_FinderSide2 = false
    };
            if (LAGGY_BodySide2 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide3 in LAGGY_BodyAndFinderCombo) then
            {
               hint "An INDEPENDENT body was found by CIVILIAN"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide2 = false; LAGGY_FinderSide3 = false
    };
            if (LAGGY_BodySide3 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide0 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A CIVILIAN body was found by OPFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide3 = false; LAGGY_FinderSide0 = false
    };
            if (LAGGY_BodySide3 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide1 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A CIVILIAN body was found by BLUFOR"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide3 = false; LAGGY_FinderSide1 = false
    };
            if (LAGGY_BodySide3 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide2 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A CIVILIAN body was found by INDEPENDENT"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide3 = false; LAGGY_FinderSide2 = false
    };
            if (LAGGY_BodySide3 in LAGGY_BodyAndFinderCombo AND LAGGY_FinderSide3 in LAGGY_BodyAndFinderCombo) then
            {
               hint "A CIVILIAN body was found by CIVILIAN"; LAGGY_BodyAndFinderCombo = Nil; LAGGY_BodySide3 = false; LAGGY_FinderSide3 = false
    };
sleep 0.1;
};

Longing for feedback.
Thanks Mandoble, I0N0S and Worldeater for all the help.

Laggy
« Last Edit: 14 Feb 2009, 15:07:12 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Detect Bodies Script (Please give Feedback).
« Reply #12 on: 14 Feb 2009, 00:20:19 »
Still not sure about the killed EH. EHs are supposed to be persistent, so, after respawn, the EH is still there and then the respawned unit is killed again but the while of the previous EH is still active and now you execute a new one. So probably you will need a different way to exit that loop instead of just while { _deadguyside != _killerside }, might be:
Code: [Select]
while { (_deadguyside != _killerside) && (!alive _deadguy) }  do

Also, once someone detects a dead guy, the script will keep publishing the global all the time while the finder is close to the dead guy and knows something about him. So, might be a good idea to add a long sleep just after _searcherside = blah blah blah. Or wait there until the finder doesnt know anything about the dead guy, or the fider is killer or the dead guy respawns.

Offline laggy

  • Members
  • *
  • "Behold a pale horse"
Re: Detect Bodies Script (Please give Feedback).
« Reply #13 on: 14 Feb 2009, 00:26:39 »
Thanks Mandoble,

Will definetly look into that tomorrow.
Too tired and maybe too tipsy to script right now. Friday night after all.
Thanks for all the feedback so far.

EDIT:
1. How do you detect respawns? Player respawns I presume?
2. Where and how would the "sleep" function affect my Eventhandler script in a "PC_PowerSavingWay"?

What I'm looking for is a script that detects if "effectWanted" combinations are "true".
The init.sqf running on a ~ 0.1 loop shouldn't be that demanding on your system. Right?

Laggy
« Last Edit: 14 Feb 2009, 02:19:07 by laggy »
And I looked and beheld a pale horse and his name that sat on him was Death and Hell followed with him.

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Detect Bodies Script (Please give Feedback).
« Reply #14 on: 14 Feb 2009, 09:34:16 »
And a note, as this is unreadable:
Code: [Select]
_searcherside = getNumber (configFile >> "CfgVehicles" >> typeOf _x  >> "side"); call compile format ["LAGGY_BodySide%1 = true", _deadguyside]; call compile format ["LAGGY_FinderSide%1 = true", _searcherside]; LAGGY_BodyAndFinderCombo = call compile format ["[LAGGY_BodySide%1,LAGGY_FinderSide%2]",_deadguyside,_searcherside]; publicVariable "LAGGY_BodyAndFinderCombo";

Code: [Select]
_searcherside = getNumber (configFile >> "CfgVehicles" >> typeOf _x  >> "side");
call compile format ["LAGGY_BodyAndFinderCombo = [%1, %2]",  _deadguyside,_searcherside];
publicVariable "LAGGY_BodyAndFinderCombo";

So, what you have inside LAGGY_BodyAndFinderCombo is, for example ["WEST", "EAST"] or ["GUER", "CIV]";