Jump to content


  • Content Count

  • Joined

  • Last visited

  • Medals

Community Reputation

44 Excellent

About dwringer

  • Rank
    Staff Sergeant

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I see what you mean but, for that example, what I was saying is that it would be equivalent to ( _previousDamage + (( _newDamage * 0.7 ) min 1.4 )) Just two different ways of writing the same thing. But all have their uses, for sure.
  2. Since you're reducing it anyway there's no real difference between that and (_previousDamage + ((_newDamage * 0.7) min 0.7)), but in the latter case it's more clear at a glance (IMHO) what the final damage cap is. I suppose it's just a stylistic choice more than anything.
  3. Okay, I said I wasn't trying for that, but I couldn't say no to a challenge 😄. Now I can say I have an example mission which (might) satisfy that criterion. At least in the few tests I've done, the ambushers wins a majority of the time. I added some improvements to the VehicleTargets class, so now it makes the LOS requirements mandatory before spawning vehicles, and it sorts the positions with a weighted average calculation similar to those used with selectBestPlaces. The result of those efforts is demonstrated by this mission, in which a convoy of 4 BLUFOR tanks drives along a road and is ambushed by 4 OPFOR tanks which are placed by a genetic algorithm. Since Arma's tank AI is insane and will choose to turn its back to enemy tanks in response to a threat, I disabled the OPFOR's ability to move, and used TOV_fnc_SimpleConvoy (from https://forums.bohemia.net/forums/topic/226608-simple-convoy-script-release/) to drive the BLUFOR tanks down the road. Here's an example of one of the ambushes it generated during my tests: After a couple of minutes the remaining two red tanks worked up the courage to move forward, did manage to take out the blue tank in the road, but were promptly destroyed. Edit: On starting the mission, pull up the map. It will take a minute or two for the OPFOR to spawn, but you can watch the positions evolve as orange dots on the map. You can get the example mission here: "Tank Trials" Example Mission: (added 9 April 2022) https://github.com/dwringer/ANIMA/releases/tag/EXM-220409-A
  4. I have always thought this should be something easily done in the editor, but sadly you're right that the kind of triggers and extra waypoints it takes become very messy. I think the best way to do it instead is using a trigger and/or scripts to add a new waypoint (possibly a new seek & destroy waypoint at their current location, or a place nearby from which they'll be able to engage the spotted enemies) immediately before the one they were going to, and set that as their current waypoint. Check out the documentation for addWaypoint, setCurrentWaypoint, and currentWaypoint. You can provide an index to addWaypoint that will place it immediately before the waypoint they were already going to, use currentWaypoint to find out what that waypoint's index is. Unfortunately the whole process may require a bit of trial and error as you get used to the scripting side of it. Also check out the other pages on waypoints at the wiki. Sorry, I wish I had a simpler answer but maybe someone else has some ideas.
  5. dwringer

    How do you use your editor & script?

    Couldn't agree more with this, to me the challenge of creating something dynamic that can surprise even the creator is an endless pursuit that puts Arma head and shoulders above anything else.
  6. dwringer

    Call or Spawn

    I believe you meant to say a scheduled environment can never "turn into" an unscheduled environment. The way I'd say it is that "call" will always block until a result is returned (and can't sleep/wait), but if you use "spawn" your code will go off into a new thread where you are free to sleep, wait, "call" other things, whatever. One is also free to use "spawn" inside of a "call". But the call will return without any guarantee that the spawned code finished. At the end of the day, when you use "call" the return value you get will be the result of the called code. If you use "spawn" then the return value will be immediate, and it will be a script handle identifying the spawned thread which will go on running in parallel with the code in the context that called it.
  7. dwringer

    How do you use your editor & script?

    I think this is a really interesting question, bound to get all sorts of different answers from different people. For me, the editor has both strengths and weaknesses. Setting up waypoints in the editor has never felt right to me, because units have so much agency of their own and there are so many subtle aspects of waypoint assignment that by the time you get things working the way they should according to common sense (IMO), you've had to add all kinds of extra code and workarounds to triggers, unit init fields, and waypoint On Act fields. What the editor gets very right, IMO, is the trigger system. These can be used for all kinds of things, from simple mission init scripts and waypoint switching, to marking out areas and gathering units together to send to script functions. I really try to make full use of unit inits and triggers to do anything they can be made to do. I like putting the code here because it's easy to see in the editor and doesn't require me to Alt-Tab and navigate through labyrinths of folder structure and page through thousands of lines of code. When it comes to waypoints, I do use them in the editor because it's a lot easier than scripted solutions, but for complicated scenarios I still prefer to script them. Particularly if I want them to be dynamic in some way. I often use Game Logics to represent points in space to feed into my scripts. But, again, I often put extensive scripting inside triggers and init fields, rather than in separate files. All that said, I tend to have a huge library of function-defining scripts that I include with every mission, mostly to give me the ability to write code in the way that's most comfortable to me, with abstractions that are familiar to me. I don't like to define functions inside the editor unless it's a one-off.
  8. If the systemChat outputs anything at all, that means _filter is provably not empty. That means there is absolutely no way that "if(_filter == "") exitWith {[]};" isn't skipped. _filter is provably not equal to "", and since it's private we know it couldn't have changed. I guarantee if it printed something from the systemChat, it does skip the "if(_filter == "") exitWith {[]};" code. I can't see what the issue is because I don't know what the rest of your code looks like.
  9. If you see something output by systemchat, then the "if(_filter == "") exitWith {[]};" will be skipped, always. The systemchat confirms if _filter has a value, while the exitWith line only activates if _filter is empty. If this is working in some cases and not others, like if it prints "APC" but doesn't do anything else, it's because VVS_pre_APC doesn't work right.
  10. Hmm, I should perhaps not have used "artificial intelligence" as a tag for this because it doesn't affect unit AI in any way, but I still think of it as more of a generalized disembodied AI. Literally the only thing the VehicleTargets example does is pick places to spawn the vehicles. There are alternative ways of doing this including selectBestPlaces and silola's amazing DAC functions, but this is just a variation on that which uses a genetic algorithm to try to find the positions by evaluation a series of functions. You're right that if it can't win over 50% of the time in a 1v1, then it's not "superior", but that's not the goal here. The goal here is to be "better than randomly placing the tank somewhere in the area" or "better than the result you get using selectBestPlaces". It would be great to have such good positions as to win in a 1v1 fight, but at this time that's not the intention. The OPFOR are not given any information at all. The position finding algorithm is given two lists: one list of GameLogics which are placed along the approach BLUFOR will be taking. Positions are selected to be hidden from these gamelogics if possible. The second list is a list of GameLogics which are "kill zone" indicators. Positions are selected to have partial LOS to these logics when possible (and they are turned to face the first one to which they have LOS). As you say, sometimes the placements are ideal and other times they are imperfect. One use of this might be to run it a few times, take note of the most effective positions, and then use that knowledge to manually set up mission events. But I still enjoy the randomness for setting up skirmishes. ANIMA is really intended for people to mess around with the genetic algorithm to try creating their own position finding algorithms, or perhaps think up novel uses that I haven't implemented (of which I'm sure there are plenty). Things like the VehicleTargets and Headquarters classes, and other things from the example missions, are just examples of the applications and definitely leave room for improvement. Final Edit: I should say again, though, I appreciate your feedback and taking the time to check it out. You have definitely given me helpful things to think about. The real idea behind the VehicleTargets script was not actually to set up ambushes, but it emerged as a possible use. As the name hints, it was written to create (empty) vehicles to use as target practice, and I developed it originally on the flat tank ranges of the Hebontes map.
  11. Hey all, I'm still far from anything resembling a new release, but I feel the ANIMA engine is in good enough shape where developing applications is an equally worthwhile use of time. Here's a new example mission, showing a new application of ANIMA. Instead of creating group waypoints, this time ANIMA's position finding is used to place vehicles in a given trigger area. The vehicles are placed near cover/concealment, near roads, with LOS to some specified targets, and hidden-from-view with respect to other specified targets. The file ./classdef/VehicleTargets.hpp contains all the code that implements the new application (relying on the ANIMA system). Open the mission in the editor: Now launch it, and immediately bring up the map. You'll see some orange dots as the ANIMA algorithm evolves some positions at which to place vehicles: After the evolution process has yielded enough suitable positions, vehicles will be spawned at the found positions. These vehicles are chosen from those which were placed inside the trigger at mission start. Here you can see a few vehicles, all poised for ambush of the position at the intersection just above-right of screen center: An example of one such position, with a partially covered LOS to the ambush location: A BLUFOR tank is approaching, and you should see it enter combat around the time it reaches the targeted intersection. OPFOR positions are randomized, so it will play out differently each time, but BLUFOR is all but guaranteed to lose due to the ambush (and being significantly outnumbered). The example mission can be obtained here: https://github.com/dwringer/ANIMA/releases/tag/EXM-220407-A EDIT: Last night it was working pretty well, but today when I ran it there always seemed to be a tank that wanted to spontaneously explode itself 200m into the air. I tried to use BIS_fnc_findSafePosition to avoid this but I'm not sure if it does more good than harm. The algorithm could be tweaked to find better/safer positions but it would get a lot slower. Anyway, it works a lot better on flatter terrains in that regard.
  12. Sorry but I think there's some confusion. I'm not the OP, I was offering the OP a possible explanation for why the last car in his chain isn't being triggered. I should have clarified that's who I was replying to. My suggestion is that the second-to-last car is initialized so close to its move waypoint, that as soon as it is ordered to move into its trigger area, the waypoint is marked as complete (before the vehicle enters the trigger area!). Then, the second-to-last car just drives off without ever going into its trigger area to trigger the last car. I could be wrong, that's just what I would suspect.
  13. Although I can't see the blue/black lines linking the trigger/waypoints of the second to the last car (on the upper side), I assume they are there as you described. If they are then my thought is that the second to last car is starting so close to its "MOVE" waypoint that as soon as its switched, the "MOVE" is considered complete and thus that car never actually moves through its trigger. Vehicles don't need to get all the way to their waypoint for it to complete, although they usually will, but if they are close enough when its assigned they never actually move. In this case I believe the second-to-last car is doing this, just skipping its first MOVE right onto the next one and bypassing the small trigger area.
  14. I'm not certain but I think it might be that your variables _playerJailTimeAdjusted and _playerReleasedEarly are only defined for the first time within the loop. Outside of the loop they have no meaning, or at least not one that's well-defined. That is, they get set to true but only temporarily, so at the end during the switch they are undefined. Try adding: private ["_playerJailTimeAdjusted", "_playerReleasedEarly"]; before the loop, in the outermost script context. That will declare them in the same context as the switch, so when they get set to true they will stay that way.
  15. dwringer


    It's interesting that the recommended licenses are a bit more restrictive than the ones a lot of people use. For example, I release my code under MIT license, which is pretty lenient aside from attribution requirements. I'm not sure if the requirements of the end-user license confer additional restrictions or not, and I'd imagine the specifics are difficult to sort out, differ by country and require a legal expert for real assurances. The forum rules here, though, are rather explicit (and really mirror common sense): permission is required to reuse anyone's work for any reason. This can take the form of a permissive license, or a verbal agreement, or anything else, as long as it would stand up to an independent audit. Without permission, the code should not be used.