Jump to content
Zenophon

Zenophon's ArmA 3 Co-op Mission Making Framework

Recommended Posts

hi every time i try to load you stuff i get CTD

To use Zen you need the Zen_frameworkfunctions folder, which can be found in the Shell.Stratis folder in the Zen.rar file.

Share this post


Link to post
Share on other sites
hi every time i try to load you stuff i get CTD

Chondo is correct, you need to put the Zen_FrameworkFunctions folder into your mission folder. Copy-paste from the documentation FAQ:

Q: When I try to load a mission, the game crashes to desktop with an error about #include something not found?

A: You must always place the Zen_FrameworkFunctions folder in your mission folder before loading your mission in the editor. The #include commands in the description.ext are looking for files, and those files must be there. I cannot prevent the game from crashing, this is an engine issue only BIS can fix.

Also, see the section 'Step-wise Installation' in the topmost readme file (next to Shell.Stratis and Zen_FrameworkDocumentation).

Share this post


Link to post
Share on other sites

Zenophon really great work, i will try to get into this but i`m a absolute script noob.

CallMeSarge is there a chance to see a test version of your insurgency soon ;) ?

Share this post


Link to post
Share on other sites
Guest

New version 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

CallMeSarge is there a chance to see a test version of your insurgency soon ;) ?

You can see my init SQF linked to on pastebin in a recent previous post. In order to finish my mission, I am mesing with revive and MHQ functions (outside of the Zen Framework), once this is done I intent to post 2 versions of the mission. One version will be no mods, the other will use an array of mods to attempt to simulate units and materiel in use in the recent Ukrainian conflict.

The Zen Framework is great though, i reccomend going slowly through the tutorials and then getting stick in.

Share this post


Link to post
Share on other sites

Hi Zen,

First, thanks a lot for all the work you have done. Amazing job, especially on the clarity and organization of the framework.

Is there a repository that we can fork or subscribe to?

Also, I have a suggestion. Well, two.

The first one, in the Zen_SpawnParachute, I extended the method to accept a parameter for night missions. If true, it will spawn a IR Grenade or a Chemlight. Did this due to a mission I'm working on and was difficult to find the dropped box on the map.

Also, on Zen_SpawnVehicleCrew, I was getting the default unit assigned to the vehicle. Not a surprise, since you already told this is the default behavior. On the other hand, I'm working with custom units, so what do you think about changing the switch to accept a "custom" and looking for another parameter with a classname? I know you could just spawn a unit and order it to the vehicle, but I'm curious what do you think about using only one method.

Thanks again. Since I started coding on Arma 3, this is the first time I feel I'm using a real framework. :)

Edited by BattleToaster
typo

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

This release features a more conservative set of 14 changes, most of which are fairly minor. The most interesting addition are the first set of function argument macros. These macros represent a value (and some can accept arguments) that fits with certain argument(s) of a function. They are for Zen_ArraySort this week, providing some simple sorting comparators.

Zen_ArraySort has also been modified to use a true comparator, rather than what was basically a hashing function. The comparator must return -1, 0, or 1 if the first value is less, equal, or greater than the second. This increases the complexity of using Zen_ArraySort, and decreases performance for extreme cases (10000 integers), but it allows more complex sorting without a significant performance hit for average array sizes (less than 500). For example, one of the macros offered is a alphanumeric string sort, which would have been nearly impossible before.

Zen_FindGroundPosition has a small change that makes it return the given position, argument (1), if it fails to find a valid position. This sounds useless, but in fact it is very helpful because it does not let things spawn at (0,0,0). Although the given center might not be ideal, that point would work better than (0,0,0).

Unfortunately, the way ArmA 3 preprocesses scripts does not allow #include directives to specify an 'up directory' command (normally ..\). This prevents functions from #include'ing the library if they are in a lower directory. The only solution seems to be coping the preprocessor libraries into all folders. You must also do this for your own functions in separate folders. This is annoying and there is nothing I can do about it. Please vote: http://feedback.arma3.com/view.php?id=9629.

9/10/14

  1. Fixed: Zen_FindValidDirection and Zen_FindTerrainSlope did not remove themselves from the stack
  2. Fixed: Zen_TrackGroups attempted to process dead units and null groups
  3. Added: Framework macros ZEN_FMW_ZAS_AL, ZEN_FMW_ZAS_ANS, ZEN_FMW_ZAS_DFN, ZEN_FMW_ZAS_DNF, ZEN_FMW_ZAS_IIA, ZEN_FMW_ZAS_SL, for Zen_ArraySort
  4. Added: Standard macros ZEN_STD_OBJ_PZT, ZEN_STD_OBJ_PZS, for object heights
  5. Added: Standard macro ZEN_STD_PRS_GAD, Parser Get optional Argument with Default value
  6. Improved: Many functions now use preprocessor macros
  7. Improved: Zen_ArraySort now uses a true comparator
  8. Improved: Zen_FindGroundPosition now returns the given center position when no valid position is found
  9. Improved: Zen_OrderExtraction and Zen_OrderInsertion let the helicopter move freely when off the ground
  10. Improved: Zen_OrderVehicleMove now handles helicopters better, similar to Zen_OrderHelicopterLand
  11. Documentation: Corrected for numerous macros
  12. Documentation: Added for ZEN_FMW_ZAS_AL, ZEN_FMW_ZAS_ANS, ZEN_FMW_ZAS_DFN, ZEN_FMW_ZAS_DNF, ZEN_FMW_ZAS_IIA, ZEN_FMW_ZAS_SL, ZEN_STD_OBJ_PZT, ZEN_STD_OBJ_PZS, ZEN_STD_PRS_GAD
  13. Documentation: Updated for Zen_ArraySort, Known Issues
  14. Documentation: Improved for Zen_AddFastRope

Roadmap

For next week, I will continue with some macros for Zen_FindGroundPosition, so that things like finding a good landing zone, a city street, etc. are much easier.

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_IsSeen. This function uses a simple, mathematical approach to determining if a unit would be visible by any enemies.

For example, if you have a stealth mission in which the player pretends to be civilian, you can alert the enemy if the player gets too close and gets spotted:

if ([player, 25] call Zen_IsSeen) then {
   player setCaptive false;
};

Although that seems a little boring, you can make things more interesting:

_seenCounter = 0;
waitUntil {
   sleep 5;
   if ([player, 50] call Zen_IsSeen) then {
       _seenCounter = _seenCounter + 1;
   };
   (_seenCounter > 5)
};

Now you can vary enemy reinforcements, mission tasks, etc. based upon a quantitative level of player stealth.

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).

Feedback

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.

---------- Post added at 01:03 ---------- Previous post was at 00:10 ----------

Hi Zen,

First, thanks a lot for all the work you have done. Amazing job, especially on the clarity and organization of the framework.

Is there a repository that we can fork or subscribe to?

Also, I have a suggestion. Well, two.

The first one, in the Zen_SpawnParachute, I extended the method to accept a parameter for night missions. If true, it will spawn a IR Grenade or a Chemlight. Did this due to a mission I'm working on and was difficult to find the dropped box on the map.

Also, on Zen_SpawnVehicleCrew, I was getting the default unit assigned to the vehicle. Not a surprise, since you already told this is the default behavior. On the other hand, I'm working with custom units, so what do you think about changing the switch to accept a "custom" and looking for another parameter with a classname? I know you could just spawn a unit and order it to the vehicle, but I'm curious what do you think about using only one method.

Thanks again. Since I started coding on Arma 3, this is the first time I feel I'm using a real framework. :)

Thank you for the compliments; I have probably put just as much time into documentation as I have coding.

There is no online repository, GitHub or otherwise. You can make a local copy if you want to edit things, and I suggest something like WinMerge if you want to keep up to date with every release.

Your first suggestion is a good one, in fact I may generalize it to allow any type of smoke grenade, chemlight, IR light, etc.

The second suggestion is a bit trickier. If I allow one custom classname as the parameter, the vehicle would be filled by only that object. This removes the automation of class and side that makes the function easy to use. I could allow a list of custom classnames, for each possible kind of crew (tank, jet, etc.). However, this results in 5 classes for 3 sides (civilian never changes) giving 15 in total.

I could search CfgVehicles dynamically for classes of a certain faction (which is typically how addon units are distinguished), but determining which of them is the correct crew type would in general be nearly impossible (you cannot assume 'pilot' etc. is in the classname).

As a solution, I recommend using loadouts to simply make the unit look different. You can use Zen_GetUnitLoadout in a test mission to get addon units' default loadouts, and use the framework's custom loadout system to give certain ones to the crew. You can match the loadouts given to the types of the crew objects. This lets Zen_SpawnVehicleCrew indirectly decide the correct loadouts for the crew.

Share this post


Link to post
Share on other sites
Guest

Thanks for informing us of the new 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
hi

some how every time i try to load a demo mission i get CTD

You need to make sure each mission folder has the Zen_FrameworkFunctions folder in it. Check the front page of this thread.

hey @Zenophon

lovin the mission framework! made some minor edits to a couple functions to make them do what i wanted (like Zen_SpawnItemsOnTable - made it so you could have an array of strings and one object or an array of strings and an array of objects, then spawn the items at random positions/directions on each table taking into account the tables length, width and direction) but all in all its exactly what i needed. What makes it special is the documentation. I WISH BIS was this organized! Instead of having to serach through webpage after webpage looking for the exact function you need to use, only to find out its been depricated! FRUSTRATING!!!

anyway thankyou.

Quick question. Does the Zen_TriggerAreNear update to the position of the object if it is moving?

example: I have a moving civilian which i call Zen_TriggerAreNear on. The trigger is activated by west and its radius is 5m. Will the trigger follow the civilian, allowing 'west' to trigger it when they are within 5 meters? Or do i need a waitUntil {condition} before i call the Zen_TriggerAreNear function?

Thanks in advance.

Edited by Baconator

Share this post


Link to post
Share on other sites
You need to make sure each mission folder has the Zen_FrameworkFunctions folder in it. Check the front page of this thread.

hey @Zenophon

lovin the mission framework! made some minor edits to a couple functions to make them do what i wanted (like Zen_SpawnItemsOnTable - made it so you could have an array of strings and one object or an array of strings and an array of objects, then spawn the items at random positions/directions on each table taking into account the tables length, width and direction) but all in all its exactly what i needed. What makes it special is the documentation. I WISH BIS was this organized! Instead of having to serach through webpage after webpage looking for the exact function you need to use, only to find out its been depricated! FRUSTRATING!!!

anyway thankyou.

Quick question. Does the Zen_TriggerAreNear update to the position of the object if it is moving?

example: I have a moving civilian which i call Zen_TriggerAreNear on. The trigger is activated by west and its radius is 5m. Will the trigger follow the civilian, allowing 'west' to trigger it when they are within 5 meters? Or do i need a waitUntil {condition} before i call the Zen_TriggerAreNear function?

Thanks in advance.

Hey Bacon, any chance of sharing that method? Looks cool to have randomized itens.

Thanks!

Edited by BattleToaster
typo

Share this post


Link to post
Share on other sites

hey @Zenophon

lovin the mission framework! made some minor edits to a couple functions to make them do what i wanted (like Zen_SpawnItemsOnTable - made it so you could have an array of strings and one object or an array of strings and an array of objects, then spawn the items at random positions/directions on each table taking into account the tables length, width and direction) but all in all its exactly what i needed. What makes it special is the documentation. I WISH BIS was this organized! Instead of having to serach through webpage after webpage looking for the exact function you need to use, only to find out its been depricated! FRUSTRATING!!!

anyway thankyou.

Quick question. Does the Zen_TriggerAreNear update to the position of the object if it is moving?

example: I have a moving civilian which i call Zen_TriggerAreNear on. The trigger is activated by west and its radius is 5m. Will the trigger follow the civilian, allowing 'west' to trigger it when they are within 5 meters? Or do i need a waitUntil {condition} before i call the Zen_TriggerAreNear function?

Thanks in advance.

That makes a good point about Zen_SpawnItemsOnTable. It should stop when it runs out of tables, not just when it runs out of classes. I will make that change for next week. Then you can do:

// next release this will work for arrays of any length
0 = [([_objectClasses] call Zen_ArraySortRandom), _tables] call Zen_SpawnItemsOnTable;

Thank you for appreciating the documentation. It admittedly was tedious to document that many functions in such an exact style. I believe it is important for the framework to have method to the madness. You will also be happy to know that I don't leave any deprecated functions around.

For Zen_TriggerAreNear, yes the locations will be left as a object or group, so their positions will be reevaluated each iteration. This is the generic parser for the objective positions:

_objPos = [];
{
   if ((typeName _x) in ["OBJECT", "GROUP"]) then {
       _pos = _x;
   } else {
       _pos = [_x] call Zen_ConvertToPosition;
   };
   _objPos pushBack _pos;
} forEach _givenPos;

Share this post


Link to post
Share on other sites
Hey Bacon, any chance of sharing that method? Looks cool to have randomized itens.

Thanks!

Hey BT

I would just wait until Zen updates his framework package. That way you dont have to overwrite the function, and, if you can wait a week, it will do the exact same thing! probably even better! :biggrin_o:

@Zenophon

Ok. Thats what i needed to know. In running some tests i did find out that it updates rather quickly but if the object is moving faster than walking speed it will lag behind a bit but that's expected for server stress purposes.

Zen_SpawnItemsOnTable

That would be awesome! Ill send you what I've got, because i did run into some locality issues with MP as well as getting the right positions for the spawned items. Generally you would want to spawn the items on something that is not square, as well, the items are not a single point, so it looks weird when a laptop is floating next to a table or whatever.

Suggestion. Editing the Zen_OrderInfantryPatrol to be more usable with civilians and also incorporate you're "isSeen" function. The last element in the passed array, the boolean "Chase down the enemy", would be nice to have work for civilians, so if your convoy pulls into a town of civilians, they would all bum rush your vehicles asking for supplies or something. I tried setting this to true, which works somewhat, but because their combat mode gets set to red, they weave in and out of cover before standing next to you with a blank stare. Its rather funny to watch, but quite annoying if you're trying to make a "supply the town then have God's wrath rain down upon you" type mission.

As for incorporating the Zen_isSeen function, I can see this working quite well with the patrolling function as another optional parameter. You could pass the patrol function a radius, and with that radius define the minimum/maximum distance before the player, or an enemy unit "isSeen" before the patrol reacts. As an example, you had the last parameter set to true (granted you added functionality to the patrol script for civilian), the civilian AI would keep walking around town until the player was within 3 meters of said civilian. Said civilian would then stop what he was doing and approach (player or AI). This would allow you to very easily set up a believable civilian interaction.

Hell, you could take it a step further and turn a separate version of Zen_OrderInfantryPatrol along with Zen_FindGroundPosition into a fully functioning Civilian Interaction Module by incorporating POLPOX's calm soldier script.

Share this post


Link to post
Share on other sites
Hey BT

I would just wait until Zen updates his framework package. That way you dont have to overwrite the function, and, if you can wait a week, it will do the exact same thing! probably even better! :biggrin_o:

@Zenophon

Ok. Thats what i needed to know. In running some tests i did find out that it updates rather quickly but if the object is moving faster than walking speed it will lag behind a bit but that's expected for server stress purposes.

Zen_SpawnItemsOnTable

That would be awesome! Ill send you what I've got, because i did run into some locality issues with MP as well as getting the right positions for the spawned items. Generally you would want to spawn the items on something that is not square, as well, the items are not a single point, so it looks weird when a laptop is floating next to a table or whatever.

Suggestion. Editing the Zen_OrderInfantryPatrol to be more usable with civilians and also incorporate you're "isSeen" function. The last element in the passed array, the boolean "Chase down the enemy", would be nice to have work for civilians, so if your convoy pulls into a town of civilians, they would all bum rush your vehicles asking for supplies or something. I tried setting this to true, which works somewhat, but because their combat mode gets set to red, they weave in and out of cover before standing next to you with a blank stare. Its rather funny to watch, but quite annoying if you're trying to make a "supply the town then have God's wrath rain down upon you" type mission.

As for incorporating the Zen_isSeen function, I can see this working quite well with the patrolling function as another optional parameter. You could pass the patrol function a radius, and with that radius define the minimum/maximum distance before the player, or an enemy unit "isSeen" before the patrol reacts. As an example, you had the last parameter set to true (granted you added functionality to the patrol script for civilian), the civilian AI would keep walking around town until the player was within 3 meters of said civilian. Said civilian would then stop what he was doing and approach (player or AI). This would allow you to very easily set up a believable civilian interaction.

Hell, you could take it a step further and turn a separate version of Zen_OrderInfantryPatrol along with Zen_FindGroundPosition into a fully functioning Civilian Interaction Module by incorporating POLPOX's calm soldier script.

Zen_SpawnItemsOnTable should put the object in the center of the table; it makes sense that getPosATL would return the center, at least for XY coordinates. If there is a problem with just some tables then the algorithm is not general enough.

Zen_IsSeen sounds great, but it is not a simulation of AI sight. It just a mathematical determination of if a unit is possibly visible to the enemy. It could return true if you put your head around a corner 100 meters from the enemy. Zen_OrderInfantryPatrol uses knowsAbout because it more fairly represents what the AI can really see and accounts for their memory if the target has just gone out of sight. The distance to chase an enemy depends on the size of the patrol area. Units will leave their area if there is a clear target to attack, but will eventually give up based upon distance.

The chasing enemy feature of Zen_OrderInfantryPatrol will work for civilians if findNearestEnemy (the command currently used) returns a valid target (I don't know if it does). Otherwise, I would have to rewrite the chasing feature to search for enemies using nearTargets. This would make things needlessly more complex for non-civilian groups (which is the intended use of the function).

It's not possible stop civilians from running around crazy and not following move orders. As a workaround for that, you could spawn Blufor/Opfor units and put them in civilian clothes. They then function that same as regular soldiers, just without weapons. However, if they can be shot at, you would have to use setCaptive, which may bring some of those behaviors back.

Lastly, making something that complex does deserve its own function/module. Zen_OrderInfantryPatrol is purposefully simple so that it can be flexible and easy to use. The main loop controlling the patrol is only 45 lines. If I provide a feature like civilian interaction I need to generalize it to fit almost any mission. Most mission makers have something very specific in mind for civilian interaction (like rushing a supply vehicle), so that makes generalizing very hard to do.

Share this post


Link to post
Share on other sites

findNearestEnemy does not work for civilians unless you specifically set who their enemies are. You could do something like

civilian setFriend [west,0];
_target = _man findNearestEnemy _man;
civilian setFriend [west,1];

that should work. But it can have adverse effects on AI behavior according to the setFriend wiki if used after mission start. In the case of the civilian though, i dont really care.

Share this post


Link to post
Share on other sites
findNearestEnemy does not work for civilians unless you specifically set who their enemies are. You could do something like
civilian setFriend [west,0];
_target = _man findNearestEnemy _man;
civilian setFriend [west,1];

that should work. But it can have adverse effects on AI behavior according to the setFriend wiki if used after mission start. In the case of the civilian though, i dont really care.

Then if I use that code in Zen_OrderInfantryPatrol, the civilians should move to any west unit just as an east unit would. The only issue is their behavior state, which could be 'combat'. I will change Zen_OrderInfantryPatrol so that if the group is civilian, then it uses:

_group setBehaviour "careless";

The 'careless' mode cannot be changed by the AI, only with another setBehaviour command. That would make civilians less interested in finding cover or running around in circles.

Share this post


Link to post
Share on other sites

As much as i like to see civilians run around like chickens, that would be awesome. That would set up the mission maker for easier AI interaction, not just for civilians. You could set the side of an opfor unit to civilian, call this function, then a simple if/then condition, then set the side back to original or keep it civilian and boom, you have Nazi SS checking your papers lol

edit: no offense to any Nazi's. It's only for example.

Share this post


Link to post
Share on other sites

Yeah. I think it could work.

My problem with civs in the map is that they are usually used as decoration. Would be nice to have this kind of interaction.

In a mission I'm working, hostile troops kill civs at a random checker. I know this sounds mean, but it fits my mission objective.

Share this post


Link to post
Share on other sites

I just wish that Bohemia would bring back the ALICE module for Arma 3. Would make working/scripting with civilians so much easier. TPW does a great job with ambient civs, but he made those scripts for single player, they wont work on a dedicated server.

Edited by Baconator

Share this post


Link to post
Share on other sites

Hey Zen,

Real life has stopped me from getting much done on the mission, but I am hoping to do a play test sometime this week to dig into the issue of grids sometimes not clearing. Aside from that I am really close to completion now :D - more on that to follow. I have another loadout question. I really like using the loadouts to randomize what weapons the opfor will carry. But when it comes to launchers, it means that if a unit gets the "launcher" loadout, they then have no primary weapon, and are forced to fight other infantry with their pistol! Is there any way around this? I am still using the code you helped me out with back on page 8:

["weapons", [["arifle_TRG21_MRCO_F", "arifle_TRG21_GL_ACO_pointer_F", "LMG_Zafir_F","srifle_EBR_DMS_F","launch_RPG32_F"],"hgun_Pistol_heavy_01_F","Rangefinder"]], 
["magazines", [[["30Rnd_556x45_Stanag", 9], ["30Rnd_556x45_Stanag", 9], ["150Rnd_762x51_Box", 4], ["20Rnd_762x51_Mag", 8], ["RPG32_F", 4]], ["11Rnd_45ACP_Mag", 2], ["HandGrenade", 2], [["SmokeShell", 4], ["SmokeShellBlue", 4]]]], 

Share this post


Link to post
Share on other sites
Hey Zen,

Real life has stopped me from getting much done on the mission, but I am hoping to do a play test sometime this week to dig into the issue of grids sometimes not clearing. Aside from that I am really close to completion now :D - more on that to follow. I have another loadout question. I really like using the loadouts to randomize what weapons the opfor will carry. But when it comes to launchers, it means that if a unit gets the "launcher" loadout, they then have no primary weapon, and are forced to fight other infantry with their pistol! Is there any way around this? I am still using the code you helped me out with back on page 8:

["weapons", [["arifle_TRG21_MRCO_F", "arifle_TRG21_GL_ACO_pointer_F", "LMG_Zafir_F","srifle_EBR_DMS_F","launch_RPG32_F"],"hgun_Pistol_heavy_01_F","Rangefinder"]], 
["magazines", [[["30Rnd_556x45_Stanag", 9], ["30Rnd_556x45_Stanag", 9], ["150Rnd_762x51_Box", 4], ["20Rnd_762x51_Mag", 8], ["RPG32_F", 4]], ["11Rnd_45ACP_Mag", 2], ["HandGrenade", 2], [["SmokeShell", 4], ["SmokeShellBlue", 4]]]], 

I can make it so that the custom loadout can given multiple random weapons, just as it already can give multiple random magazines. Next release this will work:

["weapons",
   [
       [
           [
               "arifle_TRG21_MRCO_F",
               "launch_RPG32_F"
           ],
           "arifle_TRG21_GL_ACO_pointer_F",
           "LMG_Zafir_F",
           "srifle_EBR_DMS_F"
       ],
       "hgun_Pistol_heavy_01_F",
       "Rangefinder"
   ]
],
["magazines", 
   [
       [
           [
               ["30Rnd_556x45_Stanag", 9],
               ["RPG32_F", 4]
           ],
           ["30Rnd_556x45_Stanag", 9],
           ["150Rnd_762x51_Box", 4],
           ["20Rnd_762x51_Mag", 8]
       ],
       ["11Rnd_45ACP_Mag", 2],
       ["HandGrenade", 2],
       [
           ["SmokeShell", 4],
           ["SmokeShellBlue", 4]
       ]
   ]
]

This lets you choose which weapon the AT launcher goes with changes the probability of its appearance (putting it with all weapons gives 100% chance). If you don't want a connection between the rifle and having a launcher, then you must create two loadouts. If have 'Rifleman' and 'ATRifleman', then you can change their probability with this:

0 = [_unit, ["Rifleman", "Rifleman", "Rifleman", "ATRifleman"]] call Zen_GiveLoadoutCustom;

The chance of a random AI having a launcher is 1:4, and so on as you add 'Rifleman' strings.

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

This week's changes include plenty of interesting improvements to various functions (not that those preprocessor macros aren't interesting). A lot of them stem from an effort to improve ease of use when dealing with large indoor areas (like the ghost hotel).

Zen_OrderInfantryPatrol now offers its chasing function for civilians, they should move to anyone they spot and follow them around for a while. This, of course, can be disabled with chasing parameter, which is now actually working (previously the argument was not overwriting the default value).

Zen_SpawnParachute now allows you to provide any class of grenade (smoke, IR, etc.) that you want to be attached to the object as a signal. Classnames that are not technically magazines will not spawn. I am still working on how to filter out true firearm magazines effectively, so addon grenades can be used as well.

Zen_RotateAsSet, Zen_SpawnGroup, and Zen_TriggerAreRescued now respect the height of positions and objects. You can now spawn a group in the air or rotate objects with different heights (they will still only rotate in the XY plane). All of these are meant for placing units inside large buildings that have few building positions.

Zen_SpawnItemsOnTable has been improved by making sure the object is oriented to the table realistically. The items should also be shifted at random on the XY plane of the table top, with that shift oriented correctly to the table's direction.

For optimizations this week, Zen_ConfigGetLocations now remembers the results of previous arguments, so using it to find hills, towns, etc. will only require processing for that set of arguments a single time. After that it will simply return the previous result. This is the same system used by Zen_ConfigGetVehicleClasses.

Zen_SpawnAmbientVehicles has also been optimized thanks to Zen_ArraySort, so that it can detect valid towns and villages to spawn vehicles in order of distance. That way it doesn't have to look blindly for towns within the given distance. Finally, Zen_FindTerrainSlope has been very slightly optimized by using a different trig equation for the angle that requires one less operation.

Fastroping has been generally improved by having Zen_OrderHelicopterLand force AI pilots to get even closer to the exact fastrope target. Zen_OrderFastRope will also make sure that ending point of the rope (where it collides with something) is as accurate as possible, provide the helicopter isn't moving. You can now reliably fastrope onto the roof of a medium-sized building, with less than 2 meters error from the given position.

Also, the custom loadout system has been slightly modified so that a matching pair of weapon and magazine can give multiple of each. An example of this is shown in the custom loadout demonstration mission. The specifics are, of course, detailed and tedious, but the custom loadouts are meant to be an extremely flexible data structure.

Finally, there are some new macros this week, including ZEN_STD_MTH_RNP to allow a random negative or positive direction to something and ZEN_STD_OBJ_TPT to alter an object's location by giving the change in its XYZ coordinates. I noticed that although BIS added lots of new commands for vectors recently, they don't offer coordinate system transformations. So ZEN_STD_MTH_VCC and ZEN_STD_MTH_VCP will change a Cartesian vector into a Cylindrical or Spherical (3d polar) vector.

9/17/14

  1. Fixed: ZEN_FMW_MP_REA, ZEN_FMW_MP_REC, ZEN_FMW_MP_RED, ZEN_FMW_MP_RES, did not execute the function locally when they should
  2. Fixed: Zen_OrderInfantryPatrol did not recognize parameter 7, for chasing the enemy
  3. Fixed: Zen_RotateAsSet now keeps the heights of objects the same
  4. Fixed: Zen_SpawnGroup now interprets the height of the given position as ATL or ASL correctly
  5. Added: Standard macro ZEN_STD_MTH_RNP, Random Negative or Positive
  6. Added: Standard macro ZEN_STD_MTH_VCC, ZEN_STD_MTH_VCP, for vector transformations
  7. Added: Standard macro ZEN_STD_OBJ_TPT, Transform Position ATL
  8. Added: Zen_SpawnParachute now has a parameter for the signal grenade attached to the object
  9. Improved: Zen_ConfigGetLocations massively optimized for repeating argument calls
  10. Improved: Zen_GiveLoadoutCargo and Zen_GiveLoadoutCustom can now give multiple matching weapons
  11. Improved: Zen_FindTerrainSlope slightly optimized
  12. Improved: Zen_OrderFastRope now checks to correct fastrope stop height from the rope's exact position
  13. Improved: Zen_OrderHelicopterLand now makes the helicopter reach a fastrope position more accurately
  14. Improved: Zen_OrderInfantryPatrol now applies chasing the enemy for civilians, they now chase everyone
  15. Improved: Zen_SpawnAmbientVehicles optimized
  16. Improved: Zen_SpawnGroup now places all units at the exact given position
  17. Improved: Zen_SpawnItemsOnTable now exits when it runs out of paired tables
  18. Improved: Zen_SpawnItemsOnTable now orients to object to the table better
  19. Improved: Zen_TriggerAreRescued now only triggers when the units' Z positions are within 2 meters
  20. Documentation: Fixed Notepad++ SQF language readme file function hint instructions
  21. Documentation: Added for ZEN_STD_MTH_RNP, ZEN_STD_MTH_VCC, ZEN_STD_MTH_VCP, ZEN_STD_OBJ_TPT
  22. Documentation: Improved for Zen_OrderInfantryPatrolBuilding
  23. Documentation: Updated for Zen_SpawnItemsOnTable, Zen_SpawnParachute
  24. Documentation: Updated Zen_CustomLoadouts Demonstration
  25. Documentation: Tweaked Legal.txt terms for derivative frameworks

Roadmap

For next week, I plan on rewriting Zen_OrderInfantryPatrolBuilding to use a much better algorithm for creating move points in the building. Rather than just using the provided building positions, I aim to have it dynamically generate positions anywhere on the building, accounting for different floors, the roof, and different shapes of buildings.

This could also be used in Zen_SpawnInfantryGarrison to improve the units' starting positions. If this is very successful, I will put it in to a new function that can generate infinite random valid points inside of any building, essentially providing a dynamic solution instead of fixed building positions.

I am also planning on letting Zen_ArraySort use the old comparator style (it just hashes the element into a number). This will be a parameter, letting you choose the new style (a true comparator providing less-equal-greater results) or the old one.

I am also going to offer a slightly different angle with some new macros, which will essentially be snippets of SQF code (2-6 lines) that appear extremely often. For example, a helicopter insertion, spawning and patrolling groups in a marker, etc.

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_GetUnitTasks. This function returns all task strings that are assigned to the given unit. This allows you to switch the focus from tasks to objects.

For example, you have a thread running that assigns tasks to some units:

0 = _units spawn {
   // ...
   0 = [_units, /* something */] call Zen_InvokeTask;
   // ...
};

There are a lot of these tasks, all assigned to the same array of units. The tasks deal with markers that you have already placed. You don't want to deal with creating a data structure to send those task names back to your init.sqf thread and associate them with the markers. Instead, you use Zen_GetUnitTasks and Zen_GetTaskDataGlobal to check on the tasks:

// Assume _markers is already defined as some objective zones
// Assume the task titles are descriptive
while {true} do {
   sleep 30;
   _tasksArray = [_units select 0] call Zen_GetUnitTasks;
   _tasksArray = [_tasksArray, "([_x] call Zen_AreTasksComplete)"] call Zen_ArrayFilterCondition;
   {
       _data = [_x] call Zen_GetTaskDataGlobal;
       _marker = [_markers, (_data select 3)] call Zen_FindMinDistance;
       switch (true) do {
           case (["Clear", (_data select 5)] call Zen_StringIsInString): {
               // if no enemies in _marker
                   // task succeeded
           };
           case (["Protect", (_data select 5)] call Zen_StringIsInString): {
               // if object of type "X" is not alive in _marker
                   // task failed
           };
           case (["Supply", (_data select 5)] call Zen_StringIsInString): {
               // if vehicle of _units is in _marker
                   // task succeeded
           };
   } forEach _tasksArray;
};

That's a very incomplete example, but you can see how the task system allows you to work backwards from the objects by getting the tasks and their properties. You don't have to have the string name of the task to do something with it.

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).

Feedback

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

Awesome, cannot wait to try out the new custom loadouts tonight!

Zen, another question for you: In my mission, I am using the variable ENEMY SIDE which is set to East. This means that all of my enemy soldiers are middle eastern - but my mission is set in Europe, so it does not look right. I know I could use RESISTANCE to make them all independent (which has a less middle eastern looking player model) but ideally I would like to keep the enemy as Opfor but switch the player models. Reading the Zen_SpawningFunctions.txt, I think I could do it like this?

// Example 1 - current spawning code
_enemyGroup = [_spawnPos, ENEMY_SIDE, AI_SKILL, [4,8]] call Zen_SpawnInfantry; 

// Example 2 - modified spawning code
_enemyGroup = [_spawnPos, ENEMY_SIDE, AI_SKILL, [4,8],"Men", "IND_F"] call Zen_SpawnInfantry; 

If I understand correctly, the side would be opfor but the unit would be an independant model, but appearing as an opfor unit - is this correct? Is this the best way to do that?

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

×