Jump to content

Recommended Posts

Here is my Simple Auto-Gate or SAG 😉

The script is meant as a self contained system for creating automatic gate opening of bar-gates. The script works with pre-placed bar-gates, like on some of the CUP based maps, but will work just as well with bar-gates placed in the Eden editor.

It has been tested with both the ArmA 3 standard bar-gates and the CUP ones.

Just place a trigger using the editor so that the centre of the trigger is close to the bar-gate you want to control. Set the 'Name' of the trigger and set its size and orientation as required, the rest of the trigger parameters will be set by the script.

Create a folder called 'Scripts' in your mission directory and copy the 'sPK_autoGateInit.sqf' file to the directory.

You will need an 'init.sqf' file in the root directory of your mission with the following in it:

This example sets the system for GATE_NORTH and GATE_SOUTH triggers to control the vanilla bar-gate.

if ( isServer ) then {
   [
      [ GATE_NORTH, "Land_BarGate_F" ],
      [ GATE_SOUTH, "Land_RoadBarrier_01_F" ] // No comma on the last entry.
   ] call compileScript["Scripts\sPK_autoGateInit.sqf", true];
                                                   // true - compileFinal.
};

The if ( isServer ) block is to stop warnigns about running it on a player client when connecting to a dedicated server.

The compileScript is a replacement for compile preprocessorFile[LineNumbers] command.

Job done.

The system has an additional feature where you can call the script without the bar-gate class name. In this case it will display the class of the object nearest the trigger in a 'hint' and in the report file. Search for "GateClass:" in the report file:

[
   [ GATE_NORTH ],
   [ GATE_SOUTH ]
] call compileScript["Scripts\sPK_autoGateInit.sqf", true];

The output will look like:

10:35:14 "GateClass:GATE_NORTH:Land_BarGate_F"
10:35:14 "GateClass:GATE_SOUTH:Land_RoadBarrier_01_F"

Enjoy,  S

For the record, gate classes:

  • Land_BarGate_F – Vanilla bar-gate class.
  • Land_RoadBarrier_01_F – Metal frame bar-gate from Contact DLC.
  • Land_Zavora – CUP bar-gate class.
  • Land_zavora_2 – CUP bar-gate class, fractionally bigger and taller.

This is a link to a simple VR mission demonstration:

https://1drv.ms/u/s!AnX2_vGoXf5F911_Kg9MmzpPJQb8?e=ChpdqP

 

sPK_autoGateInit.sqf:

Spoiler

/*****
 * File: sPK_autoGateInit.sqf
 * Description:
 *    Initialisation file for automatic gate opening system.
 *    Gates are set so they cannot be damaged.
 *
 *    This will only run on the server.
 *
 *    To call this function (assuming it is in 'Script' directory):
 * [
 *    [ GATE_1, "Land_BarGate_F"],
 *    [ GATE_2, "Land_BarGate_F"]
 * ] call compileScript["Scripts\sPK_autoGateInit.sqf", true];
 *
 * Params:
 *    _gates: array: Array of gate trigger and classes. Each element is:
 *                      [
 *                         object, // Trigger object.
 *                         string // Optional trigger class.
 *                      ]
 * Globals:
 *    sPK_openGate: fnc: The open gate function.
 * Returns:
 *    nil: Return nothing.
 *
 * Author: shyPunK a.k.a. Strider(42|762)
 * Version: v0.04b 1 Apr 2021
 * Use at your own risk. Modify at your own need.
 */

#define sPK_reportError(errMsg) hint (errMsg); diag_log (errMsg);

// Make local variables private.
params [];

_gateClassInfo = "";

if ( ! isServer ) exitWith {
   sPK_reportError( "E:1:sPK_autoGateInit.sqf called on NON-server!" );
};

sPK_openGate = {
   params[];

   _trigger = _this param[0, objNull, [objNull]];
   _open    = _this param[1, 1, [1]]; // 1: Open gate; 0: Close gate.

   // Get the gate object.
   _gate = _trigger getVariable "sPK_Gate";

   // Animate the gate (open/close).
   _gate animateSource ["Door_1_sound_source", _open];
};

_sPK_autoGateSet = {
   //params[]; // Make local variables private.

   _trigger   = _this param[ 0, nil, [objNull] ];
   _gateClass = _this param[ 1, nil, [""] ];

   if ( isNil "_trigger" ) exitWith {
      _errMsg = format["E:2:_sPK_autoGateSet invalid parameter:%1", _this];
      sPK_reportError( _errMsg );
   };

   // Get the tirgger area.
   _triggerArea = triggerArea _trigger;

   // If gate class not specified then report the nearst object class and exit.
   if ( isNil "_gateClass" ) exitWith {

      // Get the nearest object.
      _gates = nearestObjects [ _trigger, [],
         (_triggerArea select 0) min (_triggerArea select 1) , true ];
                                                // true: Use 2D distance.

      // Create gate class info string.
      _gateInfo = format["%1:%2", str(_trigger),
                     typeOf (_gates select 1)];
      _gateClassInfo = _gateClassInfo + _gateInfo + endl;
      hint _gateClassInfo;

      // Write gate information to report file.
      diag_log ( 'GateClass:' + _gateInfo );
   };

   // Get the gate object.
   _gates = nearestObjects [ _trigger, [_gateClass],
      (_triggerArea select 0) min (_triggerArea select 1) , true ];
                                                // true: Use 2D distance.

   // The gate should be the first object.
   _gate = _gates select 0;

   // Stop the gate being damaged.
   _gate allowDamage false;

   // Configure trigger.
   _trigger setVariable[ "sPK_Gate", _gate ];
   _trigger setTriggerActivation[ "ANYPLAYER", "PRESENT", true ]; // Repeating.
   _trigger setTriggerStatements[ "this", "[thisTrigger,1] call sPK_openGate",
         "[thisTrigger,0] call sPK_openGate" ];
};

// Get passed parameter.
_gates = _this;

// Loop through the gates.
{
   _x call _sPK_autoGateSet;

} forEach _gates;

nil // Return nothing.

 

 

Edited by strider42
if(isServer) check added and explained
  • Like 5

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

×