Aller au contenu

Photo

Cannot get actions to go in order!


  • Veuillez vous connecter pour répondre
11 réponses à ce sujet

#1
Ubai

Ubai
  • Members
  • 88 messages

I am trying to get a player to play an animation, then unequip a weapon, in that exact order. This should be easy, but no matter what I try, the animation never plays and the weapon is instantly unequipped. I have tried everything I can think of, and nothing has worked. Here is my latest attempt this script is called on the player from another script:

void main()
{
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, OBJECT_SELF);
ActionPlayAnimation(ANIMATION_LOOPING_GUITARPLAY, 1.0f, 3.0f);
ActionUnequipItem(oWeapon);
}

According to everything I have found on the internet so far this should work, but it doesn't. I have tried all the various action functions, I have tried wrappers, I have tried delaying the unequip, nothing works, and I am at my wit's end. Can anyone provide me with a script that works properly or point out what is wrong?

 

Thanks!

Matt



#2
kevL

kevL
  • Members
  • 4 052 messages
instead of Action/PlayAnimation() - NwN1 functions
look into PlayCustomAnimation() - NwN2 function.

http://nwn2.wikia.co...CustomAnimation
http://nwn2.wikia.co...t_of_animations

There's a learning-curve to get the hang of it,
  • Ubai aime ceci

#3
Tchos

Tchos
  • Members
  • 5 030 messages

Note that PlayCustomAnimation is an instant command that does not go into the action queue as ActionPlayAnimation does, so if it needs to go after something, then you'd need to wrap it in something like DelayCommand or ActionDoCommand, but to do that, you'd need to also wrap it in a function that returns void, because I think PlayCustomAnimation returns an integer, and the wrappers I mention only work on void functions.


  • Ubai aime ceci

#4
Ubai

Ubai
  • Members
  • 88 messages

I have tried that already with no better results. So far I have tried PlayCustomAnimation , ActionDoCommand, AssignCommand, DelayCommand, together separately, and in just about every combination I could think of. I also tried sticking in an ActionWait, but that did nothing.

 

The problem seems to be the unequip action, it only seems to have two gears: it either fires instantly or it fires after everything else. If I use the action by itself it goes off while the player is still attacking. If I try and delay it it fires only after everything else is done. I don't know, maybe my script is interfering with the combat round, or maybe there's some trick, but I've been experimenting for two days now with no joy.

 

If anyone can replicate the problem I am having or even show me a script that works for them I would appreciate it.

 

Thanks,

Matt



#5
kevL

kevL
  • Members
  • 4 052 messages
void unequip()
{
    object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, OBJECT_SELF);
    ActionUnequipItem(oWeapon);
}

void main()
{
    PlayCustomAnimation(OBJECT_SELF, "playguitar", FALSE, 1.f);
    DelayCommand(3.f, unequip());
}

edit: that's not tested in combat tho.
  • Ubai aime ceci

#6
kevL

kevL
  • Members
  • 4 052 messages
updated version ( tested in combat )

void unequip()
{
    SetCommandable(TRUE);
    object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
    ActionUnequipItem(oWeapon);
}

void main()
{
    ClearAllActions(TRUE);
    PlayCustomAnimation(OBJECT_SELF, "playguitar", FALSE, 1.f);

    DelayCommand(3.f, unequip());
    SetCommandable(FALSE);
}

  • Ubai aime ceci

#7
Ubai

Ubai
  • Members
  • 88 messages

This works perfectly, and I think I'm going to go ahead and use it.

 

Unfortunately, I realized halfway through all this experimentation that it would be better if the weapon got unequipped as it was being "put away" so I tried putting the unequip line first to see if I could make it look a little nicer. However, the unequip goes last no matter what, even though it is wrapped in a void returning function it ignores DelayCommand and only fires after everything else in the script is done.

 

It doesn't look terrible or anything, it just looks a little odd when the player does the put away animation but is still holding the gun for a second before it actually goes back into inventory. I wish I had realized all this sooner, then I wouldn't have wasted everyone's time! :(

 

Thanks,

Matt



#8
4760

4760
  • Members
  • 1 204 messages

I tried putting the unequip line first to see if I could make it look a little nicer. However, the unequip goes last no matter what, even though it is wrapped in a void returning function it ignores DelayCommand and only fires after everything else in the script is done.

 

Did you change the delays? In kevL's script, the unequip part is run 3 seconds after the script is fired. Even if you reduced it to 1.f, it may still occur last because the other parts have a shorter duration.



#9
kevL

kevL
  • Members
  • 4 052 messages
in my testing estimation, I left it at 3.f -- but i figured a more accurate value is ~2.8f

/for "playguitar"

but that's def. tweakable

--
edit: But if you want the weapon to disappear mid-way through the animation ... that'd be more involved, if not impossible

(wonder if copy & destroy object would work...)
  • Ubai aime ceci

#10
Ubai

Ubai
  • Members
  • 88 messages

KevL, you are a genius! Copying and destroying the object works a treat. :) Here is the finished code, please let me know if anyone sees any errors or possibilities for refinement:

// unequipfirearm
/*
	Description: "Unequips" a firearm that is out of bullets. We had to use DestroyObject 
        because ActionUnequip is too hard to time correctly.
        Thanks to Tchos, KevL, and 4760 for their advice and input
        3/22/2016
*/

//wrapper for PlayCustomAnimation
void ReallyPlayCustomAnimation(object oObject, string sAnimationName, int nLooping, float fSpeed = 1.0f)
	{
         PlayCustomAnimation(oObject, sAnimationName, nLooping, fSpeed);
	}

void main()
{
    ClearAllActions(TRUE);
	//just trying to prevent any duping or other weirdness here
	SetCommandable(FALSE);
	DelayCommand(1.4f, SetCommandable(TRUE));
	//copy the gun and its variables, then destroy the one that is equipped
	object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
	CopyObject(oWeapon, GetLocation(OBJECT_SELF), OBJECT_SELF);
	AssignCommand(oWeapon, SetIsDestroyable(TRUE, FALSE) );
	DestroyObject(oWeapon, 1.5f, FALSE);
	DelayCommand(1.6f, ReallyPlayCustomAnimation(OBJECT_SELF, "cbow_unequipW", 0, 0.5f));
}

Now I can get to work on the remaining gun feats and the reload progress bar XML stuff!

 

Thanks everyone, I really appreciate all your help. :)

-Matt



#11
kevL

kevL
  • Members
  • 4 052 messages
holy bleep, that's some sweet code :o

i ain't gonna examine it, I trust it does what you want. just some notes -
- not so sure SetIsDestroyable() is necessary. Thought it was only effective on creatures. (also, Plot *items* can be destroyed w/ DestroyObject() without unflagging plot, iirc)
- the SetCommandable() is to prevent ObjectSelf from starting an auto-retaliation if attacked, in combat.

Otherwise, y, just go with it
  • Ubai aime ceci

#12
Tchos

Tchos
  • Members
  • 5 030 messages

Ah, if I had thought to mention it, that's actually how I handled the unequipping of the diving gear in my campaign.  After many approaches, I ended up destroying the gear before re-equipping the characters' original gear.  It was still a bit difficult to time, since I was doing it with an entire party of characters, and as you observed, the ActionEquip command doesn't play well with others.  I wished for a non-action equip command at the time.  I think there's still the possibility in my campaign that some of the party may need their gear manually re-equipped after changing out of the diving gear.

 

I also didn't bother with using GetItemInSlot() for the items, because I didn't have any other ones lying around the world, so I just destroyed every copy in existence, because the only ones would have been the ones being worn by the party.


  • Ubai aime ceci