Jump to content

Making a recharging weapon play reload and jamming animations


ignorantslave

Recommended Posts

Hello! I'm currently working on a custom weapon which is supposed to resemble the L-STAR light machine gun from Titanfall 2 both in looks and functionality. So you should be able to fire it forever as long as you don't let it overheat, that is, run out of ammo.

Now, recharger rifles and pistols work basically the same, and my gun uses the same ammo regen function, but using said function disables reload and jam animations, and I would like for my gun to play both in sequence if the ammo count reaches 0.

So I wrote a script, using a function from the JIP NVSE plugin to check for the actor's current ammo and play the animations when the clip is depleted, and it works technically.

scn LSTARechargeScript

int CurAmmo

begin gamemode
   Ref dude
      set dude to GetContainer
      set CurAmmo to dude.GetCurrentAmmoRounds
          if CurAmmo < 1
              dude.PlayGroup ReloadD 0 
              dude.PlayGroup JamD 0 
              dude.PlayGroup Idle 1 
          endif
end

The problem is, the PlayGroup function picks the one-handed versions of the reloadD and JamD animgroups instead of the two-handed versions which would work with my gun (I nif-bashed it around the gauss rifle mesh), and I don't know how to selectively pick the animations I want.

Is there a better way to write the script, or a completely different approach to achieve the same results?

 

Link to comment
Share on other sites

Ok, so I tried to use another JIP function, PlayAnimSequence, and while it allowed me to pick the correct reload animation for the gun, it was somehow bugged and prevented me from actually firing the gun afterwards. So I decided to use another method.

Instead of scripting a recharging weapon to play reload animations, I removed the ammo regen part and simulated it using this script

scn LSTARechargeScript

float timer
int AmmoClip
int CurAmmo

begin gamemode
   set AmmoClip to 35
   Ref dude 
   set dude to GetContainer

   if timer < 0.7
      set timer to timer + GetSecondsPassed
   else
      if dude.GetItemCount AmmoMicroBreeder == 0
           dude.AddItem AmmoMicroBreeder 1 1
      endif
      set CurAmmo to dude.GetCurrentAmmoRounds
          if CurAmmo == 0
          Return
          elseif CurAmmo < AmmoClip 
               set CurAmmo to (CurAmmo + 1)
               dude.SetCurrentAmmoRounds CurAmmo
          endif
      set timer to 0
   endif
end

I'm not sure if it's in any way efficient, and it's definitely not elegant (the total ammo count goes in the negatives) but it's functional, and now I just need to test it with NPCs. This way, the gun handles like a powerful recharger rifle/plasma gun hybrid (complete with recolored red plasma effects), with reloading being a penalty for squeezing the trigger for too long.

Link to comment
Share on other sites

Well first of all. Begin GameMode runs every frame, no matter if you use an item or not and therefor it leaks to ALL other weapons as you have not specified which weapon you have equipped. So if Equipped this weapon then: bla bla. I do not remember how to check what you are holding in you right hand, but I recall there was an obse command for it in Oblivion.

There is a more simple way really:

As a supplement to begin GamMode, you could use Begin OnEquip and OnUnEquip and set a short IGNMySpecificWeapon, set it to 1 when you equip the weapon and to 0 when you unequip it. Well use all 3.

 

Scn IGNWeaponanimationsSCR

short IGNMySpecificWeapon
ref IGNMyWeapon

Begin OnEquip
	Set IGNMyWeapon to ThisWeaponBaseID
	Set IGNMySpecificWeapon to 1
end

Begin GameMode
	If (IGNMySpecificWeapon ==1) && (GetEquipped == IGNMyweapon)
		Your code
	Endif
End

Begin OnUnEquip
	Set IGNMySpecificWeapon to 0
end

You have to check GetEquipped if it exist or not, but I recall something similar exist.

AHHHH!!!!   Begin OnActorEquip ObjectID will work as the script above still applies to all stuff you equip in the current state. That will make the check for GetEquipped pointless.

Edited by Pellape
Link to comment
Share on other sites

1 hour ago, Pellape said:

Well first of all. Begin GameMode runs every frame, no matter if you use an item or not and therefor it leaks to ALL other weapons as you have not specified which weapon you have equipped. So if Equipped this weapon then: bla bla. I do not remember how to check what you are holding in you right hand, but I recall there was an obse command for it in Oblivion.

There is a more simple way really:

As a supplement to begin GamMode, you could use Begin OnEquip and OnUnEquip and set a short IGNMySpecificWeapon, set it to 1 when you equip the weapon and to 0 when you unequip it. Well use all 3.

 

Scn IGNWeaponanimationsSCR

short IGNMySpecificWeapon
ref IGNMyWeapon

Begin OnEquip
	Set IGNMyWeapon to ThisWeaponBaseID
	Set IGNMySpecificWeapon to 1
end

Begin GameMode
	If (IGNMySpecificWeapon ==1) && (GetEquipped == IGNMyweapon)
		Your code
	Endif
End

Begin OnUnEquip
	Set IGNMySpecificWeapon to 0
end

You have to check GetEquipped if it exist or not, but I recall something similar exist.

AHHHH!!!!   Begin OnActorEquip ObjectID will work as the script above still applies to all stuff you equip in the current state. That will make the check for GetEquipped pointless.

Hey thanks for the reply! I decided to take a peak at another mod which uses similar scripts for special weapon behavior, and there were OnEquip checks to prevent the above leak from happening.

So I wrote it like this

scn LSTARechargeScript

float timer
int AmmoClip
int CurAmmo
int Equipped
Ref dude

begin OnEquip
   set Equipped to 1
end

begin gamemode
   if Equipped == 1
      set AmmoClip to 35
 
      set dude to GetContainer

      if timer < 0.7
         set timer to timer + GetSecondsPassed
      else
         if dude.GetItemCount AmmoMicroBreeder == 0
              dude.AddItem AmmoMicroBreeder 1 1
         endif
         set CurAmmo to dude.GetCurrentAmmoRounds
             if CurAmmo == 0
             Return
             elseif CurAmmo < AmmoClip 
                  set CurAmmo to (CurAmmo + 1)
                  dude.SetCurrentAmmoRounds CurAmmo
             endif
         set timer to 0
      endif
   endif
end

begin OnUnequip
   set Equipped to 0
end

begin OnDrop
   set Equipped to 0
end

Seems to be working. Uhm but tomorrow I will update the code with the additional conditions you proposed, just to be sure.

Link to comment
Share on other sites

@ignorantslaveYes do that as I bet that script will still be running every single frame and on ALL weapons as I cannot see if you did specify a specific form/object and using the OnActorEquip, will save some resources as well  😄   Damn the way the older games handle scripting is a bit dangerous, if you do not know this. Papyrus scripts are impossible to loop in the way F3 loop scripts and that is both good and bad. I hate Papyrus...  😉   I do not understand it really and I assure you I had a lot of debates and help from the Skyrim community, still I am not wiser.  😄  It is good however for the game performance, to not let all scripts run at each frame. I make as many Quest Scripts as possible, as they only run every 3rd second default, not every frame and I did see your nice 0.7s timer, which is very proper to use.

Another thing I dislike with Papyrus is that the modder decide if they want to share the source or not, which makes it even harder to learn how some solved some stuff as the compiled scripts are separated from the mod itself. So frustrating. Why on earth would a modder not share their scripts?  I do not understand it really, but that is me. I did make 2 mods with Papyrus and I did share my source as well.

Edited by Pellape
Link to comment
Share on other sites

  • Recently Browsing   0 members

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