Jump to content

Zenophon

Member
  • Content Count

    530
  • Joined

  • Last visited

  • Medals

Everything posted by Zenophon

  1. Overview This script teleports AI units into nearby buildings at appropriate window positions. Units will stand and face the window so they can fire out of it. Units are moved to random windows every time. If there are enough units, every possible window will be covered; otherwise, you won't know where they are watching. When there are multiple possible windows to face, units will face one at random. Units will not face a windows more than 5 meters away, and the windows will have a reasonable field of view. By using this script, you no longer have to manually place units at windows and struggle with the 2d editor. This script allows you to easily simulate the AI occupying buildings and defending their position realistically. It works for just a few units to surprise players, and on a large scale to put dozens of enemies into defensive positions all across a city. The function is carefully optimized for almost no performance impact, allowing it to dynamically examine each position for the best possible results. There is no debug, argument checking, or defensive code, to make it as simple and fast as possible, so make sure the arguments are correct. Download Google Drive: https://drive.google.com/file/d/0B-QFvxyAVKTUX0lTWHNBYWVHN3M/edit?usp=sharing Usage Place the script somewhere in your mission folder. Function parameters: 1. Array, the building(s) nearest this position is used 2. Array of objects, the units that will garrison the building(s) (opt.) 3. Scalar, radius in which to fill building(s), -1 for only nearest building, (default: -1) (opt.) 4. Boolean, true to put units on the roof, false for only inside, (default: false) (opt.) 5. Boolean, true to fill all buildings in radius evenly, false for one by one, (default: false) (opt.) 6. Boolean, true to fill from the top of the building down, (default: false) (opt.) 7. Boolean, true to order AI units to move to the position instead of teleporting, (default: false) The complete documentation is also commented at the top of the file. You can run it from anywhere with execVM: 0 = [getPosATL X, units X] execVM "Zen_OccupyHouse.sqf"; You can also compile it into a function if you plan on using it many times: Zen_OccupyHouse = compileFinal preprocessFileLineNumbers "Zen_OccupyHouse.sqf"; _units = [(getMarkerPos "mkHouse"), [X, Y, Z], 50, false, true] call Zen_OccupyHouse; When using the compile and call method, the function returns the array of units that did not fit in the building. Changelog Known Issues None Feedback If you liked/disliked it or have any suggestions for improvement, I would like to hear your thoughts. Either this thread, PM, or email is fine. Contact the author: ZenophonArmAFramework@gmail.com Legal This software is released under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0). http://creativecommons.org/licenses/by-nc/4.0/ Credits JohnnyBoy (AI take cover)
  2. So it looks like the error is in the evaluation of the arguments, not the script itself. I think the error "Type Group, expected Object" means 'group' command expected an object, but 'this' is itself a group. Try: units this since 'units' works on a group or an object. I thought 'this' was the object of the init script in the editor; I doubt they'd change that. Maybe you put the code in the wrong place. Sorry, it's been a long time since I looked at any of this.
  3. * Credits go to CallMeSarge for this great logo Introduction Ladies and gentlemen, Armaholics of all ages, I am proud to present a work over a year in the making: Zenophon's ArmA 3 Co-op Mission Framework. My framework is a library of 252 SQF functions and 87 macros organized into a carefully designed API that is both easy to use and extremely powerful. The functions cover everything from manipulating arrays to an extensive task system. Each one has been meticulously designed and tested to provide useful features with minimal bugs and issues. The framework is designed so that each function is a logical building block that achieves a straightforward effect. The strength of the framework is that each small part fits together neatly with others, allowing you to quickly implement your mission design intuitively. The framework works with any map and requires no addons. It is compatible with any mod because you choose which functions execute. There is effectively no performance impact to compile the entire framework, and every function has been diligently optimized. All 206 public functions are also carefully documented in an exacting style, and many resources are provided to help you learn to use the framework. The framework is created with these goals in mind: Simple co-op fun for both players and mission makers Bottom-up design using flexible pieces that you control Truly random and dynamic missions without extra work for mission designers Procedural mission design instead of manual placement using the editor Eliminating large, static functions with assumptions about what you want in your mission Server-oriented execution to create more efficient multiplayer missions A simplification of locality and interacting with clients in multiplayer A solid, powerful, and bug-free library to use as a foundation for your own code The framework's many functions are divided into 14 categories with a specific purpose: The Data functions are the foundation of the framework, supporting both simple and complex operations on arrays and strings. The Dialog System allows dynamic creation and display of GUI's using only function calls. The Fire Support system is a tool for mission makers, not players, to create any imaginable artillery, mortar, or airstrike. The Loadout functions, including a full custom loadout system, provide every option you need to easily equip both players and AI. The Math functions are auxiliary functions that deal with various 2D trigonometric operations on positions and polygons. The Misc functions are just that, miscellaneous. They don't fit in anywhere else, but are still useful. The Object functions deal with objects, and provide numerous ways to check on and interact with players, AI, and static objects. The Objective system is designed to make side missions extremely simple for mission makers with just one line of code. The Orders functions provide a tested and working way to make AI do things, and some offer simple but powerful randomization. The Position functions generate and check random positions, allowing infinite randomization within your control. The Preprocessor library offers both general and framework-specific macros that improve ease of use for many small tasks. The Spawning functions allow you to spawn any object, AI or static, that you need and offer both straightforward and randomized spawning. The Task system is a self-contained system meant to separate the mission maker completely from the issues of tasks, making any task operations simple. The Trigger functions perform operations on tasks based on preset conditions and are designed to complement the Task system. Download Google Drive: (Go to file>download, or ctrl+s) (.7z file) https://drive.google.com/file/d/0B-QFvxyAVKTUd0I4bFpPZTFLVTQ/edit?usp=sharing (.zip file) https://drive.google.com/file/d/0B-QFvxyAVKTUS3dDcXdURG96bFE/edit?usp=sharing Contact the author: ZenophonArmAFramework@gmail.com Changelog Documentation The included documentation explains how to use each part of this large framework in order to create missions. The documentation set features complete, standardized documentation organized by the categories for all of the framework's public functions. Further standard documentation, such as a changelog, FAQ, etc., are provided. There is a series of 20 beginner tutorials to help first-time mission makers create simple missions using framework functions. For more experienced scripters, there are 15 intermediate demonstration missions and 8 full sample missions to show more advanced scripting techniques and more framework functions. Other helpful resources, including a Notepad++ SQF language, are provided. Multiplayer and JIP The framework was designed with the idea that the server should manage everything that it can, and few to no scripts should be run on the clients. Framework functions are designed to work in a multiplayer environment (dedicated servers too, of course) without the mission designer even considering how or why. Regardless if a mission is singleplayer or multiplayer, the framework's functions will do what they say they will without you changing anything. The framework (or any function) cannot intrinsically deal with JIP and support it without any changes to your mission. Because you cannot reasonably be expected to divine what you need to do to make your usage of the framework JIP compatible, there is a JIP demonstration mission for you. Using the template there in your own mission, with a some customization, will make your mission JIP compatible. Bugs There will be bugs; this is not a final release, nor will it ever be. I have made every effort to test and debug all 194 public functions, and that that documentation agrees with the actual code. Bugs are not your fault; they come from some mistake within a framework function. It is not possible to produce bug-free software of this magnitude without mass public testing. This holds true whether or not the framework is still in beta. The development cycle of adding, improving, and fixing things goes on forever. I assure you that I have every intention of fully supporting the framework for a long time. Fixing bugs and issues will always be my first priority over adding new features or tweaking things. Feedback I am not so arrogant as to think that I have considered everything, have a perfect design and implementation, and have judged the needs of ArmA mission makers fairly. I highly encourage you to submit any suggestion that occurs to you, even if you are not sure about it. For simple feedback like 'I liked it' or 'I hated it', or if you have something important to say, this thread, PM, or email is fine. Concerning bugs, please post, PM, or email me a report (others will thank you for improving the framework) with every possible detail. Concerning issues with understanding and using framework functions, please make use of every resource you have available to you. If you have a technical question about a more obscure function, feel free to look at the source code and experiment with it. If you really cannot figure something out, PM or email me with the information needed to help you. Your issues, bugs, and feedback are important to me. This framework is important to me, and I am not going to 'get bored' or 'have real life issues' a month after release, leaving you with bugs. I have invested a lot of time into this framework, and I will continue to do so. Editor Limitations The framework can be the only resource used to create your mission, or you may use it in conjunction with the editor and your own scripts. However, you cannot use any framework function in an object's init field, a trigger's condition, etc, in the editor. You can still use framework functions in places in the editor that do not execute instantly upon mission start, such as a trigger's activation field. I have no plans to change this; it seems like a significant problem, but it is in fact advantageous once you learn how to create and organize your mission using external scripts. Your mission will be better organized and easier to change and debug with all of its code and function calls in a few SQF files. There is nothing that can be done in the editor that cannot be done with scripting. There is a lot that can be done with scripting that cannot be done in the editor. You might think that the editor is preferable to my complex framework. I can say with 100% confidence that my framework is quicker to use, more reusable, easier to test and debug, more effective, and more powerful than the editor. You will achieve better missions more quickly once you learn to use the framework. What the Framework is Not First, the framework is not a magic black box that generates lots of features for you with a few inputs. This is not a system of mission templates that lets you create a 2-hour combined arms mission in 5 minutes. This is not a random mission generator, it is not a resource for players. It is a tool for mission makers. Second, the framework does not implement abstract systems. This means things that do not achieve a direct effect in the game world or perform a concrete operation. I will never add a wounding system, weapon resting, team killing protection, points and scoring, respawn, or anything else that is superfluous to the mission itself. Third, the framework does not control the mission, your implementation does. The framework does not run any functions unless you call something (most functions also call other framework functions). There are no hidden functions observing the mission and guessing what you want next. Almost every action must be done by you manually, and others are optional. Finally, the framework is not a collection or compilation of various people's work. Everything in the framework is designed and coded by me without using any external libraries and other people's code (except for a few BIS functions for GUI stuff). I must be able to guarantee the quality and functionality of every line of code (nearly 16000 lines) if I claim to be the author of the framework. I have purposefully reinvented the wheel numerous times to allow this framework to provide the best experience possible. Legal In addition to the terms of the Legal.txt file (please read), the framework is also released under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) license. Conclusion You might also not be very impressed yet, but I assure you that you will be. I have spent over 2000 hours creating this framework. Believe me when I say that this framework is worth your time. Credits MimirAesir, Tutorials MooseMan (https://forums.bistudio.com/user/906086-pellelil/), Zen_SpawnFlare
  4. This bug occurs when the driver is not the leader of the vehicle's crew; it might also affect Zen_OrderHelicopterLand. I have updated the framework download links with a new version. You can also fix it manually if you prefer: line 96 Zen_OrderVehicleMove (((unitReady _vehicle) || (([_vehicle] call Zen_IsReady))) || (([_vehicle, _inPos] call Zen_Find2dDistance) < _completionDistance) || _isCrash || ((_vehicle isKindOf "SHIP") && ((getTerrainHeightASL getPosATL _vehicle) > -1))) line 91 Zen_OrderHelicopterLand ((unitReady _heli) || {_isCrash})
  5. In the line _yourObjective = [_ObjectivePos, (resistance), east, "Officer","elimina "] call Zen_CreateObjective; it should be 'eliminate', or the task's completion trigger won't be set correctly. By 'translated objective's text', do you mean that you modified Zen_ObjectiveCreateTask.sqf? If so, check that there are no errors in that file. Check the full log to see if there are any errors before the one from Zen_AreTasksComplete. When I run the code below in an empty mission (just a player unit and a marker), there are no errors and the objective can be completed normally: _yourObjective = ["Mk1", resistance, east, "Officer", "eliminate"] call Zen_CreateObjective; diag_log str _yourObjective; player sidechat str _yourObjective; waituntil { sleep 5; [(_yourObjective select 1)] call Zen_AreTasksComplete }; player sidechat "task complete"; For the second problem, the code placed in a unit's 'init box' in the mission editor must be run by a script after the unit is created. 'this' changes to the variable or command the script uses to get the unit; for example, _group = [...] Zen_SpawnInfantry; { _x setVariable ["ALIVE_profileIgnore", true]; } forEach (units _group);
  6. Are you spawning the units on the deck (or placing them in the editor) and then using a loadout function? There might be a delay for ArmA to create/initialize units on the ship; try adding a second or two wait before the functions run. In general, units can have their equipment changed even if they are e.g. skydiving, in a vehicle, etc.; though, as you say, being on a ship might be a special case that is bugged. The second fix is to spawn/place them on land, apply the loadout, wait/check that it is applied, then move them onto the boat. Sometimes setup like this requires a short 'mission loading' black screen so that the player doesn't see units teleporting or changing equipment.
  7. This is in the FAQ.txt under "Q: Can the framework easily spawn addon units?". The Zen_RandomBattle demonstration explains how to use Zen_ConfigGetVehicleClasses to search for vanilla vehicles; you can just replace the keywords with those of addon vehicles/people. This approach is meant to be very flexible and requires using the editor's config viewer. If you have classnames for specific vehicles, you can given them directly to Zen_SpawnAircraft, Zen_SpawnGroundVehicle, etc.. Zen_SpawnGroup and Zen_SpawnVehicle are the more basic functions that actually do the spawning, if you want to use them directly. For loadouts, the Zen_CustomLoadout demonstration explains how to get (with Zen_GetUnitLoadout) and format weapon/item/ammo classnames.
  8. Occupy House is a separate script that doesn't require the framework (thread link in my signature); it tries to position units at windows and in the right direction. It also relies on the built in positions defined by the building (buildingPos command); the framework offers Zen_FindBuildingPositions for any random point in a building (though the quality may vary). Of course, you can combine these in a mission or even edit Occupy House to use Zen_FindBuildingPositions. For placing markers, the editor is of course easier for visual placement, but you can use Zen_SpawnMarker if you want to create/delete lots of markers dynamically. Once you have the markers, you can put them into an array and use Zen_ArrayGetRandom, Zen_ArrayGetRandomSequence, and Zen_ArrayShuffle to randomly use them one at a time or in a random order. For a particular order, Zen_ArraySort can be given any comparator/hash function (there are a few macros for this). If some markers have to be removed later, Zen_ArrayFilterCondition can help. With the marker selected, Zen_FindGroundPosition (some argument macros offered here as well) is the main system for generating positions. You might also use Zen_IsUrbanArea etc. (these scale with area/objects and might not run very fast) to determine what kind of filters you need. You can then put this into a loop to repeat the objective. Zen_CreateObjective offers some presets for you; for scripting your own, Zen_TriggerAreDead etc. can be surprisingly flexible. I recommend browsing through the Index.txt in the root documentation folder; most of the functions have straightforward names, and it's much easier to find one there than looking through each full function documentation files. The tutorials, demonstrations, and sample missions have a readme/intro with a short description of what's in each one; all the documentation tries to make it clear when previous knowledge is required. As always, you can ask here for more examples or specific answers.
  9. I cannot remember a specific reason for excluding .jpg; I didn't even include the check for pictures in a list. Maybe I thought .paa was preferred or .jpg wouldn't work for some control types; it appears that .jpg is perfectly fine though. I'll change it to allow .jpg in the next update.
  10. Update and Release #53 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 marks the beginning of the framework's fifth year; for this milestone I want to offer a new level of randomness that is accessible and fits with existing functions (i.e. Zen_FindGroundPosition). The new feature is called Zen_FindLinePosition. Zen_FindLinePosition's first feature is to find a random point on any curve. This curve is any function that accepts an X value and returns a Y value. It can also find a random point between any two such curves. While the function itself is not very complex, it is fully integrated into Zen_FindGroundPosition, including verifying that road positions lie inside the curve and limiting the angles around the center. By using blacklist markers, angle limits, and every other Zen_FindGroundPosition filter, you can create a much greater variety of areas more efficiently. Some examples of this are: The calculation of roads includes a buffer to account for the discrete nature of road objects in ArmA; when the single line (green dots) crosses a road, it should find one or two road points to use. It is important to note that all Zen_FindGroundPosition options still use the given center position, so shifting the X limits far away from this may cause odd behavior. Also, consider that the function itself can be random, allowing you to weight the distribution of points within the area or around a central curve in any way you want. E.g. using the built-in random: 7/10/18 1. New Function. Zen_FindLinePosition 2. Fixed: Zen_FindGroundPosition road argument force and avoid options failed in some cases 3. Added: Zen_FindGroundPosition can use Zen_FindLinePosition 4. Improved: Zen_AddFireSupportAction and Zen_AddSupportActionCustom include the map on the support selection dialog 5. Documentation: Fixed for Zen_InvokeDialog 6. Documentation: Fixed tutorial AltisPatrol script errors 7. Documentation: Added for Zen_FindLinePosition 8. Documentation: Updated for Zen_FindGroundPosition The AltisPatrol tutorial is fixed; there were multiple errors in ReinforceGroups.sqf On a more general note, I will be reviewing all documentation that uses code in the next few months to ensure that it adheres to current framework functions and styles. The tutorials are the most out of date, but most of them should still work. If anything is inconsistent or confusing in an example, just post and I can clarify. I have made missions on various CUP maps in the past; I think the latest CUP Terrains version I tested was 1.3.0. I have looked at the changelog for 1.4 and I don't see anything that could cause such a significant problem. Can you post which terrain you are using and what the code is? I can't see that picture, but Zen_SpawnGroup (which Zen_SpawnInfantry uses) spawns all units very close together. Their AI should make them go into a normal formation immediately and maintain it when they move. You might have to repeat setFormation every time the group gets a new waypoint. Also, make sure you're not running any AI mods and that the group is local. Do the AI demonstrate the same behavior when placed close together in the editor and with editor waypoints (which are ostensibly the same as scripted)? Zen_OrderVehicleMove does everything it can for AI driving, but the issues are with lower level AI code; I consider it a success if the vehicle reaches it destination at all. Edit: It's much better to repeat the commands and ensure that the AI comply than have a function that doesn't work. The first priority is to make the functions always do what they say they will. Especially for functions dealing with the AI, as I have learned not to trust them.
  11. Update and Release #52 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 It's been a while, and this update addresses all bug reports and requests since last release as well as keeping the framework up to date with the latest ArmA version. There's always little things like helicopter pods spawning as vehicles and ropeCreate not working. The action system will be much more robust about removing null objects from its local and server lists. This does not include objects that are not alive (hence the new parameter for Zen_ArrayRemoveDead); you can put actions on destroyed objects (the transition from alive to dead may not preserve actions; this is the engine creating a new object). I've also added a check for duplicate actions; changing an action then invoking it again is still considered a duplicate action (create a new action or use Zen_UpdateAction's refresh argument). Zen_CreateObjective and the trigger functions it uses account for newly spawned units or JIP players being added to groups; previously they only scanned for new units when a entire side was given. Zen_SpawnConvoy will no longer spawns guerrilla factions or DLC factions unless you specifically input that faction. Zen_SpawnVehicleCrew will print a proper error if a very strange object spawns as a vehicle; please report any spawns that obviously are not an appropriate vehicle so I can add a special filter in Zen_ConfigGetVehicleClasses. 5/2/18 1. Fixed: Zen_ConfigGetVehicleClasses filters cargo helicopter attachment pods 2. Fixed: Zen_InvokeAction, Zen_DeleteAction, and Zen_RemoveAction filter null objects 3. Fixed: Zen_OrderFastRope did not create its ropes correctly 4. Fixed: Zen_SpawnConvoy spawned mixed factions for east and resistance sides when the faction argument was not given 5. Fixed: Zen_TransformObject argument checking allowed a scalar as the fourth argument 6. Added: Zen_ArrayRemoveDead argument to check for objects being alive 7. Improved: Zen_CreateObjective, Zen_TriggerAreDead, Zen_TriggerAreNear, Zen_TriggerAreRescued, Zen_TriggerAreaClear, and Zen_TriggerAreaSecure dynamically update the units they are considering for all inputs 8. Improved: Zen_InvokeAction prevents duplicate actions 9. Improved: Zen_OrderVehicleMove stops ground vehicles and boats at a reasonable distance from their waypoint 10. Improved: Zen_SpawnVehicleCrew prints an error and returns null if no crew can be created 11. Documentation: Fixed Zen_RespawnPatrol.Altis used Zen_TransformObject wrong 12. Documentation: Updated for Zen_ArrayRemoveDead 13. Documentation: Updated Notepad++ SQF language and autocompletion file with ArmA 1.74, 1.76, 1.78, 1.82 stable commands
  12. I was a bit vague about cleaning because I had to work out the details of implementing it. The action system is a manager and locality wrapper for addAction; it tracks global information about an abstract action as well as local information from addAction. The error is from the system's global tracking of which objects have the action; that server based list has to be cleaned of null objects. Any action system function that uses or updates the server data now calls Zen_ArrayRemoveDead 'on demand' so that the system cleans itself as it is used (Zen_DeleteActionClient already did this for local data). For example, Zen_InvokeAction would look like _nameString = _this select 0; _units = [(_this select 1)] call Zen_ConvertToObjectArray; _actionData = [_nameString] call Zen_GetActionDataGlobal; _text = _actionData select 1; _addActionArgs = _actionData select 4; // I've added this filter for null objects _oldObjects = [(_actionData select 5)] call Zen_ArrayRemoveDead; _allUnits = [_oldObjects + _units] call Zen_ArrayRemoveDuplicates; Zen_ConvertToObjectArray will filter the argument for null objects as well. Zen_RemoveAction and Zen_DeleteAction will use Zen_ArrayRemoveDead similarly. I've also changed Zen_InvokeActionClient to clean the local data and prevent duplicate actions. Don't worry about changing all this yourself, I'm going to release a new framework version in a couple days (after I test this and a few other things).
  13. There are two separate errors starting in the f_HandleRespawn function. First, Zen_InvokeAction is confused by null objects in the list of objects that already have the action (I'm guessing those units died); I'll need to modify the action system to clean its data as necessary. Second, Zen_TransformObject is given the wrong arguments on line 92; it should be 0 = [_unit, (((units group _unit) - [_unit]) call Zen_FindAveragePosition), 500, 0, random 360] call Zen_TransformObject; where the fourth arg is a 0 to skip the velocity transform rather than the 'random 360' direction transform; Zen_TransformObject was also incorrect in letting a number get through to the setVelocity command. Shell.Stratis was renamed to Shell and the mission.sqm removed some time ago to prevent confusion since there are many maps now (long ago Stratis was the only map in A3). The current instructions are based around creating a blank mission on the desired map using the editor, then copying framework files (as opposed to creating the mission files, then opening them in the editor). Some/all of the tutorial pdf's were never updated. For the markers, Eden editor has a map view ('M' by default or whatever your in-game map key is; there's probably a button on the interface as well) that makes placing markers easier (there's also a stretch tool for sizing markers accurately). Markers are preferable to triggers for use in external scripts since triggers have unnecessary complexity and overhead; it is also simpler to dynamically create markers and alter/inspect their properties in scripts. The framework isn't updated frequently because it's basically finished; the goal is to provide a robust set of tools for external scripts as well as major systems for common/standard things. Over the years, my style of coding some parts (e.g. remote execution) has become old fashioned; however, everything still works (if not, report it and I'll fix it) and you won't notice when using the functions. I still read all official patches notes for potential incompatibilities and new script commands. With the most recent bug report I'll probably release the accumulated fixes/improvements soon. The documentation talks about this much more, but essentially my framework/library is giving you a large code base and detailed documentation (and my assistance with any errors or questions) for you to learn and script missions with. The more you learn to program in SQF, the more use you will get out of the framework. The first tutorial is showing you how little code you need to create a basic mission; the amount of code will go up from there.
  14. If you place code anywhere in the editor that runs on mission start (i.e. not a trigger), it will run before an external spawning script; at the time it runs those spawned units don't exist. Anything that acts on the spawned units must run after the spawning code; also be aware of the spawning script using 'spawn' or 'execVM', which will run it on another thread. You would end up with something like _units = [...] call <Spawning_Function>; // if you want different positions you'll need a similar loop over the groups/units 0 = [..., _units, ...] call Zen_OccupyHouse; or 0 = [...] spawn <Spawning_Function>; waitUntil { // determine when <Spawning_Function> has finished } // you'll also need another way to get the objects _units = ... 0 = [..., _units, ...] call Zen_OccupyHouse; Any script using the 'buildingPos' command is entirely dependent upon the building being configured correctly. It is possible to generate entirely dynamic positions within a building, but this is more computationally expensive and can result in odd/bad positions. If you want Zen_OccupyHouse to only use part of a group, you'll need to select them somehow (i.e. any slicing/selecting function/command, maybe shuffle/sort before etc.) from the full list, e.g. // pick the first two units 0 = [getPosATL leader _x, (units _x) select [0, 2], -1, true, true] call Zen_OccupyHouse;
  15. To find a good place for a camp, you would use the slope argument (the 10th) to find a flat area, which leaves the terrain height above sea level (12th) argument. You can check the heights of the hills and valleys on the map and set a limiting value that only chooses the valleys; this would include a tolerance above the valley floor based upon their variations. If there is a overall tilt to the terrain (e.g. the valley and ridge elevations are all increasing/decreasing), you'll need to split the region into different areas with their own elevation limit (the number depending upon terrain tilt and the tolerance). Basically, any area in which the highest valley point is above the lowest ridge elevation needs to be divided. Depending on how well this works out, check out Zen_FindNearHeight and Zen_IsHillArea. A ridge looks like a hill on 2 of 4 sides (Zen_IsHillArea might return around 0.5), but Zen_IsHillArea will have a lower value for a valley (assuming the ridges and valley slope up/down equally lengthwise). Zen_FindNearHeight can be used iteratively to find the minimum of terrain (repeat Zen_FindNearHeight in an e.g. 100m radius of each point it finds until the elevation is low enough); this will move from a ridge to a valley, then down the slope of a valley (but not at random) until the minimum is local by the radius used. Once you know you're in a valley, Zen_FindTerrainGradient with a reasonable scan radius will tell you its slope. If the slope along the valley is weak, a large radius might result in errors from the valley walls (they can be asymmetric in slope magnitude), but a radius too small will not reflect the overall terrain features. About the width of the flatter part of the valley (assuming the point is centered in the valley) should work well (unfortunately this varies by valley). As you can see, scanning terrain dynamically is difficult. If nothing's working, placing several dozen preset locations manually and choosing from them is less random (also tedious to port your mission to other maps, if you're planning to do that), but runs faster and guarantees quality placement.
  16. Overview Greetings fellow Armaholics, I am proud to present Zenophon's Mini Co-op Missions (ZMCM). This mission pack is an ongoing project, although the current 'season' is over. The next 'season' will arrive eventually, with new missions to be released in an episodic fashion about every two weeks. The missions are not a campaign or connected as a series in any way; there is no overall story. Each one is a short (10 to 30 minutes) and fairly simple mission with a specific style; they are very replayable. They support anywhere from 2 to 6 players maximum, and are meant to be played by small groups of friends. They are intended to be difficult and require caution and tactics. Features Every mission is different, but the common features generally are: Lots of randomization, such as: Insertion, extraction, and objective locations Enemy skill, numbers, patrol routes, and weapons Weather, fog, date, and time No magically spawned enemies; all patrols are there from the start Fix for ridiculous AI accuracy on dedicated servers; their skill will be the same as in SP or local MP AI skill and numbers scale with the number of players Increased weapon lethality; 1-2 shot kills are now the norm Easy repacking of magazines with an action, taking a realistic amount of time Easily share magazines with teammates for their current weapon No saving, respawn, or revive in SP or MP, to promote teamwork and realism Good performance, whether you play in SP with AI teammates or in MP with friends No mods or addons required in any mission All this is done using my Mission Framework and Scripting Library (shameless advertisement, I know). Missions Currently, there are 14 missions in the pack. Each mission tries to provide a different style of gameplay in terms of difficulty, pacing, atmosphere, and the players' role. Each included mission is listed below with a short description. Abduction A very open-ended, randomized mission in which players must defeat or evade numerous patrols. The mission area could be anywhere across about a 25 square km area. The goal is to capture an enemy officer and get him to extraction. Ambush A simple mission in which players can choose from various means to stop and destroy a convoy of vehicles. The position of the ambush is chosen randomly from five preset locations. Players must contend with armed vehicles and enemy infantry before making their escape. Blackout A stealth mission in which players must evade a few armed guards in a large power plant. Players have the option of maintaining stealth with hand to hand kills or risking a fast assault with just pistols and SMGs. If detected, you'll only have a few minutes to complete the objectives before helicopters and dozens of troops surround you. No one has NVGs or suppressors in this mission. Checkpoint A 'day-in-the-life' mission with a twist, players manning a NATO checkpoint will routinely search a few civilian vehicles before being attacked by various insurgent forces. The checkpoint location, the nature of the attack, the direction of the attack are random. Cleaner A stealth infiltration mission in an urban environment. If you can keep it quiet, you'll only have a few guards to deal with; if you're detected, you'll have the wrath of the AAF upon you. You must search several randomly placed containers in a storage yard for chemical weapons, as well as clear 2 buildings to eliminate the weapon's inventors. After a HALO insertion, you're free to attack the yard however you want; a sniper weapon is stashed on a hill nearby. Convoy A very randomized convoy protection mission. The players must drive the vehicles themselves through various threats, including IED's, infantry ambushes, MG nests, roadblocks, and even APCs. Beware, as the Opfor may choose to attack from the air using paratroopers and helicopters. Lockdown A POW rescue mission with a significant change: the POWs are players. Three FIA guerrillas must rescue two US paratroopers from the AAF. The POWs can free themselves after several minutes, but must contend with AAF guards unarmed; the FIA can also rescue them directly. Either way, the players will then work to complete a secondary objective in the area before retreating. The FIA start location, patrols, and secondary objective are randomized. Pursuit A combined arms mission in which an infantry team and an attack helicopter face Opfor infantry, MRAPs, AAA, MANPADS, machinegun nests, and snipers in a large, random area in the hunt for an Opfor artillery piece. The artillery will randomly move it's position to another large area controlled by these Opfor threats about every 30 minutes. Thus, all your work to clear an area may be wasted, but the vehicle will be very vulnerable as it moves between areas. Raid Inspired by an old TV show, The Rat Patrol, this mission is a procedurally generated, open-ended patrol mission. The players will complete the primary objectives provided as well as any secondary objectives they come across. The entire mission area is populated with random enemy patrols. Players can choose to complete the mission as fast as possible, or spend as long as they want searching the area for AAF activity. Shootout This mission takes a slight detour from the serious, authentic nature of the other missions to bring you a simple and fun shoot-out style mission. You will be fighting with some Opfor over control of a randomly generated junk yard full of objects for cover. This isn't a run-n-gun mission; you'll still need some CQB tactics and teamwork to win. The mission difficulty and arena size scales to the number of players. Silence A special forces infiltration mission with undercover and assault parts. Players must secure an Opfor radio outpost to locate their target and direct an airstrike onto it. The mission offers CQB and urban fighting against Opfor attacks, and randomized patrol areas outside of town to hinder the players' extraction. The position of everything has been randomized, resulting in nearly a hundred combinations of objectives. Specter An asymmetric warfare special forces CQB style mission; players must assault and clear a large building in search of intel. The exact objective location and enemy patrols are different every time. Once they secure the building, players must cross an open area to reach their extraction vehicle. Sweep A sniper-spotter team and an assault team must use teamwork to defeat numerous Opfor infantry and vehicle patrols in an urban area. A random town on Altis will be selected, and players will start at random around it. The number of Opfor will scale to the size of the town; Opfor will receive reinforcements by ground and helicopter. There will be enemies hiding in houses to provide CQB opportunities as well as MRAPs in the town. The Opfor will detect the sniper's fire and employ mortars and vehicles to counter him. Vendetta An atmospheric sniper mission that makes players choose between trusting their sniping accuracy or risking a closer shot. A tense opening sequence is followed by an open-ended objective in which players must eliminate a target while working under a time limit. Coming Soon Well folks, I've run out of ideas for mini missions; I don't want to do missions that just repeat the same thing with slight variations of location or objectives. Thus, I'm going to stop releasing new missions for now. I'll put it as 'Season 1' is over and I've got 14 'episodes' to done, and I really want to do a 'Season 2' at some point. If anyone has some good ideas for an interesting new mini mission, I'd like to hear them and include them in the next round of mini missions. Of course, I'll still support the current missions in the pack with bugfixes and improvements. For now, I've got mission ideas that require more than 4-6 players, and I'd like to do some interesting missions for larger groups of players. Download Each mission is a separate .pbo, and all of them are packaged in an archive you can download below. Google Drive: https://drive.google.com/file/d/0B-QFvxyAVKTUQmZ0MllyN014TVE/view?usp=sharing Installation Copy the .pbo files from the .7z archive to the Missions or MPMissions folder in your ArmA 3 install directory. This is by default at (Windows 7) C:\Program Files (x86)\Steam\steamapps\common\Arma 3. All the missions can be installed and played separately; they are not connected in any way. Changelog Feedback Any feedback about the missions is welcome, particularly about their difficulty and replayability. Obviously, if you find any bugs or issues, I would like to know. Either this thread, PM, or email is fine. Contact the author: ZenophonArmAFramework@gmail.com Legal These missions are released under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) http://creativecommons.org/licenses/by-nc/4.0/
  17. Having to restart the mission has been an issue for a while; the first time the mission is run there is a varying delay in the server sending messages to clients. Having the admin use #restart in the console once the briefing is loaded will fix it. As far as I can tell this is due to some quirk of dedicated servers that only BI can fix. The radioman is chosen at random from all Opfor that aren't in a vehicle. I was a bit lazy and didn't give him specific equipment; he might be patrolling the streets or in a building. I think the radioman concept was meant to make the mission a little easier by having an increasing chance of stopping the mortars as the town is cleared; the difficulty of the mission is meant to decrease as players eliminate Opfor vehicles and reinforcements and secure more of the town.
  18. Zen_FindGroundPosition does not account for the size of buildings, rocks, etc when avoiding them; it treats them as point objects. This is done for efficiency, since using sizeOf (or even worse using boundingBox and then getting the rotation/orientation of the box) for every object will add another nested loop over all nearby objects (and that's assuming sizeOf/boundingBoxReal are correct for all static terrain objects). Currently the code finds all objects of a certain type within the given radius from a point and just counts them. This means that the avoidance distance must account for the size of the objects you are trying to avoid, e.g. if we estimate roads to have a width of 5 meters, buildings a radius of 15, and large rocks at 10, that can be added that to the size of the object you're trying to fit private _carPos = [_x, 0, [], 1, [3 , _objsize + 5], [0,360,'compass'], [1,0,_objsize + 15], [0,0,0], [0,0], [0,0,-1], [1,[0,0,-1], _objsize + 10], [0,0,0],0] call Zen_FindGroundPosition; You can tweak those tolerances for a certain map/area. It may also be helpful to use blacklist markers to remove any difficult areas (e.g. very large buildings, a very dense city, etc.); that will probably speed up the search as well (it's faster to find if a point is in an ellipse/rectangle than to check for nearby objects, particularly for larger avoidance distances).
  19. The 'MAP' control of the dialog system is essentially the same as the 'real' map. Thus, it functions and responds as the real map does. You can use 0 = ["Dialog_Map_Click", "onMapSingleClick", {Map_Pos = _pos}, []] call BIS_fnc_addStackedEventHandler; once at the beginning of the mission. When you prompt the user to click: Map_Pos = 0; waitUntil { (typeName Map_Pos == "ARRAY") }; _local_Map_Pos =+ Map_Pos; You would then use the local copy of the position in your code. This ensures we are using the correct position for that click; you can run multiple functions in parallel that are storing and using different click position instances (assuming the waitUntil of each does not run concurrently). If you need to prevent input from the real map, you can either remove the stacked EH with a BIS function or have your functions check that your dialog and map are open rather than the main map.
  20. First, did you put the framework code in the mission folder (I know this sounds ridiculous, but I have to start here)? Which mission(s) in particular don't work for you? As killick says, some (at least 'Airbase Assault') require two or more people. I picked one at random ('Clean Sweep') and didn't see any issues. Do the missions work in the editor? If it doesn't work there, it's certainly not going to work in MP. Do you have '-showScriptErrors' (or the launcher's equivalent setting) enabled, or are you checking the .rpt logs for script errors? These sample missions are fairly old and there might be a compatibility issue with the latest framework code.
  21. 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).
  22. 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.
  23. Overview This script generates a randomized, urban-like area using the new generic VR structures. It is a simple implementation, and it is mostly meant for arena-style PvP missions or CQB practice vs. the AI. You can use this function to quickly have fun in the editor, or generate a complex VR city block by block. The function uses a grid system to evenly distribute large structures and small cover objects. It uses a rectangular area marker to define the boundaries of the area. The size of each grid, each of which contains one large structure, and how many smaller objects there are per grid are entirely customizable. Each object is randomly placed and rotated within the grid. The function is very fast, generating large areas in less than a second, and it can be used as many times as you need. There is no debug, argument checking, or defensive code, to make it as simple and fast as possible, so make sure the arguments are correct. Download Google Drive: https://drive.google.com/file/d/0B-QFvxyAVKTUcDJBMFBacnRxdUU/edit?usp=sharing Usage Place the script somewhere in your mission folder Function parameters: String, an area marker Scalar, the grid size in meters, each grid gets one large structure Scalar, count of smaller VR objects, each grid gets this many The complete documentation is also commented at the top of the file You can run it from anywhere with execVM, example: 0 = ["marker", 25, 6] execVM "Zen_GenerateVRArea.sqf"; You can also compile it into a function if you plan on using it many times Zen_GenerateVRArea = compileFinal preprocessFileLineNumbers "Zen_GenerateVRArea.sqf"; 0 = ["marker", 25, 6] call Zen_GenerateVRArea; Changelog 7/15/14 7/14/15 Known Issues When using a small grid size or small marker, some of the large buildings can overlap each other. The only way to fix this is to prevent them from rotating. Using a reasonable grid size should mostly prevent this issue. There are only 5 big VR structures and 5 little VR objects right now, so it could get a little repetitive. There's nothing I can do about that unless BIS adds new objects, as I have already may every effort to randomize things. Feedback If you liked/disliked it or have any suggestions for improvement, I would like to hear your thoughts. Either this thread, PM, or email is fine. Contact the author: ZenophonArmAFramework@gmail.com Legal This software is released under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0). http://creativecommons.org/licenses/by-nc/4.0/
  24. 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.
  25. 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).
×