Joshlaryeth Posted December 15, 2020 Share Posted December 15, 2020 What would the script be like for, say: a weapon has 4 shots in a magazine and total, get remaining ammo after "weaponfire". Link to comment Share on other sites More sharing options...
NoCashNoExp Posted December 15, 2020 Share Posted December 15, 2020 (edited) 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 December 15, 2020 by NoCashNoExp Link to comment Share on other sites More sharing options...
SKKmods Posted December 15, 2020 Share Posted December 15, 2020 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 More sharing options...
NoCashNoExp Posted December 15, 2020 Share Posted December 15, 2020 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 More sharing options...
shavkacagarikia Posted December 15, 2020 Share Posted December 15, 2020 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 More sharing options...
NoCashNoExp Posted December 16, 2020 Share Posted December 16, 2020 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 More sharing options...
Recommended Posts