<Yawn> Been up all night messing with this one... anyway...here's one take on the problem. My solution makes sure only pilots can fly helos and aircraft - all other players are rejected by the vehicle or moved into the cargo slots.
This solution requires version 1.91 of OFP which means that it currently may be of no use for
most dedicated servers (BIS, we need a 1.91 linux server!! ;-)
It has two parts:
First you have to add a line to the init.sqs of the mission in question. This line sets up a global
array of class names of units that will be accepted as pilots of the vehicle(s) in question.
gAcceptedPilots = [ "SoldierWPilot", "SoldierEPilot", "SoldierGPilot", "sebnam_acpilot", "bassoarpilot"];
The above example lists the three normal BIS provided pilots (West, East and Resistance) as
acceptable pilots. Also, the AirCav pilot from the SEB Nam Pack 2 and the SOAR pilot from the
BAS Littlebird (and others) addons are able to fly aircraft.
Ok, while you wonder what good that line will do, the second part is an event handler script. Here it is:
;
; checkDriverIsPilot.sqs
;
; By Killswitch, Mar 03
;
; Work-in-progress...
;
; Purpose:
; to make sure that the driver of a vehicle is a pilot. If not,
; the unit (can be a player) that entered will be ejected
; and possibly moved to the cargo space.
;
; Usage:
; for every vehicle (sensibly only helos and airplanes) that should have
; this functionality, add this script as a GetIn event handler. This can be done
; in a few different ways. The script is called with two parameters like this:
;
; [_this, moveToCargo] exec "checkDriverIsPilot.sqs" where
;
; _this the standard parameter that all event handlers get
; moveToCargo a boolean (value: true or false). Set to true if you
; want non-pilots moved to the cargo seats if they
; try to get in as drivers.
;
; This is how you install the handler ( 1 has true for moveToCargo, 2 has false):
;
; 1 - by adding the following to the unit's "Initialization" field in the editor:
;
; this addEventHandler ["getin", { [_this, true] exec "checkDriverIsPilot.sqs"; }];
;
; 2 - doing it in a script somewhere:
;
; <vehiclename> addEventHandler ["GetIn", { [_this, false] exec "checkDriverIsPilot.sqs"; }];
;
; where <vehiclename> is the edtor name of the vehicle, e.g helo1 or my_plane
;
; 3 - in a script to keep track of the handler if one wishes to remove only that one:
;
; handlerNbr = <vehiclename> addEventhandler...
;
; and then, later, to remove it:
;
; <vehiclename> removeHandler ["getin", handlerNbr]
;
;
; Output: Will do a short groupChat self-reasoning about climbing back if not pilot.
;
; Function: this handler is run whenever someone boards a vehicle. It checks to see if
; the unit (player or AI) entered as the driver (pilot), and, if so, checks
; if the unit is of any of the predefined Pilot class types. It does so by
; comparing the type of the unit against an array of class names listing
; acceptable drivers. This list is in the global array "gAcceptedPilots" which
; is initialized in init.sqs by a line similar to the following:
;
; gAcceptedPilots = ["SoldierWPilot", "SoldierEPilot", "SoldierGPilot"];
;
; If the unit that entered the vehicle as a driver is not of the accepted type,
; it will eject itself.
;
; Variations: one can imagine having similar handlers to ensure that only units of a "Crew"
; class can enter tanks and APC:s/IFV:s as commanders/drivers/gunners
;
;
; Caveats: if the cargo space is full and a non-pilot enters, he/she will be left
; standing outside of the vehicle even if the moveToCargo parameter is set to
; true. Sort of obvious...
;
requiredVersion "1.91"
_eventParams = _this select 0;
; Boolean, wether or not to automatically move pilot wannabees to the cargo.
_bMoveInCargo = _this select 1;
; The vehicle someone just got into/mounted
_veh = _eventParams select 0;
; The position that someone took - one of "driver", "gunner", "commander" or "cargo"
_position = _eventParams select 1;
; The unit (perhaps player) that has entered the vehicle
_unit = _eventParams select 2;
;
; Did he/she get in the pilot seat? If not then all is well and we exit
;
?! (_position == "driver"): goto "done"
; Someone is in the driver seat. Is it a pilot? Check the type of the driver
; against a global list of known soldier classes that are pilots
; (gAcceptedPilots is initialized in init.sqs)
? typeof _unit in gAcceptedPilots: goto "done";
; Ok. Not pilot and in driver seat. Get the unit out of there!
_unit Action ["EJECT", _veh];
~0.2
? !_bMoveInCargo : goto "done";
? (local player && player == _unit): player groupChat "Hmm...I'm not a pilot. I'd better ride in back";
_unit moveInCargo _veh;
#done
exit
I have done my best to make it self-describing, but, to reiterate: just add a "getin" event handler
to the aircraft you want to "lock" by adding something like
this addEventHandler ["getin", { [_this, true] exec "checkDriverIsPilot.sqs"; }];
to its initialization line. Setting the second parameter to true like above will move non-pilots
to the cargo seats, if available. If set to false, the unit (player) is just silently ejected.
One criticism of this two-pronged solution could be that it is sort of unnecessary to have
the gAcceptablePilots outside of the script and moving that into the script would make it
a nice packaged solution. However, being a programmer, I cringe at the thought of
repeatedly re-initializing often (or not-so-often) used basically static data. Also, this may
make the handler just that little bit more efficient, both memory- and performance-wise.
There. Have a look at it and see if it is of any use. I haven't been able to test it in MP myself,
so YMMV.
Comments, criticisms, bug reports and improvements are welcome!
Regards.