Jump to content

[Suggestion] Modular Compiles.sqf


Guest

Recommended Posts

Thought Raymix might be interested in this one due to his compiles.sqf rant in his latest (fantastic) video ;)
 
As it stands currently, most (although not all) Epoch functions are compiled on server load into functions which can be referenced via call by other scripts; Epoch is a fantastic mod in its own right, but I think we'd all agree that what makes Epoch great is the modding community which has sprung up around it. Most - if not all servers - are using numerous community scripts to provide their playerbase with a more personal experience, and therefore most servers out there are running custom compiles.
 
There are two commonly used methods for customizing these compiles; some people load \z\addons\dayz_code\init\compiles.sqf, and then have a second, barebones compiles.sqf mission-side which redirects these functions to code contained in the mission.pbo - this was the method suggested by Raymix in his tutorial. This is great for keeping the size of the mission file down, but it also means that some functions are being precompiled, then precompiled AGAIN when the second compiles.sqf loads.
 
The other method, which I personally use, is to move compiles.sqf over to the mission file and then reference that instead; whilst this avoids replacing already compiled functions (thus compiling them twice), it increases the size of the mission file. Not by much, admittedly, but it all adds up in the end.
 
With that in mind, and given the MASSIVE amount of customization prevalent in the Epoch community these days, I'd like to suggest a new format for the default compiles.sqf.
 
For example:

if (isNil "player_build") then { player_build = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_build.sqf"; };

With these checks in place, you could call your custom compiles in init.sqf BEFORE the base Epoch compiles.sqf, and it would skip precompiling functions which have already been compiled.

 

You could reduce the size of compiles.sqf even further by storing the function names and their filenames in a nested array. The array would look something like this:

 

_compile = [ [ "player_build", "player_build" ], [ "snap_build", "snap_build" ], [ "player_wearclothes", "player_wearclothes" ] ];

_actions = [ [ "player_countmagazines", "player_countmagainzes" ], [ "player_addToolbelt", "player_addToolbelt" ] ];

 

Then iterating through these arrays using { } count _compile, etc.

 

If we could standardize on keeping the name of each file the same as the function (there are a few which vary, such as [ "fnc_usec_selfactions", "fn_selfactions" ]), we could remove the need for nested arrays entirely and just use a 1D array for each function name.

 

Iterating each precompile would be as simple as referencing _x in that case.

 

Anyway, I'd welcome further thoughts/opinions on the matter :)

Link to comment
Share on other sites

I would agree that having the if statements before the compile in the Epoch pbo version of the compiles will simplify a lot and cut down on the need to copy the compiles.sqg mission side with everything in it.

 

Not so sure on the looped compiles definition from arrays idea.  Would probably like to test the practicality (setup , maintenance etc) first.

 

Personally I would also like to see the blocks of code moved to seperate (or a single functions) sqf file and only called from compiles.sqf.  That would make changes easier as the pbo compiles.sqf would not need to be changed in order to change those code blocks.

Link to comment
Share on other sites

Could you provide a code/pseudocode example? I'm ashamed to say that I haven't even touched Arma 3 yet, and therefore most of its functions are greek to me :P

Link to comment
Share on other sites

I would agree that having the if statements before the compile in the Epoch pbo version of the compiles will simplify a lot and cut down on the need to copy the compiles.sqg mission side with everything in it.

 

Not so sure on the looped compiles definition from arrays idea.  Would probably like to test the practicality (setup , maintenance etc) first.

 

Personally I would also like to see the blocks of code moved to seperate (or a single functions) sqf file and only called from compiles.sqf.  That would make changes easier as the pbo compiles.sqf would not need to be changed in order to change those code blocks.

 

From what I can tell, most of the codeblocks in compiles.sqf are just functions which haven't yet been split into files. Whether this was for any particular reason (shared variables, etc) or just time constraints, I'm unsure of. A quick cursory inspection would seem to indicate the latter, although ideally someone like vbawol needs to weigh in on this and let us know if we've missed something obvious :)

Link to comment
Share on other sites

Well, it works :)

 

Tested it with a few functions (too tired to write out a massive list of functions at the moment); here's the test code.

 

	_compile = [
		["fnc_usec_damageActions", "fn_damageActions"],
		["fnc_inAngleSector", "fn_inAngleSector"],
		["fnc_usec_selfActions", "fn_selfActions"],
		["fnc_usec_unconscious", "fn_unconscious"],
		["player_temp_calculation", "fn_temperatur"],
		["player_weaponFiredNear","player_weaponFiredNear"],
		["player_animalCheck","player_animalCheck"],
		["player_spawnCheck","player_spawnCheck"],
		["player_dumpBackpack","player_dumpBackpack"],
		["building_spawnLoot","building_spawnLoot"],
		["building_spawnZombies","building_spawnZombies"]
	];

	{
		_prefix = "\z\addons\dayz_code\compile\";
		if (isNil (_x select 0)) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%3.sqf"";", (_x select 0), _prefix, (_x select 1)]; };
		if (!isNil (_x select 0)) then { diag_log format["Function: %1 compiled!",(_x select 0)]; };
	} count _compile;

And the result:

"DayZ Epoch: PRELOAD Functions\init [[L 1-1-A:1 REMOTE],any]"
"DayZ Epoch: MPframework inited"
AH6X_DZ: FLIR_turret - unknown animation source FLIR_turret
AH6X_DZ: FLIR_gun - unknown animation source FLIR_gun
UH1Y_DZE: ObsTurret - unknown animation source ObsTurret
UH1Y_DZE: ObsGun - unknown animation source ObsGun
"Function: fnc_usec_damageActions compiled!"
"Function: fnc_inAngleSector compiled!"
"Function: fnc_usec_selfActions compiled!"
"Function: fnc_usec_unconscious compiled!"
"Function: player_temp_calculation compiled!"
"Function: player_weaponFiredNear compiled!"
"Function: player_animalCheck compiled!"
"Function: player_spawnCheck compiled!"
"Function: player_dumpBackpack compiled!"
"Function: building_spawnLoot compiled!"
"Function: building_spawnZombies compiled!"
"DEBUG: loadscreen guard started."

Next up: modify the function so that for functions named the same as their file, it uses a string entry in the main array rather than a nested array with _x select 0, etc.

Link to comment
Share on other sites

Finished the code for the external compiles, next up: moving the code blocks to files.

/*
	FUNCTION COMPILES
*/
//Player only
if (!isDedicated) then {

	"filmic" setToneMappingParams [0.07, 0.31, 0.23, 0.37, 0.011, 3.750, 6, 4]; setToneMapping "Filmic";
	BIS_Effects_Burn = compile preprocessFile "\ca\Data\ParticleEffects\SCRIPTS\destruction\burn.sqf";

	_compile = [
		"player_zombieCheck",
		"player_zombieAttack",
		["fnc_usec_damageActions", "fn_damageActions"],
		["fnc_inAngleSector", "fn_inAngleSector"],
		["fnc_usec_selfActions", "fn_selfActions"],
		["fnc_usec_unconscious", "fn_unconscious"],
		["player_temp_calculation", "fn_temperatur"],
		"player_weaponFiredNear",
		"player_animalCheck",
		"player_spawnCheck",
		"player_dumpBackpack",
		"building_spawnLoot",
		"building_spawnZombies",
		"player_fired",
		"player_harvest",
		"player_packTent",
		"player_packVault",
		"player_unlockVault",
		["player_removeNearby", "object_removenearby"],
		"player_unlockDoor",
		"player_changeCombo",
		["player_plotPreview","object_showPlotRadius"],
		"player_upgradeVehicle",
		"player_lockVault",
		"player_updateGui",
		"player_crossbowBolt",
		"player_music",
		"player_death",
		"player_switchModel",
		"player_checkStealth",
		["world_sunRise","fn_sunRise"],
		["world_surfaceNoise","fn_surfaceNoise"],
		"player_humanityMorph",
		"player_throwObject",
		"player_alertZombies",
		"fn_gearMenuChecks",
		"object_roadFlare",
		["object_setpitchbank","fn_setpitchbank"],
		"object_monitorGear",
		"local_roadDebris",
		"zombie_findTargetAgent",
		"zombie_loiter",
		"zombie_generate",
		"wild_spawnZombies",
		"dog_findTargetAgent",
		"player_antiWall",
		["player_selectSlot","ui_selectSlot"],
		"player_gearSync",
		"player_gearSet",
		"ui_changeDisplay",
		"ui_gear_sound",
		["player_hasTools","fn_hasTools"],
		["player_checkItems","fn_checkItems"],
		["player_removeItems","fn_removeItems"],
		"player_traderCity",
		"epoch_returnChange"
	];

	{
		_prefix = "\z\addons\dayz_code\compile\";
		if (typename _x == "STRING") then {
			if (isNil _x) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%1.sqf"";", _x, _prefix]; };
		} else {
			if (isNil (_x select 0)) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%3.sqf"";", (_x select 0), _prefix, (_x select 1)]; };
		};
	} count _compile;

	call compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_murderMenu.sqf"; // recent murders menu code

	_actions = [
		"dayz_spaceInterrupt",
		["player_removeObject","remove"],
		["pz_attack","pzombie\pz_attack"],
		"player_countmagazines",
		"player_addToolbelt",
		"player_copyKey",
		["player_reloadMag","player_reloadMags"],
		"player_loadCrate",
		"player_craftItem",
		["player_tentPitch","tent_pitch"],
		["player_vaultPitch","vault_pitch"],
		"player_drink",
		"player_eat",
		"player_useMeds",
		["player_fillWater","water_fill"],
		"player_makeFire",
		"player_harvestPlant",
		"player_goFishing",
		"player_build",
		"player_wearClothes",
		"object_pickup",
		"player_flipvehicle",
		"player_sleep",
		["player_deathBoard","list_playerDeathsAlt"]
	];
	
	{
		_prefix = "\z\addons\dayz_code\actions\";
		if (typename _x == "STRING") then {
			if (isNil _x) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%1.sqf"";", _x, _prefix]; };
		} else {
			if (isNil (_x select 0)) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%3.sqf"";", (_x select 0), _prefix, (_x select 1)]; };
		};
	} count _actions;

	_system = [
		"player_monitor",
		"player_spawn_1",
		"player_spawn_2",
		["player_fireMonitor","fire_monitor"]
	];
	
	{
		_prefix = "\z\addons\dayz_code\system\";
		if (typename _x == "STRING") then {
			if (isNil _x) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%1.sqf"";", _x, _prefix]; };
		} else {
			if (isNil (_x select 0)) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%3.sqf"";", (_x select 0), _prefix, (_x select 1)]; };
		};
	} count _system;

	onPreloadStarted 			"dayz_preloadFinished = false;";
	onPreloadFinished 			"dayz_preloadFinished = true;";

	player_removeTankTrap = {
		//Object Array, Range, Error Message (@Skaronator)
		[["Hedgehog_DZ"], 1,"STR_EPOCH_ACTIONS_14"] call player_removeNearby;
	};
	player_removeNet = {
		[["DesertLargeCamoNet","ForestCamoNet_DZ","DesertLargeCamoNet_DZ","ForestLargeCamoNet_DZ"], 5,"str_epoch_player_8"] call player_removeNearby;
	};

	player_login = {
		private ["_unit","_detail"];
		_unit = _this select 0;
		_detail = _this select 1;
		if(_unit == getPlayerUID player) then {
			player setVariable["publish",_detail];
		};
	};

	// combination of check && remove items
	player_checkAndRemoveItems = {
		private ["_items","_b"];
		_items = _this;
		_b = _items call player_checkItems;
		if (_b) then {
			_b = _items call player_removeItems;
		};
		_b
	};

	dayz_HungerThirst = {
		dayz_hunger = dayz_hunger + (_this select 0);
		dayz_thirst = dayz_thirst + (_this select 1);
	};

	epoch_totalCurrency = {
		// total currency
		_total_currency = 0;
		{
			_part =  (configFile >> "CfgMagazines" >> _x);
			_worth =  (_part >> "worth");
			if isNumber (_worth) then {
				_total_currency = _total_currency + getNumber(_worth);
			};
		} count (magazines player);
		_total_currency
	};

	epoch_itemCost = {
		_trade_total = 0;
		{
			_part_in_configClass =  configFile >> "CfgMagazines" >> (_x select 0);
			if (isClass (_part_in_configClass)) then {
				_part_inWorth = (_part_in_configClass >> "worth");
				if isNumber (_part_inWorth) then {
					_trade_total = _trade_total + (getNumber(_part_inWorth) * (_x select 1));
				};
			};
		} count _this;

		//diag_log format["DEBUG TRADER ITEMCOST: %1", _this];
		_trade_total
	};

	// usage [["partinclassname",4]] call epoch_returnChange;

	dayz_losChance = {
		private["_agent","_maxDis","_dis","_val","_maxExp","_myExp"];
		_agent = 	_this select 0;
		_dis =		_this select 1;
		_maxDis = 	_this select 2;
		// diag_log ("VAL:  " + str(_this));
		_val = 		(_maxDis - _dis) max 0;
		_maxExp = 	((exp 2) * _maxDis);
		_myExp = 	((exp 2) * (_val)) / _maxExp;
		_myExp =	_myExp * 0.7;
		_myExp
	};

	ui_initDisplay = {
		private["_control","_ctrlBleed","_display","_ctrlFracture","_ctrlDogFood","_ctrlDogWater","_ctrlDogWaterBorder", "_ctrlDogFoodBorder"];
		disableSerialization;
		_display = uiNamespace getVariable 'DAYZ_GUI_display';
		_control = _display displayCtrl 1204;
		_control ctrlShow false;
		if (!r_player_injured) then {
			_ctrlBleed = _display displayCtrl 1303;
			_ctrlBleed ctrlShow false;
		};
		if (!r_fracture_legs && !r_fracture_arms) then {
			_ctrlFracture = _display displayCtrl 1203;
			_ctrlFracture ctrlShow false;
		};
		_ctrlDogFoodBorder = _display displayCtrl 1501;
		_ctrlDogFoodBorder ctrlShow false;
		_ctrlDogFood = _display displayCtrl 1701;
		_ctrlDogFood ctrlShow false;

		_ctrlDogWaterBorder = _display displayCtrl 1502;
		_ctrlDogWaterBorder ctrlShow false;
		_ctrlDogWater = _display displayCtrl 1702;
		_ctrlDogWater ctrlShow false
	};

	dayz_losCheck = {
		private["_target","_agent","_cantSee"];
		_target = _this select 0; // PUT THE PLAYER IN FIRST ARGUMENT!!!!
		_agent = _this select 1;
		_cantSee = true;
		if (!isNull _target) then {

			_tPos = visiblePositionASL _target;
			_zPos = visiblePositionASL _agent;

			_tPos set [2,(_tPos select 2)+1];
			_zPos set [2,(_zPos select 2)+1];

			if ((count _tPos > 0) && (count _zPos > 0)) then {
				_cantSee = terrainIntersectASL [_tPos, _zPos];
				if (!_cantSee) then {
					_cantSee = lineIntersects [_tPos, _zPos, _agent, vehicle _target];
				};
			};
		};
		_cantSee
	};

	dayz_equipCheck = {
		private ["_empty", "_needed","_diff","_success"];
		_config = _this;
		_empty = [player] call BIS_fnc_invSlotsEmpty;
		_needed = [_config] call BIS_fnc_invSlotType;
		_diff = [_empty,_needed] call BIS_fnc_vectorDiff;

		_success = true;
		{
			if (_x > 0) then {_success = false};
		} count _diff;
		hint format["Config: %5\nEmpty: %1\nNeeded: %2\nDiff: %3\nSuccess: %4",_empty,_needed,_diff,_success,_config];
		_success
	};

	vehicle_gear_count = {
		private["_counter"];
		_counter = 0;
		{
			_counter = _counter + _x;
		} count _this;
		_counter
	};

	player_tagFriendlyMsg = {
		if(player == (_this select 0)) then {
			cutText[(localize "str_epoch_player_2"),"PLAIN DOWN"];
		};
	};

	player_serverModelChange = {
		private["_object","_model"];
		_object = _this select 0;
		_model = _this select 1;
		if (_object == player) then {
			_model call player_switchModel;
		};
	};

	player_guiControlFlash = 	{
		private["_control"];
		_control = _this;
		if (ctrlShown _control) then {
			_control ctrlShow false;
		} else {
			_control ctrlShow true;
		};
	};
	
	gearDialog_create = {
		private ["_i","_dialog"];
		if (!isNull (findDisplay 106)) then {
			(findDisplay 106) closeDisplay 0;
		};
		openMap false;
		closeDialog 0;
		if (gear_done) then {sleep 0.001;};
		player action ["Gear", player];
		if (gear_done) then {sleep 0.001;};
		_dialog = findDisplay 106;
		_i = 0;
		while {isNull _dialog} do {//DO NOT CHANGE TO A FOR LOOP!
			_i = _i + 1;
			_dialog = findDisplay 106;
			if (gear_done) then {sleep 0.001;};
			if (_i in [100,200,299]) then {
				closeDialog 0;
				player action ["Gear", player];
			};
			if (_i > 300) exitWith {};
		};
		if (gear_done) then {sleep 0.001;};
		_dialog = findDisplay 106;
		if ((parseNumber(_this select 0)) != 0) then {
			ctrlActivate (_dialog displayCtrl 157);
			if (gear_done) then {
				waitUntil {ctrlShown (_dialog displayCtrl 159)};
				sleep 0.001;
			};
		};
		_dialog
	};

	gear_ui_offMenu = {
		private["_control","_parent","_menu"];
		disableSerialization;
		_control = _this select 0;
		_parent = findDisplay 106;
		if (!(_this select 3)) then {
			for "_i" from 0 to 9 do {
				_menu = _parent displayCtrl (1600 + _i);
				_menu ctrlShow false;
			};
			_grpPos = ctrlPosition _control;
			_grpPos set [3,0];
			_control ctrlSetPosition _grpPos;
			_control ctrlShow false;
			_control ctrlCommit 0;
		};
	};

	dze_surrender_off = {
		player setVariable ["DZE_Surrendered", false, true];
		DZE_Surrender = false;
	};

	gear_ui_init = {
		private["_control","_parent","_menu","_dspl","_grpPos"];
		disableSerialization;
		_parent = findDisplay 106;
		_control = 	_parent displayCtrl 6902;
		for "_i" from 0 to 9 do {
			_menu = _parent displayCtrl (1600 + _i);
			_menu ctrlShow false;
		};
		_grpPos = ctrlPosition _control;
		_grpPos set [3,0];
		_control ctrlSetPosition _grpPos;
		_control ctrlShow false;
		_control ctrlCommit 0;
	};

	dayz_eyeDir = {
		private["_vval","_vdir"];
		_vval = (eyeDirection _this);
		_vdir = (_vval select 0) atan2 (_vval select 1);
		if (_vdir < 0) then {_vdir = 360 + _vdir};
		_vdir
	};

	DZE_getModelName = {
		_objInfo = toArray(str(_this));
		_lenInfo = count _objInfo - 1;
		_objName = [];
		_i = 0;
		// determine where the object name starts
		{
			if (58 == _objInfo select _i) exitWith {};
			_i = _i + 1;
		} count _objInfo;
		_i = _i + 2; // skip the ": " part
		for "_k" from _i to _lenInfo do {
			_objName set [(count _objName), (_objInfo select _k)];
		};
		_objName = toLower(toString(_objName));
		_objName
	};

	dze_isnearest_player = {
		private ["_notClosest","_playerDistance","_nearPlayers","_obj","_playerNear"];
		if(!isNull _this) then {
			_nearPlayers = _this nearEntities ["CAManBase", 12];
			_playerNear = ({isPlayer _x} count _nearPlayers) > 1;
			_notClosest = false;
			if (_playerNear) then {
				// check if another player is closer
				_playerDistance = player distance _this;
				{
					if (_playerDistance > (_x distance _this)) exitWith { _notClosest = true; };
				} count _nearPlayers;
			};
		} else {
			_notClosest = false;
		};
		_notClosest
	};

	
	// trader menu code
	if (DZE_ConfigTrader) then {
		call compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_traderMenuConfig.sqf";
	}else{
		call compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_traderMenuHive.sqf";
	};

	//This is still needed but the fsm should terminate if any errors pop up.
	[] spawn {
        private["_timeOut","_display","_control1","_control2"];
        disableSerialization;
        _timeOut = 0;
        dayz_loadScreenMsg = "";
        diag_log "DEBUG: loadscreen guard started.";
        _display = uiNameSpace getVariable "BIS_loadingScreen";
        if (!isNil "_display") then {
                _control1 = _display displayctrl 8400;
                _control2 = _display displayctrl 102;
        };
		if (!isNil "dayz_DisplayGenderSelect") then {
			waitUntil {!dayz_DisplayGenderSelect};
		};

        // 120 sec timeout (12000 * 0.01)
        while { _timeOut < 12000 } do {
            if (dayz_clientPreload && dayz_authed) exitWith { diag_log "PLOGIN: Login loop completed!"; };
            if (!isNil "_display") then {
                if ( isNull _display ) then {
                        waitUntil { !dialog; };
                        startLoadingScreen ["","RscDisplayLoadCustom"];
                        _display = uiNameSpace getVariable "BIS_loadingScreen";
                        _control1 = _display displayctrl 8400;
                        _control2 = _display displayctrl 102;
                };

                if ( dayz_loadScreenMsg != "" ) then {
                        _control1 ctrlSetText dayz_loadScreenMsg;
                        dayz_loadScreenMsg = "";
                };

                _control2 ctrlSetText format["%1",round(_timeOut*0.01)];
            };

            _timeOut = _timeOut + 1;

            if (_timeOut >= 12000) then {
                1 cutText [localize "str_player_login_timeout", "PLAIN DOWN"];
                sleep 10;
                endLoadingScreen;
                endMission "END1";
            };

            sleep 0.01;
        };
	};

	dayz_meleeMagazineCheck = {
		private["_meleeNum","_magType"];
		_magType = ([] + getArray (configFile >> "CfgWeapons" >> _wpnType >> "magazines")) select 0;
		_meleeNum = ({_x == _magType} count magazines player);
		if (_meleeNum < 1) then {
				player addMagazine _magType;
		};
	};

	dayz_originalPlayer = player;
	progressLoadingScreen 0.8;
};

	fnc_veh_ResetEH = compile preprocessFileLineNumbers "\z\addons\dayz_code\init\veh_ResetEH.sqf";
	
	_compileBoth = [
		["BIS_fnc_selectRandom","BIS_fnc\fn_selectRandom"],
		["BIS_fnc_vectorAdd","BIS_fnc\fn_vectorAdd"],
		["BIS_fnc_halo","BIS_fnc\fn_halo"],
		["BIS_fnc_findNestedElement","BIS_fnc\fn_findNestedElement"],
		["BIS_fnc_param","BIS_fnc\fn_param"],
		["fnc_buildWeightedArray","fn_buildWeightedArray"],
		["fnc_usec_damageVehicle","fn_damageHandlerVehicle"],
		"object_setHitServer",
		"object_setFixServer",
		"object_getHit",
		"object_setHit",
		"object_processHit",
		"object_delLocal",
		["fnc_usec_damageHandler","fn_damageHandler"],
		"vehicle_handleDamage",
		"vehicle_handleKilled",
		["fnc_inString","fn_inString"],
		["fnc_isInsideBuilding","fn_isInsideBuilding"],
		["fnc_isInsideBuilding2","fn_isInsideBuilding2"],
		["fnc_isInsideBuilding3","fn_isInsideBuilding3"],
		["dayz_zombieSpeak","object_speak"],
		"vehicle_getHitpoints",
		"local_gutObject",
		"local_lockUnlock",
		"local_gutObjectZ",
		["local_zombieDamage","fn_damageHandlerZ"],
		"local_eventKill",
		["curTimeStr","fn_curTimeStr"],
		"player_humanityChange",
		"spawn_loot",
		"spawn_loot_small"
	];
	
	{
		_prefix = "\z\addons\dayz_code\compile\";
		if (typename _x == "STRING") then {
			if (isNil _x) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%1.sqf"";", _x, _prefix]; };
		} else {
			if (isNil (_x select 0)) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%3.sqf"";", (_x select 0), _prefix, (_x select 1)]; };
		};
	} count _compileBoth;

	_medical = [
		["player_medBandage","medBandaged"],
		["player_medInject","medInject"],		
		["player_medEpi","medEpi"],		
		["player_medTransfuse","medTransfuse"],		
		["player_medMorphine","medMorphine"],		
		["player_breaklegs","medBreakLegs"],		
		["player_medPainkiller","medPainkiller"]		
	];
	
	{
		_prefix = "\z\addons\dayz_code\medical\publicEH\";
		if (typename _x == "STRING") then {
			if (isNil _x) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%1.sqf"";", _x, _prefix]; };
		} else {
			if (isNil (_x select 0)) then { call compile format["%1 = compile preprocessFileLineNumbers ""%2%3.sqf"";", (_x select 0), _prefix, (_x select 1)]; };
		};
	} count _medical;

	world_isDay = { if ((daytime < (24 - dayz_sunRise)) && (daytime > dayz_sunRise)) then {true} else {false} };

	FNC_GetSetPos = { //DO NOT USE IF YOU NEED ANGLE COMPENSATION!!!!
		private "_pos";
		_thingy = _this select 0;
		_pos = getPosASL _thingy;
		if (surfaceIsWater _pos) then {
			_thingy setPosASL _pos;
		} else {
			_thingy setPosATL (ASLToATL _pos);
		};
	};
	FNC_GetPos = {
		private "_pos";
		if (isNil {_this select 0}) exitWith {[0,0,0]};
		_thingy = _this select 0;
		_pos = getPosASL _thingy;
		if !(surfaceIsWater _pos) then {
			_pos =  ASLToATL _pos;
		};
		_pos
	};
	local_setFuel =	{
		private["_qty","_vehicle"];
		_vehicle = _this select 0;
		_qty = _this select 1;
		_vehicle setFuel _qty;
	};
	zombie_initialize = {
		private ["_unit","_position"];
		_unit = _this select 0;
		if (isServer) then {
			_unit addEventHandler ["local", {_this call zombie_findOwner}];
		};
		_id = _unit addeventhandler["HandleDamage", { _this call local_zombieDamage }];
		_id = _unit addeventhandler["Killed", { [_this, "zombieKills"] call local_eventKill }];
	};

	dayz_EjectPlayer = {
		// check if player in vehicle
        private ["_noDriver","_vehicle","_inVehicle"];
        _vehicle = vehicle player;
		_inVehicle = (_vehicle != player);
		if(_inVehicle) then {
			_noDriver = ((_vehicle emptyPositions "driver") > 0);
			if (_noDriver && (speed _vehicle) != 0) then {
				player action [ "eject", _vehicle];
			};
		};
	};

	player_sumMedical = {
		private["_character","_wounds","_legs","_arms","_medical"];
		_character = 	_this;
		_wounds =		[];
		if (_character getVariable["USEC_injured",false]) then {
			{
				if (_character getVariable[_x,false]) then {
					_wounds set [count _wounds,_x];
				};
			} count USEC_typeOfWounds;
		};
		_legs = _character getVariable ["hit_legs",0];
		_arms = _character getVariable ["hit_arms",0];
		_medical = [
			_character getVariable["USEC_isDead",false],
			_character getVariable["NORRN_unconscious", false],
			_character getVariable["USEC_infected",false],
			_character getVariable["USEC_injured",false],
			_character getVariable["USEC_inPain",false],
			_character getVariable["USEC_isCardiac",false],
			_character getVariable["USEC_lowBlood",false],
			_character getVariable["USEC_BloodQty",12000],
			_wounds,
			[_legs,_arms],
			_character getVariable["unconsciousTime",0],
			_character getVariable["messing",[0,0]]
		];
		_medical
	};

	//Server Only
	if (isServer) then {
		call compile preprocessFileLineNumbers "\z\addons\dayz_server\init\server_functions.sqf";
	} else {
		eh_localCleanup = {};
	};

initialized = true;
Link to comment
Share on other sites

This might work and MAYBE help performance, 100% not tested...

bd24821e3e.png

 

fnc_callLazyLoadFnc = {
private ["_fnc", "_params", "_return"];
_fnc = _this select 0;
_params = _this select 1;
if (isNil _fnc) then {
_file = getText (missionConfigFile >> "EpochFunctions" >> _fnc >> "file");
// load fnc
call compile (_fnc + " = compile preprocessFileLineNumbers '" + _file + "';");
};
call compile ("_return = _params call " + _fnc);
_return
};
 
["player_build", [param1]] call fnc_callLazyLoadFnc;
 
 
// Cfg
 
class EpochFunctions {
class player_build {
file = "path\to\player_build.sqf";
};
};

Link to comment
Share on other sites

That, right there, is fucking genius.

Only "downside", if you could call it that, is that it would require changing ALL the calls throughout the Epoch code though. With that said, if it has a significant performance increase, it'd be worth it.

 

I volunteer Maca to test it out and report back to us :D

Link to comment
Share on other sites

That, right there, is fucking genius.

Only "downside", if you could call it that, is that it would require changing ALL the calls throughout the Epoch code though. With that said, if it has a significant performance increase, it'd be worth it.

 

I volunteer Maca to test it out and report back to us :D

 

Test it out for mission based compiles and leave the main compiles with the original sugestion of "if not then compile each item".  If that works fine then just move them over a bit at a time.  Just deal with the custom compiles and main compiles first then scan through for other compiles in scattered files at a later time.

 

Framework for mod makers

Move core compiles on to it

Look at anything else

 

Makes it a bit more manageable (and easier to debug should something go wrong).

Link to comment
Share on other sites

Nice work.  Looks good.

 

One small request.  How about some comments to help people new to scripting to tell them what is going on where.  Comments from others helped a lot when I started  ;) .

Damnit, tried to comment everything, the forum threw a hissyfit and went tits up. Will try again later :P

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Discord

×
×
  • Create New...