First 'Lesson'

Quiz to help learn (Not required in any way).
What does the following code segment do?
Is there a better way to write the code?
Why are there multiple ‘isKindOf’ statements instead of an array?

if (!(_veh isKindOf "Car") || !(_veh isKindOf "Tank") || !(_veh isKindOf "Helicopter_Base_F") || !(_veh isKindOf "UAV") || !(_veh isKindOf "Plane_Base_F")) || (_veh = player) exitWith { _veh vehicleChat "This pad is for vehicle service only"; };

After reading this code provided I am confused. It appears that the objective was to determine if _veh was outside a list of vehicle types and then to end the script with a message to the user if true. It seems like the expression within the if statement will always return true for multiple reasons.
I’m taking a stab at re-writing this script to accomplish the intended function as I understood it…

Correct, the way that the if statement is written, if any of the NOT isKindOf statements are true the code will end and message the player. This statement will run all of them and as long as one returns true the code will end and send the message. There are ways to write and if statement to groups the statements so that it will stop after the first true.

He is an example of a more complex if statement using Lazy evaluation which will stop condition evaluation once one condition evaluation returns false.

((_cursorObjectDistance < 7) || {(!(_noObjectParent))}) &&
{((_cursorObject isKindOf 'LandVehicle') || {(_cursorObject isKindOf 'Air')} || {(_QS_v2 isKindOf 'LandVehicle')} || {(_QS_v2 isKindOf 'Air')})} &&
{(!(missionNamespace getVariable ['QS_repairing_vehicle',_false]))} &&
{(((vectorMagnitude (velocity _QS_v2)) * 3.6) <= 1)}

A very good document to explain Lazy evaluation is KK's blog – ArmA Scripting Tutorials: How To Switch On Lazy Evaluation by KILLZONEKID

The objective of this learning code was multipurpose.
First to understand the general idea of the code was to check the kind of vehicle in a trigger area and if it was not an allowed kind (not type) of vehicle or if the player was not in a vehicle then exit the script with a message indicating the vehicle in the trigger is not allowed.
The main learning goals were to learn how to read the Arma 3 Wiki, to learn the difference between typeOf and isKindOf, and to learn the parameters allowed by isKindOf. isKindOf according the Arma 3 Wiki (isKindOf - Bohemia Interactive Community) has 3 Syntax {object isKindOf typeName ;
typeName1 isKindOf typeName2 ; typeName1 isKindOf [typeName2, targetConfig]}. In or code we are using the first Syntax {object isKindOf typeName} the other 2 syntax would not work for our objective.
The first syntax of isKindOf requires the following values:
Syntax: object isKindOf typeName
Parameters: object: Object ; typeName: String
Return Value:Boolean
By the first syntax parameters you can see that we pass and object and a string, which answers the question “Why are there multiple ‘isKindOf’ statements instead of an array?” For the first parameter we need to pass an object, the object in this case is the vehicle in the trigger which we call _veh. The isKindOf syntax requires a single string for the second parameter. As the description on the Wiki indicates “Checks whether the object is (a subtype) of the given type.” Which means that you can pass a parent value in the class structure and any sub-classes will be allowed. I have created a class tree spreadsheet so that when you will be easily able to find parents and sub-classes. Arma Class Hierarchy - Google Sheets As you can see in the spreadsheet the is a ‘AllVehicles’ class but this could not be used as it included classes like ‘Man’ and ‘ParachuteBase’ which we do not want to repair. So we continue down the hierarchy until we include all the sub-classes we want but none of the classes we do not. Use the Spreadsheet and find the classes we did use Car, Tank, Helicopter_Base_F, UAV, and Plane_Base_F and try to identify why we did not use the parent to those classes.
Next, the error identified by T-man. The code (_veh = player) would set _veh to be the same value as player, not compare the values. To compare two values you must use ‘==’. The statement should read (_veh == player). This checks that the player is actually in a vehicle. We do not what the code to run when a player walks into the trigger. But there is a way to write this that will perform faster as indicated in(Code Optimisation - Bohemia Interactive Community) if we write (!(isNull objectParent player)) it will do the same check but run twice a fast, but even though it is twice as fast the difference in speed is 0.0009 ms, not a big difference.
The second question is, in the first part of the if statement

(!(_veh isKindOf "Car") || !(_veh isKindOf "Tank") || !(_veh isKindOf "Helicopter_Base_F") || !(_veh isKindOf "UAV") || !(_veh isKindOf "Plane_Base_F"))

As a group, we are checking each of the isKindOf’s, which means that the code will evaluate every single condition, even if one fails. There is another way to check if statements called Lazy Evaluation(Code Optimisation - Bohemia Interactive Community) which should be used if possible but in our case, it can not be used as we do not want the code to stop of the first isKindOf that evaluates to false.
Last to save a little performance we can swap the two groups of if conditions as if the player is not in a vehicle then we do not need to run the other group of conditions checking for vehicle isKindOf, to make this work we need to either imbricate or nest the if statements or use lazy evaluation.
Swapping the conditions with the error corrected and using lazy evaluation would look like this:

if ((_veh == player) || {!(_veh isKindOf "Car") || !(_veh isKindOf "Tank") || !(_veh isKindOf "Helicopter_Base_F") || !(_veh isKindOf "UAV") || !(_veh isKindOf "Plane_Base_F")}) exitWith { _veh vehicleChat "This pad is for vehicle service only"; };

The first ‘(’ and last ‘)’ make it a single statement the next pair of '()'wrap or first condition ‘_veh == player’. If this is false it will continue and enter the pair of ‘{}’ and evaluate all conditions inside, if true only the first condition is evaluated.
As stated this can be written in nested if statements which would return the same result:

if (!(_veh == player)) then {
	(!(_veh isKindOf "Car") || !(_veh isKindOf "Tank") || !(_veh isKindOf "Helicopter_Base_F") || !(_veh isKindOf "UAV") || !(_veh isKindOf "Plane_Base_F")) exitWith { _veh vehicleChat "This pad is for vehicle service only"; };

With all of or corrections for errors and speed improvements the final code should read:

if ((!(isNull objectParent player)) || {!(_veh isKindOf "Car") || !(_veh isKindOf "Tank") || !(_veh isKindOf "Helicopter_Base_F") || !(_veh isKindOf "UAV") || !(_veh isKindOf "Plane_Base_F")}) exitWith {_veh vehicleChat "This pad is for vehicle service only";};


This is beautiful, I have not worked with Arma before and after reading over these lessons you have posted I already understand what I am in for. These are very well written and very useful for learning how to code with arma. I will be spending a lot of time reading over the documentation you posted.