genesis92x 810 Posted February 9, 2016 Hey all, I've done a lot of searching and testing on my own and I am having a hard time figuring this one out. I found out without having to enable filepatching you can still load information using the #include command. (For my VcomAI userconfig file). However, I need a reliable way to test if the file actually exists before executing the #include command because it will cause a crash otherwise. Filepatching seems to stop most ways I know of to check if a script exists or not. Does anyone know how to load up a userconfig file without having to force them to enable filepatching? Thank you. Here is my current code: Any help is greatly appreciated. PublicScript = compileFinal "[] call (_this select 0); systemchat format ['%1',_this select 0];"; if (isServer) then { #include "\userconfig\VCOM_AI\AISettingsV2.hpp"; if !(isNil "VCOMAI_Func") then { [] call VCOMAI_Func; } else { VCOMAI_Func = compile preprocessFileLineNumbers "VCOMAI\Functions\VCOMAI_DefaultSettings.sqf"; [] call VCOMAI_Func; }; [VCOMAI_Func] remoteExec ["PublicScript",0,true]; }; Edit: Got enable/disable mixed up for filepatching. Fixed in post. Share this post Link to post Share on other sites
das attorney 858 Posted February 9, 2016 Hi, I don't know what your userconfig looks like, but if it contains a class then you can check if it exists in sqf with isClass. So you would have in the UC: class myUserConfig { attribute1 = 0; etc... }; Then you check with: if isClass (configFile >> "myUserConfig") then { // stuff } else { // other stuff }; Not sure exactly if I understood your problem properly, but I hope that helps. Share this post Link to post Share on other sites
genesis92x 810 Posted February 10, 2016 Hi, I don't know what your userconfig looks like, but if it contains a class then you can check if it exists in sqf with isClass. So you would have in the UC: class myUserConfig { attribute1 = 0; etc... }; Then you check with: if isClass (configFile >> "myUserConfig") then { // stuff } else { // other stuff }; Not sure exactly if I understood your problem properly, but I hope that helps. Thanks das attorney, I think that is definitely headed in the right direction - I am messing around with it now. If it helps this is what my userconfig looks like - It's rather simple. VCOMAI_Func = { //Variable for finding out which config was loaded. VCOM_AIConfig = "Userconfig folder"; //Turn this on to see certain debug messages VCOM_AIDEBUG = 0; //Turn on map markers that track AI movement VCOM_UseMarkers = false; //Turns off VCOMAI for AI units in a players squad NOAI_FOR_PLAYERLEADERS = 1; //Will AI garrison static weapons nearby? VCOM_STATICGARRISON = 1; //How far can the AI hear gunshots from? VCOM_HEARINGDISTANCE = 600; //Should AI be able to call for artillery. 1 = YES 0 = NO VCOM_Artillery = 1; //Should we let AI use flanking manuevers? false means they can flank VCOM_NOPATHING = false; //Should AI use smoke grenades? Besides default A3 behavior? VCOM_USESMOKE = true; //Chance of AI using grenades VCOM_GRENADECHANCE = 20; //The longer an AI's target stays in 1 location, the more accurate and aware of the target the AI becomes.DEFAULT = [WEST,EAST,CIVILIAN,RESISTANCE]; VCOM_IncreasingAccuracy = true; //VCOM_SideBasedMovement- Remove sides from the array below to force that specific AI side to not execute any advance movement code. (I.E. Moving to reinforce allies, being alerted by distant gunshots and etc). AI with this will still react normally in combat. DEFAULT = [WEST,EAST,CIVILIAN,RESISTANCE]; VCOM_SideBasedMovement = [WEST,EAST,CIVILIAN,RESISTANCE]; //VCOM_SideBasedExecution- Remove sides from the array below to remove that specific AI side from executing any of the VCOMAI scripts at all. DEFAULT = [WEST,EAST,CIVILIAN,RESISTANCE]; VCOM_SideBasedExecution = [WEST,EAST,CIVILIAN,RESISTANCE]; //Distance AI will respond to call of help from each other VCOM_Unit_AIWarnDistance = 600; //The following commands are to be left alone, except under rare circumstances. MarkerArray = []; VcomAI_UnitQueue = []; VcomAI_ActiveList = []; ArtilleryArray = []; //AI ACCURACY SETTINGS - You can change these numbers below //Colonel Level AI AccuracyFunctionRank6 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",1]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.2 + (random 0.3))]; }; //Major Level AI AccuracyFunctionRank5 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",1]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.3 + (random 0.3))]; }; //Captain Level AI AccuracyFunctionRank4 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",1]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.4 + (random 0.3))]; }; //Lieutenant Level AI AccuracyFunctionRank3 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",1]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.5 + (random 0.3))]; }; //Sergeant Level AI AccuracyFunctionRank2 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",1]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.6 + (random 0.3))]; }; //Corporal Level AI AccuracyFunctionRank1 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",1]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.7 + (random 0.3))]; }; //Private Level AI AccuracyFunctionRank0 = { _Unit = _this select 0; _Unit setSkill ["aimingAccuracy",(0.05 + (random 0.05))]; _Unit setSkill ["aimingShake",(0.05 + (random 0.05))]; _Unit setSkill ["spotDistance",1]; _Unit setSkill ["spotTime",(0.7 + (random 0.3))]; _Unit setSkill ["courage",(0.7 + (random 0.3))]; _Unit setSkill ["commanding",1.0]; _Unit setSkill ["aimingSpeed",1]; _Unit setSkill ["general",1.0]; _Unit setSkill ["endurance",1.0]; _Unit setSkill ["reloadSpeed",(0.7 + (random 0.3))]; }; }; Since filepatching is defaulted to off now, it is causing an issue with arma reading the config file through standard means. Using this line #include "\userconfig\VCOM_AI\AISettingsV2.hpp"; allows me to actually load up the file. However, this introduces a new problem. I need to find a way to check if the file exists first - otherwise the #include command will crash the game. Using compile will not work with filepatching off - so I'm not sure how to even check if the .hpp file exists. _contents = compile preprocessFileLineNumbers "\userconfig\VCOM_AI\AISettingsV2.hpp"; Share this post Link to post Share on other sites
pedeathtrian 100 Posted February 11, 2016 _contents = compile preprocessFileLineNumbers "\userconfig\VCOM_AI\AISettingsV2.hpp"; if !(_contents isEqualTo {}) then { #include "\userconfig\VCOM_AI\AISettingsV2.hpp"; }; Your code contains #include directive, so you run preprocessor on it before it is executed. Before you have any chance to do any preprocessFileLineNumbers, compile or isEqualTo calls. This is why it's called preprocessor. And it will fail before you can check whether it will fail or not. preprocessFileLineNumbers should actually work (and even loadFile is enough), but you should check whether it fails before the very first attempt to preprocess file containing #include directive on file being checked. Share this post Link to post Share on other sites
genesis92x 810 Posted February 12, 2016 _contents = compile preprocessFileLineNumbers "\userconfig\VCOM_AI\AISettingsV2.hpp"; if !(_contents isEqualTo {}) then { #include "\userconfig\VCOM_AI\AISettingsV2.hpp"; }; Your code contains #include directive, so you run preprocessor on it before it is executed. Before you have any chance to do any preprocessFileLineNumbers, compile or isEqualTo calls. This is why it's called preprocessor. And it will fail before you can check whether it will fail or not. preprocessFileLineNumbers should actually work (and even loadFile is enough), but you should check whether it fails before the very first attempt to preprocess file containing #include directive on file being checked. Very helpful - however Loadfile and preprocessFileLineNumbers will not work with unpacked data with filepatching disabled :< Which is the point of the userconfig folder and .hpp file. Allowing users to change information without having to unpack the mod. I also learned that #include appears to be global even if the server only runs it. Causing joining players to CTD. This is what I re-worked it to a few days ago. It works well - except for the CTD for clients without the file... So far #include is one of the few things that work with filepatching disabled. PublicScript = compileFinal "[] call (_this select 0); systemchat format ['%1',_this select 0];"; if (isServer) then { #include "\userconfig\VCOM_AI\AISettingsV2.hpp"; if !(isNil "VCOMAI_Func") then { [] call VCOMAI_Func; } else { VCOMAI_Func = compile preprocessFileLineNumbers "VCOMAI\Functions\VCOMAI_DefaultSettings.sqf"; [] call VCOMAI_Func; }; [VCOMAI_Func] remoteExec ["PublicScript",0,true]; }; Share this post Link to post Share on other sites
pedeathtrian 100 Posted February 12, 2016 It works well - except for the CTD for clients without the file... So far #include is one of the few things that work with filepatching disabled. Again, because the check (isServer) is localted in the same file and performed after file was preprocessed (and game possibly crashed). What I was suggesting (well, ok, I only implied, my bad) was to take away the check from the file with #include. Something like this: PublicScript = compileFinal "[] call (_this select 0); systemchat format ['%1',_this select 0];"; if (isServer) then { call compile preprocessFileLineNumbers "VCOMAI\Functions\VCOM_dangerous_file_loader.sqf"; }; Where "VCOMAI\Functions\VCOM_dangerous_file_loader.sqf" has all include-dependent contents and not preprocessed before check / if check fails (this check could be loadFile, as I stated in previous post, without `compile' or `call' calls, just to check that content of file are not empty): #include "\userconfig\VCOM_AI\AISettingsV2.hpp"; if !(isNil "VCOMAI_Func") then { [] call VCOMAI_Func; } else { VCOMAI_Func = compile preprocessFileLineNumbers "VCOMAI\Functions\VCOMAI_DefaultSettings.sqf"; [] call VCOMAI_Func; }; [VCOMAI_Func] remoteExec ["PublicScript",0,true]; 2 Share this post Link to post Share on other sites