Jump to content
Zenophon

Zenophon's ArmA 3 Co-op Mission Making Framework

Recommended Posts

Thanks Chondo,

Whilst messing around with this today, I can see what you mean about the EOS AI issue. I have sketched out a plan of what I am trying to do below. I completed the tutorials now, but the last 3 went over my head. I understand the basics of the framework, but not how to use some of the more advanced functions.

Objective: To create an insurgency style mission in Chernarus

Key Features:

  • Designed for Co-Op only
  • Max 16 players
  • Randomized start locations
  • Towns have Red 50x50m area markers that spawn enemy units
  • Killing all units in a marker area makes the marker go green
  • Side objectives to destroy ammo crates, triggered at 15-30 minute intervals
  • Rewards for side objectives

I am a total scripting novice, but I am thinking what I need to put in will be something like this:

  1. Use Zen_SpawnMarker to create the markers on towns, and set the colour to red
  2. Use Zen_FindGroundPosition and Zen_SpawnInfantry to create hostiles in the marker areas
  3. Use Zen_TriggerAreaClear to check if the grid is clear and set it to green (not sure for this bit - can I modify the marker, or do I remove it and add a green one in?)
  4. Use objective system with randomized sleep timer for side objectives
  5. Generate rewards with Zen_SpawnAmmoBox
  6. For randomized start - pick 8 start locations, place a marker at each, use Zen_ArrayGetRandom to determin which one is used

Again, any advice or guidance would be welcome - I am pretty out of my depth here.

Edited by CallMeSarge
Edited for typos

Share this post


Link to post
Share on other sites
Thanks Chondo,

Whilst messing around with this today, I can see what you mean about the EOS AI issue. I have sketched out a plan of what I am trying to do below. I completed the tutorials now, but the last 3 went over my head. I understand the basics of the framework, but not how to use some of the more advanced functions.

Objective: To create an insurgency style mission in Chernarus

Key Features:

  • Designed for Co-Op only
  • Max 16 players
  • Randomized start locations
  • Towns have Red 50x50m area markers that spawn enemy units
  • Killing all units in a marker area makes the marker go green
  • Side objectives to destroy ammo crates, triggered at 15-30 minute intervals
  • Rewards for side objectives

I am a total scripting novice, but I am thinking what I need to put in will be something like this:

  1. Use Zen_SpawnMarker to create the markers on towns, and set the colour to red
  2. Use Zen_FindGroundPosition and Zen_SpawnInfantry to create hostiles in the marker areas
  3. Use Zen_TriggerAreaClear to check if the grid is clear and set it to green (not sure for this bit - can I modify the marker, or do I remove it and add a green one in?)
  4. Use objective system with randomized sleep timer for side objectives
  5. Generate rewards with Zen_SpawnAmmoBox
  6. For randomized start - pick 8 start locations, place a marker at each, use Zen_ArrayGetRandom to determin which one is used

Again, any advice or guidance would be welcome - I am pretty out of my depth here.

Here is how I would set up a sector control style objective for multiple towns. This code is aiming for efficiency and adaptability. I also included side missions based upon a timer. This is tested and working on Altis. It spawns enemy groups in towns when the players get close, and updates the color of the marker if a town is clear.

// These constants make it easy to change every occurrence of the value later
#define ENEMY_SIDE east
#define AI_SKILL "Infantry"

// First we get all towns, hopefully this works for the Chernarus config
// You might need to tweak what the location names are
_townMkArray = [["NameCity", "NameVillage"]] call Zen_ConfigGetLocations;

{
   // You can also make them checkered/striped etc. with different commands
   _x setMarkerColor "colorRed";
   _x setMarkerAlpha 1;
   _x setMarkerSize [200, 200];
} forEach _townMkArray;

// Schedule the first side objective
_sideObjTime = time + (60*([15, 30] call Zen_FindInRange));

// Holds arrays of groups in each town
_townPatrolsArray = [];

// Holds all the markers where AI have been spawned
// _townMkArray is now all markers where AI have not spawned
_townMkArraySpawned = [];

// Assume the only Blufor units are the players
_players = ([west] call Zen_ConvertToObjectArray);

// Infinite loop that runs every ten seconds
while {true} do {
   {
       // Only spawns patrols if at least one player is within 700 meters
       if !([_players, getMarkerpos _x, [700, 700], 0, "Ellipse"] call Zen_AreNotInArea) then {
           // Holds groups that patrol this marker
           _groupsArray = [];

           // Spawn 2 groups per marker
           for "_i" from 1 to 2 do {
               _spawnPos = [_x] call Zen_FindGroundPosition;
               _enemyGroup = [_spawnPos, ENEMY_SIDE, AI_SKILL, [4,6]] call Zen_SpawnInfantry;
               0 = [_groupsArray, _enemyGroup] call Zen_ArrayAppend;
           };

           // Equip and patrol the units in their marker
           0 = [_groupsArray, ENEMY_SIDE] call Zen_GiveLoadout;
           0 = [_groupsArray, _x] spawn Zen_OrderInfantryPatrol;

           // Update the spawned and not spawned arrays
           0 = [_townPatrolsArray, _groupsArray] call Zen_ArrayAppend;
           0 = [_townMkArraySpawned, _x] call Zen_ArrayAppend;
           _townMkArray set [_forEachIndex, 0];
       };
   } forEach _townMkArray;

   // Remove towns where AI have spawned
   _townMkArray = _townMkArray - [0];

   {
       // _townMkArraySpawned lines up with _townPatrolsArray
       // _groupsArray is the array of groups patrolling the current town
       _groupsArray = [(_townPatrolsArray select _forEachIndex)] call Zen_ArrayRemoveDead;

       // Checks if the enemy is gone or dead
       if ([_groupsArray, _x] call Zen_AreNotInArea) then {
           _x setMarkerColor "colorGreen";

           // 0 the indexes for this town
           _townMkArraySpawned set [_forEachIndex, 0];
           _townPatrolsArray set [_forEachIndex, 0];

           // Anything else to be done upon clearing the area
       };
   } forEach _townMkArraySpawned;

   // Remove cleared towns from the arrays
   _townMkArraySpawned = _townMkArraySpawned - [0];
   _townPatrolsArray = _townPatrolsArray - [0];

   // Check if the clock is past when the side objective is scheduled
   if (time > _sideObjTime) then {
       _playerCenter = _players call Zen_AveragePositions;
       _objPos = [_playerCenter, [400, 700]] call Zen_FindGroundPosition;

       // Create the objective and reset the timer
       0 = [_objPos, _players, ENEMY_SIDE, "Box", "Eliminate"] call Zen_CreateObjective;
       _sideObjTime = time + (60*([15, 30] call Zen_FindInRange));

       // Spawn and patrol a few guards
       _objGuards = [_objPos, ENEMY_SIDE, AI_SKILL, [3,4]] call Zen_SpawnInfantry;
       0 = [_objGuards, _objPos, [10, 75]] spawn Zen_OrderInfantryPatrol;
   };

   sleep 10;
};

Unfortunately, due to a bug in Zen_ArrayRemoveDead, the check for the marker being clear of enemies will not work. This issue is already fixed internally and will be included in the release tomorrow. If you want to test it fully today, replace this line:

_groupsArray = [(_townPatrolsArray select _forEachIndex)] call Zen_ArrayRemoveDead;

with this:

_groupsArray = [([(_townPatrolsArray select _forEachIndex)] call Zen_ConvertToObjectArray)] call Zen_ArrayRemoveDead;

  • Like 1

Share this post


Link to post
Share on other sites

Hi Zen, just had a quick question please. I have been experimenting with your respawnPatrol.altis mission and am confused as to why something is occurring. If in the description.ext I set disableAI true; then when I try to run that mission on a dedicated server it will not spawn any tasks if I am the only live player in the mission. On my server, I have about 8 live people that pop on and off of the server at any given time. The server runs in persistent mode, so it's always available for whomever wants to get on and play. Normally, we just work as a specialized task force and do not use a lot of bluFor AI to assist with our tasking. So, basically, I do not want to have AI enabled for playable characters, but if I do not keep it enabled, the mission will not spawn tasks.

Any thoughts sir?

I think you have done some amazing work here that will greatly help the community. I have been writing all of my own scripts since Arma 3 came out and it has been frustrating and a true struggle at time. After looking at your work here for a few days now, I'm very impressed and appreciative that you would share this.

Respectfully,

Zlin

Share this post


Link to post
Share on other sites
Here is how I would set up a sector control style objective for multiple towns. This code is aiming for efficiency and adaptability. I also included side missions based upon a timer. This is tested and working on Altis. It spawns enemy groups in towns when the players get close, and updates the color of the marker if a town is clear.

Zen, I just tested that code on Altis - it's amazing! I will spend some more time playing with it this week - thanks for showing me the way!

Share this post


Link to post
Share on other sites
Hi Zen, just had a quick question please. I have been experimenting with your respawnPatrol.altis mission and am confused as to why something is occurring. If in the description.ext I set disableAI true; then when I try to run that mission on a dedicated server it will not spawn any tasks if I am the only live player in the mission. On my server, I have about 8 live people that pop on and off of the server at any given time. The server runs in persistent mode, so it's always available for whomever wants to get on and play. Normally, we just work as a specialized task force and do not use a lot of bluFor AI to assist with our tasking. So, basically, I do not want to have AI enabled for playable characters, but if I do not keep it enabled, the mission will not spawn tasks.

Any thoughts sir?

I think you have done some amazing work here that will greatly help the community. I have been writing all of my own scripts since Arma 3 came out and it has been frustrating and a true struggle at time. After looking at your work here for a few days now, I'm very impressed and appreciative that you would share this.

Respectfully,

Zlin

That sample mission is designed to work only with AI enabled; the same is true of Zen_InfantryPatrol.Altis, as they were already fairly complicated. They are meant to show users how to combine what is shown in the JIP demonstration with a mission. That demonstration does not mention how to get everything working when there are no AI.

For how to set up JIP with no AI, see the Zen_AssaultFrini.Altis sample mission. The mission content is purposefully simple, as the only goals are to show respawn and JIP with an unknown number of humans joining at any time. Also, you can download and open the two missions I have released that use the framework (links in my signature). They both handle both enabled and disabled AI by detecting if a player took over an AI or is a new object.

P.S. Thank you for your kind words, it feels great to know I am helping other mission makers do their best work.

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 update has 19 changes, and I am trying to focus on bugfixes and stabilizing things. There is only one new function: Zen_GetAllInBuilding. It is fairly simple as well as tested and working.

This week also sees a reorganization of some functions. This does not affect how you use any functions, nor can it break any existing mission code. The Position System, Zen_FindGroundPosition, now shares its folder with some related functions. All of the functions in what is now Position Functions category deal with evaluating terrain and similar. The index and documentation have been updated with the functions in their correct places.

Zen_FindGroundPosition has also received several fixes, two of which were hotfixed shortly after release. I apologize for the issues, and I am trying to make releases with as few issues as possible.

To accompany the new Position Functions category, Zen_IsNearWater has been renamed Zen_IsNearTerrain and offers options to check for land, water, or both within an area. If you have used Zen_IsNearWater directly in your mission, you need to update it to comply with this change. As always, I would remind users that legacy code and deprecated functions are not supported.

The most significant optimization this week is for Zen_SpawnMarker, which now no longer checks if the marker it is creating already exists; this makes it about ten times faster. It is impossible to create a duplicate marker because Zen_SpawnMarker can generate markers with 121^10 (that's 672,749,994,932,560,068,608 or over 672 quintillion) unique names. Zen_FindMaxTerrainSlope is also twice as fast when the radius is less than 60 meters by checking fewer times. The larger the radius, the higher the distance between points to check.

There was also an issue reported in which a convoy would spawn with some damage to the vehicles; two changes have been made to prevent this, but the issue might be in Zen_SpawnConvoy itself. I will continue to test and look into this issue.

8/6/14

  1. New Function: Zen_GetAllInBuilding
  2. Fixed: Zen_ArrayRemoveDead did not filter out groups of dead units properly
  3. Fixed: Zen_FindGroundPosition near roads screening check failed for object positions
  4. Fixed: Zen_FindGroundPosition near water screening check failed for land positions
  5. Fixed: Zen_FindGroundPosition off the map check did not work in VR
  6. Fixed: Zen_SpawnVehicle allowed boats to spawn on top of each other
  7. Added: Zen_IsNearTerrain now has a parameter for land, water, or both
  8. Improved: Position System category is now the Position Functions category, several functions have been moved there
  9. Improved: Zen_CreateObjective now prevents the convoy from spawning damaged
  10. Improved: Zen_FindMaxTerrainSlope optimized when using a small radius
  11. Improved: Zen_IsNearWater renamed to Zen_IsNearTerrain
  12. Improved: Zen_RotateAsSet now lifts objects off the ground to prevent vehicles damaging their tires
  13. Improved: Zen_SpawnMarker greatly optimized
  14. Documentation: Fixed code typo in Steal the Car sample mission
  15. Documentation: Fixed Spawning Demonstration joining convoy group to vehicle did not work
  16. Documentation: Added for Zen_GetAllInBuilding
  17. Documentation: Improved for Zen_FindMaxTerrainSlope, Zen_IsForestArea, Zen_MultiplyDamage
  18. Documentation: Updated for Zen_IsNearTerrain
  19. Documentation: Updated Index and category documentation

Roadmap

Due to coding other things, fixing bugs, and extensively testing things that were in fact not bugs but engine issues, the functions Zen_IsHillArea and Zen_IsUrbanArea have been delayed once again. However, I am fairly certain how to go about coding both of those, so I will try to get them finished and debugged by next week.

The next significant feature I want to add is one I have been thinking about for a long time: a preprocessor library to accompany the framework. It would offer constants that could substitute for function arguments, e.g. a constant for Zen_ArraySort to sort markers by size. There would also be function-like macros that took arguments to simplify or automate common actions, e.g. appending to an array.

However, before I get to coding the macros, I need to have a good plan for incorporating this into the current framework organization and usage structure. It will probably have to be done in such a way that you can choose to include the library header or not in your functions. I still have not decided if it should be split into multiple header files.

If you have any ideas for good macros or how to seamlessly include this feature, feel free to send me your thoughts.

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 found useful, PM me and I can spotlight it.

The function chosen for this week is: Zen_ShowHideMarkers. This function automates all remote execution in multiplayer for manipulating who can see markers. Instead of trying to run different code on every client's machine, you can now just list the player objects. This is useful in PvP missions and large co-op missions where different groups of players do not share the same objective or see the same markers.

For example, if you had two groups of players operating separately, you could hide certain details from the other group:

0 = [["mkCache0", "mkCache1", "mkCache2"], group A, group B] call Zen_ShowHideMarkers;
0 = [["mkCrash", "mkPow", "mkOfficer"], group B, group A] call Zen_ShowHideMarkers 

You could also simulate one side getting UAV support in a PvP mission:

_opforGroups = [east] call Zen_ConvertToGroupArray;
_opforMarkers = [];
{
   _marker = [_x, "", "colorOpfor", [1, 1], "o_inf"] call Zen_SpawnMarker;
   0 = [_opforMarkers, _marker] call Zen_ArrayAppend;
} forEach _opforGroups;

0 = [_opforMarkers, west, east] call Zen_ShowHideMarkers;

This makes giving certain markers and information to one side very simple. By switching east and west, you can get the opposite effect. All of this works without knowing how many players are on which side or what their names are etc.

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

As expected, 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.

The specific request this week is: the preprocessor library. As I said before, I want to hear all ideas about what sort of things could be included to make using the framework easier. If you have code that you repeat a lot with a few differences, or arguments you always use with a function to do something, send me your idea and it can become a macro.

  • Like 1

Share this post


Link to post
Share on other sites
Guest

Thanks for informing us about the updated release again :cool:

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 Zen, just had a quick question please. I have been experimenting with your respawnPatrol.altis mission and am confused as to why something is occurring. If in the description.ext I set disableAI true; then when I try to run that mission on a dedicated server it will not spawn any tasks if I am the only live player in the mission. On my server, I have about 8 live people that pop on and off of the server at any given time. The server runs in persistent mode, so it's always available for whomever wants to get on and play. Normally, we just work as a specialized task force and do not use a lot of bluFor AI to assist with our tasking. So, basically, I do not want to have AI enabled for playable characters, but if I do not keep it enabled, the mission will not spawn tasks.

Any thoughts sir?

I think you have done some amazing work here that will greatly help the community. I have been writing all of my own scripts since Arma 3 came out and it has been frustrating and a true struggle at time. After looking at your work here for a few days now, I'm very impressed and appreciative that you would share this.

Respectfully,

Zlin

Hi Zlin, I've been in the same boat but I've managed to get "Altis Patrol" working without AI by deleting the player group array portion and putting this in:

// Concatenate all playable units into single array of objects

_allplayersArray = ([west] call Zen_ConvertToObjectArray);

It's a bit of a Frankenstein hatchet job but I've never messed around scripts until I came across this framework.

Thanks for all your efforts Zenophon. The tutorials and effort that have gone into this is mindbogglingly good.

Share this post


Link to post
Share on other sites

Hi there

I think these are some great scripts. I am no coder and really have some trouble understanding how all of these work - I can easily enough call a script. I am just not sure how this work?

I would like to use the spawn ai "Infantry" in an area I have marked and then create a custom Objective or 2 and then have the AI patrol said area.

would it be possible to do a quick youtube video explaining how we can use and modify these scripts? I have gone thought the documentation and demo missions but I must be missing something I learn better when shown.

thank you in advance

Angry

Share this post


Link to post
Share on other sites
Hi Zlin, I've been in the same boat but I've managed to get "Altis Patrol" working without AI by deleting the player group array portion and putting this in:

// Concatenate all playable units into single array of objects

_allplayersArray = ([west] call Zen_ConvertToObjectArray);

It's a bit of a Frankenstein hatchet job but I've never messed around scripts until I came across this framework.

Thanks for all your efforts Zenophon. The tutorials and effort that have gone into this is mindbogglingly good.

Thanks Lambert! I'm continuing to go through the sample missions as well and see what else I can figure out.

---------- Post added at 13:49 ---------- Previous post was at 13:47 ----------

Zen, sorry but another question please...

How do your scripts handle the removal of units/vehicles that were not destroyed/killed as part of the task? I use Arma Server Monitor on my dedicated server and while running the respawnPatrol.altis mission I'm noticing that the AI count seems to stay pretty high, sometimes over 200. This concerns me in regard to managing server resources.

Thanks in advance for any reply you can provide.

Zlin

Share this post


Link to post
Share on other sites
Hi there

I think these are some great scripts. I am no coder and really have some trouble understanding how all of these work - I can easily enough call a script. I am just not sure how this work?

I would like to use the spawn ai "Infantry" in an area I have marked and then create a custom Objective or 2 and then have the AI patrol said area.

would it be possible to do a quick youtube video explaining how we can use and modify these scripts? I have gone thought the documentation and demo missions but I must be missing something I learn better when shown.

thank you in advance

Angry

By demo I assume you mean the demonstration missions. Those are targeted mostly at intermediate level scripters.

The tutorials are meant to introduce users who haven't coded a lot before to using functions. Have you fully read the first few tutorials, not just looked at the code but followed the .pdf files' explanations? The tutorials are listed in order in TutorialIntroduction.pdf in their folder. The first several tutorials show variations of what you describe.

Zen, sorry but another question please...

How do your scripts handle the removal of units/vehicles that were not destroyed/killed as part of the task? I use Arma Server Monitor on my dedicated server and while running the respawnPatrol.altis mission I'm noticing that the AI count seems to stay pretty high, sometimes over 200. This concerns me in regard to managing server resources.

Thanks in advance for any reply you can provide.

Zlin

That mission should be able to spawn at most 104 AI every turn; the least it could spawn would be 48. Spawning happens at lines 299 to 312 of the init. The code to cleanup AI after an objective is done is between lines 329 and 339. Also, about half of those AI will probably be killed by the players.

Every turn, only AI within 500 meters of a player remain when then next objective and patrols spawn. When players complete that objective, they are very far away from the previous one, so everything there is removed.

In the worst case, 200 AI will remain (100 from the current objective and 100 from the last). However, in practice this number should be much lower. Statistically 75 AI will spawn for each objective, and less than 20 will remain when an objective is complete. If players stick together, the no-despawn area around them is only 17.4% of the total area.

Of course, the code could not be working and no AI are removed. If you can, check if far away bodies and AI are really being deleted. As admin you can use the debug console and the camera to check.

Share this post


Link to post
Share on other sites

Hi Zen,

I looked at the demo code you prepared in detail - I am afraid some of it (ok, a lot of it) is still going over my (novice) head. I decided to start smaller.

I want to put 10 markers on the map (SM1-SM10). I want to then pick a marker at random, and trigger an objective in that marker. I then want to spawn a reward crate in the same marker as the objective. This is what I cobbled together, but when i call _Objective1Pos = ["_selectedmarker"] , slectedmarker does not exist. Any idea what I have done wrong?

// Select a marker from one of 10 at random
_markerArray = ["SM1","SM2","SM3","SM4","SM5","SM6","SM7","SM8","SM9","SM10"];
_selectedmarker = [_markerArray] call Zen_ArrayGetRandom;

// create an objective for the selected marker
_Objective1Pos = ["_selectedmarker"] call Zen_FindGroundPosition;
_yourObjective1 = [_Objective1Pos, (group x11), east, ["box","Wreck"],"eliminate"] call Zen_CreateObjective;

// Wait until objective completed 
waituntil { sleep 5; [[(_yourObjective1 select 1)]] call Zen_AreTasksComplete };

// trigger a reward crate in the same marker as the objective
_selectedmarker = ["BLUFORResupplyTwo"] call Zen_FindGroundPosition;
0 = [_selectedmarker, "Box_NATO_Wps_F"] call Zen_SpawnVehicle;
0 = [_selectedmarker, "Nato Ammo", "ColorBlue",[1,1],"mil_join"] call Zen_SpawnMarker;

Error screenshot - 2014-08-07_00004_zpsd5e68813.jpg

And also one other question, if I may. This code:

// Schedule the first side objective 
_sideObjTime = time + (60*([15, 30] call Zen_FindInRange)); 

Does this mean that the objective will start between 15 and 30 minutes?

Edited by CallMeSarge

Share this post


Link to post
Share on other sites
Hi Zen,

I looked at the demo code you prepared in detail - I am afraid some of it (ok, a lot of it) is still going over my (novice) head. I decided to start smaller.

I want to put 10 markers on the map (SM1-SM10). I want to then pick a marker at random, and trigger an objective in that marker. I then want to spawn a reward crate in the same marker as the objective. This is what I cobbled together, but when i call _Objective1Pos = ["_selectedmarker"] , slectedmarker does not exist. Any idea what I have done wrong?

// Select a marker from one of 10 at random
_markerArray = ["SM1","SM2","SM3","SM4","SM5","SM6","SM7","SM8","SM9","SM10"];
_selectedmarker = [_markerArray] call Zen_ArrayGetRandom;

// create an objective for the selected marker
_Objective1Pos = ["_selectedmarker"] call Zen_FindGroundPosition;
_yourObjective1 = [_Objective1Pos, (group x11), east, ["box","Wreck"],"eliminate"] call Zen_CreateObjective;

// Wait until objective completed 
waituntil { sleep 5; [[(_yourObjective1 select 1)]] call Zen_AreTasksComplete };

// trigger a reward crate in the same marker as the objective
_selectedmarker = ["BLUFORResupplyTwo"] call Zen_FindGroundPosition;
0 = [_selectedmarker, "Box_NATO_Wps_F"] call Zen_SpawnVehicle;
0 = [_selectedmarker, "Nato Ammo", "ColorBlue",[1,1],"mil_join"] call Zen_SpawnMarker;

And also one other question, if I may. This code:

// Schedule the first side objective 
_sideObjTime = time + (60*([15, 30] call Zen_FindInRange)); 

Does this mean that the objective will start between 15 and 30 minutes?

The variable _selectedMarker already holds a string that is a marker; it stands in for a literal string. Thus you don't need to put it in quotes:

_Objective1Pos = [_selectedmarker] call Zen_FindGroundPosition;

For the time, yes that is 15 to 30 minutes. The 'time' command returns seconds, so I multiply the random number by 60 to convert that to seconds. This just makes it easier to change the number of minutes directly than if I made the range [900, 1800].

Share this post


Link to post
Share on other sites

Hi,

first of all, thanks for the Framework.

Today I wanted to create my first script based mission, but I think I found an issue with the first function I wanted to use...

the function Zen_SpawnHelicopter raised the following error:

"Vehicle is of unknown textSingular type"

74.489

[30e7d0c0# 113: heli_light_03_f.p3d]

["Zen_SpawnVehicleCrew",[30e7d0c0# 113: heli_light_03_f.p3d],74.489]

["Zen_SpawnHelicopter",[[10,10],"I_Heli_light_03_F"],74.489]

It took some time, until I found out, that "textSingular" (in line 100 in Zen_SpawnVehicleCrew) seems to depend on the language version of the game.

While the function checks only for "helicopter" etc, my textSingular had the value "helikopter" (german).

I have no idea how to solve this problem in general, I switched to the english version of Arma (as I wanted to do that for a long time), and the error was gone.

But if I understand this right, anyone who wants to host a mission on a server not running the english version would run into trouble.

the textSingular is also used in Zen_ConfigGetVehicleClasses, but I did try out if that makes trouble, too,

Share this post


Link to post
Share on other sites

Same Problem here :

"Vehicle is of unknown textSingular type"

74.489

[30e7d0c0# 113: heli_light_03_f.p3d]

["Zen_SpawnVehicleCrew",[30e7d0c0# 113: heli_light_03_f.p3d],74.489]

["Zen_SpawnHelicopter",[[10,10],"I_Heli_light_03_F"],74.489]

I solved this by adding one Case

case "case "air": {
       switch (toLower (getText (_vehicleConfigEntry >> "textSingular"))) do {
           case "helicopter": {
               _crewClasses set [(count _crewClasses), _heliPilotClass];

               if (_turretCount > 0) then {
                   _crewClasses set [(count _crewClasses), _heliPilotClass];
                   for "_i" from 2 to _turretCount do {
                       _crewClasses set [(count _crewClasses), _heliCrewClass];
                   };
               };
           };
           case "helikopter": {
               _crewClasses set [(count _crewClasses), _heliPilotClass];

               if (_turretCount > 0) then {
                   _crewClasses set [(count _crewClasses), _heliPilotClass];
                   for "_i" from 2 to _turretCount do {
                       _crewClasses set [(count _crewClasses), _heliCrewClass];
                   };
               };
           };				

Share this post


Link to post
Share on other sites
Hi,

first of all, thanks for the Framework.

Today I wanted to create my first script based mission, but I think I found an issue with the first function I wanted to use...

the function Zen_SpawnHelicopter raised the following error:

...

It took some time, until I found out, that "textSingular" (in line 100 in Zen_SpawnVehicleCrew) seems to depend on the language version of the game.

While the function checks only for "helicopter" etc, my textSingular had the value "helikopter" (german).

I have no idea how to solve this problem in general, I switched to the english version of Arma (as I wanted to do that for a long time), and the error was gone.

But if I understand this right, anyone who wants to host a mission on a server not running the english version would run into trouble.

the textSingular is also used in Zen_ConfigGetVehicleClasses, but I did try out if that makes trouble, too,

Same Problem here :

I solved this by adding one Case

...

I did not anticipate that config values would change based upon language. The solution to this is to use a string table to substitute different text based upon the current language. Hopefully these values are in the stringtable provided by BIS. In that case it is only a matter of finding the right keys for each value. Otherwise, I have to launch the game in every language offered and look at the config values for all different kinds of vehicles.

Luckily, the only function affected directly is Zen_SpawnVehicleCrew. However, I would also note that Zen_ConfigGetVehicleClasses is also using these config values to generate class lists dynamically. Every framework function that uses it to find classnames could encounter problems because the values are hard coded.

To be clear, if your game language is not English, the following functions may not work for some languages with some combinations of arguments:

  • Zen_SpawnAircraft
  • Zen_SpawnHelicopter
  • Zen_SpawnVehicleCrew *

* Only not working for aircraft

I apologize for the inconvenience; this is a beta after all. There are workarounds to using all of these functions that will work work any language. If you encounter another situation that does not work, post it and I will look at solving it specifically. Editing framework code can work, but I will offer solutions that are not internal hotfixes. That way, your mission code will remain compatible with future releases.

For spawning a crew, if you know what kind of vehicle will spawn, you can hard code the classnames to fill it with:

_heli = [[10,10], "I_Heli_light_03_F", 40] call Zen_SpawnVehicle;
_crew = [_heli, ["i_helipilot_f", "i_helipilot_f"]] call Zen_SpawnGroup;
0 = [_crew, _heli, "All"] call Zen_MoveInVehicle;
0 = [_crew, "Crew"] call Zen_SetAISkill;

Unfortunately, you would have to change the side, number, and type of the crew if the vehicle changed.

Edit: I have looked at the config differences for different languages, and the issue only affects functions that are using textSingular to distinguish helicopters from jets and UAVs from UGVs. I have edited the list of functions affected.

The correct localized strings are not provided by BIS's stringtable, so I need to create one to accompany the framework that will localize these three textSingular values:

  • fast mover
  • helicopter
  • UAV

This is nowhere near the amount of tedious work it could have been, and it will certainly be included in the release this Wednesday. Thank you for your patience.

Edited by Zenophon

Share this post


Link to post
Share on other sites

Hi Zen

Thanks for the awesome scripts. There is sooooooo much depth that I can still hardly understand everything even after I have done all the tutorial and most of the showcase examples. I have can implement your framework to an extend but I am a novice at scripting so bare with me ;)

I have created a firing range for me and my buddies to test mods etc and wanted to add some of your helper scripts such as magazine repacking (why bis have never added this option to the game is beyond me). I also wanted to add a couple of patrols just to make the base feel alive. When I designed the training range I had no problem when I previewed the mission. Everything was working fine and all the scripts I called from your framework worked, but when I published it and wanted to test the mission online, your scripts suddenly didnt work.

My question is it because I didnt call your JIP script or could it be because of the mods such as MCC I am running?

Thanks a bunch for answering such a noob question.

Cheers

Share this post


Link to post
Share on other sites

Hi Zen. I can't for the life of me figure something out about your scripts and was hoping you could shed more light please. What I am still trying to do with your scripts is; 1 - have a multi-player server with NO AI units attached to the actual playable characters, 2 - have it generate endless tasks. My issue still always seems to come back to tasks won't generate if there are no AI players grouped with the playable characters. All of my playable characters start at a common point. The server runs in persistent mode. I want players to be able to come and go as they please and still be able to get tasks even if they are the only player on the map. I have gone through several of the tutorial missions and I feel I understand what is going on with them. However, every time I add a second playable character to my test maps, the tasking system no longer functions at all on my DEDICATED SERVER.

I can tell that you put a lot of work into your framework, and I do truly appreciate your efforts, but there is still a lot of things that aren't explained very well. I have had the issue too of thinking I am explaining something well when I'm trying to teach someone something, all to find out that I am still too close to the subject matter and still don't cover things that someone new would ask.

I have also looked at your co-op 8 player mission that you had recommended and again, it's just not what I'm looking for. The co-op 8 mission has a real cool heli insertion at the beginning but that is just not what I'm looking for. I just want my playable characters to all start on the ground, at a common base, and be able to get continuous tasking. I don't think what I am trying to do should be this difficult. I have written all of my other mission scripts from scratch and have not had this much trouble getting tasking for playable characters without AI having to be attached to them. I'm sure it's just something simple that I'm missing but if you could just shed a little more light on how your tasking scripts work it would be greatly appreciated.

Thanks again for your work and contribution.

Z

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 update has 16 changes, with many fixes and a few improvements. Most importantly, there is a new file that must be put into your mission folder for the framework to operate correctly. This is a StringTable.xml file that localizes some specific config values so that a few functions will work regardless of your language setting.

Also, very importantly, the framework code in the Description.ext has changed. This must be updated for all missions by replacing the old three lines with the new code in the sample description.ext. This was done to ensure not compatibility issues with missions that use custom config entries under CfgCommunicationMenu and cfgNotifications.

There is also one new function, Zen_IsUrbanArea. It is similar to Zen_IsForestArea, but handles buildings and roads instead of trees.

The more minor fixes this week include another argument checking mistake for Zen_ConfigGetVehicleClasses, getting Zen_SpawnVehicle to use the height as ATL or ASL, and Zen_InvokeFireSupport never firing three possible type of ammunition.

Zen_OrderExtraction and Zen_OrderInsertion now make helicopters behave more realistically by not turning off their engines momentarily. This used to be done to keep them from moving, but now they are forced to stay on the ground my other means.

8/13/14

  1. New Function: Zen_IsUrbanArea
  2. Fixed: Zen_ConfigGetVehicleClasses did not allow 'All' string for side through argument checking
  3. Fixed: Zen_GiveLoadout did not pass the given loadouts properly to specific loadout functions
  4. Fixed: Zen_InvokeFireSupport did not fire a few types of rounds correctly
  5. Fixed: Zen_SpawnAircraft, Zen_SpawnHelicopter, and Zen_SpawnVehicleCrew did not always work when the game language was not English
  6. Fixed: Zen_SpawnVehicle did not put vehicles at the correct given height above sea level
  7. Fixed: Zen_SpawnVehicle could put some large vehicles partly inside the ground
  8. Added: Framework StringTable.xml file for localization purposes
  9. Improved: Framework Description.ext code changed
  10. Improved: Zen_AddLoadoutDialog now localizes the 'OK' and 'Cancel' buttons to all languages
  11. Improved: Zen_OrderExtraction and Zen_OrderInsertion now force helicopters to leave their engines on but not move
  12. Improved: Zen_OrderVehicleDrop now requires that helicopter be closer to the drop point
  13. Improved: Zen_SpawnAircraft, Zen_SpawnBoat, Zen_SpawnGroundVehicle, and Zen_SpawnHelicopter now print an error when given an empty string
  14. Documentation: Added for Zen_IsUrbanArea
  15. Documentation: Updated Zen_RandomBattle demonstration and topmost Readme.txt
  16. Documentation: Tweaked Zen_RespawnPatrol sample mission

Roadmap

That last promised function, Zen_IsHillArea, should be done next week. It is only a matter of interpreting the terrain slope and difference in elevation relative area size into a 0-1 number.

I am still designing the preprocessor library; two obvious categories have emerged: function-specific values that can fill in for arguments, and general purpose argument macros for common code.

Due to popular demand, I am going to improve the demonstration dealing the JIP so that it handles disabled AI (players join as a new object, not into an AI). I am trying to make the solution as elegant and readable as possible, so beginners and experts alike can use the code.

Function Spotlight

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

The function chosen for this week is: Zen_FindNearHeight. This functions uses a random search pattern to find the position with the highest elevation. It is very useful for finding hills and high points that are not named locations on the map. It could be used to put a sniper team on a hill near a town, or you are looking for a possible landing zone. For example:

_hill = ["mkTown", 500] call Zen_FindNearHeight;
_snipers = [_hill, west, "sniper", 2, "menSniper"] call Zen_SpawnInfantry;

The function checks a number of random points in the radius; how many times is determined as a function of the radius size. After you have the high point, you can make use of Zen_FindGroundPosition or another position function to check that it is a certain type of point. For example, a helicopter landing zone near the player:

for "_i" from 0 to 320 step 60 do {
   _center = [player, 100, _i] call Zen_ExtendPosition;
   _hill = [_center, 100] call Zen_FindNearHeight;
   if (([_hill, 50] call Zen_IsForestArea) < 0.3) exitWith {
       _lz = [_hill, [1, 50], 0, 1, 0, 0, 0, 0, 0, [1, 20, 10], [1, [0, -1, -1], 15]] call Zen_FindGroundPosition;
   };
};

Looking at the arguments to Zen_FindGroundPosition to avoid steep slopes and trees, you can see why a preprocessor constant for find an LZ is a good idea.

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

As expected, 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.

The specific request this week is: spawning randomization. I want to know how much mission makers use exact vehicles, soldiers, and loadouts, and how much you let things be random. This will help me determine if I should offer parameters that can be both precise and random, or just focus on one of those.

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

---------- Post added at 19:59 ---------- Previous post was at 19:18 ----------

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

Hi Zen

Thanks for the awesome scripts. There is sooooooo much depth that I can still hardly understand everything even after I have done all the tutorial and most of the showcase examples. I have can implement your framework to an extend but I am a novice at scripting so bare with me ;)

I have created a firing range for me and my buddies to test mods etc and wanted to add some of your helper scripts such as magazine repacking (why bis have never added this option to the game is beyond me). I also wanted to add a couple of patrols just to make the base feel alive. When I designed the training range I had no problem when I previewed the mission. Everything was working fine and all the scripts I called from your framework worked, but when I published it and wanted to test the mission online, your scripts suddenly didnt work.

My question is it because I didnt call your JIP script or could it be because of the mods such as MCC I am running?

Thanks a bunch for answering such a noob question.

Cheers

Without seeing your init.sqf I cannot offer an specific fixes. However, make sure that all framework functions are used only on the server and after 'sleep 1' in the init.sqf. Any functions used before this can have duplicate effects by running on all clients and will not propagate in MP correctly. The only things meant to be put above 'sleep 1' or 'if !(isServer) exitWith {}' are those put there in the tutorials and sample missions.

If you intent for things like repacking magazines to work with JIP, then you must include the code from the JIP demonstration and set it up correctly. However, if all players are there from the start (ready at briefing) then JIP is not necessary.

Hi Zen. I can't for the life of me figure something out about your scripts and was hoping you could shed more light please. What I am still trying to do with your scripts is; 1 - have a multi-player server with NO AI units attached to the actual playable characters, 2 - have it generate endless tasks. My issue still always seems to come back to tasks won't generate if there are no AI players grouped with the playable characters. All of my playable characters start at a common point. The server runs in persistent mode. I want players to be able to come and go as they please and still be able to get tasks even if they are the only player on the map. I have gone through several of the tutorial missions and I feel I understand what is going on with them. However, every time I add a second playable character to my test maps, the tasking system no longer functions at all on my DEDICATED SERVER.

I can tell that you put a lot of work into your framework, and I do truly appreciate your efforts, but there is still a lot of things that aren't explained very well. I have had the issue too of thinking I am explaining something well when I'm trying to teach someone something, all to find out that I am still too close to the subject matter and still don't cover things that someone new would ask.

I have also looked at your co-op 8 player mission that you had recommended and again, it's just not what I'm looking for. The co-op 8 mission has a real cool heli insertion at the beginning but that is just not what I'm looking for. I just want my playable characters to all start on the ground, at a common base, and be able to get continuous tasking. I don't think what I am trying to do should be this difficult. I have written all of my other mission scripts from scratch and have not had this much trouble getting tasking for playable characters without AI having to be attached to them. I'm sure it's just something simple that I'm missing but if you could just shed a little more light on how your tasking scripts work it would be greatly appreciated.

Thanks again for your work and contribution.

Z

The only framework documentation resource that addresses what you are trying to do is the Zen_AssaultFrini sample mission. The JIPSync.sqf file there is designed to handle JIP players when there are no AI.

The problem is that when you disable the AI, players that join that mission are created as new objects. This means that because they previously did not exist, existing tasks cannot be sent to them without extra code that merges their object into the framework task system data. You also need to set up giving tasks in the mission so that all current players get that task.

This will be much easier if you give all Blufor players the same tasks, rather than giving different groups of players different tasks. Then, if all players leave the server, you will be able to give the first new player tasks without trying to figure out which set of tasks he should get.

First, when giving a task, use Zen_ConvertToObjectArray to give it to all Blufor units:

_task = [([west] call Zen_ConvertToObjectArray), "Description", "Title"] call Zen_InvokeTask;

Then, in the JIP sync code, you must include the new player object in the array of objects of each task:

{
   _x set [1, (_x select 1) + [player]];
} forEach Zen_Task_Array_Global;
publicVariable "Zen_Task_Array_Global";

I pointed you to my Black Ops mission not for the mission itself, but for the JIPSync.sqf logic that handles what to do with players that join. It check whether or not the player is a new object, so it can assign the task properly. One of the tests I ran for that mission was to join and leave several times, into different groups, from two separate client machines on a dedicated server. Even having the dead objects in the task data did not interfere with giving the client the tasks every time.

I personally don't like solutions that involve dealing with internal framework data, so I am going to improve the JIP demonstration to handle no AI using Zen_ReassignTask instead of this manual approach. That will be included in the release next week, and it should make that JIP code a solution for all missions.

Edited by Zenophon
  • Like 1

Share this post


Link to post
Share on other sites

I've a question. Maybe your framework has something to deal with this, maybe not.

What happens if you send a pv request to the server

Zen_MP_closurePacket = ["f_func",[arguments]];
publicVariableServer "Zen_MP_closurePacket";

and then send another, same func but different argument. What happens if multiple clients potentially send the same pv's?

Situation is quite plausible if you design a function to accept multiple arguments. Would the latter packets possibly overwrite the prior packets before they were processed? Would the spawned functions have unknown effects because of how they are processed in the que? Would it be better to create multiple functions even if they are redundant to handle such instances?

Specifically thinking about a check on a respawn, where the function accepts perhaps body and unit or maybe checks for player vs ai. In either case, client 1 could send more than one pv to the server as a request, and client 2, if they were both killed by the same grenade could also be sending the same pv as well.

Share this post


Link to post
Share on other sites
Guest

Thanks for informing us about the updated release again :cool:

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 Zen,

I have been digging in to the example code you gave me for the Insurgency style mission - it is pretty impressive, and I am learning more each time I look at it! I have a few more questions of course! I'd appreciate any advice you can give when you have time.

1. Chernarus map

So the good news is, the code

_townMkArray = [["NameCity", "NameVillage"]] call Zen_ConfigGetLocations; 

works fine on chernarus - towns have the marker and spawn ememies, great. However, I get these error messages every time something spawns. The error does not seem to affect the spawn happening. Is this because I am using a mod map (Chernarus)?

http://i227.photobucket.com/albums/dd250/joelees/zen_bug1_zps09503e9b.jpg (203 kB)

2. Groups and the repack function

I have my units set up in the editor as follows - a basic rifleman named "D1", and four unamed units that are grouped to that unit, as shown below:

zen_question_zps71b274b1.jpg

When testing, I found if I joined the server as D1, I can repack magazines. If I join the server as another unit (say the auto rifleman in the group), I cannot repack. The code I am using is:

0 = [(group D1)] call Zen_AddGiveMagazine;
0 = [(group D1)] call Zen_AddRepackMagazines;

Does the unit D1 need to be present on the server for the units in group D1 to access the repack function?

3. Custom loadouts

I love the custom loadout function! I have got it working in the mission, but I am struggling with RPGs. I wanted RPGs to appear on some units randomly, not all units, so I used the following code to set the custom loadout:

//custom loadout
_loadout1 = [
   [["uniform", ["U_OG_Guerilla1_1","U_OG_Guerilla3_1","U_OG_Guerilla3_2","U_OG_leader"]],
   ["vest", ["V_BandollierB_rgr", "V_BandollierB_khk", "V_Chestrig_blk", "V_Chestrig_oli", "V_TacVest_khk", "V_TacVest_oli", "V_TacVest_camo","V_HarnessOGL_brn"]],
   ["backpack", ["B_AssaultPack_mcamo", "B_OutdoorPack_blk", "B_Kitbag_mcamo", "B_Bergen_mcamo", "B_Bergen_blk", "B_TacticalPack_mcamo", "B_TacticalPack_rgr"]],
   ["headgear", ["H_Shemag_khk", "H_Shemag_olive", "H_Shemag_tan", "H_Bandanna_sgg", "H_ShemagOpen_khk", "H_Cap_blk_ION", "H_Beret_red", "H_Bandanna_surfer", "H_Watchcap_blk"]],
   ["assignedItems", ["ItemMap","ItemCompass","ItemWatch","ItemRadio","ItemGPS","NVGoggles"]],
   ["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_65x39_caseless_mag", 9],["RPG32_F", 4], ["20Rnd_762x51_Mag", 8], ["150Rnd_762x51_Box", 4]], ["11Rnd_45ACP_Mag", 2], ["HandGrenade", 2], [["SmokeShell", 4], ["SmokeShellBlue", 4]]]],
   ["items", ["FirstAidKit", "FirstAidKit"]],
   ["primaryAttachments", ["muzzle_snds_H","acc_pointer_IR",["optic_Hamr", "optic_aco"]]]
   // ["goggles",""],
   // ["secondaryAttachments",[]],
   // ["handgunAttachments",[]]
]] call Zen_CreateLoadout;

However, it seems like RPGs do not spawn on units, but the other weapons randomize just fine - can you tell me what I have done wrong please?

Thanks again for your input and advice. If there is anything I can do to help you (photoshopping or video making are two things I can do), please let me know.

Share this post


Link to post
Share on other sites

So why does this

0 = [
	[
		["uniform",["U_B_CombatUniform_mcam", "U_B_CombatUniform_mcam_tshirt", "U_B_CombatUniform_mcam_vest", "U_B_CombatUniform_mcam_worn"]],
		["vest",["V_HarnessOSpec_gry"]],
		["backpack",["B_AssaultPack_mcamo"]],
		["headgear",["H_Booniehat_mcamo", "H_Booniehat_dirty", "H_MilCap_mcamo", "H_Cap_oli", "H_Cap_blk","H_Watchcap_blk"]],
		["goggles",["G_Aviator","G_Lowprofile","G_Squares_Tinted","G_Shades_Green"]],
		["assignedItems",["ItemMap","ItemCompass","ItemWatch","ItemRadio","ItemGPS","NVGoggles"]],
		["weapons",[["arifle_MXM_Black_F","arifle_MX_Black_F","arifle_MX_GL_Black_F","srifle_EBR_F","arifle_MX_SW_Black_F"],"hgun_Pistol_heavy_01_F","Laserdesignator"]],
		["magazines",[[["30Rnd_65x39_caseless_mag",6],["30Rnd_65x39_caseless_mag",6],["30Rnd_65x39_caseless_mag",6],["20Rnd_762x51_Mag", 8],["100Rnd_65x39_caseless_mag_Tracer",4]],["11Rnd_45ACP_Mag",3],["HandGrenade",2]]],
		["items",["FirstAidKit","FirstAidKit",["optic_MRCO","optic_Arco"]]],
		["primaryAttachments",["muzzle_snds_H","acc_flashlight","optic_Hamr"]],
		["secondaryAttachments",[]],
		["handgunAttachments",["muzzle_snds_acp","optic_MRD"]]
	],
	"Quadra"
] call Zen_CreateLoadout;

give a no config entry error when another player joins, but this

0 = [
	[
		["uniform",["U_B_CombatUniform_mcam_worn"]],
		["vest",["V_HarnessOSpec_gry"]],
		["backpack",["B_AssaultPack_mcamo"]],
		["headgear",["H_Booniehat_dirty"]],
		["goggles",["G_Squares_Tinted"]],
		["assignedItems",["ItemMap","ItemCompass","ItemWatch","ItemRadio","ItemGPS","NVGoggles"]],
		["weapons",["srifle_EBR_F","hgun_Pistol_heavy_01_F","Laserdesignator"]],
		["magazines",[["20Rnd_762x51_Mag",8],["11Rnd_45ACP_Mag",3],["HandGrenade",2]]],
		["items",["FirstAidKit","FirstAidKit","optic_DMS"]],
		["primaryAttachments",["muzzle_snds_H","acc_flashlight","optic_Hamr"]],
		["secondaryAttachments",[]],
		["handgunAttachments",["muzzle_snds_acp","optic_MRD"]]
	],
	"Quadra MK"
] call Zen_CreateLoadout;

does not? It lies in the magazines somewhere, but it looks right to me. Any help?

Share this post


Link to post
Share on other sites

Is there a variable that one can reference that has the loadout reference picked by a player?

Example would be player gets spawned with random loadout (custom). Player may want to pick from one of a number of loadouts, and want that for rest of mission (random is not always so great if you spawn with a sniper rifle amongst vehicles lol). If there was a way to reference if A. the player has chosen a loadout from a dialog and B. what that loadout was (name or array index), then one could do more with it. (ie. allow that kit to auto propagate on spawn for X times or just if a loadout was chosen by the player, always respawn him with it, etc etc).

Thanks.

Share this post


Link to post
Share on other sites
Hi Zen,

I have been digging in to the example code you gave me for the Insurgency style mission - it is pretty impressive, and I am learning more each time I look at it! I have a few more questions of course! I'd appreciate any advice you can give when you have time.

1. Chernarus map

So the good news is, the code

_townMkArray = [["NameCity", "NameVillage"]] call Zen_ConfigGetLocations; 

works fine on chernarus - towns have the marker and spawn ememies, great. However, I get these error messages every time something spawns. The error does not seem to affect the spawn happening. Is this because I am using a mod map (Chernarus)?

http://i227.photobucket.com/albums/dd250/joelees/zen_bug1_zps09503e9b.jpg (203 kB)

2. Groups and the repack function

I have my units set up in the editor as follows - a basic rifleman named "D1", and four unamed units that are grouped to that unit, as shown below:

http://i227.photobucket.com/albums/dd250/joelees/zen_question_zps71b274b1.jpg

When testing, I found if I joined the server as D1, I can repack magazines. If I join the server as another unit (say the auto rifleman in the group), I cannot repack. The code I am using is:

0 = [(group D1)] call Zen_AddGiveMagazine;
0 = [(group D1)] call Zen_AddRepackMagazines;

Does the unit D1 need to be present on the server for the units in group D1 to access the repack function?

3. Custom loadouts

I love the custom loadout function! I have got it working in the mission, but I am struggling with RPGs. I wanted RPGs to appear on some units randomly, not all units, so I used the following code to set the custom loadout:

//custom loadout
_loadout1 = [
   [["uniform", ["U_OG_Guerilla1_1","U_OG_Guerilla3_1","U_OG_Guerilla3_2","U_OG_leader"]],
   ["vest", ["V_BandollierB_rgr", "V_BandollierB_khk", "V_Chestrig_blk", "V_Chestrig_oli", "V_TacVest_khk", "V_TacVest_oli", "V_TacVest_camo","V_HarnessOGL_brn"]],
   ["backpack", ["B_AssaultPack_mcamo", "B_OutdoorPack_blk", "B_Kitbag_mcamo", "B_Bergen_mcamo", "B_Bergen_blk", "B_TacticalPack_mcamo", "B_TacticalPack_rgr"]],
   ["headgear", ["H_Shemag_khk", "H_Shemag_olive", "H_Shemag_tan", "H_Bandanna_sgg", "H_ShemagOpen_khk", "H_Cap_blk_ION", "H_Beret_red", "H_Bandanna_surfer", "H_Watchcap_blk"]],
   ["assignedItems", ["ItemMap","ItemCompass","ItemWatch","ItemRadio","ItemGPS","NVGoggles"]],
   ["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_65x39_caseless_mag", 9],["RPG32_F", 4], ["20Rnd_762x51_Mag", 8], ["150Rnd_762x51_Box", 4]], ["11Rnd_45ACP_Mag", 2], ["HandGrenade", 2], [["SmokeShell", 4], ["SmokeShellBlue", 4]]]],
   ["items", ["FirstAidKit", "FirstAidKit"]],
   ["primaryAttachments", ["muzzle_snds_H","acc_pointer_IR",["optic_Hamr", "optic_aco"]]]
   // ["goggles",""],
   // ["secondaryAttachments",[]],
   // ["handgunAttachments",[]]
]] call Zen_CreateLoadout;

However, it seems like RPGs do not spawn on units, but the other weapons randomize just fine - can you tell me what I have done wrong please?

Thanks again for your input and advice. If there is anything I can do to help you (photoshopping or video making are two things I can do), please let me know.

1. This error is non blocking, meaning that it doesn't stop anything or return some other position; you can just ignore it. Is obviously not supposed to appear when the position is on the map. It is based upon config file data. I assume you are using the Chernarus from here:

http://www.armaholic.com/page.php?id=23863

I just downloaded that to port a mission to Chernarus/Takistan. Looking at the config, the value is there and gives a resulting map size of 10100 meters. However, that is not the true size of the map (about 15360 meters), so there is a mistake somewhere. I am working on fixing this, but it is difficult when it is different for every map.

2. Yes, D1 as an object (player or AI) must exist in the mission, else 'D1' returns null. This should cause an engine error to print on the screen, something like 'undefined variable in expression'. There are several solutions; you could name all of them, then loop through until one is not null. You could also put a marker on the group, and use Zen_GetAllInArea. Finally, you could just give the repack action to all west units.

3. The weapons and their magazines must line up, and the TRG21 takes different magazines:

["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]]]],

It is working for me using those weapons and magazines, with the rest of the loadout unchanged.

---------- Post added at 16:58 ---------- Previous post was at 16:11 ----------

So why does this
0 = [
   [
       ["uniform",["U_B_CombatUniform_mcam", "U_B_CombatUniform_mcam_tshirt", "U_B_CombatUniform_mcam_vest", "U_B_CombatUniform_mcam_worn"]],
       ["vest",["V_HarnessOSpec_gry"]],
       ["backpack",["B_AssaultPack_mcamo"]],
       ["headgear",["H_Booniehat_mcamo", "H_Booniehat_dirty", "H_MilCap_mcamo", "H_Cap_oli", "H_Cap_blk","H_Watchcap_blk"]],
       ["goggles",["G_Aviator","G_Lowprofile","G_Squares_Tinted","G_Shades_Green"]],
       ["assignedItems",["ItemMap","ItemCompass","ItemWatch","ItemRadio","ItemGPS","NVGoggles"]],
       ["weapons",[["arifle_MXM_Black_F","arifle_MX_Black_F","arifle_MX_GL_Black_F","srifle_EBR_F","arifle_MX_SW_Black_F"],"hgun_Pistol_heavy_01_F","Laserdesignator"]],
       ["magazines",[[["30Rnd_65x39_caseless_mag",6],["30Rnd_65x39_caseless_mag",6],["30Rnd_65x39_caseless_mag",6],["20Rnd_762x51_Mag", 8],["100Rnd_65x39_caseless_mag_Tracer",4]],["11Rnd_45ACP_Mag",3],["HandGrenade",2]]],
       ["items",["FirstAidKit","FirstAidKit",["optic_MRCO","optic_Arco"]]],
       ["primaryAttachments",["muzzle_snds_H","acc_flashlight","optic_Hamr"]],
       ["secondaryAttachments",[]],
       ["handgunAttachments",["muzzle_snds_acp","optic_MRD"]]
   ],
   "Quadra"
] call Zen_CreateLoadout;

give a no config entry error when another player joins, but this

0 = [
   [
       ["uniform",["U_B_CombatUniform_mcam_worn"]],
       ["vest",["V_HarnessOSpec_gry"]],
       ["backpack",["B_AssaultPack_mcamo"]],
       ["headgear",["H_Booniehat_dirty"]],
       ["goggles",["G_Squares_Tinted"]],
       ["assignedItems",["ItemMap","ItemCompass","ItemWatch","ItemRadio","ItemGPS","NVGoggles"]],
       ["weapons",["srifle_EBR_F","hgun_Pistol_heavy_01_F","Laserdesignator"]],
       ["magazines",[["20Rnd_762x51_Mag",8],["11Rnd_45ACP_Mag",3],["HandGrenade",2]]],
       ["items",["FirstAidKit","FirstAidKit","optic_DMS"]],
       ["primaryAttachments",["muzzle_snds_H","acc_flashlight","optic_Hamr"]],
       ["secondaryAttachments",[]],
       ["handgunAttachments",["muzzle_snds_acp","optic_MRD"]]
   ],
   "Quadra MK"
] call Zen_CreateLoadout;

does not? It lies in the magazines somewhere, but it looks right to me. Any help?

I have run the top loadout hundreds of times with no error:

for "_i" from 0 to 99 do {
   0 = [player, "Quadra"] call Zen_GiveLoadoutCustom;
};

I assume you mean the error that pause the game and pop up a windows saying something like 'No config entry cfgMagazines\...'. If it does not actually list a magazine, but is '.' or empty string, I think this either an engine error or a script trying to access some invalid config value. Even this works:

player addMagazine "";

The mistake is not in your loadout, and, at least for me, not in Zen_GiveLoadoutCustom. I can only assume it is a bug in the engine, a corrupt file, etc.

Is there a variable that one can reference that has the loadout reference picked by a player?

Example would be player gets spawned with random loadout (custom). Player may want to pick from one of a number of loadouts, and want that for rest of mission (random is not always so great if you spawn with a sniper rifle amongst vehicles lol). If there was a way to reference if A. the player has chosen a loadout from a dialog and B. what that loadout was (name or array index), then one could do more with it. (ie. allow that kit to auto propagate on spawn for X times or just if a loadout was chosen by the player, always respawn him with it, etc etc).

Thanks.

No, after the loadout is given, nothing is recorded about what unit has what loadout. However, this is a perfect use for Zen_GetUnitLoadout. On each client machine:

player setVariable ["Zen_Loadout_Data", ([player] call Zen_GetUnitLoadout)];

Unfortunately, due to a bug in Zen_GetUnitLoadout (which is already fixed internally), until next week you will have to use:

_loadoutData = ([player] call Zen_GetUnitLoadout);
((_loadoutData select 7) select 1) resize ((count ((_loadoutData select 7) select 1)) - 2);
player setVariable ["Zen_Loadout_Data", _loadoutData];

I apologize for the strange code, but it works fine.

You could also put that into a 'killed' eventhandler, then get the data when they respawn.

_loadoutTemp = [(player getVariable "Zen_Loadout_Data")] call Zen_CreateLoadout;
0 = [player, _loadoutTemp] call Zen_GiveLoadoutCustom;
0 = [_loadoutTemp] call Zen_RemoveLoadout;

  • Like 1

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

×