Jump to content
Zenophon

Zenophon's ArmA 3 Co-op Mission Making Framework

Recommended Posts

For fastroping not working, that might be reference to engine-based fastroping. The fastrope code will just force each unit to exit, then just move their position in steps until they get to the ground. I doesn't always look that smooth, but it works. In the fastrope.sqf script, you have the vehicle to fastrope from in the action's arguments

 

// replace air1 with _vehicle.
0 = [_vehicle, _x] spawn Zen_OrderFastRope;
Zen_OrderInsertion with the fastrope argument is the easy way to force players/AI to fastrope. If you want to present an action, Zen_AddFastRope is fairly close to what you're doing; it's not quite as smooth because each player can fastrope independently, causing Zen_OrderFastRope to run multiple times. In general, you can always use 'air1 = this' in the editor init field to get a global variable rather than the name field.

 

Thanks, Zenophon! Thank you for your pointers and the work in general you've put into the framework. Scripting is still 98% black magic to me, and I am amazed at the usefulness of your framework.

Share this post


Link to post
Share on other sites

Update and Release #38

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 links 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 will be on Armaholic soon. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc.

Changelog

This release includes only one minor fix and an update for the dialog system. A new text entry control has been added; you can link it to buttons to get the entered text as a string.

I'm also happy to report that the preprocessor up directory command has been fixed by BIS. You can now use "..\ " to point up a directory. That means it's no longer necessary to put the framework and standard preprocessor libraries in every sub-folder.

I'm now returning to a once a month release schedule, as the dialog system is almost complete. I'm planning on overhauling the fire support actions to use dialogs as well as renovating a lot of code examples in the documentation.

11/2/15

  • Fixed: Zen_OrderVehicleMove did not adjust the cleanup radius for aircraft
  • Fixed: Zen_UpdateControl did not allow updates to several control types
  • Added: Zen_CreateControl control type 'TextField'
  • Documentation: Updated for Dialog system
  • Documentation: Updated KnownIssues.txt
  • Like 1

Share this post


Link to post
Share on other sites

Update and Release #39

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 links 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 will be on Armaholic soon. 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 another control type for the dialog system as well as updated and modernized documentation code. I have reviewed almost all of the documentation and corrected old information, old typos, and attempted to correct any logical or MP mistakes as well as modernize the code style (such as by using ZEN_FMW_MP_REAll, etc.). All the sample missions have been tested once more and are still in working order. The tutorials have not been reviewed; those will be updated next release.

The new ProgressBar control type is likely one of the last additions to the dialog system. I've seem to run out of control types that can be dynamically added. Things like check boxes, radio buttons, etc. can be created using buttons and text boxes. For next release, I'll give example code that implements a multiple choice type dialog.

12/7/15

  • Fixed: Zen_OrderAircraftPatrol, Zen_OrderBoatPatrol, and Zen_OrderVehiclePatrol did not filter out destroyed objects at the right time, causing errors
  • Fixed: ZEN_FMW_Array_RemoveIndexes did not remove the right elements when the indexes were not in ascending order
  • Added: Zen_CreateControl control type ProgressBar
  • Added: Zen_CreateControl property Progress
  • Documentation: Updated Notepad++ SQF language and autocompletion file with ArmA 1.54 stable commands
  • Documentation: Fixed numerous typos and old information in all documentation
  • Documentation: Updated numerous demonstrations and sample missions with more modern code
  • Documentation: Updated for Dialog System
  • Like 1

Share this post


Link to post
Share on other sites

Hi Zenophon, quick question: are units meant to stay stationary when using Zen_OrderInfantryPatrolBuilding?

Share this post


Link to post
Share on other sites

Update and Release #40

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 links 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 will be on Armaholic soon. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc.

Changelog

Another framework release welcomes you to the new year. This release contains mostly improvements and fixes for Zen_AddFireSupportAction and its fellow fire support action functions. Now each fire support is menu entry on a dialog, and the dialog is accessed via an action by players who have supports available to them. Bugs have been fixed, the MP synchronization streamlined, and cancellation improved. The order of arguments to Zen_AddFireSupportAction has changed, correct those if you are using guided supports.

A note for players, please use the refresh button provided on the fire support dialog. The dialog will never update itself automatically. I've tried to eliminate any errors or incorrect behaviour that occur when the dialog is not refreshed, but it's better if you just refresh.

A note for mission makers, please update the framework #includes in your description.ext to what's in the sample description.ext; the communication menu entry previously used by the fire support action system has been removed. Otherwise, you will get a crash to desktop.

Also for mission makers, update your JIP code to account for the new fire support actions (if you use those actions in the mission). You'll also need to update the PV's the server sends to include every framework public variable. These changes are reflected in the JIP demonstration.

1/11/16

  • Fixed: Zen_AddFireSupportAction caused an error when no guidance object was given for an unguided support
  • Fixed: Zen_AddFireSupportAction did not display a radio message
  • Fixed: Zen_FindGroundPosition did not consider all roads within the preferred distance
  • Fixed: ZEN_FMW_Array_RemoveIndexes did not use the given index array
  • Added: Zen_AddFireSupportAction parameter for support description
  • Improved: Zen_AddFireSupportAction now uses a dialog to select supports
  • Improved: Zen_AddFireSupportAction does not count a usage of a support if it is canceled before it hits
  • Removed: Unused fire support notification config (update your description.ext #include's)
  • Documentation: Improved JIP code in sample missions
  • Documentation: Updated for Zen_AddFireSupportAction, Zen_GetFireSupportActionData, Zen_UpdateFireSupportAction

Feedback

 

Hi Zenophon, quick question: are units meant to stay stationary when using Zen_OrderInfantryPatrolBuilding?

Not for more than about 10 seconds, then they should get a new point to move to. I tested it briefly by standing next to a building and using:

_group = [player, west, 1, 2] call Zen_SpawnInfantry;
0 = [_group, player, false, "aware", 2] call Zen_OrderInfantryPatrolBuilding;
Do the units begin by moving around and then eventually stop, or do they never move around at all?

 

Example

As mentioned last release, the dialog system does not have built-in check box or radio button controls, but you can create them from the existing controls. Here's the example code for that.

// /**
F_ChooseOptionCheckBox = {
    _textBox = _this select 0;

    _data = [_textBox] call Zen_GetControlData;
    _properties = _data select 2;
    _indexes = [_properties, "Data", 0] call Zen_ArrayGetNestedIndex;
    _bool = (_properties select (_indexes select 0)) select 1;

    if (_bool) then {
        0 = [_textBox, ["Text", ""], ["Data", false]] call Zen_UpdateControl;
    } else {
        0 = [_textBox, ["Text", "X"], ["Data", true]] call Zen_UpdateControl;
    };
    call Zen_RefreshDialog;
    if (true) exitWith {};
};

F_Submit = {
    player commandChat str _this;
};

_dialogID = [] call Zen_CreateDialog;

_controlTextA = ["Text", ["Text", ""], ["Position", [0, 2]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;
_controlTextB = ["Text", ["Text", ""], ["Position", [0, 4]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;
_controlTextC = ["Text", ["Text", ""], ["Position", [0, 6]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;
_controlTextD = ["Text", ["Text", ""], ["Position", [0, 8]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;

_controlButtonA = ["Button", ["Text", "Alpha"], ["Position", [2, 2]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionCheckBox"], ["Data", _controlTextA]] call Zen_CreateControl;
_controlButtonB = ["Button", ["Text", "Bravo"], ["Position", [2, 4]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionCheckBox"], ["Data", _controlTextB]] call Zen_CreateControl;
_controlButtonC = ["Button", ["Text", "Charlie"], ["Position", [2, 6]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionCheckBox"], ["Data", _controlTextC]] call Zen_CreateControl;
_controlButtonD = ["Button", ["Text", "Delta"], ["Position", [2, 8]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionCheckBox"], ["Data", _controlTextD]] call Zen_CreateControl;

_controlButtonSubmit = ["Button", ["Text", "Submit"], ["Position", [2, 10]], ["Size", [5,2]], ["ActivationFunction", "F_Submit"], ["LinksTo", [_controlTextA, _controlTextB, _controlTextC, _controlTextD]]] call Zen_CreateControl;
_controlButtonClose = ["Button", ["Text", "Close"], ["Position", [2, 12]], ["Size", [5,2]], ["ActivationFunction", "Zen_CloseDialog"]] call Zen_CreateControl;

{
    0 = [_dialogID, _x] call Zen_LinkControl;
} forEach [_controlTextA, _controlTextB, _controlTextC, _controlTextD, _controlButtonA, _controlButtonB, _controlButtonC, _controlButtonD, _controlButtonSubmit, _controlButtonClose];

player addAction ["Checkbox Dialog", {0 = [_this select 3] spawn Zen_InvokeDialog;}, _dialogID];
//*/

////////////////////////////////////////////////////////////////////////////////////////////////
/// And now for radio button style
////////////////////////////////////////////////////////////////////////////////////////////////

// /**
F_ChooseOptionRadioButtons = {
    _data = _this select 0;
    _textBox = _data select 0;
    _allBoxes = _data select 1;

    {
        if (_x != _textBox) then {
            0 = [_x, ["Text", ""], ["Data", false]] call Zen_UpdateControl;
        };
    } forEach _allBoxes;

    0 = [_textBox, ["Text", "X"], ["Data", true]] call Zen_UpdateControl;

    call Zen_RefreshDialog;
    if (true) exitWith {};
};

F_Submit = {
    player commandChat str _this;
};

_dialogID = [] call Zen_CreateDialog;

_controlTextA = ["Text", ["Text", ""], ["Position", [0, 2]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;
_controlTextB = ["Text", ["Text", ""], ["Position", [0, 4]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;
_controlTextC = ["Text", ["Text", ""], ["Position", [0, 6]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;
_controlTextD = ["Text", ["Text", ""], ["Position", [0, 8]], ["Size", [2,2]], ["Data", false]] call Zen_CreateControl;

_controlButtonA = ["Button", ["Text", "Alpha"], ["Position", [2, 2]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionRadioButtons"], ["Data", [_controlTextA, [_controlTextA, _controlTextB, _controlTextC, _controlTextD]]]] call Zen_CreateControl;
_controlButtonB = ["Button", ["Text", "Bravo"], ["Position", [2, 4]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionRadioButtons"], ["Data", [_controlTextB, [_controlTextA, _controlTextB, _controlTextC, _controlTextD]]]] call Zen_CreateControl;
_controlButtonC = ["Button", ["Text", "Charlie"], ["Position", [2, 6]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionRadioButtons"], ["Data", [_controlTextC, [_controlTextA, _controlTextB, _controlTextC, _controlTextD]]]] call Zen_CreateControl;
_controlButtonD = ["Button", ["Text", "Delta"], ["Position", [2, 8]], ["Size", [10,2]], ["ActivationFunction", "F_ChooseOptionRadioButtons"], ["Data", [_controlTextD, [_controlTextA, _controlTextB, _controlTextC, _controlTextD]]]] call Zen_CreateControl;

_controlButtonSubmit = ["Button", ["Text", "Submit"], ["Position", [2, 10]], ["Size", [5,2]], ["ActivationFunction", "F_Submit"], ["LinksTo", [_controlTextA, _controlTextB, _controlTextC, _controlTextD]]] call Zen_CreateControl;
_controlButtonClose = ["Button", ["Text", "Close"], ["Position", [2, 12]], ["Size", [5,2]], ["ActivationFunction", "Zen_CloseDialog"]] call Zen_CreateControl;

{
    0 = [_dialogID, _x] call Zen_LinkControl;
} forEach [_controlTextA, _controlTextB, _controlTextC, _controlTextD, _controlButtonA, _controlButtonB, _controlButtonC, _controlButtonD, _controlButtonSubmit, _controlButtonClose];

player addAction ["Radio Button Dialog", {0 = [_this select 3] spawn Zen_InvokeDialog;}, _dialogID];
//*/

Share this post


Link to post
Share on other sites

Thank you for doing this framework, it's helping me learn my way around scripting but still way to go. :)

 

All good with Altis Patrol Tutorial until this line of code which is in the second part of the tutorial.

 

_civilianVehicleTypes = ["C_Hatchback_01_F", "C_Hatchback_01_sport_F",
"C_Offroad_01_F", "C_Quadbike_01_F", "C_SUV_01_F",
"C_Van_01_transport_F"];
_altistownMarkers = call Zen_ConfigGetTowns;  This line there is no file (call Zen_ConfigGetTowns) not sure which other file to call.

 

Thank you for this framework :)

Share this post


Link to post
Share on other sites

It should be:

_altistownMarkers = [["NameVillage", "NameCity", "NameCityCapital"]] call Zen_ConfigGetLocations;

However, that appears to be the same line that's in the most current release. Check that you've updated to the latest version; use the google drive link to be sure.

Share this post


Link to post
Share on other sites

This framework looks and sounds amazing, and I would love to start working with it. Have you considered setting up and using a github repository for the framework, instead of file hosts? This would allow anyone interested to contribute to the development, and you can create a Wiki, deal with issues, and stage releases directly on Github.

Share this post


Link to post
Share on other sites

Thank you I have the latest version - I used the google drive link and it was the same.  Thanks so much for the frame I now get what you mean by using a framework instead of the editor.  Very awesome and I've never done scripting before but starting to understand it better, thanks to you.  :)

Share this post


Link to post
Share on other sites

Holy hell. This seems like an astounding amount of work. Well done, and thanks for the continued development.

Share this post


Link to post
Share on other sites

This framework looks and sounds amazing, and I would love to start working with it. Have you considered setting up and using a github repository for the framework, instead of file hosts? This would allow anyone interested to contribute to the development, and you can create a Wiki, deal with issues, and stage releases directly on Github.

I have considered github, but the biggest issue for me is that I have to be able to guarantee the quality of the framework. I'm not saying this would happen for sure, but if I put the framework on github and a dozen people fork it, there's an issue with version control.

A wiki might be nice, but the strength of a wiki or any web documentation is the ability to link to other pages. The vast majority of documentation is self-contained function descriptions or sample code. Using the Notepad++ function hints is just as fast as searching a wiki, but people who don't use Notepad++ are left out. Maybe a Sublime Text SQF and function hint plugin would be nice, but don't use ST and don't know how to make a custom language for it.

Develop of the framework is about 90% done; of course there are hundreds of potential things to add, but most of them don't fit the framework's premise. I think confused people a little when a picked the word 'framework'; 'function library' really is a better name. It's a base to code on more than a 'plug-in' system.

 

Thank you I have the latest version - I used the google drive link and it was the same. Thanks so much for the frame I now get what you mean by using a framework instead of the editor. Very awesome and I've never done scripting before but starting to understand it better, thanks to you. :)

Holy hell. This seems like an astounding amount of work. Well done, and thanks for the continued development.

Thanks, I'm glad other people don't have to repeat all the work I did go right to creating missions.

Share this post


Link to post
Share on other sites
 

I have considered github, but the biggest issue for me is that I have to be able to guarantee the quality of the framework. I'm not saying this would happen for sure, but if I put the framework on github and a dozen people fork it, there's an issue with version control.

 

Forks are almost always just so people can make a commit and push it upstream, to the main repository. You wouldn't have to worry about separate versions floating around, that's not really an issue that exists anywhere else. If people create unicorn versions via fork and then create their own issues, that's their problem and not yours or the frameworks.

Share this post


Link to post
Share on other sites

Forks are almost always just so people can make a commit and push it upstream, to the main repository. You wouldn't have to worry about separate versions floating around, that's not really an issue that exists anywhere else. If people create unicorn versions via fork and then create their own issues, that's their problem and not yours or the frameworks.

I'm familiar with how github works; I'm thinking of potential users who aren't aware of that. People will have questions like: Which version do I use? Can you fix a bug in this other version? When will you add feature X from fork Y into the main framework? How do I combine features from multiple forks I've downloaded?

It's not that I'm against open source software. It's that a closed development has allowed me to design the API carefully and deliver a cohesive product. I encourage users to write their own scripts that rely on the framework; for example, if someone writes a revive script that uses framework function as part of its code, I'll promote that in this thread. Those are extensions to the framework that enhance it for users but are not directly part of it.

I choose what I add to the framework carefully based upon what existing feature it could improve or if it would really add something useful or unique. For example: the dialog system; everyone seemed to be writing their own dialog configs and using SQF GUI commands (lbAdd etc.). So I took a different perspective and created a high-level GUI programming system; it turned out fairly well considering the limitations (I can only dynamically create built-in BIS control classes). I limit the framework to generalized, widely usable functions (whether they are large or small).

Another issue is that the framework is approaching 15 thousand lines of code, and while the public documentation is complete, there is no internal documentation about how things are actually done (there aren't even more than a few comments in the code); even the function documentation follows a bunch of formatting rules. If someone has a bug report or a feature request, it is much faster that I do it than wait for someone to code it on their fork (then I still have to do QA and documentation for it).

That's sort of a long-winded reply, but I just wanted to explain my thought process and reasoning for anyone who's interested. Also, it's been a while since I put this request out there: if anyone has a function or system that you've created as part of a mission that you think would be useful to other mission maker, release it. The best way to design scripts that other people can use is to see what's useful to you when making a mission.

Share this post


Link to post
Share on other sites

Hi, I'm just beginning to learn how to use this framework, and recently I've been working through infantry showcase v2. I've been experiencing some consistent delays whenever I've called the Zen_SpawnInfantry function, and I'm wondering if thats just the nature of this function. As an example, I take the example from infantry showcase v2, in line 72, where a group spawn is called at the start of the mission;

_b_leaderPos = ["mkBluforPoint"] call Zen_FindGroundPosition;
_leadGroup = [_b_leaderPos, west, AI_SKILL, 4] call Zen_SpawnInfantry;
0 = [_leadGroup] call Zen_GiveLoadoutBlufor;

but I'm finding that this one group can take upto 2mins or even longer to spawn in. I've also experienced this in the spawning demonstration, where I literally sat around for ages without anything spawning in. This question is not so much about code optimisation of the framework, but more about why this is occurring, and if there is anything I can do/ or be aware of, to speed it up. 

 

If I were to spawn in units, using this method; 

_spawnedGroup = ["Zen_Spawn_Marker_Three", ["B_recon_M_F", "B_recon_F"]] call Zen_SpawnGroup;

then its extremely fast, and the mission flow isn't impacted on.

 

On an aside, does Zen_SpawnGroundVehicle also spawn the crew? Should I use the ambient vehicle spawn to insert empty vehicles?

 

thanks

Share this post


Link to post
Share on other sites

Hi, I'm just beginning to learn how to use this framework, and recently I've been working through infantry showcase v2. I've been experiencing some consistent delays whenever I've called the Zen_SpawnInfantry function, and I'm wondering if thats just the nature of this function. As an example, I take the example from infantry showcase v2, in line 72, where a group spawn is called at the start of the mission;

_b_leaderPos = ["mkBluforPoint"] call Zen_FindGroundPosition;
_leadGroup = [_b_leaderPos, west, AI_SKILL, 4] call Zen_SpawnInfantry;
0 = [_leadGroup] call Zen_GiveLoadoutBlufor;

but I'm finding that this one group can take upto 2mins or even longer to spawn in. I've also experienced this in the spawning demonstration, where I literally sat around for ages without anything spawning in. This question is not so much about code optimisation of the framework, but more about why this is occurring, and if there is anything I can do/ or be aware of, to speed it up. 

 

If I were to spawn in units, using this method; 

_spawnedGroup = ["Zen_Spawn_Marker_Three", ["B_recon_M_F", "B_recon_F"]] call Zen_SpawnGroup;

then its extremely fast, and the mission flow isn't impacted on.

 

On an aside, does Zen_SpawnGroundVehicle also spawn the crew? Should I use the ambient vehicle spawn to insert empty vehicles?

 

thanks

 

 

Try it without the loadout line 0 = [_leadGroup] call Zen_GiveLoadoutBlufor; and see if it's that which is slowing it down.

 

As far as the spawning questions, if you go into the frameworkdocumentation section and open the the txt files (in this case for ambient and ground vehicles open the Zen_SpawningFunctions.txt) the functions are listed and explain what they do and all the options you can use in the functions! You'll find them very robust for customization.

 

If certain parts of the mission are holding up the whole of the mission you might want to dig into how to code a mission using multithreading so the mission can move on without having to wait (if feasible). For example the spawning of ambient vehicles takes a long time because it has to find a good spot in a city then place a vehicle there, and the more vehicles you have the longer it takes so I use:

[] spawn {
	0 = [getMarkerPos "IslandPatrol", 10000, [0, 2]] call Zen_SpawnAmbientVehicles;
};

So I have a marker that covers the entire Altis map called "IslandPatrol". getMarkerPos "IslandPatrol" finds the center point of that marker. 10000 is the distance around that marker to populate cities with ambient vehicles. And [0, 2] means place from 0 to 2 vehicles in each city.

 

The [] spawn means that it opens a separate thread to run that function and the  rest of the mission continues to load at the same time. I'm not a coding expert and there are probably better ways to do this but that's what I do. Keep in mind that you can pass through a city and vehicles can spawn there after your past it!

Share this post


Link to post
Share on other sites

I've also experienced this in the spawning demonstration, where I literally sat around for ages without anything spawning in.

 

Besides the tutorials, the Zen_RandomPositions.Altis and Zen_SpawningDemonstration.Altis demonstrations were part of my contribution to the framework.

 

The spawning demo took one minute from clicking the Preview button in editor to rendering of all objects. This is little slower than I remember it and the delay is probably caused by placing vehicles on a road. The random positions demo ran between three and four minutes which is about right - the avoid clutter portion of the code is about half of that time.

 

A similar delay also occurs in the Fire Support Mission when the convoy is placed on the road.

 

As biggdogg notes, none of the tutorials and few of the demos are optimized for speed. For another spawning example, the WarlordRandom Tutorial shows how to spawn multiple threads that run in the background. In this case each thread controls the behavior of a single AI group.

 

To speed things up a little, I run ARMA from Steam with these command line parameters:

 

-noSplash -noPause -noBenchmark -showScriptErrors -world=empty -cpuCount=8 exThreads=7 maxMem=4096 maxVram=2048

 

Mimir.

Share this post


Link to post
Share on other sites

Thanks for your input guys. After reviewing my arma launch params and checking the lines of code against the spawning function in my mission, infantry seems to be placed much quicker than previously experienced. Also I didn't realise that, [ ] spawn, opened a separate thread. thats really useful to know. 

 

ton

Share this post


Link to post
Share on other sites

Zen_SpawnInfantry dynamically reads the config file using Zen_ConfigGetVehicleClasses to find units to spawn. Every unique search is saved by Zen_ConfigGetVehicleClasses and reused if the same search parameters are used again. The searches must run again each time a mission runs, and the search time is largely dependent upon the simulation's framerate.

You can avoid having to do this during the mission by using the engine down-time (and hence high framerate) during the briefing (shift-click on the preview button in the editor to force the briefing to appear) to quickly complete these searches and allow Zen_ConfigGetVehicleClasses to automatically save them for later. Something like:

// After this line
if (!isServer) exitWith {};

// copy the default search for Zen_SpawnInfantry for each side
{
    ["Men", _x, "All", "All", "All", "Both", ""] call Zen_ConfigGetVehicleClasses;
} forEach [east, west, resistance];

// Execution stops until the mission begins (past briefing)
sleep 1;

There's no need to assign the result to a variable. If you are giving specific factions or other class types to Zen_SpawnInfantry, you can prime those as well here (use Zen_ConfigGetVehicleClasses's documentation). A few seconds spent looking at the briefing is all that should be needed to complete every search.

Also, SQF is not truly multithreaded; there is only one engine thread serving as a SQF virtual machine (the compiler/translator that makes SQF code change the state of the simulation). 'spawn' creates a logically separate thread that is rotated through this single VM along with every other SQF thread. Thus, spawning something like Zen_SpawnAmbientVehicles allows the init.sqf to have a share of the processing time rather than halting completely, but it's at the cost of speed to both threads.

Share this post


Link to post
Share on other sites

Update and Release #41

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 links 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 will be on Armaholic soon. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc.

Changelog

This release sees the final upgrade to the Support Action System and the first new function in almost 5 months. I've dropped 'Fire' from the name as it now supports custom functions in which scripters can do anything they want. These custom supports are added using a new function and integrated into the existing data management function (I didn't change the names so as to save users the trouble). A custom support shows up in the menu like the fire supports and is of course MP and JIP compatible.

The custom supports can be canceled after 10 seconds, so to prevent abuse by players I suggest waiting 10 seconds in your support function before doing anything. A cancellation by the player will terminate your support function's thread. Custom supports run local to the player that called them. The arguments given to your custom function are included in the documentation for Zen_AddSupportActionCustom.

2/9/16

  • New Function: Zen_AddSupportActionCustom
  • Fixed: Zen_AddFireSupportAction caused an argument check error in Zen_InvokeFireSupport
  • Fixed: Zen_AddFireSupportAction did not return a value of the correct type upon argument error
  • Fixed: Zen_AddFireSupportAction did not allow the caller to cancel the support when the guidance target was remote
  • Added: Zen_ExecuteCommand new command for setOxygenRemaining
  • Documentation: Fixed JIP demonstration had old code
  • Documentation: Added for Zen_AddSupportActionCustom
  • Documentation: Updated for Zen_GetFireSupportActionData, Zen_RemoveFireSupportAction, and Zen_UpdateFireSupportAction

Code Example

In this section, I will present a function or piece of code that shows something not present in the existing documentation. These examples are adapted to be general, accessible, and customizable. They are meant to be useful to mission makers who want to include the code as part of their mission, as well as those who want to learn general coding techniques and specific framework implementations. These are not contrived or coded with any specific skill level in mind; they are taken from full missions I have finished or am working on with minimal changes. Of course, if you have any questions about an example, suggestions or your own example to present, or find any bugs, please let me know.

Our first example is a straightforward roadblock function. Its only parameter is a marker; it uses the direction of this marker to orient the roadblock, making the direction easy to determine visually in the editor. It spawns an MRAP and two guards on the road as well as guards patrolling beside the road and a supply truck.  It returns all the AI units spawned, the supply truck, and the MRAP in an array. You can change the side, the vehicles spawned, the skill and number of the AI, give different loadouts or put equipment the vehicles, etc. to customize this to suite your mission.

F_SpawnRoadblock = {
    private ["_mrap", "_marker", "_vehicle", "_roadGroup", "_sideGroups", "_markerPos", "_sideMarker", "_group", "_truck"];
    _marker = _this select 0;

    _mrap = [([_marker, 5, markerDir _marker, "compass"] call Zen_ExtendPosition), "O_MRAP_02_F", 0, markerDir _marker + 90 * ZEN_STD_Math_RandNegativePositive()] call Zen_SpawnVehicle;
    _mrap lock 2;

    _roadGroup = [_marker, east, "Infantry", 2] call Zen_SpawnInfantry;
    _sideGroups = [];
    for "_i" from 1 to 2 do {
        _markerPos = [_marker, 25 * (if (_i % 2 == 0) then {(1)} else {(-1)}), markerDir _marker + 90, "compass"] call Zen_ExtendPosition;
        _sideMarker = [_markerPos, "", "colorBlack", [10, 35], "Rectangle", markerDir _marker, 0] call Zen_SpawnMarker;
        _group = [_sideMarker, east, "Infantry", [1, 2]] call Zen_SpawnInfantry;
        0 = [_group, _sideMarker] spawn Zen_OrderInfantryPatrol;
        _sideGroups pushBack _group;

        if (_i == 1) then {
            _truck = [_markerPos, "O_Truck_02_covered_F", 0, markerDir _marker] call Zen_SpawnVehicle;
        };
    };

    0 = [[_roadGroup, _sideGroups], ZEN_FMW_Loadout_StdInfantryPreset] call Zen_GiveLoadoutOpfor;
    {
        _x setCaptive true;
    } forEach ([_roadGroup, _sideGroups] call Zen_ConvertToObjectArray);

    ([([_roadGroup, _sideGroups] call Zen_ConvertToObjectArray), _truck, _mrap])
};

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

×