Jump to content


  • Content count

  • Joined

  • Last visited

  • Medals

Community Reputation

87 Excellent


About Zenophon

  • Rank
    Gunnery Sergeant

Profile Information

  • Gender
  • Location
  1. For your specific case, you could do what I'm going to do: change the units update in all the trigger functions to not include the 'if (typeName (_this select 0) == "SIDE")' check (yes, Zen_TriggerAreNear had the wrong index), so that they always update (e.g. if an array of groups is given) and make Zen_CreateObjective give the true argument to its trigger functions so it can use this feature as well. This will fix the problem without having to change how any code uses these functions. However, the above assumes that we want all units of the side to be able to complete the objective or (if we use groups instead of sides) that the JIP unit will join a defined group. These assumptions cover a large number of possible usages. In a more general case, there are a few things you can do to change the units the trigger is considering. One solution is to use the return values of Zen_CreateObjective to spawn a new thread to check for the JIP player. This is fine for JIP players; the trigger functions can run on any machine as well as have duplicates running (across machines or on the same machine) without issue. // create the objective the same way _a_ret_objective = [_objPos, west, west,"Box","reach"] call Zen_CreateObjective; // and put it in Zen_JIP_Args_Server (I think it should be 11 in Infantry Patrol) Zen_JIP_Args_Server set [11, _a_ret_objective]; // ... // and in the JIP sync code, spawn the trigger for the player using this information _a_ret_objective = Zen_JIP_Args_Server select 11; 0 = [player, _a_ret_objective select 1, "succeeded", _a_ret_objective select 0] spawn Zen_TriggerAreNear; However, this method only allows for adding players, not removing them. You could modify Zen_CreateObjective to return the thread _h_trigger = scriptNull; switch {// ... // ... case "reach": { _h_trigger = [_rangers, _taskUniqueName, "succeeded", _objects] spawn Zen_TriggerAreNear; }; }; // ... call Zen_StackRemove; ([_objects, _taskUniqueName, _h_trigger]) // ... // note that this is now global a_ret_objective = [_objPos, west, west,"Box","reach"] call Zen_CreateObjective; then terminate and update the thread when a JIP client joins // in the server's JIP code (Zen_SyncJIPServer) // All global variables on the server are accessible in this scope terminate (a_ret_objective select 2); // I've put west here just to match the code you've given // The units given to the trigger could be found in any way you want 0 = [west, a_ret_objective select 1, "succeeded", a_ret_objective select 0] spawn Zen_TriggerAreNear; See the JIP demo's changing of Zen_TrackInfantry threads for a similar example (that one uses a group instead of a side).
  2. Husker-71, Zen_GiveLoadoutIndfor is essentially a lot of preset loadouts with slight randomizations in each one; they're all based upon one faction in vanilla ArmA, the AAF (same for the Opfor and Blufor functions, those are the basic CSAT and NATO equipment). Those functions exist to provide a quick way to change/randomize loadouts for the common default factions. If you want full control over the units' equipment, you need to use Zen_CreateLoadout, Zen_GiveLoadoutCustom, etc. to manually specify all of the items the units will use. The custom loadout system also gives you a lot of randomization options within each loadout; however, you'll need to learn the formatting to create them (there is a demonstration for this). Alternatively, you can write your own loadout scripts (e.g. export from virtual arsenal) or use another system that gives you detailed control. The '_x' is a special variable name used to mean the current element in a forEach loop (as well as in the condition of the 'count' command); since there is no forEach loop, _x has no value. If you are in singleplayer, just use the 'player' command; for multiplayer, you'll need to define the players as a group, an array of objects/groups, etc. and be prepared for players leaving/dying or, if you plan to support JIP, joining.
  3. You would need the equations for the sides of the rectangle. I think the best way would be to step around the sides from the corners and mirror each position. Note that I'm using Zen_ExtendVector from my framework, but any equivalent vector addition command will do. Note that I did not test this, so I might have made a mistake with the angles or something. If it draws a rectangle at the wrong rotation, first try swapping _a and _b.
  4. As another reference, look at the init of my Evade and Survive mission; the mission is spawning enemies infinitely around the player with a cap on concurrent enemies. For any long-term, ambient spawning, you would take the usual spawning code and put into a loop with some timer/limit to space out the spawns. You can change the random position's parameters to suit your mission (e.g. within markers, around an object, etc.); giving an object as the parameter will use the position of that object at the time the code runs. For patrolling those groups, I suggest either terminating and recreating the patrol thread for patrols in the same area (see Multi thread management demonstration), or using a single threaded patrol manager (you can try my multi patrol function in the release #48 post as a starting point). Also, see the FAQ for an explanation of Zen_SpawnInfantry's unit selection arguments. You might also be interested in the custom loadout system; there is a demonstration for it. For the cleanup of dead bodies, you could put an EH on each unit and delete them with a timer, or you could make cleanup 'sweeps' on an interval, e.g. Many orders functions, like Zen_OrderInsertion and Zen_OrderHelicopterLand recommend that you use 'spawn' to invoke them. This is because they have a long execution time (typically dependent on how long the AI takes to complete the action) that will interrupt the current thread. This means that calling or spawning more than one of them will cause overlapping orders and conflicting decisions for the AI. For a detailed look see the multi thread mangement demonstration and the 'Multi-Threading and Spawn vs. Call' section of the SQF overview. In short, you need to use 'spawn' for the order, save the thread handle (the return value of 'spawn'), and then use 'terminate' to stop that thread from running before issuing new orders. This is true for both procedural (common top-down execution) and event-driven (i.e. the actions you're using) styles, e.g. // the player uses the insertion action/command h_heliOrders = [[Maeh_transSys_insertionHeli, [Maeh_transSys_LZMarker, "TransportSystem_Spawn"], playableUnits, "normal", 50, "land", false] spawn Zen_OrderInsertion; and in another script/thread/EH/action //... the player selects another command // note that checking for scriptDone is not strictly necessary, but allows you flexibility to e.g. let the previous script finish etc. if !(scriptDone h_heliOrders) then { terminate h_heliOrders; }; // now we have no previous conflicting orders, and the thread variable/pointer is updated h_heliOrders = [[Maeh_transSys_insertionHeli, "TransportSystem_Spawn", "normal", 50, false, false] spawn Zen_OrderHelicopterLand; Depending on your system's structure, h_heliOrders can be global, local, assigned to an object, put into a larger data structure etc. Note that putting 'h_' first is just my personal style to denote a script handle and help me keep track of them in the code. To repeat the documentation I referenced, threads are global on each machine and cannot be transfered or defined remotely. Finally, the use of spawn to get a thread is distinct from using spawn to get scheduled execution, but if you are using EH's the spawn will also be necessary for that reason (see the FAQ for a discussion of that).
  5. According to the changelog, the release on 11/20/16 included this fix to Zen_SpawnInfantryGarrison; I've checked the current release and it definitely has it (there have occasionally been code and changelog discrepancies). Thank you for the detailed bug report so I could verify that.
  6. Update Overview Greetings fellow Armaholics, this release fixes an issue with playable slots not spawning the unit in some missions (resulting in the player controlling a seagull). Changelog 8/11/17 Fixed: Non group leader slots could not be used
  7. I can reproduce this issue and I'll be releasing a fix shortly. The solution, for anyone having the same issue, is to delete and recreate every playable unit in the editor (except the group leaders). I have no idea why this fix works.
  8. You'll have to write a function that creates the jet, makes it fly over, etc. and then given the name of your custom function as the second argument to Zen_AddSupportActionCustom. The documentation for Zen_AddSupportActionCustom lists the arguments that will be passed to your function. Note that you could even call a regular fire support (from Zen_CreateFireSupport) manually in your custom function to do the actual explosion (and the jet would just be for visual effect).
  9. Update and Release #51 Introduction Greetings fellow scripters and Armaholics, in this latest installment, I will continue to discuss the development of the framework and, of course, shamelessly advertise the framework in any way possible. If this sounds boring, you can download the latest version from the original post. As always, the links to Google Drive for the .7z and .zip versions are already up to date. For those looking for older versions, go to file>revisions. The new version will be on Armaholic soon. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc. Changelog This release falls on the third anniversary of the framework's first release; thusfar, I have counted 806 total changes to the framework. I am truly grateful for all of the comments and suggestions that allowed for so many fixes, improvements, and additions. The vast majority of what I had planned to do is finished; I will continue to maintain the framework with bugfixes and small improvements. Added in this release is Zen_ArrayRemoveType, which is basically the remove version of Zen_ArrayGetType. This might be a useful shortcut instead of writing a code condition for Zen_ArrayFilterCondition; it also searches recursively and should be slightly faster. Now that BIS have allowed ctrlCreate to use control classes defined in the mission's .ext file, the dialog system can take advantage of that to be on truly equal footing with tradition dialog creation. Zen_InvokeDialog will look for the type of defined control and apply properties appropriately (e.g. types 1, 11, 16, and 41 are considered buttons). The template subsystem is now tied into the action system, with Zen_CreateTemplate and Zen_SpawnTemplate being able to copy-paste existing actions onto the new objects. This greatly reduces the hassle of manually applying your actions to the correct spawned object. 7/10/17 New Function: Zen_ArrayRemoveType Fixed: Zen_ExtendVector did not use relative height if its second argument was a vector Fixed: Zen_RefreshDialog did not remove controls properly in some cases Improved: Zen_CreateControl now allows mission defined control classes as the first argument Improved: Zen_CreateTemplate and Zen_SpawnTemplate now copy actions added using the framework's action system Documentation: Added for Zen_ArrayRemoveType Documentation: Updated Notepad++ SQF language and autocompletion file with ArmA 1.72 stable commands
  10. The framework's task system appears to fail when all objects assigned to a task are deleted (like when the players leave) because it automatically deletes tasks for which there are no units. This is done because there is no direct command to remove the data entry itself, only units that have the task. This is most likely the issue if you are testing the JIP code alone by joining, leaving, then joining your persistent server with team AI disabled. To account for this, you need to manually create a proxy unit that will hold the task for players. Any invisible/disabled proxy AI unit (preferably local to the server) somewhere on the map will work; you would include this unit with the players when you use Zen_InvokeTask (or you could use Zen_ReassignTask to this unit when some players still exist). You can then use Zen_ReassignTask normally for this task on JIP players.
  11. Update Overview Greetings fellow Armaholics, this release ports appropriate missions to Tanoa, for a total of 45 variants on 9 maps. Changelog 6/17/17 1. Added: Fatigue parameter for all missions Abduction 1. Added: Tanoa version Ambush 1. Added: Tanoa version Checkpoint 1. Added: Tanoa version Convoy 1. Fixed: Removed debug markers (Takistan version) Sweep 1. Added: Tanoa version
  12. Update and Release #50 Introduction Greetings fellow scripters and Armaholics, in this latest installment, I will continue to discuss the development of the framework and, of course, shamelessly advertise the framework in any way possible. If this sounds boring, you can download the latest version from the original post. As always, the links to Google Drive for the .7z and .zip versions are already up to date. For those looking for older versions, go to file>revisions. The new version will be on Armaholic soon. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc. Changelog This release introduces a major addition to the framework, a system for managing actions. It currently uses ArmA's traditional action menu, since it is simple and doesn't seem to going anywhere. There are several benefits of this system; you no longer have to write your own functions for adding and removing actions, all MP synch'ing is done for you, and adding actions to JIP client is much easier. All framework functions and documentation have been updated to take advantage of this new system. This now allows you to interact with actions added by framework functions; you can add and remove them manually during the mission. All framework actions now have a global variable stated in their the function's documentation. The JIP demonstration and all sample missions that implement JIP have been updated. The updating of actions and the usage of many framework action functions has changed. Also of note is another new function, Zen_ArrayTranspose. This function makes a two dimensional transpose of an array, which means it leaves nested, nested arrays and lower intact. It is mainly intended for transforming data structures to separate a list of properties from their assigned identifiers. ZEN_FMW_Code_GetRemoteVarArray and ZEN_FMW_Code_GetRemoteVarArrayT have been added to make remote access to such data structures easier. In order to provide the greatest possible performance increase to the dialog system, Zen_RefreshDialog now allows the user to optimize the refresh process for their specific dialog/refresh. You can now specify which controls to force refresh (without checking for changes, i.e. you know there were changes), which to ignore (i.e. you know there were no changes), and which to check and update normally (the remainder from those two arguments). This allows you create separate, efficient refreshes for different parts of your dialog, massively speeds up refreshing of large text blocks (e.g. cycling pages of text), and improves the users' experience. 5/24/17
  13. There's nothing wrong with your code or the arguments to Zen_OrderVehiclePatrol. After testing a lot of different possibilities, the fix for this is a simple 'doMove' command added to the existing 'move' and 'addWaypoint' commands in Zen_OrderVehiclePatrol. Testing a large sample (30 vehicles) without 'doMove' gives about a 60% compliance rate; adding doMove makes it 100%. I cannot explain why 'doMove' works when 'move' does not; repeating the 'move' command does not always work. Various other factors (vehicle type, side, the method for spawning the crew, checking if the vehicle has complete a move order) have no effect on this as far as I can tell. This fix will be duplicated to various other Orders functions for the next framework release (which should be in about a week, as I'm finishing up some new things). If you want to modify Zen_OrderVehiclePatrol yourself, just add (driver _veh) doMove _mpos; as lines 60 and 93 after the 'move' line.
  14. You are correct, publicVariable does say you don't need to manually publicVariable anything to JIP clients, if the latest value has been PV'd previously (which is the case with your code). I don't remember if I every tried using this when I was creating my JIP code. I probably just did it manually to be certain it would work. This is somewhat a case of 'trust but verify'. publicVariableClient must be run on the server; it's essentially repeating the automatic synch'ing that PV should already have done. Note that variables that are not always PV'd from the server at every update (i.e. a 'server-side' variable that is not guaranteed to be up to date on a client) do require this (e.g. the catch-all Zen_JIP_Args_Server). You're using the variables as global rather than server-based, but this is an alternate style. I cannot reproduce this; can you post the exact arguments you gave the function? It might be an issue with how the function is interpreting the patrol area (e.g. giving the vehicle a destination it cannot reach). Also, there are issues with AI simply not obeying a move order, but I've never been able find a cause for it. You could also try adding more vehicles, if none of them move, it's not just random AI confusion. The type, side, etc. of the vehicle should have no effect on the result (you can even mix vehicles of different sides).
  15. Detecting that a client in JIP should be done correctly by the framework; it will give you the _Zen_Is_JIP boolean in the init. It will also wait for the player to initialize before compiling the framework. Task1 is undefined because running publicVariable only sends the variable to current clients. The JIP client doesn't have this variable defined, or any of the information it needs when it starts. Zen_SyncJIPServer is given as a template in the JIP demonstration to show how to the JIP client 'asks' the server for the information it needs, but you must define it in your mission and customize it. For example, in your mission it could include (owner _this) publicVariableClient "Task1"; Once the waitUntil is over, the JIP client can use that variable. Also, using Zen_ReassignTask assumes that the JIP player's object did not previously exist. That means that other clients have no information about it either; thus, every client must be updated with the tasks of the new object. If you've disabled friendly AI, then using Zen_ReassignTask is correct. If the player object did exist (as an AI), the JIP demonstration shows how to use the private function Zen_InvokeTaskClient to update tasks. There is a mistake in the JIP demonstration with Zen_InvokeTaskClient; the line should end with '(_x select 6), (_x select 8)] call Zen_InvokeTaskClient;', since tasks now support different icons. The error doesn't stop tasks from working though.