gc8 970 Posted March 13, 2018 Hi I wanted to ask you all how would you solve this programming problem with arma classes that I have. Here's my code: class State1 { condition = "[_player,""16Rnd_9x21_Mag""] call hasItem"; }; class State2 { condition = "([_player,""16Rnd_9x21_Mag""] call hasItem) && (_player distance2d end) < 2"; }; The problem is I don't like when there's duplicated code and would like to have the later condition in form like this: condition = "State1.condition && (_player distance2d end) < 2"; But as far as I know that's not possible with arma classes, or is it? any suggestions are welcome! Share this post Link to post Share on other sites
Dedmen 2581 Posted March 16, 2018 No not possible. You can just use a preprocessor macro though. But in the end it will still be duplicate. https://community.bistudio.com/wiki/PreProcessor_Commands#.23define Share this post Link to post Share on other sites
Arkensor 96 Posted March 16, 2018 You could go for something like getting the condition value from Class1 with GetText( configfile >> "yourclass" >> "condition" ), call compile that to evaluate if that is true or false and then combine that with && and your second expression. 1 Share this post Link to post Share on other sites
Larrow 2779 Posted March 16, 2018 Could always separate each condition to its own property, then only inherit conditions needed and blank out those not needed. Not particularly pretty and could get messy depending on how many states you have and all state would need to be && (without extra config properties). Just an idea to a problem. //Where commented properties are inherited( there just for example purposes ) class State1 { condition = "[_player,""16Rnd_9x21_Mag""] call hasItem"; }; class State2 : State1 { //condition = "[_player,""16Rnd_9x21_Mag""] call hasItem"; condition1 = "(_player distance2d end) < 2"; }; class State3 : State2 { condition = ""; //Override original condition //condition1 = "(_player distance2d end) < 2"; condition2 = "alive _player"; }; class State4 : State2 { //condition = "[_player,""16Rnd_9x21_Mag""] call hasItem"; //condition1 = "(_player distance2d end) < 2"; condition2 = "alive _player"; }; //Function and _player for conditions hasItem = { params[ "_unit", "_item" ]; _item in magazines _unit }; _player = player; //Get State conditions paths _conditions = configProperties[ missionConfigFile >> "State1", "configName _x select[ 0, 9 ] == 'condition'" ]; if ( { _x params[ "_CfgPath" ]; //Get condition code _check = getText( _CfgPath ); //If its not a blank string if !( _check isEqualTo "" ) then { //Return compiled result call compile _check }else{ //Else treat as true true }; //If all true }count _conditions isEqualTo count _conditions ) then { //Do what ever _text = "Passed:"; { _text = format[ "%1\n%2", _text, getText( _x ) ]; }forEach _conditions; hint _text; }else{ hint "failed"; }; 3 Share this post Link to post Share on other sites
Muzzleflash 111 Posted March 16, 2018 First of all there is some philosophical issues to resolve. For instance, what is the truth value of the following states? class State1 { condition = "not State2.condition"; }; class State2 { condition = "not State1.condition"; }; To resolve this, and a lot of other potential problems, my suggestion is to divide it into previous and current values of the condition. We are going to create a variable representing the current value (or status) of each condition. Needs to be global since we can't assign by string otherwise, e.g. using setVariable. Also different syntax since '.' not allowed in global variables. So we might rewrite your condition as, where TAG can be something else of course: class State1 { condition = "[_player,""16Rnd_9x21_Mag""] call hasItem"; }; class State2 { condition = "TAG_State1_Status && (_player distance2d end) < 2"; }; So go through each State config before evaluating and: // First time setup. You have all the classnames, e.g. "State1" and "State2" in TAG_StateConfigNames. { // Create a variable containing the previous value. private _varName = format ["TAG_%1_Status", _x]; // Assume false in beginning missionNameSpace setVariable [_varName, false]; } forEach TAG_StateConfigNames; Then everytime you evaluate, you use the current values to compute the next values: // Every time you evaluate EvaluateStates = { private _nextValues = []; { // Assume you have gotten x.condition into _condition as code here somehow. For example private _condition = compile (getText (configFile >> "MyPath" >> _x >> "condition")); // Though you probably want to maybe cache the compiling ^^ private _status = nil call _condition; _nextValues pushBack [_x, _status]; } forEach TAG_StateConfigNames; // Update for next iteration the condition values { missionNameSpace setVariable _x; } forEach _nextValues; }; The side effect of this approach is that any condition depending on another condition is always an evaluation behind. 2 Share this post Link to post Share on other sites
gc8 970 Posted March 16, 2018 (edited) Thanks for the replies everyone, interesting discussion.. I coded similar solution on the other day than what Larrow did. In my solution each class can define "condition" which is not supposed to be inherited and "conditionNumber" where number is the State Number and this variable will be inherited. So I can do: class State1 { condition1 = "[_player,""16Rnd_9x21_Mag""] call hasItem"; }; class State2: State1 { condition = "(_player distance2d end) < 2"; // or condition2 = for further inheritence }; And the State2 will have both conditions evaluated. Edited March 16, 2018 by gc8 added condition2 Share this post Link to post Share on other sites