Jump to content
Sign in to follow this  
seannybgoode

help a brother out - need some clarification on arma 3 scripting

Recommended Posts

Here is a function for checking the sea level distance from airborne objects to a pos on the ground.

// wf_fnc_distance_to.sqf
// By Riouken


_obj1 = _this select 0;
_obj2 = _this select 1;




_pos_obj1 = [_obj1 select 0,_obj1 select 1];
_pos_obj2 = [_obj2 select 0,_obj2 select 1];


_result = _pos_obj1 distance _pos_obj2;


_result

I create it in a "init" file that I only run on the server(that way it is available anywhere on the server machine)

wf_fnc_distance_to = compile preprocessFileLineNumbers "server\fnc\wf_fnc_distance_to.sqf";

Now I can call it from any script on the server machine like this:

Here is a script(actually this is another function that I call it from) that I call it in:

_loc = _this select 0;
_cargo = _this select 1;


_spwnpos = [(getMarkerPos "air_spawn") select 0, (getMarkerPos "air_spawn") select 1,600];


_dir = [_spwnpos, _loc] call BIS_fnc_dirTo;


_c130array = [_spwnpos, _dir, "C130J_US_EP1", WEST] call bis_fnc_spawnvehicle;
_c130 = _c130array select 0;
_c130 allowDamage false;


_transgrp = group _c130;

_wp = _transgrp addWaypoint [_loc, 0];
[_transgrp, 0] setWaypointType "MOVE";
_c130 flyinHeight 400;


_dropcargo = false;
while {! _dropcargo} do
   {
       [color=#ff0000]_dist = [getPosAsl _c130,_loc] call wf_fnc_distance_to;[/color]

       if (_dist < 300) then 
           {
               _dropcargo = true;
           };
   sleep 1;
   };


waitUntil {_dropcargo};


if (_cargo == "Land_Misc_Cargo1E_EP1") then
   {
       _dropcargo = [_c130,_cargo] spawn wf_fnc_supply_drop;
       sleep .07;
       _dropcargo = [_c130,_cargo] spawn wf_fnc_supply_drop;
   }else
   {

       _dropcargo = [_c130,_cargo] spawn wf_fnc_supply_drop;
};


sleep 3;
_wp = _transgrp addWaypoint [_spwnpos, 1];
[_transgrp, 1] setWaypointType "MOVE";


_backtobase = false;
while {! _backtobase} do
   {
       _dist = [getPosAsl _c130,_spwnpos] call wf_fnc_distance_to;

       if (_dist < 500) then 
           {
               deleteVehicle _c130;
           };
   sleep 5;
   };

---------- Post added at 07:35 PM ---------- Previous post was at 07:22 PM ----------

Here is a silly example of a very limited scope for a function.

while {time > 10} do {


   _starttime = time;

   // This function will only be availble in this loop that we created it in.
   _howLongHasItBeen = {


           _newtime = (_this select 0) - _starttime;
           _newtime


       };




   While {true} do {




       _newtime = [time] call _howLongHasItBeen;


       hint str _newtime;
   sleep 1;
   };
sleep 1;
};






// _howLongHasItBeen would not work out side the loop above.

Edited by Riouken

Share this post


Link to post
Share on other sites

So wf_fnc_distance_to holds a reference to that script. Correct? So as long as you have that variable, you can call the function?

Parameters are passed to the function via an array, and then select 0, and select 1 are accessing those parameters. Correct?

I see what you're doing there, where a function is in a single sqf file. Is there a way to have multiple functions in a single file and then call one or the other?

Consider this simple Java class (Note this is taken from an actual project, so don't worry too much about what's going on inside the methods):

Here are my instance variables:

public class FloatingString extends BitmapFont
{
private static String FNT_FILE_PATH = "fnt/8bitwonder.fnt";
private static String TGA_FILE_PATH = "fnt/8bitwonder_0.tga";
private static float CHANGE_IN_Y = 1.5f;
private static float LIFETIME = 1f;

private float x;
private float y;
private float time;
private String string;

private boolean isExpired;

And the constructor - the method that gets run when an instance of the class is invoked:

	
public FloatingString(float x, float y, float scale, String str)
{
	super(new FileHandle(FNT_FILE_PATH), new FileHandle(TGA_FILE_PATH), false);
	this.setColor(1.0f, 1.0f, 1.0f, 0.5f);
	this.setScale(scale);
	this.x = x;
	this.y = y;
	this.time = 0;
	this.string = str;
	this.isExpired = false;
}

And a couple of methods:

public boolean effectIsExpired()
{
	return this.isExpired;
}

public void draw(SpriteBatch spriteBatch)
{
	this.time += Gdx.graphics.getDeltaTime();
	y += CHANGE_IN_Y;
	if(!(this.time > LIFETIME))
		super.draw(spriteBatch, this.string, this.x, this.y);
	else
		this.isExpired = true;

Now say I want to use this class file:

FloatingString myFloatingString = new Floating String(10f, 10f, 10f, "THIS IS MY FLOATING STRING OBJECT);

Now I've initialized the object and run the constructor, so I can call the methods in the object at will:

if(myFloatingString.effectIsExpired())
{
do thing
}

or I can call the method responsible for drawing as many or as few times as I like:

myfloatingString.draw(someSpriteBatch);

Do we see any construct like this in SQF? Or does each .sqf file run from top to bottom and that's it, and there's no way to call a specific part of the code?

Share this post


Link to post
Share on other sites

So wf_fnc_distance_to holds a reference to that script. Correct? So as long as you have that variable, you can call the function?

Yes that is correct.

Parameters are passed to the function via an array, and then select 0, and select 1 are accessing those parameters. Correct?

Yes

I see what you're doing there, where a function is in a single sqf file. Is there a way to have multiple functions in a single file and then call one or the other?

Yes there is, you can build and compile them all in one file and then reference them later:

This is a client function file from Domination, its a bit more advanced, he is using prepocessor commands and macros to compile and save them but yes it can be done.

#define THIS_FILE "x_playerfuncs.sqf"
#include "x_setup.sqf"


if ((GVAR(string_player) in GVAR(is_engineer)) || GVAR(with_ai) || GVAR(with_ai_features) == 0) then {
#ifndef __ACE__
FUNC(sfunc) = {
	private "_objs";
	if (vehicle player == player) then {
		_objs = nearestObjects [player, ["LandVehicle","Air"], 7];
		if (count _objs > 0) then {
			GVAR(objectID2) = _objs select 0;
			if (alive GVAR(objectID2)) then {
				(damage GVAR(objectID2) > 0.05 || fuel GVAR(objectID2) < 1)
			} else {
				false
			}
		}
	} else {
		false
	}
};
#else
FUNC(sfunc) = {
	private "_objs";
	if (vehicle player == player && (player call ace_sys_ruck_fnc_hasRuck)) then {
		_objs = nearestObjects [player, ["LandVehicle","Air"], 7];
		if (count _objs > 0) then {
			GVAR(objectID2) = _objs select 0;
			if (alive GVAR(objectID2)) then {
				(damage GVAR(objectID2) > 0.05 || fuel GVAR(objectID2) < 1)
			} else {
				false
			}
		}
	} else {
		false
	}
};
#endif
FUNC(ffunc) = {
	private ["_l","_vUp","_winkel"];
	if (vehicle player == player) then {
		GVAR(objectID1) = position player nearestObject "LandVehicle";
		if (!alive GVAR(objectID1) || player distance GVAR(objectID1) > 8) then {
			false
		} else {
			_vUp = vectorUp GVAR(objectID1);
			if ((_vUp select 2) < 0 && player distance (position player nearestObject GVAR(rep_truck)) < 20) then {
				true
			} else {
				_l=sqrt((_vUp select 0)^2+(_vUp select 1)^2);
				if (_l != 0) then {
					_winkel = (_vUp select 2) atan2 _l;
					(_winkel < 30 && player distance (position player nearestObject GVAR(rep_truck)) < 20)
				}
			}
		}
	} else {
		false
	}
};
};


FUNC(PlacedObjAn) = {
if (GVAR(string_player) == _this) then {
	if (GVAR(player_is_medic)) then {
		_m_name = "Mash " + _this;
		[QGVAR(w_ma),_m_name] call FUNC(NetCallEvent);
		__pSetVar [QGVAR(medtent), []];
		_medic_tent = __pGetVar(medic_tent);
		if (!isNil "_medic_tent") then {if (!isNull _medic_tent) then {deleteVehicle _medic_tent}};
		__pSetVar ["medic_tent", objNull];
		"Your mash was destroyed !!!" call FUNC(GlobalChat);
	};
	if (GVAR(player_can_build_mgnest)) then {
		_m_name = "MG Nest " + _this;
		[QGVAR(w_ma),_m_name] call FUNC(NetCallEvent);
		__pSetVar [QGVAR(mgnest_pos), []];
		_mg_nest = __pGetVar(mg_nest);
		if (!isNil "_mg_nest") then {if (!isNull _mg_nest) then {deleteVehicle _mg_nest}};
		__pSetVar ["mg_nest", objNull];
		"Your MG nest was destroyed !!!" call FUNC(GlobalChat);
	};
	if (GVAR(eng_can_repfuel)) then {
		_m_name = "FARP " + _this;
		[QGVAR(w_ma),_m_name] call FUNC(NetCallEvent);
		__pSetVar [QGVAR(farp_pos), []];
		_farp = __pGetVar(GVAR(farp_obj));
		if (!isNil "_farp") then {if (!isNull _farp) then {deleteVehicle _farp}};
		__pSetVar [QGVAR(farp_obj), objNull];
		"Your FARP was destroyed !!!" call FUNC(GlobalChat);
	};
};
};
#ifndef __TT__
FUNC(RecapturedUpdate) = {
private ["_index","_target_array", "_target_name", "_targetName","_state"];
PARAMS_2(_index,_state);
_target_array = GVAR(target_names) select _index;
_target_name = _target_array select 1;
switch (_state) do {
	case 0: {
		_target_name setMarkerColorLocal "ColorRed";
		_target_name setMarkerBrushLocal "FDiagonal";
		hint composeText[
			parseText("<t color='#f0ff0000' size='2'>" + "Attention:" + "</t>"), lineBreak,
			parseText("<t size='1'>" + format ["Enemy mobile forces have recaptured %1!!!", _target_name] + "</t>")
		];
		format ["Attention!!! Enemy mobile forces have recaptured %1!!!", _target_name] call FUNC(HQChat);
	};
	case 1: {
		_target_name setMarkerColorLocal "ColorGreen";
		_target_name setMarkerBrushLocal "Solid";
		hint composeText[
			parseText("<t color='#f00000ff' size='2'>" + "Good work!" + "</t>"), lineBreak,
			parseText("<t size='1'>" + format ["You have captured %1 again!!!", _target_name] + "</t>")
		];
	};
};
};
#endif
FUNC(PlayerRank) = {
private ["_score","_d_player_old_score","_d_player_old_rank"];
_score = score player;
_d_player_old_score = __pGetVar(GVAR(player_old_score));
if (isNil "_d_player_old_score") then {_d_player_old_score = 0};
_d_player_old_rank = __pGetVar(GVAR(player_old_rank));
if (isNil "_d_player_old_rank") then {_d_player_old_rank = "PRIVATE"};
if (_score < (GVAR(points_needed) select 0) && _d_player_old_rank != "PRIVATE") exitWith {
	if (_d_player_old_score >= (GVAR(points_needed) select 0)) then {(format ["You were degraded from %1 to Private !!!",_d_player_old_rank]) call FUNC(HQChat)};
	_d_player_old_rank = "PRIVATE";
	player setRank _d_player_old_rank;
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
	__pSetVar [QGVAR(player_old_score), _score];
};
if (_score < (GVAR(points_needed) select 1) && _score >= (GVAR(points_needed) select 0) && _d_player_old_rank != "CORPORAL") exitWith {
	if (_d_player_old_score < (GVAR(points_needed) select 1)) then {
		"You were promoted to Corporal, congratulations !!!" call FUNC(HQChat);
		playSound "fanfare";
	} else {
		(format ["You were degraded from %1 to Corporal !!!",_d_player_old_rank]) call FUNC(HQChat);
	};
	_d_player_old_rank = "CORPORAL";
	player setRank _d_player_old_rank;
	__pSetVar [QGVAR(player_old_score), _score];
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
};
if (_score < (GVAR(points_needed) select 2) && _score >= (GVAR(points_needed) select 1) && _d_player_old_rank != "SERGEANT") exitWith {
	if (_d_player_old_score < (GVAR(points_needed) select 2)) then {
		"You were promoted to Sergeant, congratulations !!!" call FUNC(HQChat);
		playSound "fanfare";
	} else {
		(format ["You were degraded from %1 to Sergeant !!!",_d_player_old_rank]) call FUNC(HQChat);
	};
	_d_player_old_rank = "SERGEANT";
	player setRank _d_player_old_rank;
	__pSetVar [QGVAR(player_old_score), _score];
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
};
if (_score < (GVAR(points_needed) select 3) && _score >= (GVAR(points_needed) select 2) && _d_player_old_rank != "LIEUTENANT") exitWith {
	if (_d_player_old_score < (GVAR(points_needed) select 3)) then {
		"You were promoted to Lieutenant, congratulations !!!" call FUNC(HQChat);
		playSound "fanfare";
	} else {
		(format ["You were degraded from %1 to Lieutenant !!!",_d_player_old_rank]) call FUNC(HQChat);
	};
	_d_player_old_rank = "LIEUTENANT";
	player setRank _d_player_old_rank;
	__pSetVar [QGVAR(player_old_score), _score];
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
};
if (_score < (GVAR(points_needed) select 4) && _score >= (GVAR(points_needed) select 3) && _d_player_old_rank != "CAPTAIN") exitWith {
	if (_d_player_old_score < (GVAR(points_needed) select 4)) then {
		"You were promoted to Captain, congratulations !!!" call FUNC(HQChat);
		playSound "fanfare";
	} else {
		(format ["You were degraded from %1 to Captain !!!",_d_player_old_rank]) call FUNC(HQChat);
	};
	_d_player_old_rank = "CAPTAIN";
	player setRank _d_player_old_rank;
	__pSetVar [QGVAR(player_old_score), _score];
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
};
if (_score < (GVAR(points_needed) select 5) && _score >= (GVAR(points_needed) select 4) && _d_player_old_rank != "MAJOR") exitWith {		
	if (_d_player_old_score < (GVAR(points_needed) select 4)) then {
		"You were promoted to Major, congratulations !!!" call FUNC(HQChat);
		playSound "fanfare";
	} else {
		(format ["You were degraded from %1 to Major !!!",_d_player_old_rank]) call FUNC(HQChat);
	};
	_d_player_old_rank = "MAJOR";
	player setRank _d_player_old_rank;
	__pSetVar [QGVAR(player_old_score), _score];
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
};
if (_score >= (GVAR(points_needed) select 5) && _d_player_old_rank != "COLONEL") exitWith {
	_d_player_old_rank = "COLONEL";
	player setRank _d_player_old_rank;
	"You were promoted to Colonel, congratulations !!!" call FUNC(HQChat);
	playSound "fanfare";
	__pSetVar [QGVAR(player_old_score), _score];
	__pSetVar [QGVAR(player_old_rank), _d_player_old_rank];
};
};


FUNC(GetRankIndex) = {["PRIVATE","CORPORAL","SERGEANT","LIEUTENANT","CAPTAIN","MAJOR","COLONEL"] find (toUpper (_this))};


FUNC(GetRankString) = {
switch (toUpper(_this)) do {
	case "PRIVATE": {"Private"};
	case "CORPORAL": {"Corporal"};
	case "SERGEANT": {"Sergeant"};
	case "LIEUTENANT": {"Lieutenant"};
	case "CAPTAIN": {"Captain"};
	case "MAJOR": {"Major"};
	case "COLONEL": {"Colonel"};
}
};


FUNC(GetRankFromScore) = {
if (_this < (GVAR(points_needed) select 0)) exitWith {"Private"};
if (_this < (GVAR(points_needed) select 1)) exitWith {"Corporal"};
if (_this < (GVAR(points_needed) select 2)) exitWith {"Sergeant"};
if (_this < (GVAR(points_needed) select 3)) exitWith {"Lieutenant"};
if (_this < (GVAR(points_needed) select 4)) exitWith {"Captain"};
if (_this < (GVAR(points_needed) select 5)) then {"Major"} else {"Colonel"}
};


FUNC(GetRankPic) = {
switch (toUpper(_this)) do {
	case "PRIVATE": {"\CA\warfare2\Images\rank_private.paa"};
	case "CORPORAL": {"\CA\warfare2\Images\rank_corporal.paa"};
	case "SERGEANT": {"\CA\warfare2\Images\rank_sergeant.paa"};
	case "LIEUTENANT": {"\CA\warfare2\Images\rank_lieutenant.paa"};
	case "CAPTAIN": {"\CA\warfare2\Images\rank_captain.paa"};
	case "MAJOR": {"\CA\warfare2\Images\rank_major.paa"};
	case "COLONEL": {"\CA\warfare2\Images\rank_colonel.paa"};
}
};


#ifndef __TT__
if (isNil "d_with_carrier") then {
FUNC(BaseEnemies) = {
	private "_status";
	_status = _this select 0;
	switch (_status) do {
		case 0: {
			hint composeText[
				parseText("<t color='#f0ff0000' size='2'>" + "DANGER:" + "</t>"), lineBreak,
				parseText("<t size='1'>" + "Enemy troops in your base." + "</t>")
			];
		};
		case 1: {
			hint composeText[
				parseText("<t color='#f00000ff' size='2'>" + "CLEAR:" + "</t>"), lineBreak,
				parseText("<t size='1'>" + "No more enemies in your base." + "</t>")
			];
		};
	};
};

FUNC(XFacAction) = {
	private ["_num","_thefac","_element","_posf","_facid","_exit_it"];
	PARAMS_1(_num);
	_thefac = switch (_num) do {
		case 0: {QGVAR(jet_serviceH)};
		case 1: {QGVAR(chopper_serviceH)};
		case 2: {QGVAR(wreck_repairH)};
	};
	waitUntil {(sleep 0.521 + (random 0.3));(X_JIPH getVariable _thefac)};
	_element = GVAR(aircraft_facs) select _num;
	_posf = _element select 0;
	sleep 0.543;
	_facid = -1;
	_exit_it = false;
	while {!_exit_it} do {
		sleep 0.432;
		switch (_num) do {
			case 0: {if (__XJIPGetVar(GVAR(jet_s_reb))) then {_exit_it = true}};
			case 1: {if (__XJIPGetVar(GVAR(chopper_s_reb))) then {_exit_it = true}};
			case 2: {if (__XJIPGetVar(GVAR(wreck_s_reb))) then {_exit_it = true}};
		};
		if (!_exit_it) then {
			if (player distance _posf < 14 && (X_JIPH getVariable _thefac) && _facid == -1) then {
				if (alive player) then {
					_facid = player addAction ["Rebuild Support Building" call FUNC(RedText),"x_client\x_rebuildsupport.sqf",_num];
				};
			} else {
				if (_facid != -1) then {
					if (player distance _posf > 13 || !(X_JIPH getVariable _thefac)) then {
						player removeAction _facid;
						_facid = -1;
					};
				};
			};
		} else {
			if (_facid != -1) then {player removeAction _facid};
		};
	};
};
};
#endif


FUNC(ProgBarCall) = {
private ["_captime", "_wf", "_curcaptime", "_disp", "_control", "_backgroundControl", "_maxWidth", "_position", "_newval"];
PARAMS_1(_wf);
disableSerialization;
_captime = _wf getVariable QGVAR(CAPTIME);
_curcaptime = _wf getVariable QGVAR(CURCAPTIME);
_curside = _wf getVariable QGVAR(SIDE);
_disp = __uiGetVar(DPROGBAR);
_control = _disp displayCtrl 3800;
_backgroundControl = _disp displayCtrl 3600;
_maxWidth = (ctrlPosition _backgroundControl select 2) - 0.01;
_position = ctrlPosition _control;
_newval = if (_curside != GVAR(own_side_trigger)) then {(_maxWidth * _curcaptime / _captime) max 0.02} else {_maxWidth};
_position set [2, _newval];
_r = 1 - (_newval * 2.777777);
_g = _newval * 2.777777;
_control ctrlSetPosition _position;
//_control ctrlSetBackgroundColor (if !(_wf getVariable QGVAR(STALL)) then {[0.543, 0.5742, 0.4102, 0.8]} else {[1, 1, 0, 0.8]});
_control ctrlSetBackgroundColor (if !(_wf getVariable QGVAR(STALL)) then {[_r, _g, 0, 0.8]} else {[1, 1, 0, 0.8]});
_control ctrlCommit 3;
};


FUNC(ArtyShellTrail) = {
private ["_shpos", "_trails", "_ns", "_sh", "_trail"];
PARAMS_3(_shpos,_trails,_ns);
if (_trails != "") then {
	_sh = _ns createVehicleLocal [_shpos select 0, _shpos select 1, 150];
	_sh setPosASL _shpos;
	_sh setVelocity [0,0,-150];
	_trail = [_sh] call compile preprocessFile _trails;
	waitUntil {isNull _sh};
	sleep 1;
	deleteVehicle _trail;
};
};


FUNC(ParaExploitHandler) = {
if (animationState player == "halofreefall_non") then {
	if ((_this select 4) isKindOf "TimeBombCore") then {
		deleteVehicle (_this select 6);
		player addMagazine (_this select 5);
	};
};
};


#ifdef __ACE__
FUNC(DHaha) = {
private ["_endtime", "_oldident"];
_endtime = __pGetVar(GVAR(HAHA_END));
if (isNil "_endtime") then {_endtime = -1};
if (time < _endtime) exitWith {
	_endtime = _endtime + 600;
	__pSetVar [QGVAR(HAHA_END), _endtime];
};
_endtime = time + 600;
__pSetVar [QGVAR(HAHA_END), _endtime];
_oldident = __pGetVar(ACE_Identity);
["ace_sys_goggles_setident2", [player, "ACE_GlassesHaHa"]] call CBA_fnc_globalEvent;
[_oldident] spawn {
	private ["_oldident", "_curident"];
	PARAMS_1(_oldident);
	while {time < __pGetVar(GVAR(HAHA_END))} do {
		if (alive player) then {
			_curident = __pGetVar(ACE_Identity);
			if (_curident != "ACE_GlassesHaHa") then {
				["ace_sys_goggles_setident2", [player, "ACE_GlassesHaHa"]] call CBA_fnc_globalEvent;
			};
		};
		sleep 1;
	};
	["ace_sys_goggles_setident2", [player, _oldident]] call CBA_fnc_globalEvent;
};
};
#endif


FUNC(LightObj) = {
private "_light";
_light = "#lightpoint" createVehicleLocal [0,0,0];
_light setLightBrightness 1;
_light setLightAmbient[0.2, 0.2, 0.2];
_light setLightColor[0.01, 0.01, 0.01];
_light lightAttachObject [_this, [0,0,0]];
};

Consider this simple Java class (Note this is taken from an actual project, so don't worry too much about what's going on inside the methods):

Do we see any construct like this in SQF? Or does each .sqf file run from top to bottom and that's it, and there's no way to call a specific part of the code?

Nope, SQF is not OO. each file will run based on its code and with the exceptions that we talked about earlier in the thread, ie saving data into variables or passing it to something else, once the sqf runs thats it.

I have to post this here, it would not let me post otherwise lol.

Share this post


Link to post
Share on other sites

So do all SQF functions not return any value? So we would return values via manipulating the global variables?

Share this post


Link to post
Share on other sites
Well I can't give SQF any points for best practices. I can already see that using the global namespace for anything that needs to be shared between threads as problematic. I'm sure that it gets confusing with large missions, and it's probably actually a big source of the problem when it comes to the Arma 3 security issues, since anything that needs to be shared must be visible to everything else.

That's why you should avoid using them whenever possible. Also, to avoid conflicts, you have to make sure the name is unique. Tags are used for exactly that purpose.

Now my question is can functions be public or private?

A function is basically a data type of code. Data types are held in variables so there's your answer :).

_privateFunction =
{
  private "_ret"; // This is important to prevent scope conflicts - function runs as a subscope of whatever scope it was called in
  _ret = 1 - damage player;
  // Last statement in a block of code is the return value
  _ret
};

TAG_publicFunction = // Since global variables have no namespacing we have to use the tags
{
  private "_ret";
  1 - damage player
};

Share this post


Link to post
Share on other sites
To hopefully get this back on topic... There are some conversion mods out there but it does not work the same as some other engine's like "source" etc... In arma you do not have as much access to the engine. Almost every thing is done with the API. So almost everything is done either mission/script based or Mod based.

For some good examples of conversion mods and how they are done here are some you can download and open up to see how it works.

http://dayzmod.com/

http://www.invasion-1944.com/download-i44/

http://www.cityliferpg.com/

Thank you exactly the answer I was looking for.

And every one else cheers for the good input and the additional reading.

Share this post


Link to post
Share on other sites

Am I right in thinking this is more of an event driven scripting language?

SQF files are not objects they are functions that may or may not return something?

Always use the server to store state unless absolutely sure that its not possible?

Is there a place to get a list of events that you can add functions to be run from?

This is becoming a great resource of information for arma 3 beginners but have previous object orientated experience. God I cant wait for the arma 3 java api.

Share this post


Link to post
Share on other sites
Am I right in thinking this is more of an event driven scripting language?

SQF files are not objects they are functions that may or may not return something?

Always use the server to store state unless absolutely sure that its not possible?

Is there a place to get a list of events that you can add functions to be run from?

This is becoming a great resource of information for arma 3 beginners but have previous object orientated experience. God I cant wait for the arma 3 java api.

1. Its a lot like procedural programing

2. SQF files are code. Not all are functions. Functions are saved to a variable and used at some point.

3. Yes in general when dealing with Multi Player you want to run as much of the code on the server as you can, and just localize the code that needs to run on the clients.

4. http://community.bistudio.com/wiki/ArmA:_Event_Handlers

http://community.bistudio.com/wiki/addEventHandler

5. Dont get your hopes up to far about Java, if or when it does arrive, the overhead from the system may not provide enough of a reason to use it over sqf except in explicit cases.

---------- Post added at 07:28 AM ---------- Previous post was at 07:21 AM ----------

The big idea behind functions is this: if your only going to need a peice of code once then just leave it in the .sqf and the call it with execVM. But if you will be using it more than once, its better for performance if you just compile it once and save it to a variable and then just call it from memory when you need it.

Share this post


Link to post
Share on other sites
1. Its a lot like procedural programing

2. SQF files are code. Not all are functions. Functions are saved to a variable and used at some point.

3. Yes in general when dealing with Multi Player you want to run as much of the code on the server as you can, and just localize the code that needs to run on the clients.

4. http://community.bistudio.com/wiki/ArmA:_Event_Handlers

http://community.bistudio.com/wiki/addEventHandler

5. Dont get your hopes up to far about Java, if or when it does arrive, the overhead from the system may not provide enough of a reason to use it over sqf except in explicit cases.

---------- Post added at 07:28 AM ---------- Previous post was at 07:21 AM ----------

The big idea behind functions is this: if your only going to need a peice of code once then just leave it in the .sqf and the call it with execVM. But if you will be using it more than once, its better for performance if you just compile it once and save it to a variable and then just call it from memory when you need it.

Cheers bud, very informative.

Share this post


Link to post
Share on other sites

Have a look at Mr-Murray ArmA Editing Guide. It's quit dated now , being for ArmA (think he tried to update it for ArmA2) but the general scripting principles remain the same and are explained in detail. There's a wealth of information int there.

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
Sign in to follow this  

×