Jump to content

mrcurry

Member
  • Content Count

    615
  • Joined

  • Last visited

  • Medals

Posts posted by mrcurry


  1. 14 hours ago, bbaanngg said:

    Placing the above code in the init.sqf and running the mission looks promising at first. The save event handler properly avoids the circular reference error, and loading the save also restores the hashmap, but unfortunately, if you run the following code after loading the save:

    
    p get "m1" set ["a", 2];  
    p get "m2" get "a";

    It does not return 2. Which shows that "m1" and "m2" no longer reference the same map.

     

    Yeah that fits the bill with the other issue I mentioned but as long as the object structure is static it should be trivial to deconstruct/reconstruct the references manually.

     

    P.s. out of curiosity what possessed you to do pointclouds in sqf? 😛


  2. 29 minutes ago, soldierXXXX said:

    because value that you give to the key must be hashable to be properly stored

    The key in this case is a string, "a" or "b" are very hashable.

    The stored value is the reference to the first HashMap.

     

    29 minutes ago, soldierXXXX said:

    Question is what is the use case of having hashmap inside hashmap? Why cannot be either array of hashmaps or hashmap with key and array value? 

    Nesting HashMaps like this is very useful for quick lookups of complex nature. Example: You have some thing that doesn't support setVariable, you can use nested hashmaps to replicate similar functionality where the lower level contains "variables" and their values while the upper level acts as a registry for each "thing".

    The lower level keys can be shared across multiple things which means easy to use and value lookup is fast even with massive amounts of objects with a lot of variables.

     

    And to clarify: This works fine during runtime. This is only a problem during save/load of a mission.

     

    A bug report is also a way to get verification if it is or isn't a bug. 🙂

     

    • Like 1

  3. 23 hours ago, bbaanngg said:

    Can anyone explain this behavior?

     

    Honestly seems like a bug. Good find if so, I wonder does it only happen when 'm' is empty? Or if it's not a missionNamespace variable?

     

    Last I checked loaded HashMaps doesn't retain group or object references either, unlike arrays. My guess is the serializer doesn't know how to handle them properly.

     

    You should post it to the Feedback Tracker  but I wouldn't hold my breath for a fix expect a fix. It's quite a niche issue and you can work around it by converting HashMaps to arrays on save, then use the Loaded eventhandler and createHashMapFromArray to rebuild.


  4. 5 hours ago, CryptEarth said:

    ...

     

    Unfortunately I was only able to get it work with a HEMTT and not with an Offroader or the small Truck - but I guess there's some trick around it.

    At least I finally found a starting point to get it done properly from within the engine instead of fiddle around myself with attachTo.

     

    setVehicleCargo only works with certain combinations of vehicles and cargo. As an FYI, for the command to work the following must be true:

    • The vehicle needs to have a defined capacity ( mass and volume  ) 
    • The cargo needs to be defined with appropriate values for the same.
    • The cargo must no exceed the capacity of the vehicle.

    You can read more details here but to summarise that's all defined on the config side so as a mission creator at best you can test the combination using:

     

    vehicle canVehicleCargo cargo

     

    Note that the returned value is not true/false but rather an array of Booleans: [ willFitIntoCurrentVehicle, willFitIntoEmptyVehicle ]

     

    • Thanks 1

  5. 3 hours ago, redarmy said:

    have this in init on a tank for example. it seems to handle random damage based on where tank is hit ofourse,but frequently,when say the tank is at 60% health,the next hit actually shows the tank returned to 70 or 80%. Making tank invunreble

     

    From HandleDamage wiki:

    Quote

    If code provided returns a numeric value, this value will overwrite the default damage of given selection after processing. 

     

    From the explanation thread linked on the same page:

    Quote

    _this select 2 (damage): Damage to the above selection (sum of dealt and prior damage)

    With your current setup you are setting the damage for the selection to 25% of the resulting damage level, hence the healing effect.

     

    AFAIK the event handler executes before the damage is applied, if true you need to subtract the current damage (getHit) from the damage parameter to get the delta (incoming damage).

     

    Multiply that by 0.25 to get the reduction and add the current damage back to get the modified resulting damage level.


  6. 4 hours ago, RabbitxRabbit said:

    Is there a way to have your ai ignore it for a few seconds so that it attacks the players before they start shooting at it?

    When you switch it's side also use: unit setCaptive true;

     

    Then when you want it to be shot at do: unit setCaptive false;


  7. 23 hours ago, RudyRedTop said:

    I started looking through the Cam Lao Nam Mike force mission and actually learned a lot of cool stuff on how it works. I've determined that for my purposes the only actual functionality I would need is the packaging wrecks into crates function but I suspect it's not going to be as simple as pulling "fn_veh_asset_package_wreck.sqf" into my own mission because there are a lot of other functions and variables that are linked to it as well.

     

    Don't remember how Mike Force does it exactly but I'm pretty sure it involves the interaction wheel-feature. Here are steps to reproduce a similar functionality using actions instead:

    1. Identify when a recoverable vehicle is destroyed, see addEventHandler and EH Killed.
    2. Add an action to the wreck to do the following steps, see addAction
    3. Get the type, position and direction of the vehicle, see typeof, getPos, getDir
    4. Delete the wreck and replace it with a container, see deleteVehicle and createVehicle
    5. Store the type of the wreck in the container, see setVariable
    6. (Optional) Add an action to see what kind of wreck it is, see addAction.

    That's it for the packing. For recovery:

    1. At your recovery point add a trigger to continuously check for containers which contain a vehicle, trigger should detect Anything Present and it's condition need to filter for only wreck containers, see triggers and getVariablethisList
    2. When the trigger activates get the type of the first container, see getVariable, thisList
    3. Delete the container and replace it with a new copy of the wreck, see deleteVehicle and createVehicle
    4. Reapply the event handler from step 1 of the packing process to the newly created vehicle

    If you got any further questions or need some code examples just ask.


  8. On 3/9/2024 at 12:56 PM, RS30002 said:

    it's something with the goat. if i put a normal civilian i get the action to take the meat.....but i need it to work on an animal lol

     

    Animals are agents (simpler version of units) and cannot be the target of an action.

     

    Best bet is to put the action on the player and in the condition check cursorObject is the required thing.


  9. 10 hours ago, trollzor45 said:


    So, I'm stuck again 😞

    Clicking play again in the launcher STILL closes my first instance before starting the second one.

     

    So shortcut it is.

    All the launcher does to launch the game with mods is to set the -mod startup param.

    We can do the same in many ways, but the easiest is probably using shortcuts.
    That's the way it used to be done, way back before fancy launchers and workshop-support. 😛
     

    1. Browse to your game's install location.
      From steam: Open steam library -> Right-click the game -> Manage -> Browse local files.
       
    2. Locate the mod's installation folder and its relative path compared to your arma3.exe.
      • If it's a workshop mod it's located in the hidden !Workshop folder,
        if you can't find your mod in there the launcher probably hasn't finished installing it yet so just let it do that first.
        Workshop.png?rlkey=upk7tpmwk77p6yyqviovb
         
      • If it's non-workshop then only you know where you installed it but inside your game's root folder starting with an @ is the recommended approach.
         
    3. Create a shortcut to the arma3.exe.
       
    4. Right-click the Shortcut -> Properties -> Shortcut-tab
       
    5. At the very end of the "Target" field add:
      "-mod=<your mod path>"
      For example:
      Shortcut.png?rlkey=ka313padbhhmynjab9ltn

      If you want to launch with multiple mods you can chain them together like so:
      "-mod=<mod path 1>;<mod 2>;<mod3>"

      Here I'm launching with Prairie Fire (vn) and 3den Enhanced:
      multimod.png?rlkey=dn8kz591nutfhzodjdf8u
       
    6. Launch the game by using the shortcut and verify the mod has been activated by looking in the lower left corner of the main menu.
      verify.png?rlkey=bndu6uuwzrhvhoi6gww4g76


    Using this method you can definitively launch as many instances of Arma 3, the only limit is how much hellfire you want to create on/underneath/near your desk.
    working.png?rlkey=raf7wpxf50ba04poodz7dj


  10. 21 hours ago, RS30002 said:

    how do i use:

     

    
    TAG_react_condition = { true }; // _this contains the group to check, can be used to stop certain groups from responding

    i want to exclude some named units in the area, to not get the seek and destroy waypoint

     

    Something like this: 

    TAG_react_condition = { 
    	!(_this in [group unit_name_1, group unit_name_2]) 
    };

     

    Edit

     @RS30002 A better way is to do this:

    TAG_react_condition = { 
    	_this getVariable ["react_to_explosions", true] // Check the group's setting, by default all groups react
    };

    and in group's init (Attributes for the group/collection):

    this setVariable ["react_to_explosions", false]; // Disables reaction
    // or
    this setVariable ["react_to_explosions", true]; // Enables reaction

    This way you do not have to list every group that should ignore it, instead you can control everything in the editor without having to do additional changes to code every time you add a new group that shouldn't react.

    This also allows you to turn it on and off at will, for example when the group reaches a certain waypoint.

     

    You could also add interesting behaviours by checking against the skill of the unit, make more "disciplined" units stick to their post maybe...

    TAG_react_condition = {
     	_this getVariable ["react_to_explosions", true] 
    	&&
    	leader _this skillFinal "commanding" < 0.5 // only groups with poor leadership will react
    };

     

    • Like 1
    • Thanks 1

  11. 16 hours ago, Play3r said:

    @mrcurry i nned your help again.

     

    i can only make the script run one time. 

    if i place a explosive charge on the ground, and detonate it the units in the radius (set to 500) comes running.

    If i then place a new one they just keep going there own ways they don't come to look.

     

    @RS30002 Can you tried that?

     

    That's my bad, I missed to reset the "is reacting" flag when they were done with the investigation.

    They should react as soon as the investigation is complete now, even if they are on their way back to the original position.

    Also refactored the code a little bit to not run unnecessarily for soldier's who aren't group leaders.

    I've updated the code in this post. Tested and works.

     

    A better approach would be to queue up explosions and have the groups react in a prioritized fashion based on the closest one and spread the jobs about among several reacting groups... but I think the current setup is good enough.

    • Like 1
    • Thanks 1

  12. 1 hour ago, trollzor45 said:


    Are you referring to a way where multiple instances are running through steam? Because with what I have now, this method won't launch more than one instance. Through steam, it'll shut down the first instance, THEN start the second. I need both at the same time.

    To explain, the method I was referring to previously for hosting multiple clients is to directly launch the Arma 3 EXE file from its root folder. Which means my first instance (host) would be launched through steam, then my second instance (client) would be launched directly via the .exe. Through that method, I don't know how to launch with addons.

    Is there a way to get steam to launch multiple Arma instances? Or at the very least get the direct-from-exe instance to load with mods? I feel like I'm missing something.

     

    6 minutes ago, POLPOX said:

    You can just click PLAY button multiple times.

     

    Huh, I was gonna describe the good ol' technique of shortcuts... but that's way simpler yeah 😛

    Just remember to set your Launcher options to not close after launching the game like I had...

    A3L_Action_after_game_start.png?rlkey=0n

     

    • Like 1

  13. On 3/6/2024 at 10:57 AM, BeerBoz said:

    with the help of ChatGPT

    In short: don't.

     

    LLM's doesn't understand the code they write. At best this means they are unable to fix it unless you explicitly state what's wrong. At worst they introduce hard to spot bugs and/or security issues. On top of that you have implicit ownership of, and responsibility for, things you create. No matter which tools you use. If your shit hits the fan it's your responsibility to clean up the mess so you must either understand it or have access to someone who does.

     

    If you wish to learn code I'd happily help. There are plenty of resources online, read existing code examples and ask on these forums.

    If you want something coding related done either do it yourself or ask someone competent like over on the scripting request subforum.

     

    LLMs probably have their place in programming but that place is not (yet) helping non-programmers, that's like the blind leading the deaf.

    • Like 1

  14. On 2/29/2024 at 9:51 PM, Heavensrevenger said:

    Hello I want to spawn the explosion of the 30 mm MP-T from the LDF APC using createVehicle. I know you can spawn "HelicopterExploBig" and I was wondering if there was a CFGAmmo for the 30mm explosion.

    You could just spawn the equivalent CfgAmmo class nearby and send it into the ground using setVelocity or detonate it in the air using setDamage.

     

    To find the class you have to do some digging in the configs.


  15. On 3/2/2024 at 2:43 PM, JayBiro said:

    Essentially, I need to create a script that displays a specific PNG image on screen if an enemy is to the north, south, east or west of the player.

    
    Can this be done?

    Yes, the tricky part is actually the UI part.

     

    You need 5 image UI elements on top of each other and you need to make sure the image resolution matches.

    Then you just enable/disable the relevant UI elements as you need.

    Check out docs on the gui editor to get started.

     

    For detecting this approach should work:

    1. _near = nearEntities [ ... ], filter on base classes like "Man" or "CAManBase"
    2. _enemies = _near select {side _x == opfor }, replace "opfor" with your enemy side
    3. Loop over all _enemies, for each enemy _x get direction from player: _dir = player getDir _x
    4. Check _dir against predetermined sectors, 45 to 135 = east, 135 to 225 = south etc. Just remember to account for north wrapping around zero (left bound = 315, right bound = 45)
    5. Enable appropriate UI elements depending on the checks

     

    The code could run from the onLoad event handler of the ui or you could build the ui from code too.

     

    Let me know if you got any questions.

     


  16. On 3/1/2024 at 3:31 PM, Play3r said:

     

     

    Hi @mrcurry

     

    i get a error when i use the script.

    Don't know i i did it wrong, but did just copy the Server script to my initserver,sqf.

    also the initPlayerLocal,sqf was also got copied, but i get  error about a varible

    don't know if you can guide me on what to do, my line 27 is where right under the line:
    private _list = _position nearEntities ["CAManBase", TAG_react_radius] select { side group _x in TAG_react_sides };
            {    <- this is linie 27 in my script

     

    https://imgur.com/EvuRJTc

    i hope this helps.

     

    // Cheers Play3r

     

     

     

    I double-checked the code and there's no syntax errors on my end.

    The possible causes I can see are:

    A - You didn't the copy the entire code

    B - When you copied it some extra web characters came along for the ride

    C - You did some changes in the code after copying

     

    Considering the error message "Invalid number in expression" and it's position B seems most likely.

     

    Finding the solution:

    1. Make sure you copied the entire initServer.sqf code.
    2. When copying code from the forum make sure you copy only from a code section and only from one code section at the time. If the selection goes outside the code tags it can introduce errors. See the spoiler below for an example.
      Spoiler

      This is inside the spoiler tag

      
      //Code section 1
      //This is inside the code tag

      This is inside the spoiler tag

      
      // Code section 2

      Remember to check so you dont copy the extra line at the end

    3. If the problem persists open your initServer.sqf in a competent text editor like Notepad++ or VSCode and look for (and remove) these naughty little buggers:
      RogueUnicodeCharacters.png?rlkey=v532hly

     

    • Thanks 1

  17. 15 hours ago, trollzor45 said:

    What might be causing this?

     

    10 hours ago, Necropaulo said:

    Trigger is triggering localy, that's why when you're solo it's OK and with others players it's repeating.

     

    To expand on Necropaulo's answer: This is specifically a problem when using commands with global effect ( all clients see the effect automatically ) inside trigger code which runs locally on each machine. Every client executes the code which essentially multiplies the effect by # of players. You want a car? Everybody gets a car!

     

    15 hours ago, trollzor45 said:

    How do I fix this issue?

    If all code the trigger runs has global effect set it to "Server only", there should be a tickbox in the trigger's attributes editor.

    If you are mixing global and local you need to wrap local effects inside: if( iSserver ) then { ... };

    • Like 1

  18. It's been awhile since I worked with displays so maybe double check in your testing but as far as I can remember:

     

    On 2/27/2024 at 1:51 AM, dupa1 said:

    Does this mean that the display is completely destroyed when closing the artillery computer?

    Yes, closing the display = destroying it.

     

    On 2/27/2024 at 1:51 AM, dupa1 said:

    If I add event handlers every time the artillery computer is opened, do they stack up or are they destroyed together with the display?

    All event handlers are destroyed also.

     

    On 2/27/2024 at 1:51 AM, dupa1 said:

    Should I consider using ctrlSetEventHandler instead?

    Using Set is not recommended, it's a leftover from the old days of UI scripting. See the Biki page for more info.

    It definitely has nothing to do with the lifetime of the event handlers though.


  19. 1 hour ago, jsmith82 said:

    private _count = 0;

    {_count = _count + (_x select 2;)} forEach uniformMagazines player;

     

    You're not that far off. 🙂

     

    Firstly you have a misplaced semicolon inside the parentheses. The grammar is: Semicolon ends the statement and all round brackets (i.e. parentheses) needs to be "closed" before the end of the statement. Just don't mistake round brackets () with curly brackets {}.

     

    Secondly uniformMagazines et. al. return an array of strings so your _x select 2 just gets the 3rd (yes 3rd, 0 is the 1st) character in what happens to be the mag's name. No Bueno!

    To fix this without string-magic you can just use: magazinesAmmo player

    This command gets the data in the format you expect with the added bonus of getting uniform, vest and backpack in one go while ignoring loaded mags.

     

    If you needed more nudges just ask. 

     

    Edit: Dammit @Harzach! 😛

    • Haha 1

  20. 13 hours ago, trollzor45 said:

     I'm intending to make this multiplayer, and I'm not sure how wide of a scope "player" has.

     

    'player' script command returns the player object on the machine where it is executed. This quirk means if we're both connected to the same dedicated server the following would be true:

     

    - On my PC: name player == "mrcurry"

    - On your PC: name player == "trollzor45"

    - On the server: name player == "Error: No unit" (or "",  I don't remember exactly )

     

    13 hours ago, trollzor45 said:

    If someone walks through my say3D trigger, will ALL players play my .wav file? Or just the player who triggered it?

     

    Depends on the activation and condition of the trigger.

     

    Triggers are evaluated on every machine individually and the trigger's state (activated/not activated) is not synchronized. If you want something to happen at the same time for all machines you have to make sure the conditions in which they activate will occur at the same time across all machines.

     

    This will result in a synchronized activation:

    Trigger activation: Any player

    Condition: this

     

    This also (assuming a player-unit is named 'someDude' in editor):

    Trigger activation: Any player

    Condition: someDude in thisList

     

    This will not (see aforementioned quirk regarding 'player' above):

    Trigger activation: Any player

    Condition: player in thisList

     

    Hope that clears things up a bit, if not just ask away.

    • Like 1

  21. On 2/25/2024 at 3:06 PM, Gunter Severloh said:

    you could set a

    waypoint set it to guard

     

    Huh, wasn't aware of this caveat of the guard waypoint. Pretty neat and simple to setup.

    However I did some testing and it does seem a bit hit & miss. They'll take a full 2 minutes to react to an explosion 500 m away when there's only the explosion and no known enemy targets.

    While it's probably realistic, as a player sitting and waiting for them to move, that's tad long since there are no visual or audible cues from their decision making...

    They also won't move to where the explosion happens but rather stop nearby, and there's seem to be no search when they do arrive like with a S&D waypoint.

    Since I was already writing up something that acts closer to how I imagined it I'll just post that below.

    -----------------------------------------------------

    It'd be nice if we had a mission event handler for explosions for this but as of today no such luck. So we have to jump through some hoops.

    On 2/24/2024 at 6:28 PM, Play3r said:

    player can detonate some C4 or make a truck blow up

    Note that from the game's perspective those are 2 very different actions to monitor.

    That means you have to attack this from two directions.

    1. Handle vehicles exploding
    2. Handle player detonating an explosive

    Handle vehicles exploding

    Add event handlers to all vehicles (including spawned vehicles)

    Create initServer.sqf in your mission root and fill it with:

    Spoiler
    
    // A few settings
    TAG_react_radius = 1000;
    TAG_react_sides = [opfor];
    TAG_react_behaviours = ["SAFE","AWARE"];
    TAG_speed_of_sound = 343;
    TAG_vehicle_classes = ["Car", "Tank", "Helicopter", "Plane"];
    TAG_react_condition = { true }; // _this contains the group to check, can be used to stop certain groups from responding
    
    TAG_fnc_eh_react_to_explosion = {
    	params ["_position", "_damage", "_source"];
    	//diag_log text format ["Boom - p: %1     d: %2     s: %3", _position, _damage, _source];
    	if( _position isEqualType objNull ) then { _position = getPos _position; };	
    
    	if ( !isNull _source && _damage > 0.01 ) then {
    		
    		private _list = _position nearEntities ["CAManBase", TAG_react_radius] select { side group _x in TAG_react_sides };
    		{
    			if( behaviour _x in TAG_react_behaviours && !( group _x getVariable ["TAG_is_deciding_reaction", false] ) ) then {
    				if( leader _x == _x ) then {
    					group _x setVariable ["TAG_is_deciding_reaction", true];
    					
    					[_x, getPos _source, _x distance _position] spawn {
    						params ["_x", "_to", "_dist"];
    						private _grp = group _x;
    
    						// Simulate sound propagation and human reaction time
    						sleep ( _dist / TAG_speed_of_sound ); 
    
    						if( _grp call TAG_react_condition ) then {		
    							// Simulate human decision making time
    							sleep ( 5 + floor random 5 ); 
    
    							private _original_wp = currentWaypoint _grp;
    							private _wp = _grp addWaypoint [_to, 15, _original_wp];
    							_wp setWaypointBehaviour "AWARE";
    							_wp setWaypointType "SAD";
    							_wp setWaypointSpeed "NORMAL";
    							_wp setWaypointForceBehaviour true;
    
    							_grp setCurrentWaypoint _wp;
    							
    							sleep 15;
    
    							_wp setWaypointForceBehaviour false;
    							
    							if( _original_wp > 0 ) then {
    								// Wait for Seach & Destroy wp to complete
    								waitUntil { currentWaypoint _grp > _wp # 1 };
    
    								deleteWaypoint _wp;
    								// Return to previous waypoint
    								if( count waypoints _grp > 0 ) then {
    									_grp setCurrentWaypoint [_grp, _original_wp - 1];
    								};	
    							};
    
    							_grp setVariable ["TAG_is_deciding_reaction", false];
    						} else {
    							_grp setVariable ["TAG_is_deciding_reaction", false];
    						};
    					};
    				};
    			};
    		} forEach _list;
    	};
    };
    
    // Loop over all vehicles and add event handlers to handle explosions
    { 	
    	_x addEventHandler [ "Killed" , 
    		{
    			params ["_veh", "", "", "_useEffects"];
    			if( _useEffects && { 
    				{ alive _x && behaviour _x in ["COMBAT", "STEALTH"] } count crew _veh == 0 
    			} ) then {
    				[_veh, 1, _veh] call TAG_fnc_eh_react_to_explosion;
    			};
    		} 
    	];
    	_x addEventHandler [ "Explosion", TAG_fnc_eh_react_to_explosion ];
    } forEach vehicles;

     

     

     

    Handle player detonating an explosive

    Add event handlers for when a player placed explosive explodes.

    Create initPlayerLocal.sqf in your mission root and fill it with: 

    Spoiler
    
    player addEventHandler [
    	"FiredMan", 
    	{
    		params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle"];
    		if( _weapon == "Put" ) then {
    			// Check if a it's an explosive device
    			if( _ammo isKindOf ["TimeBombCore", configFile >> "CfgAmmo"] ) then {
    				_projectile addEventHandler [ "Explode", 
    					{
    						params ["_projectile", "_pos"];
    						private _args = [ ASLToAGL _pos, 1, _projectile ];
    						if( isServer ) then {
    							_args call TAG_fnc_eh_react_to_explosion;	
    						} else {
    							_args remoteExec ["TAG_fnc_eh_react_to_explosion", 2];
    						};
    					}
    				];
    			};
    		};
    	}	
    ];

     

     

    • Like 2
    • Thanks 1
×