Feature #23277

Mission specalized macros

Added by Sickboy over 3 years ago. Updated about 3 years ago.

Status:Closed Start date:08/09/2011
Priority:Normal Due date:09/14/2011
Assignee:Sickboy % Done:

100%

Category:Macros
Target version:v0.8.3
Component: Affected Version:
Close Reason:

Description

Some of the macros included in CBA are of lesser use to missions, or perhaps unusable in current state.
The idea would be to include an additional macros file that is specifically tailored to missions.

It should include the main macros file, and replace/supplement macros tailored towards missions.

script_macros_mission.hpp (41.1 kB) Muzzleflash, 08/09/2011 16:50

script_macros_mission_diff.hpp (2.3 kB) Muzzleflash, 08/09/2011 17:49

Associated revisions

Revision f6f93fc3
Added by Sickboy over 3 years ago

~ ADDED: Mission specialized macros (WIP). By Muzzleflash. refs #23277

Revision f6f93fc3
Added by Sickboy over 3 years ago

~ ADDED: Mission specialized macros (WIP). By Muzzleflash. refs #23277

Revision ac21b3c4
Added by Sickboy over 3 years ago

ADDED: KEY_PARAM macro. by Muzzleflash. refs #23277

Revision ac21b3c4
Added by Sickboy over 3 years ago

ADDED: KEY_PARAM macro. by Muzzleflash. refs #23277

Revision 283a33f6
Added by Sickboy over 3 years ago

FIXED: script_macros_mission should include script_macros_common, not script_component. refs #23277

Revision 283a33f6
Added by Sickboy over 3 years ago

FIXED: script_macros_mission should include script_macros_common, not script_component. refs #23277

History

Updated by Muzzleflash over 3 years ago

I changed the howto in the top to reflect the modified behaviour. Also these changes might not be the most ambitious, however, I would rather add and remove than change. Inconsistent behaviour between the include file for addons and this file will probably only cause confusion.

Removed:
MAIN- and SUBPREFIX. - COMPONENT AND PREFIX should generally be enough. However, see CUSTOM_FOLDER below in addition.
Class related macros.
XEH related macros.
Modularity macros; the c,s,f,t etc. version which I assume is what gives the '_m_' part in ace_m_Something

Kept the define obsolete functions, functions - might prove useful for some. Anyway saw no reason why they should not be able to be used.

Modified:
Paths now go into PREFIX\COMPONENT\Script.sqf

Added:
CUSTOM_FOLDER - If defined that path would be used instead of the above, eg. CUSTOM_FOLDER\Script.sqf. PREFIX and COMPONENT will still be used for variable names and, well, everything else than file paths.

Not sure about the MAINLOGIC:

Assume that

    #define MAINLOGIC main
    #define GETVARS(var1,var2,var3) (##var1##_##var2 getVariable #var3)
    #define GETVARMAINS(var1,var2) GETVARS(var1,MAINLOGIC,var2)
    #define SETVARS(var1,var2) ##var1##_##var2 setVariable
    #define SETVARMAINS(var1) SETVARS(var1,MAINLOGIC)

Is to be used with:
    #define CREATELOGICLOCAL CREATELOGICLOCALS(PREFIX,COMPONENT)
    #define CREATELOGICMAIN CREATELOGICS(PREFIX,MAINLOGIC)

To create a logic which you can do stuff with? Which means it can be also used in a mission by itself?
However, will it be easy for mission creator to ruin/overwrite-entries of the 'main' game logic of addons?

Sample output in Squint:

/**************************************************************************/
Samples In Squint:

#define PREFIX PRE
#define COMPONENT COM

--- The following:
GVAR(Hello);
GVARMAIN(World);
PREP(TheAnswer);
[SOME_ARGS] call FUNC(TheAnswer);
--- Maps to:
PRE_COM_Hello;
PRE_World;
PRE_COM_fnc_TheAnswer = compile preProcessFileLineNumbers 'PRE\COM\fnc_TheAnswer.sqf';
[SOME_ARGS] call PRE_COM_fnc_TheAnswer;

--- If this had also been defined at the top
#define CUSTOM_FOLDER CUSTOM\PLACE
--- The result would be:
PRE_COM_Hello;
PRE_World;
PRE_COM_fnc_TheAnswer = compile preProcessFileLineNumbers 'CUSTOM\PLACE\fnc_TheAnswer.sqf';
[SOME_ARGS] call PRE_COM_fnc_TheAnswer;

I tried quite a bit not to screw anything up, but might have anyway. The CUSTOM_FOLDER might be a bit dirty since it just drops the 2 first arguments. It was the only way I could implement this without having to change a lot of the other macros.

Updated by Sickboy over 3 years ago

  • Category set to Macros
  • Status changed from Assigned to Feedback
  • % Done changed from 0 to 30

Thanks a lot.

The CUSTOM_PATH idea sounds good, you're right it would probably be somewhat confusing if macros behave differently between mission and addon, yet imo for the paths it kinda would make sense - the macros with paths would be tailored towards addon prefixes inside addons, while tailored towards missions when inside a mission.

Though as pointed at BIF the PRE\COM structure can also be created inside the mission folder, and it would work, so perhaps the custom path is simply the best way to go.

The intended format would be:
script_macros_mission.hpp:

#include "\x\cba\addons\main\script_component.hpp" 
// Supplemental or replaced macros

While perhaps some changes like the CUSTOM_PATH ones could be included in the main script_macros_common.hpp

But we can adjust that too I suppose, up to you.

Ref the "main logic" this is a logic per component, default globalvariablename: PREFIX_COMPONENT_main
So the macros should operate on a unique logic, 'local' to this component.
The implementation is probably a little sloppy, I think we've barely used them.

Updated by Muzzleflash over 3 years ago

First it was named CUSTOM_PATH however this wasn't clear whether an ending '\' should be present so I changed the name into CUSTOM_FOLDER to hopefully make it more clear, however, since you read CUSTOM_PATH although I never wrote it I fear I failed. Do you have a better macroname?

I will begin make a file with just the replacements. I was not aware that you could replace macros. I though this would not work:

#define ANSWER NO
#define GETANSWER ANSWER
#define ANSWER YES

//What I thought
GETANSWER =  NO

Perhaps the logics and their setter/getters should be removed from (at least for now) in this mission version of the macro package?

Updated by Sickboy over 3 years ago

Cheers. The CUSTOM_PATH thing probably was something automatic on my side, not sure everyone shares my thought pattern :P
No idea currently on a more suitable name - easy to adjust before release in any case.

Your posted code should work, otherwise add #undef:

#define ANSWER NO
#define GETANSWER ANSWER
#undef ANSWER
#define ANSWER YES

Re the Logic macros - I dont think they should be removed for missions specifically.
You would create a logic and give it a namespaced globalvariable (CREATELOGIC macro), while the macros operate on this logic - that should be valid for missions just as addons?

Updated by Muzzleflash over 3 years ago

My posted code does work. I just though that the complete macro was established at define time and not at, uhm, 'dereferencing'.

I created the new file with the differences only manually. Apparently winmerge saw it as 2 completely different files. I kept the logic macros. I tested it in squint, by defined the prefix and component, then pasting the common macros, then the changes and the used my same puny 2*4 macro test suite and it worked. I've attached the file.

Why should it include #include "\x\cba\addons\main\script_component.hpp" that will override COMPONENT from a mission script_component.hpp.

Updated by Sickboy over 3 years ago

Tnx. You are correct, should've been #include "script_component.hpp" :) Gotto run for the night

Updated by Muzzleflash over 3 years ago

I think I misunderstood you in #2. I thought you wanted this mission version to #include the original macro header and then just define the difference. Anyway both is attached and either can be used.

Regarding the create logic macros, I think I already found a use case for them. In Domi Xeno keeps JIP data in a (H-Invisible object) using set/getVariable and I've used the same technique. However, shouldn't you be able to do this using public game logic instead, eg. one create by CREATELOGICGLOBAL?

Updated by Sickboy over 3 years ago

No you got it correctly, #include the original, and override/supplement specific things for missions.

Ref the logics; you can create global logics or local logics (CREATELOGIC vs CREATELOGICLOCAL). With publicVariable you can even propagate the global variable assignment to other machines.
The idea was to use the macros for one logic per component, like a module - what you intend to use it for is completely up to you :P

Updated by Sickboy over 3 years ago

  • Due date set to 08/14/2011

Things have been a little bit busy, hopefully some time this weekend.

Updated by Muzzleflash over 3 years ago

There is a macro to read positional parameters into variables. There's one for optional parameters. But none for key-parameters so I've been thinking on whether to add this macro, which might prove useful. It also avoid some boilerplate code (upper and lowercase) needed to use getArg:

#define KEY_PARAM(KEY,NAME,DEF_VALUE) \
    private #NAME; \
    NAME = [toLower KEY, toUpper KEY, DEF_VALUE, RETNIL(_this)] call CBA_fnc_getArg;
    TRACE_3("KEY_PARAM",KEY,NAME,DEF_VALUE)

Also I looked at the logic macros.. again. And found 2 disturbing issues and a question:

    #define CREATELOGICS(var1,var2) ##var1##_##var2## = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit ["LOGIC", [0, 0, 0], [], 0, "NONE"]
    #define CREATELOGICLOCALS(var1,var2) ##var1##_##var2## = "LOGIC" createVehicleLocal [0, 0, 0]
    #define CREATELOGICGLOBALS(var1,var2) ##var1##_##var2## = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit ["LOGIC", [0, 0, 0], [], 0, "NONE"]; publicVariable QUOTE(DOUBLES(var1,var2))
    #define CREATELOGICGLOBALTESTS(var1,var2) ##var1##_##var2## = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit [QUOTE(TRIPLES(PREFIX,COMPONENT,logic)), [0, 0, 0], [], 0, "NONE"]

What is the deal with CREATELOGICGLOBALTESTS? That can't possibly be a valid classname. I tried and got Null.
About CREATELOGICLOCALS - I once created a unit through createVehicle accidentally, and was unable to propery setVariable on it. Won't this happen here too?

When would you want to create a normal (non-local) logic and not broadcast it? If you don't broadcast it other machines can't get to it, and if they can't get to it, it might aswell be a local only?

What's this? It isn't referenced in the macro file anywhere:

#ifndef DEBUG_SETTINGS
    #define DEBUG_SETTINGS [false, true, false]
#endif

Updated by Sickboy over 3 years ago

  • Due date changed from 08/14/2011 to 09/14/2011
  • % Done changed from 30 to 40

I've added the early wip of the macros file to the repo.

Nice one on the KEY_PARAM, also added to repo.

The debug settings part is used in early debug function, the params say: [globalChat?, LocalRpt?, RemoteRpt?].
The debug function was basically replaced by TRACE, LOG, ERROR, WARN etc, but it can still be useful for debugging remotely.

CREATELOGICGLOBALTESTS expects the / an addon to define that logic CfgVehicles class, form of PREFIX_COMPONENT_logic.

As of ArmA 2 it's IIRC required to spawn logics with createUnit and a group, which has no "Local" variant.
At least an rpt message will appear otherwise, or perhaps that was with the non Local variant of createVehicle, don't remember :)
createVehicleLocal perhaps works fine. Nowadays we often use HeliHEmpty to store variables instead of logics.

As pointed out before, the logic macros are rather experimental and seems never really finished. Perhaps good to clean / fix etc sometime.

Updated by Muzzleflash over 3 years ago

Well my main interest in the logic macros was the availability of data container to store variables, especially JIP data. Most of the experienced mission makers knows about locality and jip issues and typically store data in some object and have a script(s) that process that after loading and during gameplay.

I've seen people using HeliHEmpty, however a logic does the same without making AI helicopters land on top of them. Is there some advantage to HeliHEmpty. If there is any advantage over logics, perhaps a set of similar macros should be added that returns a fresh clean object for setting variables on, eg. a HeliHEmpty object.

Updated by Sickboy over 3 years ago

Logics require createUnit with group, while HeliHEmpty do not.
Any other dummy vehicle is fine too.

Updated by Sickboy over 3 years ago

I remember one purpose of the logics:
  1. Create a GVAR(logic) CfgVehicle Class, and assign it an Init EventHandler that launches the initialization script for this module.
  2. Assign the variable name for the logic inside the initialization script
  3. Create the logic (e.g with the macros).
  • No network traffic for initialization, except for the logic that is created, and of course any other setVariables
  • Self contained module

Not unlike the way the BIS modules work (though hopefully with a lot less execVM/spawn ;-P)

Updated by Muzzleflash over 3 years ago

Think that script_macros.hpp or script_macros_common.hpp should be included instead of component in this file. Doesn't make sense for CBA to define stuff like version which doesn't apply for a mission anyway. Also in addons you are instructed to include script_macros_common.hpp directly, don't see why a mission be different in this regard.

Updated by Sickboy over 3 years ago

IMO the mission domain is like an addon domain, so the script_component.hpp can be defined inside the mission, and include the CBA macro files, like any addon (component) would do too.

Updated by Muzzleflash over 3 years ago

Just to be sure i'm talking about script_macros_mission.hpp including the script_component.hpp inside CBA.

Right now I have structure like this:
MF\functions\array.sqf -> includes
MF\functions\script_component.hpp -> this includes
#include "\x\cba\addons\main\script_macros_mission.hpp" -> which includes
#include "\x\cba\addons\main\script_component.hpp" -> which includes

#include "\x\cba\addons\main\script_mod.hpp" and #include ""\x\cba\addons\main\script_macros.hpp" -> where the latter includes
#include "\x\cba\addons\main\script_macros_common.hpp"

Maybe I have misunderstood something but I don't see why the need to first setup stuff for CBA just to be overwritten anyway, eg. PREFIX and COMPONENT.

Updated by Sickboy over 3 years ago

Yes slight misunderstanding.

script_component.hpp should only be loaded from the mission.
script_mod.hpp too.

script_component includes script_mod, which includes \x\cba\addons\main\script_macros_mission.hpp, which includes \x\cba\addons\main\script_macros_common.hpp

Perhaps you could leave the script_mod file out of it and put those defines in script_component.hpp

Or otherwise you could see the mission as a prefix, containing script_mod.hpp, and then add subfolders for components (each with a script_component.hpp), etc.

Updated by Muzzleflash over 3 years ago

Here is how I see it all being used:

I don't plan on using script_mod.hpp just to have a single #define. Scripters setup the folder structure anyway they please. In each folder containing script there is a script_component.hpp which something like this minimum:

#include "x\cba\addons\main\script_macros_mission.hpp" 

#define PREFIX MF
#define COMPONENT awesome
//Override CUSTOM_FOLDER if needed
//#define CUSTOM_FOLDER scripts\awesome

In some script file this get's included:

//Local script_component.hpp (the above file in same folder)
#include "script_component.hpp" 

//Enjoy macros....
//....

I don't see the why "x\cba\addons\main\script_macros_mission.hpp" should include CBA's internal script_component.hpp. Just including either script_macros.hpp or script_macros_common.hpp should be enough and avoid any extras/unwanted defines. Eg. as it is now PREFIX and COMPONENT will be CBA and main by standard which can give accidental overwrites of CBA stuff if the scripter forget to #define it in the local script_component.hpp. Then better to have it undefined IMO.

Btw. is there some caching in place through some macro? Have been testing in the editor and been unable to "run" a newer version of a file.

Updated by Sickboy over 3 years ago

No, script_macros_mission.hpp indeed should NOT include script_component.hpp.
Functions include script_component, script_component includes script_macros_mission and script_macros_mission includes script_macros_common

Updated by Sickboy over 3 years ago

Btw. is there some caching in place through some macro? Have been testing in the editor and been unable to "run" a newer version of a file.

Yep, globally disable by placing @CBA\optional\cba_disable_cache.pbo into some modfolder and load it, or use the CfgSettings class and the cba caching properties in mission description.ext.

COMPILE_FILE macros and all that are based on them use the caching. Implementation is still undergoing improvements.

Updated by Muzzleflash over 3 years ago

Sickboy wrote:

No, script_macros_mission.hpp indeed should NOT include script_component.hpp.
Functions include script_component, script_component includes script_macros_mission and script_macros_mission includes script_macros_common

Okay now we understand each other. Then that should be fixed. Very first line of script_macros_mission.hpp is currently:

#include "\x\cba\addons\main\script_component.hpp" 

Updated by Sickboy over 3 years ago

  • % Done changed from 40 to 50

Rgr, overlooked :)

Updated by Sickboy over 3 years ago

  • Target version changed from 855 to v0.8.3

Updated by Sickboy over 3 years ago

I have changed the normal PATH macro for scripts to include leading \
for missions this doesnt make sense, so for missions it still uses without leading \

On a side note (main macros), the EXPLODE macros should be without private, i've restored them and added EXPLODE_#_PVT variants.

Updated by Sickboy over 3 years ago

  • % Done changed from 50 to 70

Updated by Sickboy about 3 years ago

  • Status changed from Feedback to Closed
  • % Done changed from 70 to 100

Also available in: Atom PDF