Jump to content

Zenophon

Member
  • Content Count

    530
  • Joined

  • Last visited

  • Medals

Everything posted by Zenophon

  1. Summary Greetings fellow scripters, I have finally coded and tested a lot of new logic and improvements for the script. These changes will improve its overall quality and reliability, as well as provide new options to make it easier to use than ever. All of the known issues have been fixed, and some user suggestions have been adapted and incorporated into the script. I want to thank everyone who gave feedback and helped with the development process; your suggestions will improve the experience for all users. The new version is already hosted on Google Drive, and will be on Armaholic soon. All relevant sections of the original post have been updated. While the script has become much more complex, from an optimization standpoint all of the new features only increase processing time by about 50%. This is not really an issue because the script only took a couple dozen milliseconds in the first place. Also note that some buildings will take a little longer than others. With all the new features might be bugs, even though I made a reasonable effort to test things on various buildings and with different combinations of the new parameters. If you find something, post here or PM me and I can get a hotfix out in a day or two. Changelog 7/28/14 Fixed: Units facing the wrong window Added: Parameter for distance to select multiple buildings Added: Parameter for units being on a roof Improved: Now checks that unit has a good FOV from the windows Improved: Units can no longer face a windows greater than 5 meters away Improved: Units on a roof now crouch Tweaked: Height of human eye to the exact value in ArmA
  2. I would also add that SQF is not truly multithreaded, meaning that there is only one engine thread processing SQF statements. It uses a scheduler to determine what executes when. It can also be interrupted to execute non-scheduled code, such as eventhandlers firing. Sleep does not just tell the thread to pause, it tells the engine to move on and start executing from the next thread. The engine uses sleep to queue up when it should jump to the next thread. However, the more you suspend that thread, the more others will get time to execute. You must prioritize waits and loops to balance which are time sensitive and which are not. Thus, if you have a waitUntil loop, which, without sleep, runs every frame (max dedicated server framerate is 50), the engine must stop and return to the thread with this loop every frame for a few milliseconds. If no other SQF threads are running, this is fine. You will not see a measurable performance impact for using the 'distance' command every frame. You will see a performance impact if 10 threads want to execute 100 of lines of code every frame, because the engine maintains a .3ms delay between commands (in scheduled environments). 10 threads * 100 lines/thread * .3ms/line = .3 seconds; you would be better off executing each thread every few seconds. Due to this delay, performance is dependant upon framerate, but any improvement in performance from a high framerate is negated by running every frame. Finally, you also don't want to use sleep frivolously. Many functions are better left to run all the way through, even if they execute thousands of lines. Making the engine jump from thread to thread using sleep in the name of optimization can just make things worse. Sometimes, optimization is not about using fewer resources and more about taking less time so the engine can move on.
  3. For waiting until the player lands, their are two questions here. Can the player be shot at will parachuting? When will the player be least likely to see them spawn? If the player is far away and lands out of sight, then waiting is fine. If the player could landing 100 meters away, you want all patrols there from the start. Spawning multiple areas of patrols is mostly about freedom of movement. Can the player choose which town to attack first? Or is the mission more linear? If you can't be sure where to player will go, you have to spawn all patrols right at the beginning. If the mission is linear, it is more efficient and saves processing to not spawn the patrols. Generally a good rule is: if the player can't see or interact with something, don't spawn it. There is a middle ground to this: only spawn patrols when the player gets close. You can use a loop or open new threads that wait for the player to get near the town. Something like: 0 = [] spawn { waitUntil { sleep 5; (([player, "mkTown"] call Zen_Find2dDistance) < 500) }; // spawn patrols... }; If you want to get into more complex solutions, look at the Even Queue demonstration. The system I use there is designed for exactly what you describe: a non-linear mission with patrols and objectives in different places. It also then allows you to have events in your mission change how it plays out; e.g. something different happens based upon which objective players did first.
  4. You can dynamically spawn AI with functions like BIS_fnc_SpawnGroup and other spawning scripts people have written (including my co-op framework, see my sig). You can also just use createUnit to do it manually. You would then get the group the function spawned as a return value and use the units command to get the array of units to put in a building. The only thing the script does to make the AI stay there is use doStop. Anything that tells them to move again will override that. You can force them to stay in place with disableAI. Something like: { _x disableAI "Move"; } forEach units group this; You can change 'this' to a spawned object, or 'group this' to the group returned by a spawning function.
  5. I didn't know that; still, some mission makers might prefer that all units are inside the building. It would also be good to make units on the roof crouch/prone, which I can do if I check for them being on the roof. No it should not; it will only use a building position if the unit would have an unobstructed line of sight 15m in the direction they are facing. I can tweak that number based upon feedback. There might be a few buildings with 1 large room and no windows, but it works fine for most of the small residential buildings on Altis.
  6. That was inevitable, as I can't test every building. Fortunately I think I know how to fix that without preventing units from being on balconies, etc. Unfortunately, it might prevent units from being on a roof that is actually reachable. Therefore, I will make a parameter to enable/disable putting units on the roof. Until then, I will add this as a known issue. I will probably also fix the the first known issue next release as well. That too involves a similar modification to the current position checking system.
  7. Thanks Foxhound, I've edited the post with the link to Armaholic.
  8. Introduction Greetings fellow scripters and Armaholics, in this latest installment, I will continue to discuss the development of the framework and, of course, shamelessly advertise the framework in any way possible. If this sounds boring, you can download the latest version from the original post. As always, the link to Google Drive for the .7z and .zip versions are already up to date. For those looking for older versions, go to file>revisions. The new version should be on Armaholic when Foxhound sees this or I PM him. Please bring an technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc. Changelog This update has 25 changes, which is a good set of improvements, but certainly not that many for a whole week of development. The most important change is a new function: Zen_FindRoadDirection, the first new function since the public release of the framework. Incidentally, it makes use of Zen_ArraySort, the function spotlighted last week. There are also 6 coding bug fixes, including a major fix for Zen_ArraySort. The change to Zen_ArraySort was hotfixed several hours after release; hopefully no one tried the function and couldn't get it work. Last week's improvements to Zen_SpawnParachute broke its ability to land objects on rooftops; that feature has now been restored and is working 100%. Two task system bugs were also fixed; Zen_AreUnitsTasksComplete is now actually working, and Zen_UpdateTask no longer shows the wrong notification. The last of the bug fixes are a set of changes in Zen_OrderVehicleMove, Zen_SpawnConvoy, and Zen_CreateObjective to get 'convoy' type objectives working consistently. I cannot solve AI driving problems, but the convoy should now at least attempt to move in all situations. For anyone creating convoys without Zen_CreateObjective, Zen_OrderVehicleMove is now more effective than ever at getting the whole group to move. Other highlights include optimizations to the various framework action functions, and making those actions a custom color. I chose a light blue that is visible during the day or night and isn't distracting. Also, Blufor soldiers look fairly convincing while wearing a few of the new bandannas; this realistically represents what soldiers might wear in dusty environments. Zen_SpawnAmbientVehicles now puts vehicles at the sides of the road (but sometimes in the middle of intersections) much more realistically than before. Sometimes, it looks more like they were placed in the editor than randomly by a function! The documentation was not forgotten, with several fixes to the tutorials to make sure they are working perfectly. The sample missions have also received comments and readability improvements, along with a table of contents. For those who thought they were too confusing before, give some of the easier ones a try. 7/23/14 Roadmap Looking to next week, some new functions and minor improvements are planned. Zen_ConfigGetVehicleClasses will get a parameter for the selection of DLC vehicles, Zen_FindGroundPosition will help you prevent generating positions off the map (in the black), and Zen_SetAISkill will reduce of presets only at night to a more realistic level. The new functions are very much work in progress ideas; however, they are meant to determine if a certain area of land is a certain type. Their names might go like: Zen_IsForestArea, Zen_IsHillArea, Zen_IsUrbanArea, and so on. If they are all very similar, I might just combine them into one function with another parameter for the type of land. The point of these is to provide dynamic evaluation of a unknown area of terrain in code, so that your code can look at an area of the map and make a reasonable decision, like a human looking at the editor would. Function Spotlight As users of my framework know, there are an enormous number of functions at your disposal. The amount of documentation that has to be sifted through can be extremely daunting. Each week I spotlight a function and talk about its usefulness. If you have found an obscure function (not in tutorials, barely seen in demonstrations or sample missions) that you found useful, PM me and I can spotlight it. The function chosen for this week is: Zen_OrderVehicleDrop. This function makes dynamically dropping any vehicle very easy. You need only provide an existing aircraft, a drop point, and what to drop. It can drop an existing object by teleporting under the aircraft, or give a classname and a new object will be spawned. You can place a helicopter in the editor, or spawn one with a function, then use: 0 = [Heli, player, "B_MBT_01_TUSK_F"] spawn Zen_OrderVehicleDrop; This will drop a tank directly onto the player's position. Obviously, a tank couldn't be carried by a helicopter, but you are free to drop any vehicle, ammo box, or static weapon you want. With the improvements to Zen_SpawnParachute, which is used by this function, the objects you drop can land on rooftops as well. You can also make the helicopter leave the area easily: 0 = [Heli, [player, Heli], "Box_NATO_Wps_F"] spawn Zen_OrderVehicleDrop; The player will get an ammo drop and see the helicopter returning to its original position. Although, you might want to delete the helicopter later, if you don't use it again. Beta As already stated, the framework is in the beta stage of development. I am making every effort to quality control releases, but there will be bugs. Both new features and old ones could have bugs, issues, and things people just don't like. There is no ETA or plan for a 'final' version. The framework is a work in progress, and it will continue to progress while there are improvements to be made (there always will be). Feedback A few bugs have been pointed out by users, and those fixes are included in the changelog above. I want to thank everyone who has used/supported the framework. The specific request this week is: function documentation. I want your opinion about how complete and helpful the description of each function is. Was anything left out? Are you unsure exactly what it will do? Any feedback on this, like all feedback, is appreciated.
  9. Is your character a civilian or on the civilian side somehow? This causes the function that determines which side of loadout to give to just give civilian clothes. Because the preset loadouts are for every side the function must give loadouts based upon side to prevent soldiers from getting enemy equipment. For civilians, it never gives weapons as that would make them combatants and not civilians. This does not apply to custom loadouts. Try playing as a Blufor or Opfor soldier, and see if the presets work then.
  10. Zenophon

    Exiting UnitPlay Function

    I assume BIS_fnc_UnitPlay requires that you use this command: https://community.bistudio.com/wiki/spawn You can use the return value from calling the function: _thread = [...] spawn BIS_fnc_UnitPlay; And end the thread with this command: https://community.bistudio.com/wiki/terminate terminate _thread; This will work if the function is controlling the object directly and does not spawn another thread or do something tricky. I looked at it quickly in the functions viewer and it seems fairly straightforward.
  11. I would be glad to add some more parameters, but I don't know what they would be. It already adapts to the size and direction of the marker and has parameters for the spacing and clutter in the area. If you want a specific part made adjustable, just say what it is and I can release an updated version.
  12. Zen_AddLoadoutDialog is meant to be put on an object like a car, an ammo box, etc. I actually never tested it by putting it on the player (and I don't recommend that, from both a usability and realism standpoint). All of the preset loadouts (see the documentation for Zen_GiveLoadoutBlufor etc.) can be used with this function, as well as any custom loadouts you have created with Zen_CreateLoadout. You can mix and match them to your liking, just remember to give custom loadouts a real name, or they will display as random ASCII characters. The dialog does not do anything automatically, you need to use the action and select a loadout from the menu. For the AI, because AI in your group are local to you, when they use the action the dialog appears on your screen and your choice affects them. Use command menu 6 to get them to use the action. Putting all custom framework actions in a different color is a good idea, just to differentiate them from default BIS actions. Though I will probably opt for a softer color than bright red. Hopefully that makes in to release this Wednesday.
  13. Yeah, adding the AI behavior parameter to Zen_OrderInfantryPatrolBuilding is very easy. That will be included in the next version, which will be released this Wednesday. For the loadout, it is working for me when I do something like this: // _loadout is created somewhere above _patrolGroupsArrayOpfor = []; for "_i" from 1 to 5 do { _spawnPosition = ["mkSpawn"] call Zen_FindGroundPosition; _patrolGroup = [_spawnPosition, east, "infantry", [3, 4]] call Zen_SpawnInfantry; _patrolGroupsArrayOpfor set [(count _patrolGroupsArrayOpfor), _patrolGroup]; }; 0 = [_patrolGroupsArrayOpfor, _loadout] call Zen_GiveLoadoutCustom; You can also try this after the spawning loop: player sideChat str _innerGuardsGroupArray If the game prints out a list of names like O alpha 1-1... etc. then the array has the correct data. If it still doesn't work, you can give loadouts to the groups individually as they spawn: _spawnPosition = ["mkSpawn"] call Zen_FindGroundPosition; _patrolGroup = [_spawnPosition, east, "infantry", [3, 4]] call Zen_SpawnInfantry; 0 = [_patrolGroup , _loadout] call Zen_GiveLoadoutCustom;
  14. No need to apologize for questions; it's no trouble. When I run that code, I get an error and a stack trace about 'custom' not being a loadout. It should be: 0 = [player, "custom", _loadout] call Zen_GiveLoadout; Where the 'custom' literal identifier goes before the loadouts names. I will admit that the documentation for that function is a little esoteric. You can just use: 0 = [player, _loadout] call Zen_GiveLoadoutCustom; Which is a more direct function. Zen_GiveLoadout is meant for situations in which you cannot hard-code the side or even type of loadout. Both of the above are working for me with the rest of the loadout code. For this code, do you have an object named 'X'? This is the generic name I give to the leader of the player group. You could try: 0 = [group player, BLUFOR_LOADOUTS] call Zen_GiveLoadoutCustom; The only reason I do not use 'player' in my mission is because it is undefined on a dedicated server; in that case the server needs a global object name. In this mission, the loadouts have literal string names that can be used directly. This is not done in the Custom Loadout demonstration. You have two options when creating the loadout: // this loadout is given a random name, assigned to _loadout1 _loadout1 = [[...]] call Zen_CreateLoadout; // this loadout gets the name 'Loadout Name', assigned to _loadout2 _loadout2 = [[...], "Loadout Name"] call Zen_CreateLoadout; For the first one, you must use the variable '_loadout1' to refer to the loadout. For the second, you can use '_loadout2' or "Loadout Name" when giving the loadout, getting its data, etc. All the prepreprocessor #include/#define things are just copy-paste commands to make things more compact and avoid repeating code. I would only recommend doing that when the loadouts are already working. You can also put all loadouts in one file; you could #include just one .sqf file that contains dozens of loadouts, then use #define to set up the lists of loadouts.
  15. No, there are no variable wildcards. It also would not be a great feature, because how would the engine know which 'block's you meant; you might not want to delete all of them. However, what you want is possible in a different way: for "_i" from 1 to 10 do { deleteVehicle call compile ("block" + str _i); }; This is tested and working, just change '10' to the number. It also doesn't matter if the object doesn't exist, so you can use e.g. 9999 to delete all 'block' objects.
  16. Zen_MultiplyDamage is a function and Zen_Damage_Increase is a integer global variable that it uses. Zen_MultiplyDamage puts a handle damage eventhandler on the given units designed to increase only bullet damage to them. You must call the function for it to have any affect. A very brief overview of Zen_Damage_Increase is in the text documentation for Zen_MultiplyDamage. The need for a global variable is so that the damage increase can be changed at any time across all machines in MP. Initially in development, it would simply multiply the damage by a constant, but this gets out of hand e.g. with .50 caliber rounds and such. Using a number like 7/8 allows the function to read the 'hit' config value for the bullet, add that number, then multiply the damage by the ratio of increased 'hit' to old 'hit'. The equation would look like so: _damage = ((_hit + Zen_Damage_Increase) / _hit) * _damage; The function's code doesn't look exactly like that, but you get the idea. The reason 7/8 is used is because that about doubles the damage of a 5.56mm NATO round, so it kills in 2 hits instead of 4. The 6.5mm rounds follow suite with 1-2 shot kills at close range. Zen_MultiplyDamage is a scripting solution instead of config solution that mods would use. There are several strengths to this: You could only apply increased damage to some units (seems unfair, but it's your choice) You can change Zen_Damage_Increase at any time, even to a negative number (not less than -5) The damage is increased for all bullets, even those from addons/mods, with needing to change anything It is simple to use, and requires no mods or dependences There are also a few disadvantages: It conflicts with any other script or mod that uses handle damage eventhandlers It is less efficient that just changing config values, as the eventhandler must run every time some one is shot For example, you could do this at the end of your init.sqf, after you are done spawning everything: 0 = [allUnits] call Zen_MultiplyDamage; Zen_Damage_Increase = 8; publicVariable "Zen_Damage_Increase"; The publicVariable is necessary to send the correct value to any client machines, so everything is fair.
  17. Did you try this? https://community.bistudio.com/wiki/finishMissionInit Or maybe just 'sleep 2;' or higher? Do things always work for low-latency players?
  18. Zenophon

    [COOP-6] Evade and Survive

    I have just tested this (kill one patrol) on a dedicated server (I am running the game and server on the same machine, but that should only affect latency) and it did not crash. Looking at the server's log, I don't see anything other than the usual BI log spam about magazines, ragdoll, etc. I have never heard of a mission being able to crash the server with a bug, but I suppose anything's possible. You might want to check the hardware on your end, in terms of recommended specs, CPU usage and temperature, etc. Try '#monitor 5' as admin to see the server's fps and up/down load. Also, have you tried playing without any mods at all? I can't know what will or will not work with mods, as obviously I cannot try them all. Looking at my code, it is quite possible that an AI mod could conflict and cause issues. Finally, can you post/send me part of the server's log file, at the end when the crash occurs. There could be some bug causing massive CPU usage or something, or it might just be a memory allocation fault.
  19. After looking through the ALIVE documentation briefly, it seems to be all modules for the editor. I see almost nothing about external scripting and if ALIVE's features can be called in code directly rather than using modules. I also don't see any documentation about what SQF functions it contains. ALIVE is also an addon that requires CBA. Obviously, correct me if I am wrong here about the scripting part. My framework is not a system of modules and not use or require the editor in any way. It is not an addon and has no dependencies; it is a simple folder of scripts. I refer to it as a framework because it supports other people's code. It is an SQF function library that offers a massive number of features for those who cannot or have not coded such functions. My framework is entirely compatible with all other mods and addons because it is just a library. The mission maker chooses what functions will run. It is very possible to create a mission using 99% scripting, which is how a prefer to make missions and why I created my framework. You could also just make use of one or two functions that you find interesting. The functions themselves are mostly smaller parts. You would need to combine many of them to get a mission going. However, this is meant to give scripters much more control over their code. The framework is not just a few large scripts that you use with one line and magically have a full mission. It is a toolset for programmers and those who prefer scripting over the editor. There are many documentation resources provided to help people learn how to use the framework, from how to use individual functions to creating very complex missions using SQF. I believe that almost everyone could benefit in at least a small way by using a few framework functions. If the scripters in your group have read this and have further questions, I would be happy to answer any questions about my framework in this thread, through PM, or in email.
  20. Introduction Greetings fellow scripters and Armaholics, due to the pace of framework development, I have decided to start a weekly news report to coincide with each new release. In these updates, I will provide a detailed explanations of changes, go over plans and the roadmap for the next week, discuss framework design topics or concerns, request specific feedback, and continue to shamelessly advertise the framework in any way possible (but mostly the last one). If these sound boring, you can skip them can download the latest version from the original post. For those that are even slightly interested, I assure you I will find many things to write each week about the framework. This week sees a update to the original post, including the thread title, to make things as polished and professional-looking as possible. As always, the link to Google Drive for the .7z and .zip versions are already up to date. For those looking for older versions, go to file>revisions. The new version should be on Armaholic when Foxhound sees this or I PM him. As always, please bring an technical issues or mistakes to my attention, so e.g. people don't download the wrong version etc. Changelog Before I get into the changes, I will briefly explain the changelog's organization. Each change is numbered, and prefixed with a general category. The categories are, in order of precedence, 'New Function', 'Fixed', 'Added', 'Improved', 'Updated', 'Tweaked', and 'Documentation'. The 'Documentation' category uses those same words to describe changes. Within each category, the changed function(s) are listed before a description of the change. Each line is then organized alphabetically by the name of the first function, with the functions also listed alphabetically. This update has 13 changes, 5 of which are just documentation. Keeping the documentation updated and correct is about a third of the work. Only one obscure bug was fixed, and the rest are either changes for ArmA 1.24 or slight usability improvements. 7/16/14 Roadmap Moving on, it was pointed out to me that for those learning the framework, there is a strange gap between the tutorials and sample missions. The demonstration missions are well explained, but they are very focused. The sample missions are just a massive wall of code that can be fairly daunting. Therefore, the sample missions will get new life next week, when I add comments (not too many or too simple), and an index with difficulty levels (see the demonstration readme for an example of that). Remember, that which is not documented, does not exist. If you can think some aspect of using the framework that is missing from the documentation, by all means say something. Also, hopefully a new function will make it out there next week: Zen_FindRoadDirection. As the title implies, it will give you the bearing of a stretch of road. It certainly doesn't make you want to jump out of your seat, but the benefit to getting convoys of vehicles spawned correctly is significant. Function Spotlight As users of my framework know, there are an enormous number of functions at your disposal. The amount of documentation that has to be sifted through can be extremely daunting. So, I have decided to include in each weekly report one function that, while obscure, is rather useful. The goal of this is to let mission makers know what they can get out of using the framework. If you have found an obscure function (not in tutorials, barely seen in demonstrations or sample missions) that you found useful, PM me and I can spotlight it. The function chosen for this week is: Zen_ArraySort. While sorting an array might sound fairly boring, it offers two features that can make it useful. First, it is extremely fast, during testing, it sorted 10,000 integers in less than 4 seconds. This is obviously far beyond any normal use, but goes to show that a good algorithm pays off. If you are interested in the technical programming aspects, I will tell you that it uses a non-in-place unstable quick sort, with an insertion sort optimization, equal value optimization, and median pivot selection. You can look at the code yourself to see how it's done. There is also a shell sort, commented in the same file. Second, it allows the use of a custom comparing function, so that it can sort objects, groups, and other data. You can use this to sort data any way that you want. For example: // This sorts an array of arrays by the number of contents in each nested array _sortedArray = [_array, {(count _this)}] call Zen_ArraySort; // This is sorts an array of strings by how many non-whitespace characters are in each string _sortedArray = [_array, {(count toArray ([_this] call Zen_StringRemoveWhiteSpace))}] call Zen_ArraySort; From a design standpoint, it might have been better to use a real comparator rather than what is little more than a hashing function. The current design is to make things easier for new scripters. Writing a comparator with less, equal, greater tests is harder than just hashing some data type to a number. If you have some experience programming and use this function, I would like to know if you would prefer that it require true comparator. Framework-Related News For the general promotion of the framework, I am including a section specifically for news about framework-related scripts and missions that are released. The framework is not only for making missions, but can also be used as a library when writing scripts or even in addons. In the future, if you have released any content that uses the framework, PM me and I can advertise for you here with a link and short description. Also, I promise to play your mission/try your script and give you feedback. Doing this doesn't just promote the framework, it helps all framework users see what kind of work can be done and will give them hints and ideas for their future projects. I firmly believe that the framework makes things easier for mission makers, and I want as many people as possible to benefit. This week, seeing how it is the first week, I have only one piece of news. I have released the first public mission using the framework. It is a infantry-focused, co-op mission where players try to survive as a small SF team in enemy territory. Check it out here: http://forums.bistudio.com/showthread.php?180473-COOP-6-Evade-and-Survive Give it a try, or at least look at the features list to see what kind of features the framework can provide. If you want to un-pbo it and look and the code, feel free. Beta As already stated, the framework is in the beta stage of development. I am making every effort to quality control releases, but there will be bugs. Both new features and old ones could have bugs, issues, and things people just don't like. There is no ETA or plan for a 'final' version. The framework is a work-in-progress, and it will continue to progress while there are improvements to be made (there always will be). Feedback For better or for worse, no bug reports have come in yet. I like to think that bodes well for the future. If you find any bugs, remember that they can only be fixed if you report them. Also, I am really interested in how you are combining the framework with the editor. The two do not seem very compatible, looking at the tutorials and sample missions; however, I understand that people know and use the editor a lot. If you want, write in about what things you do where. Where you prefer to spawn units? How do you handle tasks? Are you using triggers in the editor or looping in code? All of your responses will help me make the framework the best experience possible for all users.
  21. Zenophon

    [COOP-6] Evade and Survive

    Currently, to my knowledge, a dedicated server does not properly use its profile settings for AI skill and precision. They simply default to 1.0. When using the command 'setSkill', the raw value there is modified based upon the profile settings. If the profile precision value is 1.0, the aimingAccuracy value is tripled. This mission uses a special AI skill setting when it detects a dedicated server, to make the 'skillFinal' value the same as the 'setSkill' value. This happens when overall skill in the profile is set to 1.0 and precision at 0.5. If a player has a precision other than 0.5, then the aimingAccuracy will be different in SP or local MP. The AI has been balanced for this 1.0, 0.5 profile setting, as this is when no scaling is done. The mission plays on a dedicated server as I intend it to (feel free to give feedback); the only change the server can make is setting a different skill through the mission parameter options. In SP or local MP, the player/host has the option to scale the AI skill settings. See here: https://community.bistudio.com/wiki/skillFinal You can test this in the editor yourself by changing the difficulty options and printing the final skill (requires that you restart the mission).
  22. The parameter for behavior is already tested and working internally for Zen_OrderInfantryMove and Zen_OrderInfantryPatrol. However, for both functions, combat mode is hard-coded right now. For Zen_OrderInfantryMove, I wanted the focus to be on moving without being distracted. However, if the AI encounters the enemy, their combat mode will increase from 'safe' to 'combat' dynamically. So, in this function, I am trusting the AI to react properly (obviously if they don't that's a bug/issue that can be fixed). For Zen_OrderInfantryPatrol, the combat mode is hard-code to 'red' to improve AI aggression. Without this setting, I have found that the AI simply continue on to the next waypoint, with a significant delay due to taking cover etc., without really engaging their target. It also works with the detecting and attacking of nearby targets (see my explanation below). There is a demonstration mission about reveal and knowsAbout called Zen_AIShareInfo.sqf. Something like this algorithm is used by Zen_OrderInfantryPatrol to force patrolling groups to hunt down the enemy. However, in Zen_OrderInfantryPatrol, only the AI group that spots the enemy will go after them. Generally, my goal with Zen_OrderInfantryPatrol is: have a simple, effective patrol function with good default behavior that can be interfered with easily. By that I mean that you can run threads parallel to Zen_OrderInfantryPatrol and do things to the groups, such as force a speed or behavior, monitor all of them, use reveal to simulate radio communication, etc., without really breaking anything. To help and encourage people to set up their own AI share info and more complex management of the AI, I will add a parameter to Zen_OrderInfantryPatrol to disable the aggressive tracking. Once this is disabled, the only thing that makes Zen_OrderInfantryPatrol give new orders is if the group leader is 'unitReady'. Though, if you are going interfere too much, there really is no need to use Zen_OrderInfantryPatrol at all. You are free to look at the source code and expand upon it or use parts of it in your mission. The scary legal stuff is mostly to prevent blatant theft. You can edit and modify things as much as you want and release a mission with it (it's not like I could stop anyone anyway). As state above, Zen_OrderInfantryPatrol is well prepared for interference, shuffling units around the patrolling groups will have little impact on the function. Creating new groups will make them unaffected by the function. If I were to code group joining, I would use Zen_FindMinDistance to make joining the nearest group easy. However, I want to keep Zen_OrderInfantryPatrol fairly simple; I am not aiming for UPSMON-like quality and features. Every mission maker has an idea about how the AI should patrol, and Zen_OrderInfantryPatrol is there to provide basic functionality easily for people who don't care or don't have the experience to write complex patrol scripts. ---------- Post added at 20:15 ---------- Previous post was at 19:56 ---------- It's no bother at all, I really enjoy coding and helping people; that's why I made a framework like this. If memory serves, this snippet is from the demonstration solution to the warlord tutorial. The nested loops create a multiplicative effect. The '_i' (outer) loop will run three times. Each time it runs, the '_j' (inner) loop will run '_i' times. It is the inner loop that is spawning the groups, so if 6 groups spawn, the inner loop ran 6 times. I will trace the code by replacing the variables with literals: On the first run, _i == 0, and the '_j' loop runs 1 time and looks like this: for [{_j = 0}, {_j<= 0}, {_j = _j + 1}] do { _groupPos = [_objectivePos, [0,100]] call Zen_FindGroundPosition; On the second run, _i == 1, and the '_j' loop runs 2 times and looks like this: for [{_j = 0}, {_j<= 1}, {_j = _j + 1}] do { _groupPos = [_objectivePos, [100,200]] call Zen_FindGroundPosition; On the third run, _i == 2, and the '_j' loop runs 3 times and looks like this: for [{_j = 0}, {_j <= 2}, {_j = _j + 1}] do { _groupPos = [_objectivePos, [200, 300]] call Zen_FindGroundPosition; The sum of '_j' loop executions is 1+2+3 = 6. For each '_i' loop iteration, the distance used for Zen_FindGroundPosition increases; the distance does not increase when the '_j' loop iterates. The point of this is to show that you can use numerical patterns to make code very compact. This makes coding and maintaining things easier. You could also easily change things by multiplying '_i' by a different number or changing the upper bounds of '_i' and '_j'. To make things a bit simpler, try replacing the '_j' loop header with this: for [{_j = 0}, {_j <= 2}, {_j = _j + 1}] do { Using a '2' literal instead of '_i'. The loops now follow a simpler mathematical pattern; the '_j' loop will have 3*3 = 9 executions.
  23. Thanks Foxhound! Also, I am releasing an updated version. The download link and first post have been updated. I have decided to include a legal license, as this is likely the final release. The only coding change is that the area can rotate based upon marker angle. This script is now released under Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) Changelog 7/15/14
  24. This is a good suggestion. I did not think of it, and both Zen_OrderInfantryMove and Zen_OrderInfantryPatrol lack a parameter for AI behavior. The default behavior is 'aware' mode. Adding a behavior parameter to both functions is a very fast improvement, and will be included in the next release, which is most likely tomorrow.
  25. In general, the 'normal' way of respawning just means that you don't heavily interfere with the respawn process by using eventhandlers and scripts. What you are describing is very possible with some knowledge of SQF and locality/remote execution. There are also different approaches to get the same result. This is what I would do: For stopping respawn, put a MP respawn eventhandler on players, then check if the objective is complete any way you can. If it is not complete, kill the player and make them wait again to respawn (show a black script or something to cover it up). If the objective is complete, let the player respawn wherever you want (helps to be able to test which objective is which). With a respawn timer of about 20 seconds, player won't have to wait too long after the objective is complete. You can use some tricks with global variables on the client machines to be sure you check the latest objective and don't allow respawn more than once per objective. This works for base and instant respawn options. https://community.bistudio.com/wiki/addMPEventHandler You could also try this instead of killing them again: https://community.bistudio.com/wiki/...yerRespawnTime I haven't tried it though; it sounds like it doesn't reset the timer, just changes it in the future. For all players being dead, I would put a killed eventhandler on each player, then check if all other players are dead each time it fires. If they are, end the mission in any way you want. This will require the use of BIS_fnc_MP or equivalent, as the ending the mission happens locally as far as I know. I don't know how experienced you are with SQF, so if something is unclear just ask.
×