Jump to content
AgentRev

Execute code when unit reloads weapon

Recommended Posts

Is there any way at all to execute code whenever a remote player starts to reload its weapon? There's no "Reload" event, the "AnimChanged" and "AnimStateChanged" events are not fired on reload, the "Take" event only fires after the reload is fully completed, and I can't think of any other way. Any help would be appreciated.

Share this post


Link to post
Share on other sites

Thanks, but what I am trying to do is find out when a human player manually starts to reload his gun, regardless of how many magazines he has or how much ammo that is left in the gun. If that code was adapted to a player, it would trigger every time a mag is taken from the inventory, which happens after a reload is entirely complete or when the player drops a magazine somewhere.

Share this post


Link to post
Share on other sites

how about using keydown eventhandler and checking for reload action.

waitUntil {!(isNull (findDisplay 46))};
menu = (findDisplay 46) displayAddEventHandler ["KeyDown", "if ((_this select 1) in actionKeys ""ReloadMagazine"") then {hint 'reload'}"];

  • Like 1

Share this post


Link to post
Share on other sites
how about using keydown eventhandler and checking for reload action.

What if the player uses the action menu to reload?

Share this post


Link to post
Share on other sites
What if the player uses the action menu to reload?

however a player reloads fires this. it detects everything that is linked to reloading. whatever key you have it mapped to and the action menu.

UPDATE: looks like I was wrong or it doesn't work with arma3. it doesn't detect reloading thru action menu. just mouse buttons and keys.

Edited by Nimrod_Z

Share this post


Link to post
Share on other sites
however a player reloads fires this. it detects everything that is linked to reloading. whatever key you have it mapped to and the action menu.

UPDATE: looks like I was wrong or it doesn't work with arma3. it doesn't detect reloading thru action menu. just mouse buttons and keys.

Alright, thanks nonetheless.

Share this post


Link to post
Share on other sites

try it with the "AnimChanged" EventHandler.

Set it up, that it hints the secont return parameter, and reload. Then you see what animation is the reload anim.

Do this with all Weapons (i think every weapon has its own reload anim) and make a switch/case to check if the given anim in the second parameter is one of your collectet reload anims.

Share this post


Link to post
Share on other sites
try it with the "AnimChanged" EventHandler.

Set it up, that it hints the secont return parameter, and reload. Then you see what animation is the reload anim.

Do this with all Weapons (i think every weapon has its own reload anim) and make a switch/case to check if the given anim in the second parameter is one of your collectet reload anims.

Doesn't work on reload.

Share this post


Link to post
Share on other sites

you can use take eventhandler.

Because each time a player is reloading, is taking a magazine in his cargo. So you just have to test if (unit == cargo), wich weapons has the unit and if the unit has taken a magazine for this weapon.

  • Like 1

Share this post


Link to post
Share on other sites
you can use take eventhandler.

Because each time a player is reloading, is taking a magazine in his cargo. So you just have to test if (unit == cargo), wich weapons has the unit and if the unit has taken a magazine for this weapon.

Interesting idea, would like to know if this would work!

Share this post


Link to post
Share on other sites
you can use take eventhandler.

Because each time a player is reloading, is taking a magazine in his cargo. So you just have to test if (unit == cargo), wich weapons has the unit and if the unit has taken a magazine for this weapon.

As said in my original post, I specifically mentioned "the "Take" event only fires after the reload is fully completed". I need it to fire at the start of the reload, not at the end.

Share this post


Link to post
Share on other sites

I know, I know, this post is 5 years old...  But has anyone discovered a way since then to detect if an AI unit is in the act of reloading?  Their animationState does not change, so that does not work...

Share this post


Link to post
Share on other sites
32 minutes ago, GEORGE FLOROS GR said:

Thanks George, but that does not fire until after reload animation is complete.  My problem is with my move AI script. I want to prevent AI from moving while reloading, because they stupidly go through a door before weapon is loaded and get killed.

  • Like 2

Share this post


Link to post
Share on other sites

Well, the only way I can think of at the moment is to constantly check (I HATE it when it comes to constant checks 😠) the objects the unit is "holding" and when you spot the absence of a magazine in the gun then execute the code.

 

One example I found was in BIKI of weaponsItems command. It actually returns everything you can see on the right hand side of your inventory. So, you can perform checks for magazines and if you don't find one, prevent the unit from moving until it reloads...

This of course brings more trouble as you may have to check if the unit is out of ammo in general..., in which case its best bet is to start running and not stay put 😆.

 

Again, I really don't like performing constant checks so I will look for another solution. If I think of something I will let you know.

 

EDIT: I believe that currentMagazine will do better as you won't have to search in any array...

 

Yet to come up with a good solution though :sad_o:.

  • Like 3

Share this post


Link to post
Share on other sites
31 minutes ago, ZaellixA said:

EDIT: I believe that currentMagazine will do better as you won't have to search in any array...

Thanks man.  You have put me on the right trail I think.  currentMagazineDetail gives you the # of rounds left in magazine. In example below I have zero rounds left in in a 5 shot magazine:

currentMagazineDetail player;

// Returns:   "5Rnd .00 Buckshot(0/5)[id/cr:10001293/0]"

So If I do some fancy string parsing (get the character following first "(", and if its a zero, then the dude's weapon is empty).  To prevent having to have a constantly running loop, I could add add this check to a fired eventHandler on the unit.  I then set a variable on unit to flag him as "Reloading", and wait until the bullet count > zero before allowing him to move again.  Note I am fudging and adding magazines magically to ai units that use my move script.  It's way too much trouble to deal with units running out of ammo before completing a building clear operation.

  • Like 3

Share this post


Link to post
Share on other sites

Sounds good. I am glad you found the right command for you. Initially I though you could check the current magazine and when this goes "" or [] or nil, you would know that the gun is empty. I guess your approach saves some overhead due to the eventHandler use. So about the parsing, I believe you could use the "quite efficient" findIf command and do something like this

private _magInfo = currentMagazineDetail _unit; // Get the info
_subStrings = _magInfo splitString  "(/"; // Split between the first parentheses and the backslash (plus more that you don't need)
_numOfBullets = toArray (_subStrings select 1); // Get the second element of the split string array

Now, if there are no gun names with parentheses then this should work correctly. Of course, as always this needs TESTING... But I believe it's a good start. Thanks for sharing your solution :thumbs-up:

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
3 minutes ago, ZaellixA said:

private _magInfo = currentMagazineDetail _unit; // Get the info _subStrings = _magInfo splitString "(/"; // Split between the first parentheses and the backslash (plus more that you don't need) _numOfBullets = toArray (_subStrings select 1); // Get the second element of the split string array

That splitString is awesome thanks. 

  • Like 1

Share this post


Link to post
Share on other sites

Yep, just checked it and I have a bug fix already 😄

 

private _magInfo = currentMagazineDetail _unit; // Get the info
_subStrings = _magInfo splitString  "(/"; // Split between the first parentheses and the backslash (plus more that you don't need)
_numOfBullets = parseNumber (_subStrings select 1); // Get the second element of the split string array as number

toArray returns an array with one element, but it is still an array and you won't be able to use it easily in other parts of your code. So you replace the one-element-array in the _numOfBullets with the one element included but now as a number.

 

Sorry for not seeing this early on...

 

EDIT: I changed the code snippet in accordance to killzone_kid's comment below. Now it uses parseNumber to get the number, so no need for the toArray and all the selects.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
6 hours ago, ZaellixA said:

Get the element as number

There is parseNumber for that 

  • Like 3

Share this post


Link to post
Share on other sites
12 hours ago, johnnyboy said:

Thanks George, but that does not fire until after reload animation is complete.

We have new reload eventhandlers that fire before and after reload. But they are mod config only.

10 hours ago, johnnyboy said:

get the character following first "("

Magazine names might contain ()

https://github.com/acemod/ACE3/blob/master/addons/ballistics/stringtable.xml#L1645

Just search for Mag_Name in here and count the names containing ().

 

  • Like 3

Share this post


Link to post
Share on other sites

Hhhmmm, it's good to know those eventHandlers exist.

 

Checked the link as you said and unfortutantely there are magazines with both numbers and '('. But I didn't see any with some backslash in the name which could be used to get the amount of bullets left. I did have a quick look to find some short way to do that but unfortunately I didn't manage to do much. What I have so far is the following code which manages to get the part before the backslash (hehe, the easy part 😄). I don't have much time at the moment but I'll try again later and update with resulst

_magInfo = currentMagazineDetail _unit; // Get the magazine details
_bulletIndex = _magInfo find "/"; // Find the index of the character '/' in the string

//_numOfBullets = _magInfo select [_bulletIndex - 3, 3]; // You can chop it like this if you want
_numOfBullets = "";

for "_i" from (_bulletIndex - 3) to _bulletIndex do {
  _temp = _magInfo select[_i, 1]; // Get the current character
  // FIND A GOOD WAY TO COMPARE IT TO NUMBERS AND IF IT IS A NUMBER ADD IT TO THE _numOfBullets STRING;
  };
};

_numOfBullets = parseNumber _numOfBullets; // Get the number as a number :|

 

Once more thanks for the info Dedmen.

  • Like 2

Share this post


Link to post
Share on other sites
2 minutes ago, ZaellixA said:

But I didn't see any with some backslash in the name

Well atleast in ACE there aren't.

I think safest way is to just find the LAST ( in the string. Anything could be in the displayname, but we know how the data after the display name looks like, and the last ( is always the correct one.

  • Like 1

Share this post


Link to post
Share on other sites

Use magazinesAmmoFull instead, and just look for the mag that is in the units current muzzle that is being used to fire?

_unit addEventHandler [ "FiredMan", {
	params[ "_unit", "_weapon", "_muzzle" ];
	
	magazinesAmmoFull _unit select{
		( _x select 4 ) isEqualTo _muzzle
	} select 0 params[ "", "_ammoCount" ];
	
	if ( _ammoCount isEqualTo 0 ) then {
		hintSilent "Unit reloading";
	}else{
		hintSilent format[ "AC: %1", _ammoCount ];
	};
}];

 

  • Like 1
  • Thanks 2

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×