Jump to content

Zenophon

Member
  • Content Count

    530
  • Joined

  • Last visited

  • Medals

Everything posted by Zenophon

  1. Update and Release #34 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 Here we have the next weekly release in support of the new dialog system. Every change is for this system, including five new functions, events for lists, and new and improved properties for controls. There are now copy and remove operations for both dialogs and controls. Those copied controls and dialogs are entirely independent of their source. Removing a control will not unlink that control from existing dialogs, you must do that manually. To support list events, there are now 2 (and the potential for more later) types of event functions. 'ActivationFunction' is exactly the same as 'Function' for buttons; simply copy-paste the new property name. In addition, 'ActivationFunction' will fire when a list box element is double clicked on. 'SelectionFunction' applies only to lists, and will fire when an element is clicked. It will also fire when the dialog first displays (on the first element), and twice when double clicking on an element. If you assign both types of events to a list, you must handle those extra events in your functions. The property previously called 'TextColor' is now 'FontColor'. To standardize things, everything relating to individual characters (size, font, color, etc.) is font formatting; anything related to a text block (text, alignment, etc) is text formatting. Also, 'FontSize' is now scaled so that standard point font sizes can be entered; 12, 16, 20, etc. should be fairly close to those pt. fonts. It is not longer necessary to link controls to themselves; a control's event will be given that control's 'Data', the 'Data' of all linked controls, the 'ListData' of the selected element of all linked lists, and the 'ListData' of the control's own selected element (if it is a list itself). This should provide better support for list events and dialogs with multiple lists. Remember, event data is passed in the order that controls were linked, with 'Data' before 'ListData' for the same control. I have discovered an odd bug, in which the selectable line on a list never goes past the seventh item down. This is described in the KnownIssues.txt file as well. This does not prevent any elements from being selected, as the list will just scroll into some empty space. This is mostly an aesthetic bug and there is no clear fix. Next week, I'll be adding selective control refresh to reduce menu 'blinking' on refresh and improve performance for complex dialogs, a dialog to select fire supports added with Zen_AddFireSupportAction, and more control properties for tooltips and colors. 9/17/15
  2. Zenophon

    [COOP-6] Evade and Survive

    Update Overview Greetings fellow Armaholics, I have updated this mission to use my latest framework. All changes are a result of framework improvements. Changelog 9/14/15 Improved: Various improvements and fixes included in my latest framework
  3. Zenophon

    [COOP-8] Black Ops

    Update Overview Greetings fellow Armaholics, I have updated this mission to use my latest framework. I have also added three new objectives to the mission. All three map versions have been updated. Changelog 9/14/15 Added: Opfor helicopter crash site objective Added: Abandoned mortar position objective Added: Rescue civilian objective Improved: Various improvements and fixes included in my latest framework
  4. You mean you can't follow the steps in the tutorial, or you don't understand the point of the framework? The tutorials are guiding you through how to do something, so you can see what the effect is and what's possible. It's like following any walk-through or guide; it tells you exactly what to do so that you can see that effect in-game. The idea is that users see what is happening and learn what functions to use to do that. It's not necessary that you 100% understand everything that's going on; the point is that you can create some effect in-game with just the basics. The framework is essentially a toolbox; every function is a tool. You need to use those tools on raw materials (arguments) to get some effect. Then you use the tools one after the other to build upon their effects. The first tutorial shows you that with four functions, you can create a basic playable mission. There are now 192 functions and 87 macros that each serve a purpose as a unique and useful tool. The mountain of documentation is a user manual so that people can use these tools. What the tools do and how you use them are designed to make mission-making much easier for anyone who invests the time to learn them. This is a 'packaging' of functions into a higher-level function, which is of course doable, but it doesn't match the level of the dialog system. If each function was a unique dialog, there would be hundreds of them. I've chosen to include less in each function so that more are required to create a dialog; however, the functions can create hundreds of possible dialogs. You're free to create 'wrapper' functions like that and use them; that's good programming if you repeatedly use this dialog. I just can't do that for every possible dialog, so I leave it up to mission makers what dialogs they want to wrap into a function. Here's what you're describing, but it's up to users to make this sort of thing into a function (I'll help if you ask). That shows another feature, controls can link to their own data.
  5. Update and Release #33 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 special release brings an Alpha release of the new Dialog System. Remember, 'Alpha' means that many features are missing; I have many additions and improvements planned, but feel free to suggest more. You may encounter bugs, issues, and limitations; just report them to me and the system will benefit. The dialog system is a 100% scripted approach to creating dialogs in-game. I used only the UI classes provided in vanilla ArmA and an empty dialog class as a host for dynamically created content. I know almost nothing about writing traditional dialogs in ArmA; I barely managed to create the loadout dialog in the framework using the BI wiki. However, I can now make dozens of different dialogs of any complexity using this system. I have abstracted everything about dialogs so that users don't have to deal with the countless lines of property setting required for traditional dialogs. Dialogs and Controls are now 'objects' that are assigned 'properties' and trigger 'events'. You can display controls by linking them to a dialog; you can pass arguments ti events by linking controls together. Finally, I gave all the properties a sensible name and sufficient documentation, so you don't have to wonder what 'period = 1.2' is on a traditional dialog. Instead, you use 'Position', 'Size', etc. in an intuitive way. Traditional dialogs expect you to know what types and styles to use; my dialog system has "Button", "List", and "Text" (more will be added). The point of all this is to make it much faster to create a dialog, and then be able to read and maintain that dialog code. To expand upon the control type, control property, and function documentation, a new tutorial incorporating and simple but useful dialog into a mission is included. I have also provided a slightly longer example in the Spotlight section of this post. If you have any questions or want further examples, just ask. Planned for next week are generic events from lists, data copy/remove operations on dialogs and controls, and unlinking controls. I'll also be slowly adding every property and type of control that's possible to script. 9/10/15 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 release I spotlight a function and talk about its usefulness. If you have found an obscure function (not in tutorials, barely seen in demonstrations or sample missions) that you think is useful, PM me and I can spotlight it. The functions chosen for this release are: The Dialog System. I have attempted to document this new system as completely as possible; however, I cannot imagine every possible question or concern that may arise. Thus, since the dialog system is a visual effect, I give you an example to experiment with: This code contains the three types of controls currently offered and most of the control properties. It shows you the basic steps to create and display a dialog. It doesn't actually do anything, but I'll leave it up to you to do something clever with it.
  6. "Argument 2 contains a wrong type" is an argument checking mistake; a number was not being allowed in the second argument. That will be fixed next release; for now 'Zen_Debug_Arguments = false;' will get you past it. Zen_SpawnAmbientVehicles is populating town based upon the markers returned from Zen_ConfigGetLocations. That should be fixed indirectly, but I'll test it to make sure.
  7. This is a failure of Zen_FindGroundPosition in this configuration or similar: _pos = ["<AreaMarker>", 0, [], 1, [1, 100]] call Zen_FindGroundPosition; All road points were rejected as falling into the minimum area (0 here). The mistake is this: ([_nearestRoad, getMarkerPos _area, [_min, _min], 0, "ellipse"] call Zen_IsPointInPoly) is not equal to this: ([_nearestRoad, _area, [_min, _min], 0, "ellipse"] call Zen_IsPointInPoly) Zen_IsPointInPoly will ignore those extra arguments when _area is an area marker. The maximum geometry is the area marker, the minimum geometry is a circle of the minimum radius. Road selection must obey both constraints properly.This fix will be in the special update this Wednesday which includes the release of the new Dialog System.
  8. Update Overview Greetings fellow Armaholics, this release adds ports 3 missions, Abduction, Pursuit, and Raid, to Chernarus and Takistan. Slight modifications have been made to accommodate these maps, mostly involving their smaller size and not being surrounded by water. The objectives, patrols, etc. are exactly the same. They also benefit from all changes included in my latest framework release. I'm going to continue porting missions to different maps, mostly Chernarus and Takistan, but possibly Zargabad for some missions as well. Changelog 9/4/15
  9. After skimming through the ASR AI source code, here's what I can see. ASR AI is compatible with spawning AI through scripts during the mission. It will automatically detect any spawned soldier that is a subclass of: SoldierWB, SoldierEB, and SoldierGB (use 'isKindOf' on an object if you're not sure); then it applies the skill changes and everything else. ASR AI does not give AI groups waypoints, so it has no conflict with any framework Zen_Order... function. However, every spawning function that spawns AI, except Zen_SpawnGroup, uses Zen_SetAISkill to set their skills. Whichever function makes the skill changes last will win out, so it just depends upon the timing. To avoid a conflict and use ASR AI's skill settings, you can only use Zen_SpawnGroup to spawn AI. That excludes Zen_SpawnAircraft, Zen_SpawnGroundVehicle, Zen_SpawnHelicopter, Zen_SpawnBoat, Zen_SpawnVehicleCrew, Zen_SpawnConvoy, Zen_SpawnInfantry, Zen_SpawnInfantryGarrison, and the 'officer' and 'pow' objectives of Zen_CreateObjective. Your best option is to find and comment out every usage of Zen_SetAISkill in the framework. That's not as bad as it sounds, as most of those function don't call Zen_SetAISkill directly. Just put a // at the beginning of the line given for each file: line 39 in Zen_ObjectiveSystem\Zen_SpawnOfficer.sqf line 40 in Zen_ObjectiveSystem\Zen_SpawnPow.sqf line 70 in Zen_SpawningFunctions\Zen_SpawnInfantry.sqf line 150 in Zen_SpawningFunctions\Zen_SpawnVehicleCrew.sqf That will remove all AI skill changes from the framework. You're free to use this (or any) altered version of the framework as part of any missions you release.
  10. Update and Release #32 Introduction Greetings fellow scripters and Armaholics, in this latest installment, I will continue to discuss the development of the framework and, of course, shamelessly advertise the framework in any way possible. If this sounds boring, you can download the latest version from the original post. As always, the links to Google Drive for the .7z and .zip versions are already up to date. For those looking for older versions, go to file>revisions. The new version will be on Armaholic soon. Please bring any technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc. Changelog Another month, another Wednesday (depending on your time zone), another framework release. This release brings a host of changes to the patrol functions, including multiple patrols areas and the full Zen_FindGroundPosition blacklist/whitelist argument. All of them, Zen_OrderAircraftPatrol, Zen_OrderBoatPatrol, Zen_OrderInfantryPatrol, and Zen_OrderVehiclePatrol, can be given an array of patrol markers/points, an array of black/white lists, and an array of limited angles. When giving multiple patrols areas, please refer to the documentation (I tried to make it as readable as possible) and remember that when using multiple areas the patrol size/blacklist and limited angles arguments are not optional (use [] and 0 to skip). Also, the black/whitelists and patrol area sizes must align with their respective area in the previous argument. I didn't do a function spotlight with any examples of this, so just post or PM me if the documentation is unclear. Current usages of these functions are unaffected by the multiple areas change; however, they are affected by the new AI behavior parameter. Check your optional arguments for patrol functions. Zen_OrderInfantryPatrol already had this parameter, but now all of the patrols functions can use it. The former blacklist is the full whitelist/blacklist parameter; this is being passed directly to Zen_FindGroundPosition and works in the exact same way. Zen_OrderVehiclePatrol also has parameter for road positions; false means ignore them entirely. Zen_FindGroundPosition's handling of road parameter type 1 (prefer roads) has been optimized. The function will check if the nearest road is within the geometric area before selecting it. No other roads will be checked for performance reasons. Larger road search distances will decrease performance; they need only find 1 road. Road parameter types 2 and 3 (require and avoid) are unaffected. Continuing with the theme of roads, Zen_FindRoadDirection now prints out a full stack trace if there is no road within 50m. You can disable this (along will all argument checking) with Zen_Debug_Arguments = false;. Zen_OrderVehicleMove now detects helicopter and planes and changes the completion radius accordingly. The goal is the have the function complete execution while those vehicles move over their waypoint. This should help with chaining helicopter waypoints without stopping. Of course, the distances themselves may need to be tweaked. The framework's header has slightly changed its JIP detection check. This sounds minor but may have unforeseen effects. To be technical, the test of 'player == player' is now 'local player'. The motivation is that establishing locality is done later than defining 'player' and is very important. Please report any issues, bugs, or oddities you find with JIP that may be due to this. 9/2/15 Roadmap An early version of the new dialog system didn't make it into this update. The issue not a lack of coding, but of coding with the correct design. The style of the API (functions and their arguments) I present is very important and, in my opinion, one of the greatest strengths of the framework. The system must be as intuitive and usable as possible, with few special cases or 'that's complicated' solutions. Then the code behind the design must support it with enough foresight to be generic and extensible so I can add features later. I'm planning on making a special release in about a week with an early version of the dialogs. The initial features will include buttons, text boxes, and lists. You'll be able to 'hook' a button to a list and get arguments from it. Refreshing and closing of the dialog with be provided for you. It will probably come with it's own demonstration(s) at first, but possibly a sequence of tutorials later. Many features will not be included at first, but almost everything that's possible (and useful) will be added eventually.
  11. I don't really see many buildings in the editor, so I'm assuming it's equivalent to spawning them with createVehicle. Once the building is detected, it's preset positions will be accessible, so it's just a matter of getting the object. Did you try the fill radius argument as e.g. 50 or so meters? This will make the script use the nearestObjects command; using -1 will have it use nearestBuilding, which might be where the issue is. nearestObjects is working for me; try this in the debug console with a spawned building. buildingsArray0 = nearestObjects [getPosATL player, ["house"], 50]; buildingsArray1 = nearestObjects [getPosATL player, ["building"], 50]; hint str (buildingsArray0 arrayIntersect buildingsArray1) This is basically what the script uses; it just replaces the position and distance with its arguments. I can replace nearestBuilding when using '-1' with nearestObjects and just select the first one; but then I'd have to figure out a distance to search in that not inefficiently large or too small to find anything.
  12. You tried the simple test init I post and you still get a performance drop? That could be a hardware issue on the server. If it accepts an array of markers, it must accept an array of blacklist arrays, which isn't that bad. However, you get the same functionality with the whitelist for a small lost of efficiency and can use both the blacklist and whitelist together to makes shapes. So I'll just do both, as well as make sure it doesn't break current usages of the function. All patrols functions will get these improvements. Zen_OrderVehiclePatrol prefers roads and will usually find one. Using setBehaviour 'combat' will make them ignore roads, but the function will set them back to 'aware' for every new waypoint. I can just make roads or no roads a boolean and add a parameter for behaviour for all patrols functions (Zen_OrderInfantryPatrol already has that).
  13. Thanks, since they're interchangeable, I won't worry which map pack addon I compile with. I'll probably be done with some of the faster ports to several maps in about a week.
  14. pushBack vs. Zen_ArrayAppend is nearly equivalent; Zen_ArrayAppend just allows more arguments (like a loop of pushBack commands). 'spawn' and 'spawn' will give Zen_OrderVehiclePatrol vehAirbaseArray before it's been populated. If you wanted spawning in a separate thread: Or if you're repeating the spawning loops, which I think you're describing, something like (this is pseudocode now): as spawning many vehicles at random positions can take several seconds; Zen_OrderVehiclePatrol (or really Zen_ConvertToObjectArray) will copy the given array and not use any updates you make to it. So long as spawn one patrol thread (for all patrols functions), the performance impact will be the same. As I say, spawning and the initial assignment of waypoints will be a FPS dip, but things should be smooth after that. At 10 sec interval, even 10 Zen_OrderVehiclePatrol threads wouldn't have much performance impact. They're only calculating positions when a vehicle stops (which tends to happen at different times for every vehicle).
  15. The performance impact should be nowhere near that much. You'll see a decrease at the very start of patrolling, as it has to calculate waypoints for 30 vehicles. After that, it handles whatever vehicles have stopped at 10 second intervals. If the vehicles don't all start moving right at the beginning, it's having troubling finding good positions. The first thing I found in testing this is that Zen_FindGroundPosition is not handling road positions properly. It allows the road chosen to be outside the area, which is only an issue there are no roads in the area, but some right outside of it. The Airport does have roads around it, so I don't think this is your issue. I put together this test mission to see what I reproduce; it will also make sure that nothing else in your mission is responsible. All you need is a new mission with a player (object 'X') and a marker ('mkPatrol') anywhere on Altis (except the desert with no roads, I'm working to fix that). I made 'mkPatrol' a 600x600m square, as that nearly covered the airport; the angle and size of the marker should make little difference. On a dedicated server, use '#monitor 1' and watch the FPS; the mission will tell you which stage it's in. When I ran it, I saw the expected FPS drop for spawning the cars and when starting the patrols, but it remained at 49-50 the rest of the time. The vehicles should also respond promptly to the move commands when a thread starts. As for patrolling multiple areas, I see how having the number of vehicles in each area change dynamically would be good. Currently there's only one documented way to do this using 1 thread, that is blacklist markers. Using a single large marker and then blacklisting areas using many other markers will work. The issue is that it can be tedious to place the blacklist markers so that you get the shape you want; it also decreases performance as the number of blacklist markers grows. An easy way to do this would be to give the patrol functions the full blacklist, whitelist, whitelist parameter for Zen_FindGroundPosition. It's actually already possible to do this, but isn't allowed by the patrol functions' argument checking. All I have to do is allow [[], ...] formats for the blacklist and change the documentation to tell people this is possible. You can use a single large marker, and the 'one' whitelist (the point must be in at least one of the markers). This could be inefficient if the markers are very far apart, but then the patrolling units would have a long way to go between them, so it's up to the mission maker to use it in a sensible way. If you've disabled argument checking, you can try this right now.
  16. After testing and having it work in SP, I realized I didn't recompile all the missions for this release. The V12 everyone downloaded is V11 missions with the added Convoy mission; I didn't include the updated .pbo's for the other missions. I've uploaded the true V12 to Google Drive, and it should be on Armaholic soon. The compile dates on all the .pbo's should now be 8/24 (today) not 8/8. Sorry about that. As for a Chernarus or any other map version, some of the missions could be converted fairly quickly and others would take some time. Abduction, Convoy, Pursuit, Raid, Sweep, and Vendetta could be ported fairly quickly. Others (Ambush, Checkpoint, Silence) where things are selected from presets require placing those markers in good places. Then some are fairly map dependent; Blackout, Cleaner, and Specter won't work if a map doesn't have an similar area. Finally, porting Shootout is pointless as it's generating it's own playable area. What I would would like to do is use a single, inclusive map pack as a requirement, then port them to whatever maps make sense (most for e.g. Abduction, but fewer for Blackout). So, if Cleaner doesn't work on e.g Chernarus, maybe it could be ported to Takistan, etc. Thus, I think it's between these two: http://www.armaholic.com/page.php?id=23863 http://www.armaholic.com/page.php?id=26682 I've never tested if those are interchangeable (e.g. mission compiled with AiA map works with A3MP); I'll test that. Obviously, if they're not, I want to pick the one with the most active users and least bugs, to make it easier for people. If anyone has reasons why one is preferable to the other, let me know. If there's another map that's supported by those (Fallujah, etc.) but not included directly, people can request a mission be ported to that map.
  17. It won't save even once; no 'Save and Exit' button either? Just put this in the debug console and click local exec. enableSaving [true, true]; Maybe I turned on auto saving instead of manual saving...I was sure I saw 'Save' appear in the editor.
  18. Update Overview Greetings fellow Armaholics, this release adds a new mission, Co-6 Convoy, to the pack. It gives players a convoy of vehicles to drive to a destination. As I cannot control which route players will take, all possible roads will be covered by some threat. The number of threats and convoy size will scale with the number of players. Thanks to some user feedback, Silence puts more responsibility on the players to follow the mission plan correctly. Thus, you can now play the entire mission with your scuba gear if you'd like, but it will be easier if you follow the plan. The mission no longer waits for everyone to be ready, so use teamwork instead of running ahead or leaving people behind. Sweep has received a mortar overhaul; I've tried to make them less psychic and annoying and more of a realistic challenge. The mortars themselves fire less frequently and can run out of ammunition, and their detection of the sniper/spotter has been improved. Every shot decreases the AI's uncertainty of the shooter's position, but if the sniper/spotter has moved significantly, the AI are once again unsure. The mortars will not fire on the town itself, to prevent possible friendly fire. Finally, a random Opfor soldier has been designated the radioman; killing him will stop the mortars. However, you don't know who he is or if you've killed him or not. Specter's insertion helicopter cargo has been tweaked; those parachutes were useless anyway. Lockdown now allows hand to hand kills by the POWs on the guards patrolling outside; it's a great way to get free and grab a gun if you can do without being shot. Changelog 8/21/15 Roadmap 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' 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.
  19. Which mission has militia with scopes? Only about 1 out of 20 of them should have that; they're all using presets with almost only CCO's. Their skill varies with the number of players; I don't designate one enemy group as militia, one as SF, etc. It's done overall for the mission. I just tested the MH-9; each parachute is taking up about 1/6 of the space. A rifle is about 1/10, and magazines and grenades about 1/100. I'll clear the parachutes and anything else useless from the inventory; that should leave enough room.
  20. I'm actually a college student (physics major). I do various programming and computer stuff for fun. Zen_SpawnInfantry, Zen_SpawnInfantryGarrison, and Zen_OrderInfantryPatrol work fine with civilians. So spawning them looks a lot like other spawning code: _civGroups = []; for "_i" from 1 to 10 do { _pos = [_mkTown] call Zen_FindGroundPosition; if (random 1 > 0.5) then { _group = [_pos, civilian, 0, 1] call Zen_SpawnInfantry; _civGroups pushBack _group; } else { _group = [_pos, civilian, 0, 1] call Zen_SpawnInfantryGarrison; }; }; 0 = [_civGroups, _mkTown, [], 0, "limited", "careless", false] spawn Zen_OrderInfantryPatrol; Civilians may freak out and run away when they see combat. If you don't want that, you can spawn them as resistance, make them captive, and give them civilian clothes. Also, the Co-6 Sweep mission from my ZMCM pack has a lot of stuff like this with civilians. All the functions work anywhere after they are compiled at the start of the Init.sqf. Basically anything called from the init.sqf or editor after the mission gets past the briefing (not editor init fields). There's also the issue with unscheduled execution, see the FAQ.txt answer about that if you're using eventhandlers. For more detail: https://community.bistudio.com/wiki/Initialization_Order I discourage the use of editor triggers because they are very hard to maintain/debug. You could use a framework function from an editor trigger activation, but not as it's condition (triggers run before the Init.sqf). What is the equivalent of an editor trigger in SQF is something like this in the Init.sqf (or any script): 0 = [] spawn { waitUntil { sleep 2; (condition) }; activation }; Why is this better? First, I can set 'sleep 2' to any number I want, so checking every 30 seconds or every frame (remove sleep entirely) is possible. Editor triggers always check per frame (that is rarely necessary).Second, you can pass arguments to spawn that have been returned by previous function calls; e.g. compute a random position and wait for the player to get there. An editor trigger would need that random position to be a global variable computed before the mission began (some pre-init script). Third, I can start and stop this SQF code at any time. Just assign it to a function and spawn or terminate it's thread at will. You can create a trigger from SQF code, but then you might as well be typing waitUntil instead of createTrigger. Sorry for that rant; as for your code, yes, you can put that in a trigger activation (might want to make it a function and call it there) or below a waitUntil loop. The kind of trigger you use will not impact how your code works. Using the spawn/waitUntil method will allow you to pass arguments to the code though; I always find that much clearer to read that using global variables (which you're not using there so...).
  21. Thanks for your appreciation; I always value feedback. Feel free to be as critical as you want; I like as many details and suggestions as possible so I can fix/improve things. I just realized that the debug console shows up in SP, so I can't really play the realism card about saving (there's also teamswitching). I always say that saving can break running SQF scripts, which is only true for unserialized scripts (by default they're serialized) that do GUI stuff. I'll enable it in SP and if it breaks anything, hopefully players will report it. They can always run a local LAN to get a MP environment. The gear box in Silence is a sort of checkpoint to keep players organized. However, now that you mention it, there not really necessary to force players into the exact plan I had in mind (which is based on a real SF mission just with a different main objective). With actions, those decisions are now optional, so if users want to play the whole mission with the SDAR, swim to extraction without a wetsuit, etc., that won't break the mission (obviously following the plan would be easier, but not forced). I'll also make the extraction boat and driver captive/invulnerable to make sure he's there. The lack of binoculars, scopes, etc. are meant to make the missions harder. With only eyes and ironsights/1x optic, spotting requires patience and sniping the AI at 500m with a 4x scope isn't an option. A few loadouts might give binoculars at night, if I didn't do detailed, custom loadouts for the mission (I have a lot of presets I use for standard infantry). The night missions are meant to be even slower paced and cautious. In Specter, the loadout gives the correct 30 round 0.45 magazine, but the wrong 11 round magazine is loaded into in the helicopter. I'll tweak the extra stuff in the helicopter as well, I guess the game thinks it can't hold very much.
  22. I can add a condition that about 90% of the Opfor are dead will complete the mission, in addition to clearing the town. Thus, if the Opfor leave the town, but you haven't killed 90% of them, the mission will still complete. The mortars are intentionally annoying, but I can give them a realism overhaul. Adding a spotter or the mortars themselves to the town (and thus a way to stop them), more time between firing, more random inaccuracy of where they think the sniper is, limited ammunition, more realistic detection of the sniper (based upon distance, kills, etc.), and no detection/firing when the sniper is in the town. I'll test what all that does for the sniper, and maybe add something else to hinder him, as well as apply the detection logic to the spotter. If they split up, they'll each have a chance of being fired on or hunted down if they're detected.
  23. Update Overview Greetings fellow Armaholics, this release adds a new mission, Co-4 Raid, to the pack. It places the players in armed FIA trucks on patrol in a large area of AAF activity. There are many objectives of opportunity to be found. Due to the very random procedural generation of the mission, it will take about 60 seconds of time in-game before all playable content has been created. Thanks to some user feedback, Blackout now has a reasonably large explosion for the players to see as they escape. Due to the rather weak flares, the AI now receive a spotting skill bonus once the alarm has been triggered. That should help them put up a better fight instead of just running around randomly. Also, if the mission is played in SP, the player now has command over all the AI. The insertion and extraction in Silence have been tweaked. All the players are now required to actually get in the boat to complete the mission. I said something about an SDV earlier, but using the boat makes more sense (I could switch to an SDV for insertion, but it's just aesthetics). The point where the boat stops to drop off and pick up the players has been moved closer to the shore. This should result in less time wasted swimming as well as provide a more realistic ending. Changelog 8/8/15 New Mission: Co-4 Raid BlackoutFixed: All friendly AI are added to the player's group in SP Added: Explosion for planted bombs once the players are far enough away Tweaked: AI now receives better spotting skill after the alarm has been triggered SilenceImproved: Players must now swim to the boat for extraction Tweaked: Distance to swim to and from the boat decreased
  24. The Init.sqf template is to help scripters with locality, order of execution, and make sure they're using the framework functions as intended. The titleText is optional, but the others are not. Again, I really recommend reading at least the topmost readme.txt file and starting with the tutorials; their goal is to teach how to setup the framework and use its functions (other documentation will help with more advanced scripting using the framework). The 'call' command is used to run code that already been compiled into a variable of type 'code' (it's an official type). execVM is used to compile a script (.sqf file) then run the function (compiled code). The framework compiles its many functions like so: Zen_ArrayAppend = compileFinal preprocessFileLineNumbers "Zen_FrameworkFunctions\Zen_DataFunctions\Zen_ArrayAppend.sqf"; So that they are preprocessed and compiled only once, then you can use call or spawn on that variable (hence no .sqf ending) to run them: 0 = [_array, 12345] call Zen_ArrayAppend; This is simply more efficient than execVM (which recompiles every time) and makes the framework a more professional-looking API. Call also allows the function to run in a lower scope, which is preferable in many cases (I'll stop there because you asked for layman explanation).0 = ... is technically incorrect (can't assign to literal), but allowed if the function explicitly returns something (even void). It's just to improve code readability and '0' is faster to type than 'null'. None of these will cause an error: 0 = call {(1)}; 0 = 1; 0;
  25. Update and Release #31 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 The release brings several minor fixes and any improvements I've thought of in the past few weeks. The main addition is a new function, Zen_GetUnitFireSupportActions, which provides better management capability for the fire support actions. It functions just like Zen_GetUnitTasks. Hopefully, all of the locality issues in the fire support action system have solved with this final fix to Zen_AddFireSupportAction (and is private helper functions). Zen_AddFireSupportAction also has a cancel action feature implemented. This action appears automatically whenever a fire support is used. Cancelling a fire support does not return a usage, so cancelling your only use of a support will waste it. The cancel button exists as an emergency abort to prevent friendly fire, not because the fire support will miss and you want a do-over. Zen_OrderVehicleMove had some confusion about who is unitReady when a move is complete. Some vehicles may have only the driver, the commander, or both changing their ready status. This also affects Zen_IsReady, but that function is unchanged. If this fix works for all vehicles, there's no need to spend time figuring out the details of which vehicle behaves which way. Zen_StringGetDelimitedPart is now significantly more robust, as the delimiters can now be any arbitrary string. Otherwise it functions as before; Zen_StringGetDelimitedPart is the subject of the function spotlight this release, so look there for examples and more information. In order to improve wounding realism, I thought of a simple addition to Zen_MultiplyDamage. It now increases the unit's fatigue based upon the damage received. I think the decrease in movement speed and aiming ability provides a much better simulation of the injury/adrenaline/shock/fear of being shot. The amount of fatigue added can be tweaked, so feel free to give feedback (as always). Finally, Zen_FindGroundPosition now uses the worldSize command as a backup if the world is not found in the preset list. This should allow compatibility with any addon map. Note, the entire map is only used when an area marker or point and distance are not given in the arguments. 8/5/15 Roadmap I said a while ago that a new, large feature additions to the framework are a possibility. The feature I can now announce is a framework system for dialogs. I'm aware that there are many tutorials and templates for dialogs out there, and a lot of mission makers have their own dialogs they're familiar with. However, I intend to offer a completely new style of creating and managing dialogs that doesn't require creating/editing description.ext classes or any of the research/knowledge required to do that. Instead, the dialog system will mimic a real programming language's GUI library. It will offer dynamic creation of dialogs using framework functions, object-oriented management of dialogs, and event-driven UI actions. The goal is that almost any UI design can be implemented quickly and intuitively using the functions and documentation I provide. Then, the function of the buttons, content of lists, etc. will be events that the mission maker writes function for. I intend for every mission maker to be able to design, create, and display as many dialogs as they want to enhance the usability and presentation of their mission, all using just this new addition to the framework's API. 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 release I spotlight a function and talk about its usefulness. If you have found an obscure function (not in tutorials, barely seen in demonstrations or sample missions) that you think is useful, PM me and I can spotlight it. The function chosen for this release is: Zen_StringGetDelimitedPart. This function achieves the same effect as it has always done; however, it now can use any string as a delimiter. First, a simple example of how the new arguments work: player sidechat str (["(1)", "(", ")"] call Zen_StringGetDelimitedPart); These these examples are formatted as print statements so you can try them out. That example was possible with the old version of Zen_StringGetDelimitedPart; I've just split the delimiters into two different arguments. Next, an example of the new feature: player sidechat str (["ab12345cd6789", "ab", "cd"] call Zen_StringGetDelimitedPart); The delimiters and string or just arbitrary test values for now. One more test example: player sidechat str (["ab12345", "ab", "cd"] call Zen_StringGetDelimitedPart); If the end delimiter is not found, everything past the start delimiter will be returned. Now for a discussion of why this is useful.When you want to store a lot of information, the go-to data structure is an array. You've got the basic stacks, queues, etc., but for recording many things per item, you would use a multidimensional array. Zen_StringGetDelimitedPart is now able to mimic getting data from a many elements in a nested array using a single string. The strength of Zen_StringGetDelimitedPart is that order no longer matters, a missing property is easier to handle, and you don't have to remember what is at what index. Compare: _multiDimArray = [["A", 27, 200]]; // We access a nested array using a key _nestedArray = [_multiDimArray, "A", 0] call Zen_ArrayGetNestedValue; // The actual value of the data is irrelevant _value = _nestedArray select 2; For this to work, you must ensure that (_nestedArray select 2) isn't out of bounds, contains the data we think it does, and doesn't have some default value we can't use. I just did that for _multiDimArray, but that's not an option for a lot of data being managed dynamically.Then using the string method: _stringDict = [["A", "Time: 27, Points: 200"]]; // Same look-up _nestedArray = [_stringDict, "A", 0] call Zen_ArrayGetNestedValue; // Now it's obvious what we are retrieving _value = [(_nestedArray select 1), "Points: ", ","] call Zen_StringGetDelimitedPart; If the "Points: " block is missing, we simply get an empty string. This is the 'soft' method of encoding data; it's not necessary to declare every block for every data string. It also allows more readable code. For example: // Now this array has many elements _nestedArray = [_stringDict, _key, 0] call Zen_ArrayGetNestedValue; _text = [(_nestedArray select 1), "Display Name: ", ","] call Zen_StringGetDelimitedPart; if (_text == "") then { _text = [(_nestedArray select 1), "Classname: ", ","] call Zen_StringGetDelimitedPart; if (_text != "") then { _text = getText (configFile >> "cfgVehicles" >> _text >> "TextSingular") }; }; This allows the data string to supply a display name in any number of ways without having to make each one an element in the nested array. The only downside to this system is that changing a value takes longer: _nestedArray = [_stringDict, _key, 0] call Zen_ArrayGetNestedValue; // if we want to add a block _nestedArray set [1, (_nestedArray select 1) + "Display Name: Test,"]; // but if we want to change an existing block _stringData = _nestedArray select 1; _text = [_stringData, "Display Name: ", ","] call Zen_StringGetDelimitedPart; _oldBlock = "Display Name: " + _text + ","; _newBlock = "Display Name: Fun,"; _stringData = [_stringData, _oldBlock, _newBlock, true] call Zen_StringFindReplace; _nestedArray set [1, _stringData]; You also need to be careful not to add duplicate blocks, as only the first will be read. Note that Zen_StringGetDelimitedPart is case sensitive, so Zen_StringFindReplace must be as well.Finally, I'm not saying the string data method is much better than array. I'm just presenting the pros and cons of each based upon my experience. Sorry if this dragged on too long. Feedback Did you follow these steps from the step-wise installation? 4: From the sample mission, Shell.Stratis, copy Zen_FrameworkFunctions, Init.sqf, Description.ext, and StringTable.xml into your mission directory If you already have a mission with an Init.sqf, Description.ext, or StringTable.xml: Open each file in Shell.Stratis and copy ALL of the code to the TOP of your corresponding file 5. Do not place the Zen_FrameworkDocumentation folder in your mission folder.Does your init.sqf look anything like this: Framework functions don't work from editor init fields or in trigger conditions. They can work in trigger activations though. Also, object names aren't written in strings, just p1, m1, etc. I highly recommend that you start with the first tutorial to see some usage examples.
×