Jump to content

Getting Ammo Count


Joshlaryeth

Recommended Posts

I also wanted to get the current amount of bullets in the player's magazine. I have done my research and flipped through the FO4 papyrus documentation multiple times. So, let me give you a summary and tell you what I've found.

 

Problems (These are limitations of CK):

 

1 - There's no way to get the number of bullets in the player's magazine.

2 - There's no way to get the player's gun weapon ammo capacity (i.e the maximum number of bullets that the gun's chamber can hold).

3 - There's a way to get the type of ammo the weapon is using. The function is called GetAmmo() but it only returns the default ammo so if they player installed a mod that changes the ammo type, GetAmmo() will not work properly.

 

Possible Workarounds:

 

1 - If we could somehow detect the player firing and update a virtual ammo counter in our script. When the player reloads their weapon, the ammo counter would be reset to the gun's max ammo capacity so it heavily relies on (2) to in order to work.

 

We can successfully detect if the player reloaded by listening to the "reloadComplete" animation event.

 

"weaponFire" animation event only works for semi automatic weapons, for automatic weapons the event is called multiple times for each shot. This means that for automatic weapons our ammo counter would be incorrect.

 

Another solution, listen to player onItemRemoved event with the ammo type of the weapon as filter (again heavily relies on (3) in order to work). The premise is that if 1 bullet was removed from the player's inventory while their weapon is drawn then it MIGHT be a bullet that was shot. Huge emphasis on might because it also might be a single bullet that was sold, moved to a container, dropped from inventory or other edge cases that I am not aware of.

 

2,3 - You could maintain a list of weapons and their ammo capacity/type but there's mods that modify ammo count/ammo type. There's no way to get a list of mods attached to a weapon in CK

 

Another solution (Requires F4SE), F4SE has a script called instance data which allows you to accurately get the weapon's ammo capacity and the ammo type even with mods attached that modify them. I could never get this working, if you manage to get it working kudos to you.

 

TL;DR: There are even more edge cases that I am not going to discuss because this is already too much. Only test these things if you're invested in making this mod. But my personal advice is that it's not worth it in my opinion.

Edited by NoCashNoExp
Link to comment
Share on other sites

You have hit all the same ammo data issues I have over a couple of years of poking the concept. But I can help with base game ammo type.

 

This is based on an ObjectReference *NOT* a weapon form, typically by dropping the weapon from a container because it may or may not have OMODs and therefore retain it ObjectReference in inventory.

Function DoingStuff()

Weapon EquippedWeaponForm  =  ThisActor.GetEquippedWeapon()
ThisActor.UnequipItem(EquippedWeaponForm, abPreventEquip = false, abSilent = true)
ObjectReference EquippedWeaponReference = ThisActor.DropObject(EquippedWeaponForm, aiCount = 1)
Ammo EquippedWeaponAmmo = GetAmmoForWeapon(EquippedWeaponReference)

EndFunction

;******************************************************************************************************************** 

Ammo Function GetAmmoForWeapon(ObjectReference ThisWeapon) 

Ammo ThisAmmo = (ThisWeapon.GetBaseObject() as Weapon).GetAmmo() 

If (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted) == True) 

   If (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted38) == True) 
      ThisAmmo = pAmmo38Caliber 
   ElseIf (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted308) == True) 
      ThisAmmo = pAmmo308Caliber
   ElseIf (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted45) == True)
       ThisAmmo = pAmmo45Caliber 
   ElseIf (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted50) == True) 
      ThisAmmo = pAmmo50Caliber 
   Endif
EndIf 

Return ThisAmmo 

EndFunction 

;******************************************************************************************************************** 

Link to comment
Share on other sites

 

You have hit all the same ammo data issues I have over a couple of years of poking the concept. But I can help with base game ammo type.

 

This is based on an ObjectReference *NOT* a weapon form, typically by dropping the weapon from a container because it may or may not have OMODs and therefore retain it ObjectReference in inventory.

Function DoingStuff()

Weapon EquippedWeaponForm  =  ThisActor.GetEquippedWeapon()
ThisActor.UnequipItem(EquippedWeaponForm, abPreventEquip = false, abSilent = true)
ObjectReference EquippedWeaponReference = ThisActor.DropObject(EquippedWeaponForm, aiCount = 1)
Ammo EquippedWeaponAmmo = GetAmmoForWeapon(EquippedWeaponReference)

EndFunction

;******************************************************************************************************************** 

Ammo Function GetAmmoForWeapon(ObjectReference ThisWeapon) 

Ammo ThisAmmo = (ThisWeapon.GetBaseObject() as Weapon).GetAmmo() 

If (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted) == True) 

   If (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted38) == True) 
      ThisAmmo = pAmmo38Caliber 
   ElseIf (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted308) == True) 
      ThisAmmo = pAmmo308Caliber
   ElseIf (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted45) == True)
       ThisAmmo = pAmmo45Caliber 
   ElseIf (ThisWeapon.HasKeyword(pdn_HasReceiver_Converted50) == True) 
      ThisAmmo = pAmmo50Caliber 
   Endif
EndIf 

Return ThisAmmo 

EndFunction 

;******************************************************************************************************************** 

 

Thank you so much, that helps quite a lot. I already resorted to using F4SE but if I ever decide to convert the mod to use papyrus only, this is definitely a step in the right direction.

Link to comment
Share on other sites

if you are using f4se there is also an alternate way to get it without using instance data, from ammo count interface element directly

int Function GetMagazineAmmoCount()
 int ret = -1
 if UI.IsMenuOpen("HUDMenu")
   string txt = UI.Get("HUDMenu", "root1.RightMeters_mc.AmmoCount_mc.ClipCount_tf.text") as string
   ret = txt as int
 endif
 return ret
endFunction
Link to comment
Share on other sites

 

if you are using f4se there is also an alternate way to get it without using instance data, from ammo count interface element directly

 

int Function GetMagazineAmmoCount()
 int ret = -1
 if UI.IsMenuOpen("HUDMenu")
   string txt = UI.Get("HUDMenu", "root1.RightMeters_mc.AmmoCount_mc.ClipCount_tf.text") as string
   ret = txt as int
 endif
 return ret
endFunction

 

Thank you so much, I can finally clean up the messy workaround that I've wrote to get ammo count.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...