Jump to content
Zenophon

Zenophon's ArmA 3 Co-op Mission Making Framework

Recommended Posts

Thanks Zen - all makes sense.

Like Beerkan, I have also had an issue since update - my .rpt is getting majorly spammed with this:

2014/10/03, 21:31:29 "-- Zen_CheckArguments Error --"
2014/10/03, 21:31:29 "Argument 2 is the wrong type"
2014/10/03, 21:31:29 29.066
2014/10/03, 21:31:29 [[b Alpha 1-1:1,B Alpha 1-1:3 (OhShitSarge) REMOTE],"!(isPlayer _x)"]
2014/10/03, 21:31:29 ["Zen_CheckArguments",[[b Alpha 1-1:1,B Alpha 1-1:3 (OhShitSarge) REMOTE],"!(isPlayer _x)"],29.066]
2014/10/03, 21:31:29 ["Zen_ArrayFilterCondition",[[b Alpha 1-1:1,B Alpha 1-1:3 (OhShitSarge) REMOTE],"!(isPlayer _x)"],29.066]
2014/10/03, 21:31:29 "Init"
2014/10/03, 21:31:29 "-- Zen_CheckArguments Error --"
2014/10/03, 21:31:29 "Argument 2 is the wrong type"
2014/10/03, 21:31:29 29.087
2014/10/03, 21:31:29 [[b Alpha 1-1:1,B Alpha 1-1:3 (OhShitSarge) REMOTE],"!(isPlayer _x)"]
2014/10/03, 21:31:29 ["Zen_CheckArguments",[[b Alpha 1-1:1,B Alpha 1-1:3 (OhShitSarge) REMOTE],"!(isPlayer _x)"],29.087]
2014/10/03, 21:31:29 ["Zen_ArrayFilterCondition",[[b Alpha 1-1:1,B Alpha 1-1:3 (OhShitSarge) REMOTE],"!(isPlayer _x)"],29.087]
2014/10/03, 21:31:29 "Init"

I can post the whole RTP if needed. I tested by rolling back to the previous version, and the issue went away. My init sqf is here. As usual, any advice would be appreciated.

Zen_ArrayFilterCondition has been modified to use code to evaluate elements. This improves performance (no more 'compile'), and allows the usage of predefined functions (and functional macros) to be used as the condition.

On line 236, it should be:

_players = [_players, {!(isPlayer _this)}] call Zen_ArrayFilterCondition; 

'_this' replaces '_x', and {} replace "". The logic of the condition does not change.

Share this post


Link to post
Share on other sites

Thanks Zen, that worked great as usual. I now have 2 outstanding issues to resolve:

Remember the code you gave me to increase the number of infantry if the player count was greater than 4? I finally tested it, and it seems to affect the mission in a strange way. I tested this by lowering the t obe more than 2 players and it still happened. The symptoms of the issue are that enemy groups custom load outs stop working, and that the number of squads present does not increase. This is the line of code here:

            // Spawn 2 or 4 groups per marker depending on player count
           for "_i" from 1 to (if (count _players > 2) then {4} else {2})  do {  
               _spawnPos = [_x] call Zen_FindGroundPosition; 
               _enemyGroup = [_spawnPos, ENEMY_SIDE, AI_SKILL, [4,8], "men", "SUD_USSR"] call Zen_SpawnInfantry; 
               0 = [_groupsArray, _enemyGroup] call Zen_ArrayAppend; 
		}; 

What would the best way to debug this issue be?

The second issue I have is that JIP is still not functioning properly. Back on page 12 you mentioned an issue with the 11th argument, I never did get round to addressing this, as I was not sure how to fix it. JIP is currently not working as intended, and joining players do not receive a load out. Again, any advice you could offer would be appreciated.

Full mission files here.

Share this post


Link to post
Share on other sites
Thanks Zen, that worked great as usual. I now have 2 outstanding issues to resolve:

Remember the code you gave me to increase the number of infantry if the player count was greater than 4? I finally tested it, and it seems to affect the mission in a strange way. I tested this by lowering the t obe more than 2 players and it still happened. The symptoms of the issue are that enemy groups custom load outs stop working, and that the number of squads present does not increase. This is the line of code here:

            // Spawn 2 or 4 groups per marker depending on player count
           for "_i" from 1 to (if (count _players > 2) then {4} else {2})  do {  
               _spawnPos = [_x] call Zen_FindGroundPosition; 
               _enemyGroup = [_spawnPos, ENEMY_SIDE, AI_SKILL, [4,8], "men", "SUD_USSR"] call Zen_SpawnInfantry; 
               0 = [_groupsArray, _enemyGroup] call Zen_ArrayAppend; 
		}; 

What would the best way to debug this issue be?

The second issue I have is that JIP is still not functioning properly. Back on page 12 you mentioned an issue with the 11th argument, I never did get round to addressing this, as I was not sure how to fix it. JIP is currently not working as intended, and joining players do not receive a load out. Again, any advice you could offer would be appreciated.

Full mission files here.

The issue might be that you can't put if statements as the bounds of a for loop. Try making the number of groups a variable returned from the if statement. You can then debug how many groups there are supposed to be, and if that many really are spawned. Since the loadout code isn't in the for loop, that bug is more likely the result of '_groupsArray' have the wrong value.

_groupsCount = (if (count _players > 2) then {4} else {2});
player sideChat str _groupsCount;

// Spawn 2 or 4 groups per marker depending on player count
for "_i" from 1 to _groupsCount do {
   _spawnPos = [_x] call Zen_FindGroundPosition;
   _enemyGroup = [_spawnPos, ENEMY_SIDE, AI_SKILL, [4,8], "men", "SUD_USSR"] call Zen_SpawnInfantry;
   0 = [_groupsArray, _enemyGroup] call Zen_ArrayAppend;
};

player sideChat str _groupsArray;

For the loadouts, 'loadout2' is defined twice. You can use Zen_CreateLoadout before sleep and before the clients exit to create the same loadout on all machines. However, you must give the loadout a string name (which is the same as 'loadout2') so that all client machines will have the same identifier as the server. Otherwise, 'loadout2' is not actually a loadout on a different machine, but that client has the same data stored under a different string identifier.

loadout2 = [
   /**
       Loadout Data
   */
], "BLUFOR_Loadout_01"] call Zen_CreateLoadout;

The name itself doesn't matter, so long as some constant string is provided.

Then, in JIPSync.sqf, you must run that same loadout code that you ran on the server, just with an extra argument for remote execution.

0 = [player, loadout2, false] call Zen_GiveLoadoutCustom;

Zen_AddFastRope is used on the vehicle that players can fastrope from, not on the players that can fastrope. If you want players to be able to fastrope from a helicopter, you need to call Zen_AddFastRope when the vehicle is spawned. You can then append that vehicle to Zen_JIP_Args_Server, so that JIP machines have the fastrope action on the helicopter.

Share this post


Link to post
Share on other sites

Hi Zen,

OK, so partial success!

I tested in MP on a dedicated server - when the right number of players was present from the start of the mission, double units spawned and all hell broke loose! Happy days!

However, the JIP is an epic pain in my rectum. I am not sure what I have done wrong, but the following are issues - some of these may not be solvable, and I can live with that - I am getting close to releasing the mission without JIP because it is so close to being done and I want to stop making and start playing, lol! Current JIP issues are:

  1. Loadouts still not working in JIP - players spawn in as vanilla bluefor. This error message appears.
  2. If a player joins mid mission and increases the player count, this does not affect the number of units spawning (despite it making the player total greater than the required amount).
  3. Other functions described in the INIT appear to be unavilable to JIP players - teleport to MHQ, Repack and Swap magazine

Reading back what I have just described, it seems clear that I have not implemented the JIP correctly, but I am out of my depth with how to fix it. I have placed the updated mission files with your latest amends here - do you have any other ideas about what I screwed up here? Thanks again for all the help and advice!

Share this post


Link to post
Share on other sites
Hi Zen,

OK, so partial success!

I tested in MP on a dedicated server - when the right number of players was present from the start of the mission, double units spawned and all hell broke loose! Happy days!

However, the JIP is an epic pain in my rectum. I am not sure what I have done wrong, but the following are issues - some of these may not be solvable, and I can live with that - I am getting close to releasing the mission without JIP because it is so close to being done and I want to stop making and start playing, lol! Current JIP issues are:

  1. Loadouts still not working in JIP - players spawn in as vanilla bluefor. This error message appears.
  2. If a player joins mid mission and increases the player count, this does not affect the number of units spawning (despite it making the player total greater than the required amount).
  3. Other functions described in the INIT appear to be unavilable to JIP players - teleport to MHQ, Repack and Swap magazine

Reading back what I have just described, it seems clear that I have not implemented the JIP correctly, but I am out of my depth with how to fix it. I have placed the updated mission files with your latest amends here - do you have any other ideas about what I screwed up here? Thanks again for all the help and advice!

First, I made a mistake about the loadout for JIP, it should be:

0 = [player, "BLUFOR_Loadout_01", false] call Zen_GiveLoadoutCustom;

Or whatever string you gave the Blufor loadout that is created before 'sleep'. 'Loadout2' is undefined for the clients, but the loadout string itself points to valid loadout data.

Second, if you have disabled friendly AI, new players are new objects. They must be handled differently in JIP and anywhere in the mission that depends upon the players. I rewrote the JIP demonstration about a month ago so that it can handle both cases (with and without AI). You can use that new template for the JIPSync.sqf file for your mission. The JIP code is more complex and still requires customization for your mission.

For detecting JIP players during the main loop, the code should already be creating the players array from west units. It should not be in the forEach loop though:

while {true} do {
   // Redefine the players array to account for respawn/JIP
   _players = [west] call Zen_ConvertToObjectArray;
   _players = [_players, {!(isPlayer _this)}] call Zen_ArrayFilterCondition;

   // some debug
   player sidechat str count _players;

   {
       // ...code...
   } forEach _townMkArray;

   // ...code...
};

Are you sure that new areas that spawn (already spawned areas will not spawn more units) don't have the correct number of groups? Does the debug (you can change the chats to diag_log to make it easier to debug on a dedicated server) for the player count disagree with the number of groups that spawn?

The VAS action is defined as a function 'Fnc_MPAddVASAction', which is used with BIS_fnc_MP in vehrespawn_mhq.sqf. BIS_fnc_MP is supposed to to call that function persistently for all JIP clients. If JIP clients don't see the action and clients at the start do, BIS_fnc_MP isn't working. You would have to manually implement calling that function for JIP for certain vehicles. You can modify Zen_JIP_Args_Server from any thread on the server, then use that element in JIPSync.sqf to put the action on the vehicle.

Framework actions, repacking and giving magazines, don't work because the JIP code isn't set up for JIP players spawning into the mission, only for JIP players taking over existing AI. As I said, using the JIP demonstration code with a few tweaks should work fine.

Share this post


Link to post
Share on other sites

Hi Zen,

thanks, I will try this out - I did have a mini eureka moment last night. I had picked up what you said several pages back about AI being a dependency, and all recent testing was done with AI on. I have just realized that whilst I have 10x bluefor dudes, only 4 or so are appearing in the game - I cannot believe I did not notice this before now! Right back at the beginning, I had a weird issue with turning AI off and the mission not running - I think this is related to that. OK: cue some wild ass speculation: by placing the playable units on map in the editor, I somehow did something wrong, and that's why not all of them are showing up. I will try your advice described above, and also try re-creating the 10 playable units. Unfortunately work means I may not get to this until the end of the week now though - Thanks again dude!

Edited by CallMeSarge
Typos

Share this post


Link to post
Share on other sites

Hi Zen,

I rebuilt JIPsync.sqf as per the most recently modified example, and the 10 minutes of testing I squeezed in tonight seems to indicate it is working! I am going to test further over the weekend. When new players join, loadouts are called and player count for enemy spawning calculates correctly. I am getting the following error message re the loadout when a player joins in progress, but the correct loadout is still called.

This is not a showstopper though. So a bit of tidying and a bit of testing and I should be good to go - thanks again for the advice!

Share this post


Link to post
Share on other sites
Hi Zen,

I rebuilt JIPsync.sqf as per the most recently modified example, and the 10 minutes of testing I squeezed in tonight seems to indicate it is working! I am going to test further over the weekend. When new players join, loadouts are called and player count for enemy spawning calculates correctly. I am getting the following error message re the loadout when a player joins in progress, but the correct loadout is still called.

This is not a showstopper though. So a bit of tidying and a bit of testing and I should be good to go - thanks again for the advice!

That error just means that you called Zen_CreateLoadout with the same loadout string name twice. Zen_CreateLoadout prints an error and stops rather than overwriting the old data, which it assumes you did not intend to overwrite. The error is harmless and does not affect giving the loadout. If you did intend to redefine a loadout, you must you Zen_UpdateLoadout as the error says.

You just have to search your code for all uses of Zen_CreateLoadout and find the ones that repeat the name. Due to character limits on diag_log, if the loadout data is long enough, other parts of the error might not print to the log. Hints will also continue off the screen. However, the sidechat should print everything.

Share this post


Link to post
Share on other sites

Zeus and Curator help please! (Multiplayer)

I've started using the Zen spawn functions to massively simplify and control AI active on the map as players move from place to place. Your framework's performance (and simplicity!) is fantastic. The only problem I'm not running into is finding a way for the spawned units to be placed under Zeus control. Is there anything buried in the other functions for Zeus compatibility or suggestions on a work around?

Share this post


Link to post
Share on other sites
Zeus and Curator help please! (Multiplayer)

I've started using the Zen spawn functions to massively simplify and control AI active on the map as players move from place to place. Your framework's performance (and simplicity!) is fantastic. The only problem I'm not running into is finding a way for the spawned units to be placed under Zeus control. Is there anything buried in the other functions for Zeus compatibility or suggestions on a work around?

Possibly some combination of these:

https://community.bistudio.com/wiki/addCuratorEditableObjects

https://community.bistudio.com/wiki/addCuratorEditingArea

Both claim they must be run on the server, but if you are spawning units on the server with the framework then no remote execution is required.

If that doesn't work, what I would do next is open some of the curator .pbo files in ArmA's install directory (default is C:\Program Files (x86)\Steam\steamapps\common\Arma 3\Curator\Addons). However, a lot of Zeus is engine based (hence all the scripting commands), so I don't know if you will find anything useful.

Share this post


Link to post
Share on other sites

I'll give that a shot tonight. If I'm reading this correctly, I should be able to do something like:

_zenspawn = <zen spawn stuff>

zeus1 addCuratorEditableObjects [[_zenspawn],true ];

Painfully straightforward once you point that out Zenophon. I've been getting lazy relying on FETT and advZeus.

-------------------------------------------

Working (probably not the most efficient way):

_zenspawn = [<vars>] call zen_spawninfantrygarrison;

<zeus module name> addCuratorEditableObjects [(allMissionObjects "Man"), false]; (not the unit name linked to the curator module)

I suspect there's a better way to check for just the group spawned. When I tried using the _zenspawn group as the 'object' in addCuratorEditableObjects all I got was an 'object expected' error.

Edited by Daishiknyte
Updated info

Share this post


Link to post
Share on other sites

Hey Zen! Could you give me a hand?

It's a newbie question, but...

How do I use the Preprocessors? I found the whole idea amazing, but I cant get it to work!

My example:

ZEN_FMW_CS_SPP("teste",1,west)

"teste" is the name of the marker.

How I am suppose to use them? Is there any limitations (besides already described in the documentations)?

Thanks again and keep the good work!

Share this post


Link to post
Share on other sites
I'll give that a shot tonight. If I'm reading this correctly, I should be able to do something like:

_zenspawn = <zen spawn stuff>

zeus1 addCuratorEditableObjects [[_zenspawn],true ];

Painfully straightforward once you point that out Zenophon. I've been getting lazy relying on FETT and advZeus.

-------------------------------------------

Working (probably not the most efficient way):

_zenspawn = [<vars>] call zen_spawninfantrygarrison;

<zeus module name> addCuratorEditableObjects [(allMissionObjects "Man"), false]; (not the unit name linked to the curator module)

I suspect there's a better way to check for just the group spawned. When I tried using the _zenspawn group as the 'object' in addCuratorEditableObjects all I got was an 'object expected' error.

Zen_SpawnInfantryGarrison returns a group, so you must convert that to an array of objects:

_zenspawn = [<vars>] call Zen_SpawnInfantryGarrison;
zeus addCuratorEditableObjects [(units _zenspawn), false];

Share this post


Link to post
Share on other sites

Introduction

Greetings fellow scripters and Armaholics, in this latest installment, I will continue to discuss the development of the framework and, of course, shamelessly advertise the framework in any way possible.

If this sounds boring, you can download the latest version from the original post. As always, the link to Google Drive for the .7z and .zip versions are already up to date. For those looking for older versions, go to file>revisions. The new version should be on Armaholic when Foxhound sees this or I PM him. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc.

Changelog

Lucky release #13 is the first release in the new bi-monthly schedule, and the release for ArmA stable version 1.32, this release contains quite a few fixes and some significant improvements.

Zen_ArrayFilterCondition and its macros have been improved so that they actually work. No one seemed to notice. Also, Zen_SpawnAmbientVehicles failed on repeated calls because it was deleting the markers it used. However, Zen_ConfigGetLocations stores the markers to return again later, so they must remain throughout the mission. A note about that was added to the documentation for Zen_ConfigGetLocations

Several spawning functions now have a faction parameter. This parameter applies when the functions select a random vehicle based upon a side. The faction is not used when classnames are given directly. The documentation of these functions has been improved to be much clearer about the difference between a side and classnames.

Zen_SpawnConvoy can now offer a faction parameter because it dynamically get vehicle classnames to spawn. These have been tested so that in vanilla ArmA 3 they provide nearly the same values as were previous hard-coded. This means that Zen_SpawnConvoy can now spawn any addon vehicles using the same vehicle type logic.

Zen_SpawnConvoy can filter for specific vehicles because Zen_ConfigGetVehicleClasses has been massively improved for detecting armed vehicles. All the weapons of the vehicle, for the driver and all the turrets, and compiled and filtered to remove 'false' weapons (flares, smoke, etc.). This leaves only the true weapons that can do damage.

Three new macros have been added, two for ordering AI in and out of vehicles. Those are for AI only and will not force players out of a vehicle, nor force a player leader to order his group to board a vehicle. They are the same code used in Zen_OrderInsertion and Zen_OrderExtraction, just made easy to use. ZEN_FMW_ZAF_FNS is just the opposite of ZEN_FMW_ZAF_FS.

Zen_OrderExtraction and Zen_OrderInsertion have been changed to remove the feature of keeping a helicopter's engines on while on the ground. This is due to AI pilot's very persistent ability to take off when units receive an order to get in or out. The previous solution suffered from timing and performance issues, and other simply can't override the AI's need to hover. Forcing the engines off slows things down, but works 100% of the time.

Finally, all stable branch 1.32 scripting commands have been added to the included Notepad++ language and autocompletion file. I doubt anyone uses it, but you should give it a try if you haven't. It makes things easier and faster.

10/15/14

  1. Fixed: Zen_ArrayFilterCondition now exits with an error properly if the condition function returns void
  2. Fixed: Zen_CreateObjective gave extra arguments to Zen_SpawnConvoy
  3. Fixed: ZEN_FMW_ZAF_FT and ZEN_FMW_ZAF_FS did not place the argument as a nested string correctly
  4. Fixed: ZEN_FMW_ZAF_FS reversed the searched and key string
  5. Fixed: Zen_SpawnAmbientVehicles did not sort for nearby locations correctly
  6. Fixed: Zen_SpawnAmbientVehicles deleted location markers that should be persistent, due to Zen_ConfigGetLocations caching
  7. Fixed: Zen_SpawnFortification did not check argument 2
  8. Fixed: ZEN_STD_MTH_VCC now uses vectorMagnitude in 3D to comply with 1.32 changes
  9. Added: Framework macro ZEN_FMW_ZAF_FNS, for Zen_ArrayFilterCondition
  10. Added: Zen_SpawnAircraft, Zen_SpawnBoat, Zen_SpawnConvoy, Zen_SpawnHelicopter, and Zen_SpawnGroundVehicle now have a faction parameter
  11. Added: Zen_SpawnFortification now has a parameter for the static weapon class
  12. Added: Standard macros ZEN_STD_OBJ_OGO, ZEN_STD_OBJ_OGI, for ordering AI in and out of vehicles
  13. Improved: Zen_ConfigGetVehicleClasses detects armed vehicles with significantly better reliability
  14. Improved: Zen_ConfigGetVehicleClasses now detects armed and unarmed men
  15. Improved: Zen_PrintError now uses systemChat, affects all errors
  16. Improved: Zen_OrderExtraction and Zen_OrderInsertion no longer keep the helicopter's engines on, too many issues
  17. Improved: Zen_SpawnAircraft and Zen_SpawnHelicopter no longer print an error when selecting a random civilian vehicle
  18. Improved: Zen_SpawnConvoy now dynamically searches for vehicle classnames
  19. Documentation: Fixed JIP demonstration and Assault Frini sample mission now do not remote execute loadout functions
  20. Documentation: Added 1.32 scripting commands to Notepad++ SQF language and autocompletion file
  21. Documentation: Added for ZEN_FMW_ZAF_FNS, ZEN_STD_OBJ_OGO, ZEN_STD_OBJ_OGI
  22. Documentation: Updated for Zen_SpawnAircraft, Zen_SpawnBoat, Zen_SpawnConvoy, Zen_SpawnFortification, Zen_SpawnGroundVehicle, Zen_SpawnHelicopter
  23. Documentation: Improved for Zen_ConfigGetLocations

Roadmap

I am going to work on Zen_OrderExtraction and Zen_OrderInsertion getting AI pilot to keep the engines running and land properly. It seems ridiculous that something so simple is so frustrating. If you have any ideas about an effective solution to this, I'd be glad to hear them.

I will also add more macros, probably finally getting to arguments for Zen_FindGroundPosition, as there are a lot of possibilities and a lot of tweaking to do.

Regarding changing constants and hard-coded values, e.g. for Zen_SpawnVehicleCrew, there is no easy way of doing this that is very user-friendly. Due to the preprocessor not allowing up directory commands (..\), using #include for constants in functions requires the user copy the header file into every subdirectory. Setting up a global array with a lot of values just opens a lot of possibilities of an index being off, users editing the wrong values, removing or adding to the array. Mistakes and errors like those waste a lot of time.

Therefore, the simplest solution to changing hard-coded defaults is simply editing the framework code to change things for your mission. It's simpler to just have a few versions of a file for your different missions or addon combinations. Odds are the function won't change for months, since releases are every two weeks, and I only modify about 10-20 functions each time. If you want some help about what to change, I am more than willing to point out where things are in the code.

Function Spotlight

As users of my framework know, there is an enormous number of functions at your disposal. The amount of documentation that has to be sifted through can be extremely daunting. Each week I spotlight a function and talk about its usefulness. If you have found an obscure function (not in tutorials, barely seen in demonstrations or sample missions) that you think is useful, PM me and I can spotlight it.

The function chosen for this week is: Zen_ArrayFilterCondition. This is a rather useful function, because it completely generalizes a common array operation: removing elements that don't pass a check. Since the three macros for this function now work:

// Assume _weapons is an array of firearm classnames, pistols, rifles, etc.
_handguns = [_weapons, ZEN_FMW_ZAF_FNS("hgun_")] call Zen_ArrayFilterCondition;

That makes things easy, but in general you'll have to write your own conditions. The rules for the condition are simple. It must be a code argument; you can use 'compile' to turn a string into code directly in the arguments. It must return a boolean value, anything else will cause the function to print an error. Finally, you can use '_this' as the element currently being evaluated.

Also, remember that the condition is being run from out of scope, so local variables cannot be used, but global variables can. You can avoid string operations by using global variables:

// Assume some group has just spawned
X = leader _group;
_nearObjects = [_objects, {((_this distanceSqr X) > 250000)}] call Zen_ArrayFilterCondition;

I am using the square of the distance for a slight performance increase, that's actually 500 meters. You can also use string formatting to put in local variables:

// Assume _group is some special group
_lesserGroups = [_groupsArray, compile format["(count units _this) > %1", count units _group]] call Zen_ArrayFilterCondition;

Due to the limitation of string formatting, you cannot simply put the name of any group or object into the string, unless it has a named reference. Otherwise, a value like 'B Alpha 1-1' will be put in, and the code won't run.

Types that are always safe are non-reference types, like strings, numbers, etc. In order to put in a string, you need to use single quotes, '', to nest the strings. For example, this is the code for ZEN_FMW_ZAF_FT:

(compile format ["((toLower typeName _this) == '%1')", (toLower T)])

The '%1' places T (the given string) into single quotes, giving 'T'. Otherwise, it would simply put in the string without any quotes, making it an identifier.

Finally, a technical note on performance: the condition is evaluated as O(n), once for every element of the array. This means that complex conditions will not reduce performance as they will for Zen_ArraySort, which is O(n*log(n)) (on average for a quick sort).

Beta

As already stated, the framework is in the beta stage of development. I am making every effort to quality control releases, but there will be bugs. Both new features and old ones could have bugs, issues, and things people just don't like.

There is no ETA or plan for a 'final' version. The framework is a work in progress, and it will continue to progress while there are improvements to be made (there always will be).

Some of the bugs have been pointed out by users, and those fixes are included in the changelog above. I want to thank everyone who has used/supported the framework.

Share this post


Link to post
Share on other sites
Guest

Thanks for informing us of the newest version :)

Release frontpaged on the Armaholic homepage.

================================================

We have also "connected" these pages to your account on Armaholic.

This means in the future you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have.

When you have any questions already feel free to PM or email me!

Share this post


Link to post
Share on other sites
Hey Zen! Could you give me a hand?

It's a newbie question, but...

How do I use the Preprocessors? I found the whole idea amazing, but I cant get it to work!

My example:

ZEN_FMW_CS_SPP("teste",1,west)

"teste" is the name of the marker.

How I am suppose to use them? Is there any limitations (besides already described in the documentations)?

Thanks again and keep the good work!

The limitations are due to the blind copy-paste nature of the preprocessor. It very useful but makes things less user friendly. There are no errors to tell you if something doesn't work and why, beyond generic syntax errors. You can't put expressions into the arguments and have them be evaluated as in a function call. Anything between the commas is just pasted in order into a template.

The macro you are using is for spawning around a point (SPP), with a marker you should use SPM:

ZEN_FMW_CS_SPM("teste", 1, west)

The very abbreviated names are not making using them any easier. As there are more and more macros, even I can't remember what the letters stand for. Next release I think I'm going to expand at least the last few letters into some words. For example, ZEN_FMW_CS_SpawnPatrolMarker instead of ZEN_FMW_CS_SPM. It makes the names longer, but that's not an issue if the macro replaces 5 lines of code.

Thanks Zenophon :smile_o:

ArmA3.de Mirror updated :

Zenophon's ArmA 3 Co-op Mission Making Framework by Zenophon

Kind regards

Miller

Thank you for hosting my framework. I will add that mirror to the original post.

Share this post


Link to post
Share on other sites

Ahhhw man!

I knew was something bloody stupid, but didn't know what.

Also, I already done an entire mission using your framework. Our clan adopted your framework as well and now we are doing another 2 missions. Everyone is very pleased with your work, Zen!

We want to thank you and let you know that.

Thanks, mate!

Toaster

Edited by BattleToaster
typo

Share this post


Link to post
Share on other sites

Well, my mission has started acting all kinds of screwy - objectives not clearing, the main loop stopping running. But since I have about 12 mods in there, I am not sure if it is a mod issue or a mistake I have made - I am going to spend the weekend recreating the modded version from the stable unmodded version. Question - do you guys run any source control when working with the framework? I am doing manual backups at the start of each session, tried to get Tortoise SVN running but could not figure it out. What do you use?

//// EDIT //// EDIT //// EDIT //// EDIT //// EDIT //// EDIT //// EDIT ////

OK, I found the problem :)

When a player joins the came via JIP, something goes wrong with the side missions / objective system. Once a player has joined, objectives can no longer be completed. I implemented and tested this in the version without mods (aside from the map of course - I switched from A3MP to AIA Terrain). I tested with both players joining at the start and it all works fine - so I thihnk I still have not got the JIP sync working properly. I made sure I am running the latest version of the framework. My JIP file is here:

http://pastebin.com/CR39FeGZ

And my whole mission set is here: https://drive.google.com/file/d/0B5q8Njbw82EFc2xyOXo0cTRTN3M/view?usp=sharing

Any advice would be hugely appreciated!

Edited by CallMeSarge

Share this post


Link to post
Share on other sites

Zen, what's up?

I found a possible bug in the Zen_OrderInfantryPatrol.

In the line 8, you forgot to add another ["String"] to pass on the CheckArguments. Without it, I can't set the _behaviorMode when I call the method with that parameter set.

To reproduce the error:

 0 = [_unit, _marker, [], 0, "limited", "safe"] spawn Zen_OrderInfantryPatrol; 

Error: Argument 6 is the wrong type.

Fix (Zen_OrderInfantryPatrol.sqf)

Begins line 8:


if !([_this, [["VOID"], ["ARRAY", "OBJECT", "GROUP", "STRING"], ["ARRAY"], ["ARRAY", "SCALAR"], ["STRING"], ["STRING"], ["BOOLEAN"]], [[], [], ["STRING", "SCALAR"], ["SCALAR"]], 2] call Zen_CheckArguments) exitWith {
   call Zen_StackRemove;
};

PS: Thanks for the tip on PHP code, Sarge!

Thanks!

Toaster

Edited by BattleToaster
PHP tags

Share this post


Link to post
Share on other sites
Ahhhw man!

I knew was something bloody stupid, but didn't know what.

Also, I already done an entire mission using your framework. Our clan adopted your framework as well and now we are doing another 2 missions. Everyone is very pleased with your work, Zen!

We want to thank you and let you know that.

Thanks, mate!

Toaster

Good to hear, your thanks is much appreciated.

Well, my mission has started acting all kinds of screwy - objectives not clearing, the main loop stopping running. But since I have about 12 mods in there, I am not sure if it is a mod issue or a mistake I have made - I am going to spend the weekend recreating the modded version from the stable unmodded version. Question - do you guys run any source control when working with the framework? I am doing manual backups at the start of each session, tried to get Tortoise SVN running but could not figure it out. What do you use?

//// EDIT //// EDIT //// EDIT //// EDIT //// EDIT //// EDIT //// EDIT ////

OK, I found the problem :)

When a player joins the came via JIP, something goes wrong with the side missions / objective system. Once a player has joined, objectives can no longer be completed. I implemented and tested this in the version without mods (aside from the map of course - I switched from A3MP to AIA Terrain). I tested with both players joining at the start and it all works fine - so I thihnk I still have not got the JIP sync working properly. I made sure I am running the latest version of the framework. My JIP file is here:

http://pastebin.com/CR39FeGZ

And my whole mission set is here: https://drive.google.com/file/d/0B5q8Njbw82EFc2xyOXo0cTRTN3M/view?usp=sharing

Any advice would be hugely appreciated!

At the very top of the init, change the lines that delete the AI to:

if !(isMultiplayer) then {
   {
       if (_forEachIndex > 0) then {
           deleteVehicle _x;
       };
   } forEach units player;
};

Then add this to the Description.ext:

disabledAI = 1;

That will make the server to allow those AI to spawn, rather than spawning and deleting them. I don't know if that was the problem, but it is not the typical way of removing AI in MP. Players will be able to JIP and respawn at base normally.

If that doesn't work, here are some more things to test:

First, do JIP players get all of the tasks, even those that have already been completed, regardless of when they join?

Their tasks should be fully synch'd as soon as they join. Those tasks should mirror those of their team leader.

Do JIP players continue to get new tasks that are assigned?

This will make sure that the array of players is being updated properly, so new JIP players are included in future tasks, considered when spawning zones, etc.

Does completing an objective update the task for non-JIP players?

Players that joined at the start of the mission shouldn't be affect by JIP players. The objective completion threads run on the server and broadcast the task changes to all the clients.

Does JIP affect the clearing of zones of enemy in any way?

Do they fail to clear when a JIP player is the only one inside? Do they not spawn when only a JIP player is close?

Zen, what's up?

I found a possible bug in the Zen_OrderInfantryPatrol.

In the line 8, you forgot to add another ["String"] to pass on the CheckArguments. Without it, I can't set the _behaviorMode when I call the method with that parameter set.

To reproduce the error:

 0 = [_unit, _marker, [], 0, "limited", "safe"] spawn Zen_OrderInfantryPatrol; 

Error: Argument 6 is the wrong type.

Fix (Zen_OrderInfantryPatrol.sqf)

Begins line 8:


if !([_this, [["VOID"], ["ARRAY", "OBJECT", "GROUP", "STRING"], ["ARRAY"], ["ARRAY", "SCALAR"], ["STRING"], ["STRING"], ["BOOLEAN"]], [[], [], ["STRING", "SCALAR"], ["SCALAR"]], 2] call Zen_CheckArguments) exitWith {
   call Zen_StackRemove;
};

PS: Thanks for the tip on PHP code, Sarge!

Thanks!

Toaster

Good find, I must have tested that change with argument checking turned off. You can simply keep that second ["STRING"] in there, or turn off argument checking altogether:

Zen_Debug_Arguments = false;

Disabling the checking of arguments will usually give a noticeable performance boost (possibly more than 30%). I suggest leaving it on while creating and testing a mission, and disable it for a stable release of the mission.

Share this post


Link to post
Share on other sites

Hi Zen,

OK, implemented that code and tested - some interesting results:

First, do JIP players get all of the tasks, even those that have already been completed, regardless of when they join?

Yes, existing tasks can be seen by JIP players

Do JIP players continue to get new tasks that are assigned?

Yes, new tasks sync up fine between Existing and JIP players

Does completing an objective update the task for non-JIP players?

No - neither JIP players nor regular players can clear objectives if a JIP player is present on the server. If no JIP player is present, objectives clear normally.

Does JIP affect the clearing of zones of enemy in any way?

No, zones clear fine

Do they fail to clear when a JIP player is the only one inside? Do they not spawn when only a JIP player is close?

No, this works fine for JIP players

I did hit an additional issue though - I finally got fed up of VAS and replaced it completely with the Zen Loadout system, using the example from MultiSquadObjectives.Altis to create loadout "stations" in the base and on the three MHQ vehicles. When a JIP player joins, they cannot access the loadouts though.

Latest mission files are here, and insight you can give me would be MASSIVELY appreciated!

Share this post


Link to post
Share on other sites
Hi Zen,

OK, implemented that code and tested - some interesting results:

First, do JIP players get all of the tasks, even those that have already been completed, regardless of when they join?

Yes, existing tasks can be seen by JIP players

Do JIP players continue to get new tasks that are assigned?

Yes, new tasks sync up fine between Existing and JIP players

Does completing an objective update the task for non-JIP players?

No - neither JIP players nor regular players can clear objectives if a JIP player is present on the server. If no JIP player is present, objectives clear normally.

Does JIP affect the clearing of zones of enemy in any way?

No, zones clear fine

Do they fail to clear when a JIP player is the only one inside? Do they not spawn when only a JIP player is close?

No, this works fine for JIP players

I did hit an additional issue though - I finally got fed up of VAS and replaced it completely with the Zen Loadout system, using the example from MultiSquadObjectives.Altis to create loadout "stations" in the base and on the three MHQ vehicles. When a JIP player joins, they cannot access the loadouts though.

Latest mission files are here, and insight you can give me would be MASSIVELY appreciated!

After quite a bit of testing and looking through the code, realized that only one thing could be the problem. The only change to tasks for JIP is done by Zen_ReassignTask. I had assumed that it was working, but in fact it was not. I feel like I should have seen that earlier. Nevertheless, the bug is not directly in Zen_ReassignTask, but in a private function that it calls.

This function is called Zen_CleanGlobalTaskArray and its file (of the same name) is in the Task System folder. The entire correct code for the function is this:

// This file is part of Zenophon's ArmA 3 Co-op Mission Framework
// This file is released under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)
// See Legal.txt

private ["_cleanUnitsArray"];

{
   _cleanUnitsArray = [(_x select 1)] call Zen_ArrayRemoveDuplicates;
   if (count _cleanUnitsArray == 0) then {
       Zen_Task_Array_Global set [_forEachIndex, 0];
   } else {
       _x set [1, _cleanUnitsArray];
   };
} forEach Zen_Task_Array_Global;

Zen_Task_Array_Global = Zen_Task_Array_Global - [0];
publicVariable "Zen_Task_Array_Global";

if (true) exitWith {};

The change is on line 12 of the file, in which is previously replaced the entire task data with just the objects that had the task. It now correctly updates the second element of the task data to remove duplicate objects. I had also forgotten the private statement.

For now, you can just copy that into the file and it should work fine (I actually tested it this time). It also removes duplicates correctly now. It's really too late to make a full release this Wednesday; a lot of changes are work-in-progress, let alone tested. Hopefully, anyone else with this problem in the next week (that function is used elsewhere in the task system) will see this and copy the new code.

Ironically, that change was designed to handle JIP better by remove duplicate objects that might be introduced with repeated JIP players. The point was to make sure mission makers didn't have to worry about players joining, leaving, and joining multiple times for the same player slot when the object name would be the same.

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

×