Jump to content
Zenophon

Zenophon's ArmA 3 Co-op Mission Making Framework

Recommended Posts

Testing the new Zen_SpawnVehicleCrew, in the UH80 using the "Gunner" option, it spawns the 2 gunners and the copilot.

I suppose it is they way is has to be but....can it spawn only the 2 gunners? XD

Share this post


Link to post
Share on other sites
Testing the new Zen_SpawnVehicleCrew, in the UH80 using the "Gunner" option, it spawns the 2 gunners and the copilot.

I suppose it is they way is has to be but....can it spawn only the 2 gunners? XD

Zen_SpawnVehicleCrew should spawn only true gunners (i.e. they have a weapon) when given only 'gunner'. This code works for me:

_heli = [player, "B_Heli_Transport_01_F", 40] call Zen_SpawnVehicle;
0 = [_heli, west, "gunner", true] call Zen_SpawnVehicleCrew;

The helicopter spawns and is missing the copilot, but the door gunners and pilot are there.

Share this post


Link to post
Share on other sites
Zen_ConfigGetVehicleClasses uses the 'access' attribute to filter out a lot of base classes. Only classes with access = 2 are shown in the editor, and those the only classes Zen_ConfigGetVehicleClasses checks as possibilities. Without this optimization it's harder to identify and skip over unspawnable classes. You can use Zen_SpawnGroup as a workaround, as it only checks if the class is a subclass of "Man".

Ahh. I did read this and I didn't pick up on that this was a workaround. Mark that down as a fail....LOL. Thanks Zenophon!

Here's a request!

Can you add the ability to have divers patrol an area? If there's not already. (Zen_OrderInfantryPatrol doesn't work because it looks for above ground positions) The under water experience for Arma3 is vastly overlooked I think. It would be nice if they're patrol waypoints would randomly change depth as well or if you could set their depth to a value above the sea floor would be good too.

Share this post


Link to post
Share on other sites
Zen_SpawnVehicleCrew should spawn only true gunners (i.e. they have a weapon) when given only 'gunner'. This code works for me:

_heli = [player, "B_Heli_Transport_01_F", 40] call Zen_SpawnVehicle;
0 = [_heli, west, "gunner", true] call Zen_SpawnVehicleCrew;

The helicopter spawns and is missing the copilot, but the door gunners and pilot are there.

Lol, it is not working for me. Same code in a mission spawns a heli with complete tripulation....

Redownloaded your framework, and still working wrong.

Share this post


Link to post
Share on other sites
Ahh. I did read this and I didn't pick up on that this was a workaround. Mark that down as a fail....LOL. Thanks Zenophon!

Here's a request!

Can you add the ability to have divers patrol an area? If there's not already. (Zen_OrderInfantryPatrol doesn't work because it looks for above ground positions) The under water experience for Arma3 is vastly overlooked I think. It would be nice if they're patrol waypoints would randomly change depth as well or if you could set their depth to a value above the sea floor would be good too.

I'll add support for divers into Zen_OrderInfantryPatrol. Ideally, I could just set the height of the waypoint by looking at the terrain type and have the divers follow that height above the sea floor. However, divers might run up onto any land in the patrol zone though, so I might make an 'underwater' parameter.

Lol, it is not working for me. Same code in a mission spawns a heli with complete tripulation....

Redownloaded your framework, and still working wrong.

I verified the game cache on Steam, and I'm running 1.34 stable. I tried it again in a different test mission, and it still worked as intended. I've made some internal changes for bugs I found in addition to fixing the bugs reported, so that must be it.

I'll just update the latest release to my internal version. Hopefully that's the last hotfix necessary for this release; it should fix everything that went wrong with this release.

Share this post


Link to post
Share on other sites

Done some more tests....

Seems one of the addons I use it's making spawn an extra copilot XD.

Will have to check which one of them it is.

Vanilla Arma works perfectly. Thanks Zen!

---------- Post added at 22:57 ---------- Previous post was at 20:58 ----------

"Helmet Mounted Displays Mod" adds weapons to the copilot, a jammer and the ability to launch the flares.

That's causing issues with "Zen_GetTurretPaths".

Share this post


Link to post
Share on other sites
I'll add support for divers into Zen_OrderInfantryPatrol. Ideally, I could just set the height of the waypoint by looking at the terrain type and have the divers follow that height above the sea floor. However, divers might run up onto any land in the patrol zone though, so I might make an 'underwater' parameter.

Thanks Zenophon. I hope more people than just me appreciate this!

Question for you.

Do you have cleanup functionality in your framework? What I mean by that is, can you delete dead/alive units/vehicles from a task area after the task has been completed?

The reason I ask is because I'm using your framework to develop a procedurally generated mission with no end. It spawns the missions randomly in random locations so I need to remove all alive AI,dead bodies and alive and dead vehicles from completed task areas.

Share this post


Link to post
Share on other sites
Done some more tests....

Seems one of the addons I use it's making spawn an extra copilot XD.

Will have to check which one of them it is.

Vanilla Arma works perfectly. Thanks Zen!

---------- Post added at 22:57 ---------- Previous post was at 20:58 ----------

"Helmet Mounted Displays Mod" adds weapons to the copilot, a jammer and the ability to launch the flares.

That's causing issues with "Zen_GetTurretPaths".

Thanks, that's actually a bug with Zen_GetTurretPaths. If a commander type position has smoke, flares, etc., it sees that as a weapon. I'll add in some logic to distinguish true weapons from countermeasures and equipment that are listed as weapons in the config.

Zen_ConfigGetVehicleClasses already does that to distinguish armed and unarmed vehicles, but I also want to make it very general so that addon vehicles that use their own type of e.g. flare launcher are detected as well. At the very least it will work with vanilla vehicles and addon vehicles that use the standard BIS laser, flare, etc.

Thanks Zenophon. I hope more people than just me appreciate this!

Question for you.

Do you have cleanup functionality in your framework? What I mean by that is, can you delete dead/alive units/vehicles from a task area after the task has been completed?

The reason I ask is because I'm using your framework to develop a procedurally generated mission with no end. It spawns the missions randomly in random locations so I need to remove all alive AI,dead bodies and alive and dead vehicles from completed task areas.

I do not have a framework function that provides cleanup; a robust cleanup function would probably become its own system with internal data. You can code your own simple cleanup by just looping through the arrays of dead objects returned by the game engine. An example of that is in the Zen_InfantryPatrol sample mission.

For removing any living units, you can use Zen_GetAllInArea to find any living units in an area, then delete them and any vehicles they are in.

In the future, cleanup of both alive and dead units will probably be a feature of my AI caching script, which I'm leaning towards making an external script from the framework that requires it.

You can also try letting the game engine handle dead cleanup, using description.ext params. I've never used them, so I can't tell you which are the best to use:

https://community.bistudio.com/wiki/Description.ext

There are seems to be a manual element to it, as you can use this command:

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

Share this post


Link to post
Share on other sites

Regarding body cleanup, I tried description.ext earlier this year and it did not function properly, so I used scripts. There are some peculiar downfalls to cleaning bodies with scripts which I encountered recently. This led me to trying the description.ext parameters again, and now they work great. Here is what I am using which has been working great

//corpseManagerMode = (0-none 1-all 2-none_but_respawned 3-all_but_respawned)
corpseManagerMode = 1;
corpseLimit = 10;
corpseRemovalMinTime = 30;
corpseRemovalMaxTime = 120;

Now for my question. If I create a side task of "eliminate mortar", it functions properly (is achieved by destroying the mortars). But, I cannot see how to easily get the mortars to actually fire upon known targets. Am I missing something?

Another more generic question I have is why do functions sometimes not need or want 0 = [] call ?

Meaning, sometimes if I make a function that does not return anything, I can use 0 = [] and other times there is a generic error and it is fixed by omitting 0 = .

for example, here are two functions

f_mission_create_officer_objective = { // create secondary objective - eliminate officer
// create additional objective 
_posBoss = [arMissionCoordinates,[10,30]] call Zen_FindGroundPosition;
_objectiveBoss = [_posBoss,HUMANSIDE,AISIDE,"custom","Eliminate",["O_officer_F","O_Soldier_SL_F","o_soldier_a_f","o_soldier_ar_f","O_Soldier_GL_F"]] call Zen_CreateObjective;
// instruct created units to patrol small area 
0 = [(_objectiveBoss select 0),arMissionCoordinates,[10,80],[0,360],"limited","safe",false] spawn Zen_OrderInfantryPatrol;
// append created group into main opfor group array 
0 = [arSpawnedEnemy,(_objectiveBoss select 0)] call Zen_ArrayAppend;
};
f_mission_create_mortar_objective = { // create secondary objective - eliminate mortar(s)
// find position(s) and create objective(s)
_intRadii = [arMissionCoordinates,posIns] call Zen_Find2dDistance;
for "_i" from 0 to (floor(random(2))) + 1 do {
	_posMortar = [arMissionCoordinates,[_intRadii / 4,_intRadii / 2],0,1,[1,75],0,0,0,0,[1,15,30],[2,[1,-1,-1],10]] call Zen_FindGroundPosition;
	_objectiveMortar = [_posMortar,HUMANSIDE,AISIDE,"Mortar","Eliminate"] call Zen_CreateObjective;
	0 = [arSpawnedEnemy,(_objectiveMortar select 0)] call Zen_ArrayAppend;
};
};

Interstingly I have to use the calls like thus:

0 = [] call f_mission_create_mortar_objective;

[] = call f_mission_create_officer_objective;

I am assuming it is because one function returns a void handle to another function call?

Share this post


Link to post
Share on other sites
I do not have a framework function that provides cleanup; a robust cleanup function would probably become its own system with internal data. You can code your own simple cleanup by just looping through the arrays of dead objects returned by the game engine. An example of that is in the Zen_InfantryPatrol sample mission.

For removing any living units, you can use Zen_GetAllInArea to find any living units in an area, then delete them and any vehicles they are in.

In the future, cleanup of both alive and dead units will probably be a feature of my AI caching script, which I'm leaning towards making an external script from the framework that requires it.

You can also try letting the game engine handle dead cleanup, using description.ext params. I've never used them, so I can't tell you which are the best to use:

https://community.bistudio.com/wiki/Description.ext

There are seems to be a manual element to it, as you can use this command:

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

Regarding body cleanup, I tried description.ext earlier this year and it did not function properly, so I used scripts. There are some peculiar downfalls to cleaning bodies with scripts which I encountered recently. This led me to trying the description.ext parameters again, and now they work great. Here is what I am using which has been working great

//corpseManagerMode = (0-none 1-all 2-none_but_respawned 3-all_but_respawned)
corpseManagerMode = 1;
corpseLimit = 10;
corpseRemovalMinTime = 30;
corpseRemovalMaxTime = 120;

Thanks to you both, Zenophon and m0nkey for pointing me in the right direction. I have much to learn!

I'll add support for divers into Zen_OrderInfantryPatrol. Ideally, I could just set the height of the waypoint by looking at the terrain type and have the divers follow that height above the sea floor. However, divers might run up onto any land in the patrol zone though, so I might make an 'underwater' parameter.

I was thinking about this and would the height above the sea floor take into account the massive rock formations under the water? Although it would be funny to watch a diver bonking his head off the rocks trying to get to his next way point! LOL Or would the AI pathing account for that automatically?

Edited by CDN_BiggDogg

Share this post


Link to post
Share on other sites
Regarding body cleanup, I tried description.ext earlier this year and it did not function properly, so I used scripts. There are some peculiar downfalls to cleaning bodies with scripts which I encountered recently. This led me to trying the description.ext parameters again, and now they work great. Here is what I am using which has been working great

//corpseManagerMode = (0-none 1-all 2-none_but_respawned 3-all_but_respawned)
corpseManagerMode = 1;
corpseLimit = 10;
corpseRemovalMinTime = 30;
corpseRemovalMaxTime = 120;

Now for my question. If I create a side task of "eliminate mortar", it functions properly (is achieved by destroying the mortars). But, I cannot see how to easily get the mortars to actually fire upon known targets. Am I missing something?

Another more generic question I have is why do functions sometimes not need or want 0 = [] call ?

Meaning, sometimes if I make a function that does not return anything, I can use 0 = [] and other times there is a generic error and it is fixed by omitting 0 = .

for example, here are two functions

f_mission_create_officer_objective = { // create secondary objective - eliminate officer
// create additional objective 
_posBoss = [arMissionCoordinates,[10,30]] call Zen_FindGroundPosition;
_objectiveBoss = [_posBoss,HUMANSIDE,AISIDE,"custom","Eliminate",["O_officer_F","O_Soldier_SL_F","o_soldier_a_f","o_soldier_ar_f","O_Soldier_GL_F"]] call Zen_CreateObjective;
// instruct created units to patrol small area 
0 = [(_objectiveBoss select 0),arMissionCoordinates,[10,80],[0,360],"limited","safe",false] spawn Zen_OrderInfantryPatrol;
// append created group into main opfor group array 
0 = [arSpawnedEnemy,(_objectiveBoss select 0)] call Zen_ArrayAppend;
};
f_mission_create_mortar_objective = { // create secondary objective - eliminate mortar(s)
// find position(s) and create objective(s)
_intRadii = [arMissionCoordinates,posIns] call Zen_Find2dDistance;
for "_i" from 0 to (floor(random(2))) + 1 do {
	_posMortar = [arMissionCoordinates,[_intRadii / 4,_intRadii / 2],0,1,[1,75],0,0,0,0,[1,15,30],[2,[1,-1,-1],10]] call Zen_FindGroundPosition;
	_objectiveMortar = [_posMortar,HUMANSIDE,AISIDE,"Mortar","Eliminate"] call Zen_CreateObjective;
	0 = [arSpawnedEnemy,(_objectiveMortar select 0)] call Zen_ArrayAppend;
};
};

Interstingly I have to use the calls like thus:

0 = [] call f_mission_create_mortar_objective;

[] = call f_mission_create_officer_objective;

I am assuming it is because one function returns a void handle to another function call?

The AI mortar crew should be in the gunner seat and able to fire. You can use reveal and knowsAbout to give and check targets. If they don't fire automatically, try the command in the notes for fireAtTarget.

I've tried to reproduce to '0 = call' generic error, but I haven't been able to find exactly what causes it. Technically, it should never be allowed because 0 is not a assignable identifier (commonly called a left-value) but rather a constant and a right-value. 'call ...' is always safe.

Thanks to you both, Zenophon and m0nkey for pointing me in the right direction. I have much to learn!

I was thinking about this and would the height above the sea floor take into account the massive rock formations under the water? Although it would be funny to watch a diver bonking his head off the rocks trying to get to his next way point! LOL Or would the AI pathing account for that automatically?

I think most large rocks are objects that are part of the map, but not technically the ground. Thus, getTerrainHeightASL will not account for them. It's possible that units would spawn inside of very large rocks. I am working on making Zen_FindGroundPosition detect those large rocks and structures. The 'avoid house' parameter will likely become 'avoid large objects' parameter.

Zenophon will you be working to make your framework headless client compatible with the latest update?

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

I already is. Everything related to AI spawning and orders can be send to the HC machine to execute. The vast majority of framework functions can run on any machine; I just suggest running everything on the server for general neatness and performance.

Whichever machine spawns an AI (using createUnit) becomes the owner of the AI. Simply put all AI spawning into global functions, then remote execute them on the HC (you can also account for an HC not existing and run them on the server). You can use BIS_fnc_MP or my framework's own remote execution method.

Share this post


Link to post
Share on other sites
I already is. Everything related to AI spawning and orders can be send to the HC machine to execute. The vast majority of framework functions can run on any machine; I just suggest running everything on the server for general neatness and performance.

Whichever machine spawns an AI (using createUnit) becomes the owner of the AI. Simply put all AI spawning into global functions, then remote execute them on the HC (you can also account for an HC not existing and run them on the server). You can use BIS_fnc_MP or my framework's own remote execution method.

I wonder how do you achieve it using both methods.

For BIS_fnc_MP I assume we should use the "target" option and set it to

A) an array with the HC object (defined in the editor by "HC" for example) which should result in something like

[[[],"Spawn_IA.sqf"],"BIS_fnc_execVM", [HC]] call BIS_fnc_MP;

B) using a group as target

something like

 grp_HC = group HC; [[[],"Spawn_IA.sqf"],"BIS_fnc_execVM", grp_HC] call BIS_fnc_MP;

But how we can achieve the same functionality with ZEN Framework? Your remote execution method is kinda obscure XD we just publish a public variable and let the magic work, but we have little control on where it is going to be executed

Well, still I can define on the script a conditional exit. Is there something like "isHeadlessClient" on the arma Engine?

If not, HC are players? how could I define a specific HC (player) to execute something? IE, this should be valid?

if !(player == HC) exitWith {};

Share this post


Link to post
Share on other sites
I wonder how do you achieve it using both methods.

For BIS_fnc_MP I assume we should use the "target" option and set it to

A) an array with the HC object (defined in the editor by "HC" for example) which should result in something like

[[[],"Spawn_IA.sqf"],"BIS_fnc_execVM", [HC]] call BIS_fnc_MP;

B) using a group as target

something like

 grp_HC = group HC; [[[],"Spawn_IA.sqf"],"BIS_fnc_execVM", grp_HC] call BIS_fnc_MP;

But how we can achieve the same functionality with ZEN Framework? Your remote execution method is kinda obscure XD we just publish a public variable and let the magic work, but we have little control on where it is going to be executed

Well, still I can define on the script a conditional exit. Is there something like "isHeadlessClient" on the arma Engine?

If not, HC are players? how could I define a specific HC (player) to execute something? IE, this should be valid?

if !(player == HC) exitWith {};

In my framework, Zen_MP_Closure_Packet is the variable linked to a PVEH (this is the magic; the engine knows to run this code) on all machines. The EH just executes the code with arguments defined in Zen_MP_Closure_Packet, and you have complete control over where it executes.

There are two methods to control remote execution on specific machines. First, code the logic into the function itself using any check necessary to stop execution using exitWith. Second, you can use publicVariableServer and publicVariableClient.

BIS_fnc_MP is using the second method for you, and in the framework I just do it manually. For targeting an HC, you can use the macro ZEN_FMW_MP_REClient. There are other macros provided that automate different execution logic.

// if HC is the object the client connects to
ZEN_FMW_MP_REClient("f_SpawnOpfor", [_pos], HC)

You can see the code for those macros in the library files, and there are two demonstrations about using Zen_MP_Closure_Packet. The PVEH code is in InitHeader.sqf.

Share this post


Link to post
Share on other sites

Hey Zen,

Many thanks for the regular updates to your framework. Awesome work there. Still can't believe you don't link to a Paypal account to thank you for your efforts.

I find your example missions a great source of inspiration.

Can I ask if there's any chance, when you release an update to your framework, you also release updates to your published missions?

i.e.

Co-6 Evade and Survive

COOP-8-Black-Ops

Share this post


Link to post
Share on other sites
Hey Zen,

Many thanks for the regular updates to your framework. Awesome work there. Still can't believe you don't link to a Paypal account to thank you for your efforts.

I find your example missions a great source of inspiration.

Can I ask if there's any chance, when you release an update to your framework, you also release updates to your published missions?

i.e.

Co-6 Evade and Survive

COOP-8-Black-Ops

Yeah, it seems like I always forget to update those. I hope you don't mind if I wait until the release this Wednesday to update the missions. The last framework update wouldn't change the missions very much, but this next release has a lot of general fixes and improvements.

Updating the missions always reminds me that I haven't finished and released a new mission in months; working on the framework takes priority. However, I do have various things in progress.

Share this post


Link to post
Share on other sites

In fact, an excellent work.

AI it has impact in performance obviously, but not so much as some others. Every server with a decent cpu will be able to run a considerable number of AI without major issues. I see your framework perfect for some good old game mods like Domination or Insurgency.

I just have 2 situations where I ask your help, if possible.

1. I have a issue with Opfor (AI) reinforcements by helicopter using the fast rope script, every time they spawn and soon the heli approach land and AI start to "rope" the heli engine dies and crash killing the reinforcements. Can you help me here?

2. Aircraft patrol for Opfor (AI) works quite well if is made by a helicopter, however I cant make it work, for instance, with a To-199 Neophron, soon it spawn it go down like a solid rock, I have tried different values with Zen_SpawnAircraft and also with Zen_OrderAircraftPatrol but no luck. Can you also help me here?

Share this post


Link to post
Share on other sites
In fact, an excellent work.

AI it has impact in performance obviously, but not so much as some others. Every server with a decent cpu will be able to run a considerable number of AI without major issues. I see your framework perfect for some good old game mods like Domination or Insurgency.

I just have 2 situations where I ask your help, if possible.

1. I have a issue with Opfor (AI) reinforcements by helicopter using the fast rope script, every time they spawn and soon the heli approach land and AI start to "rope" the heli engine dies and crash killing the reinforcements. Can you help me here?

2. Aircraft patrol for Opfor (AI) works quite well if is made by a helicopter, however I cant make it work, for instance, with a To-199 Neophron, soon it spawn it go down like a solid rock, I have tried different values with Zen_SpawnAircraft and also with Zen_OrderAircraftPatrol but no luck. Can you also help me here?

For #1, I can't seem to reproduce this issue. This code works for me without any mods on stable branch:

_heli = [player, "B_Heli_Transport_01_F"] call Zen_SpawnHelicopter;
_group = [player, west, "infantry", 4] call Zen_SpawnInfantry;
0 = [_group, _heli] call Zen_MoveInVehicle;
0 = [_heli, player, _group, "normal", 40, true] spawn Zen_OrderInsertion;

Try that in an empty mission with just a player unit and the framework.

For #2, this is bug in which Zen_SpawnVehicle does not give the jet a starting velocity, and Zen_SpawnAircraft attempts to and fails due to a timing issue with direction and velocity commands. This is easy to fix and will be included in the release tomorrow. To avoid timing issues in the future, I will give Zen_TransformObject a speed parameter, so it can set the orientation and velocity of the object.

Share this post


Link to post
Share on other sites

For #2, this is bug in which Zen_SpawnVehicle does not give the jet a starting velocity, and Zen_SpawnAircraft attempts to and fails due to a timing issue with direction and velocity commands. This is easy to fix and will be included in the release tomorrow. To avoid timing issues in the future, I will give Zen_TransformObject a speed parameter, so it can set the orientation and velocity of the object.

Well yeah, but its so cool to spawn a few of them at about 800m, and see them accelerating into a dive then pull up a couple hundred meters above the ground. Sounds awesome too. I even found that you can cause certain ones to crash and others not, depending on height spawned at. This makes a great random way to have a wreckage as an objective lol.

A question. If you create a fortification, is there a method to find the outer limits of the said "objects", so if you wanted to spawn a vehicle you would know it would be outside of, but near to, the fortification. Using [x,y] with ZFGP now, where x is the size of the fortification parameter.

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 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 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 marks the 5 month (that's 22 weeks or 154 days) point since the first framework release. I only mention it because this release and the first fall on the 10th. This release is also significant because it contains the greatest number of changes to date. The full 32 changes includes a high of 11 bug fixes as well. In total, (while we're counting) there have been 343 total changes.

A few of these fixes were included in a hotfix two days after the last release. This release has been much more thoroughly tested and shouldn't be plagued with silly mistakes. Since I can't discuss every change in detail, I'll just point out the significant ones.

Zen_FindBuildingPositions has been nearly (some of it survived) rewritten. Buildings that only had about 1/100 success rate per attempt are nearly 100%. Buildings below sea level (hard to find) now work properly. All the 3D positions on different floors above a 2D position are now checked and included, rather than just one point on one floor. Finally, note that Zen_SpawnVehicle will by default attempt to avoid other objects when it spawns something; remember to allows object collisions when spawning an object in a building.

Zen_FindGroundPosition is the recipient of several fixes, including indirect benefits from improvements to Zen_GetAmbientClutterCount and Zen_FindTerrainSlope. The most glaring error, in which Zen_FindGroundPosition failed to print an error informing the user that no valid point was found when it made less than 1000 attempts. However, most significantly, a feature has been added: the ability to quantitatively check a point against the given filters.

Zen_FindGroundPosition can now count how many filters fail, then use that number when accepting or rejecting the point. As a user, you can now enter the minimum value that is success; by default it remains 0, which behaves the same as the old true/false logic. Furthermore, Zen_FindGroundPosition stores the position with the fewest failures. In the event that it is unsuccessful, it returns that position (which is the best it could do). Thus, you are guaranteed as many filters as possible are satisfied.

By user request, Zen_OrderInfantryPatrol now supports divers. By user bug report, Zen_SpawnVehicle (and indirectly Zen_SpawnAircraft) gives all planes a starting velocity, and Zen_TransformObject has a speed parameter. Zen_GetTurretPaths also discounts flares, smoke, etc. when determining a commander/copilot position. Tank commanders with a .50 caliber MG are still considered gunners (they have a real weapon to fire).

12/10/14

  1. Fixed: Zen_CreateObjective did not rotate individual convoy vehicles to face along the road
  2. Fixed: Zen_FindBuildingPositions checked argument 3 wrong
  3. Fixed: Zen_FindGroundPosition did not always print an error message when no valid point was found
  4. Fixed: Zen_GiveLoadout did not send the right arguments to preset loadout functions
  5. Fixed: Zen_GiveLoadoutCustom did not send remote execution arguments correctly
  6. Fixed: Zen_MoveInVehicle did not set the default turret types correctly
  7. Fixed: Zen_MoveInVehicle did not count FFV positions when checking if the vehicle had room for all passengers
  8. Fixed: Zen_SpawnAircraft did not give the aircraft a reasonable starting velocity
  9. Fixed: Zen_SpawnConvoy did not account for the troop vehicle having no passenger seats
  10. Fixed: Zen_SpawnInfantryGarrison did not verify that it had valid positions in the building
  11. Fixed: ZEN_STD_OBJ_AnimateDoors used the entire path of the door config instead of just the classname
  12. Added: Zen_FindGroundPosition parameter for the maximum number of filters to satisfy
  13. Added: Zen_FindTerrainSlope parameter for the average slope in a radius
  14. Added: Zen_OrderInfantryPatrol parameter for patrols of divers
  15. Added: Zen_TransformObject parameter for object speed
  16. Improved: Zen_FindBuildingPositions checking algorithm is much more reliable
  17. Improved: Zen_FindBuildingPositions includes positions on all possible floors of a building at the same 2D location
  18. Improved: Zen_FindBuildingPositions sets a minimum number of positions to find
  19. Improved: Zen_FindGroundPosition terrain slope parameter has an option for average in radius
  20. Improved: Zen_FindGroundPosition house avoid parameter includes more structures that are not technically houses
  21. Improved: Zen_FindGroundPosition ambient clutter rock avoid parameter includes more rocks
  22. Improved: Zen_GetAmbientClutterCount detects more rocks, especially large ones
  23. Improved: Zen_GetTurretPaths filters for true weapons when deciding gunner or commander/copilot turrets
  24. Improved: Zen_MoveInVehicle places troops in FFV positions when given 'cargo'
  25. Improved: Zen_OrderExtraction and Zen_OrderInsertion keep the helicopter's engines on when on a slope
  26. Improved: Zen_OrderVehicleDrop now gives the dropped object the velocity of the aircraft
  27. Improved: Zen_SpawnConvoy places troops in FFV positions in the troop vehicle
  28. Improved: Zen_SpawnVehicle now automatically gives jet aircraft some starting speed
  29. Documentation: Corrected code syntax error in Zen_SpawningDemonstration
  30. Documentation: Corrected for Zen_FindBuildingPositions, Zen_StringGetDelimitedPart, ZEN_STD_Math_TransformATL
  31. Documentation: Updated for Zen_FindGroundPosition, Zen_OrderInfantryPatrol, Zen_TransformObject
  32. Documentation: Updated Notepad++ SQF language and autocompletion file with ArmA 1.36 stable commands

Roadmap

For next release, there is Zen_ConfigGetVehicleClasses filtering based upon class inheritance, possibly Zen_TerrainGradient, argument macros for Zen_SetWeather, and maybe something like Zen_IsRiver or Zen_IsIsland (that's is island, not isis land). I will experiment with giving Zen_OrderFastRope physics ropes, but no promises.

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_OrderSlingLoad. This function makes it easy to have the AI take care of your sling-loading. I also want users to test this function or give some suggestions, as it's currently fairly simple. It's not that exciting on its own, but, with some other AI functions, you can get AI behavior that gives your mission an edge.

// Assume some Blufor base at 'mkBase'
_motorPool = ["mkBase", 30, 0, 1, 0, [45, 90]] call Zen_FindGroundPosition;
_heliPad = ["mkBase", 30, 0, 1, 0, [0, 45]] call Zen_FindGroundPosition;
_veh = [_motorPool, "b_mrap_01_f"] call Zen_SpawnVehicle;
_heli = [_heliPad, "B_Heli_Transport_03_F", 0] call Zen_SpawnHelicopter;

// assume some _group is far away
_h_slingload = [_heli, _veh, ZEN_FMW_Math_RandomPoint(_group, 25)] spawn Zen_OrderSlingLoad;

ZEN_STD_Code_WaitScript(_h_slingload)
ZEN_STD_OBJ_OrderGetIn(units _group, _veh)

waitUntil {
   sleep 2;
   ([_group] call Zen_AreInVehicle)
};

// Zen_ConvertToPosition is used to get a fixed position
// Otherwise, Zen_OrderVehiclePatrol would follow _group's position, making it the new center
0 = [_veh, ([_group] call Zen_ConvertToPosition)] spawn Zen_OrderVehiclePatrol;
_h_land = [_heli, _heliPad] spawn Zen_OrderHelicopterLand;

ZEN_STD_Code_WaitScript(_h_land)

// if the helicopter isn't needed
ZEN_STD_OBJ_DeleteVehCrew(_heli)

If selecting a vehicle at random, you might want to check ZEN_STD_OBJ_CountCargoSeats >= 'count units _group'. You can also delete the helicopter when it gets far enough away with ZEN_FMW_Code_WaitDistanceGreater. When in doubt, macro your way to victory.

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.

_______________

Well yeah, but its so cool to spawn a few of them at about 800m, and see them accelerating into a dive then pull up a couple hundred meters above the ground. Sounds awesome too. I even found that you can cause certain ones to crash and others not, depending on height spawned at. This makes a great random way to have a wreckage as an objective lol.

A question. If you create a fortification, is there a method to find the outer limits of the said "objects", so if you wanted to spawn a vehicle you would know it would be outside of, but near to, the fortification. Using [x,y] with ZFGP now, where x is the size of the fortification parameter.

Zen_SpawnFortification's second parameter gives you the radius from the center location. Each object spawned has a different 3D model size, given by boundingBoxReal. You can use the macros ZEN_STD_OBJ_BBX (or Y or Z) to get what boundingBoxReal gives for the X, Y, or Z size (half of that is the distance from boundingCenter). Each object will be rotated to face away from the center of the fortification; I don't remember if 0/180 degrees is the X or Y model distance in 2D.

I'm fairly certain none of the objects spawned will be more than a few meters across. It would be safe to spawn a vehicle radially from the center of the fortification at about radius + 6; 6 meters account for the XY size of any fortification and the vehicle itself. For a helicopter, you can tweak that to get the rotors for enough from any tall fortifications.

By radially, I mean this is easy in polar coordinates with Zen_ExtendPosition; just let the angle be 'random 360'. Using Zen_FindGroundPosition, the minimum radius could be that safe distance and the maximum however much further it makes sense to go.

Share this post


Link to post
Share on other sites

Great update there Zen, thanks for all your efforts. :yay:

Share this post


Link to post
Share on other sites
Guest

Thanks for informing us of about the newest version again :)

Release frontpaged on the Armaholic homepage.

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

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

This means soon 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

Congrats on yet another update, and the largest to date, and the 5 month milestone ;) I am super thankful I happened upon this when you first released it. I've got way too many hours involved but that lets my stuff get pretty complicated, and thus pretty detailed and fun.

Here is a question, maybe request. Zen_AreInArea wants to find all. What about an option to find any? Assume there is a marker created, and you wanted to know if any of the human players or human groups were within that area. A trigger could be used for any blufor etc, but in staying away from those and using scripts, that would be a good feature I think.

In the meantime, anybody have an idea on the best method to use to do the check without using a trigger? The goal is every 30 seconds to test if any unit on the players side (west) are within the perimeter of the AO (area of operations, aka the marker, the radius of objective, etc). If there is one, then do something, if not, then do nothing. Forcing players to stay within the boundries of the AO to complete the objective I guess is the real goal.

Many ways to do it, trying to find the least intensive (of course). Thinking that stepping through the array of west units and checking if distance is < radius is the easiest, but is it the best?

Another feature request could be that Zen_SpawnConvoy allows one to supply an array of vehicle classnames, so that users may define this, and the number as well. The convoy might not stay together once an engagement starts, but there are types of missions/objectives where some armor would be nice to go up against too.

As an FYI Zenophon, I think the issue with InvokeTask was due to using Variable=west and then using Variable in the function call. I changed everything to west and got rid of the Variable, and in the last dozen tests it works every time.

Share this post


Link to post
Share on other sites

Nice update, have to test more things but for now.

Something that's happening since I've started using it. Zen_SpawnInfatryGarrison on buildings named "military offices" (the big white houes in Stratis Airport) have people spawned on the roof. Which is kind inmersive-broken.

Also, If I place a building with the editor, the framework does not seem to detect it to place units inside. Maybe Arma engine does not consider it as a building??

---------- Post added at 22:57 ---------- Previous post was at 21:57 ----------

PD, can you check if this

ZEN_FMW_Code_SpawnMarker("mkPatrol", 2, west);

is correct and working? it throws me an error.

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

×