Aller au contenu

Photo

A throwing feat I'm creating is driving me crazy


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

#1
psiiijay

psiiijay
  • Members
  • 258 messages
I'm adding a feat that lets you throw an opponent to the ground using something like an Aikido move - I'm trying to get the target (after all the checks succeed) to play the wildshape animation (this makes it look like he is turning to the other side) then I want the target to face away from the PC + lie down on the ground. This would look I believe like the target got flipped and fell.
 
So: 
     
DelayCommand(0.7, AssignCommand(oTarget, SetFacing(GetFacing(oPC))));
DelayCommand(0.2, ReallyPlayCustomAnimation(oTarget, "*wildshape",0,1.0));
DelayCommand(0.8, ReallyPlayCustomAnimation(oTarget, "*pronedamageB",0,1.0));
DelayCommand(0.9, SetCommandable(FALSE, oTarget));
DelayCommand(3.9, SetCommandable(TRUE, oTarget));
 
The only thing this does is making the target lie on the ground without turning away of playing the windshape animation. Got any Ideas? 
 


#2
Dann-J

Dann-J
  • Members
  • 3 161 messages

Try assigning the commands before delaying them (after using ClearAllActions(TRUE) on the target creature). That should put them in the action queue of the target creature in the correct order.

 

Be warned that stringing together delayed actions in the action queue will never work all the time. If you can get it working 80-90% of the time then you're doing well.



#3
kevL

kevL
  • Members
  • 4 056 messages
a few things in additions to Dj's

lose the asterisk on "wildshape" - it doesn't use a weapon stance
I get the impression that PlayCustomAnimation() actually does go in the action queue automatically. might be wrong, but note that in addition to AssignCommand() there's also ActionDoCommand() - which both seem related to queued actions.

note, SetCommandable(FALSE/TRUE) ought hold the action queue 100%

The following script 'worked' /*cough
//
void Release(object oTarget);

// * main *
void main()
{
    object oPC = OBJECT_SELF;
    object oTarget = GetNearestObject(OBJECT_TYPE_CREATURE);

    AssignCommand(oTarget, ClearAllActions(TRUE));

    PlayCustomAnimation(oTarget, "wildshape", FALSE);
    AssignCommand(oTarget, SetFacing(GetFacing(oPC)));
    PlayCustomAnimation(oTarget, "*pronedamageB", TRUE);

    AssignCommand(oTarget, SetCommandable(FALSE, oTarget));

    float fDur = 6.f; // <- set the duration here
    DelayCommand(fDur, Release(oTarget));
}

//
void Release(object oTarget)
{
    SetCommandable(TRUE, oTarget);
    PlayCustomAnimation(oTarget, "%", FALSE);
}
But trying to weave together those animations *seamlessly* is probably an effort in futility. /shrug



PS. I think it looks better if target is SetFacing() -before- the wildshape .... then, flip

#4
Dann-J

Dann-J
  • Members
  • 3 161 messages

SetCommandable() certainly increases your chance of success. I have a resting sequence where the party gets arranged in a circle around a campfire and they all sit down cross-legged on the ground. When the scene fades back from black after resting, they all stand up and play one of several possible random animations (yawn, brush off, shrug, etc). It works perfectly about 95% of the time, but every now and then...

 

computer-says-no.jpg



#5
kevL

kevL
  • Members
  • 4 056 messages
loop it 50 times until they get the message
jk,

#6
psiiijay

psiiijay
  • Members
  • 258 messages

You guys are amazing :) - Really glad for all the help - KevL, I'm checking your script now



#7
psiiijay

psiiijay
  • Members
  • 258 messages

I tried everything - the wild shape works but the delayed facing command does not...

I don't get why... I even put ClearAllactions before it +gave the command 4 times at 0.4 , 0.5, ext, but still nothing :(

Any ideas?



#8
Tchos

Tchos
  • Members
  • 5 042 messages

My understanding is that AssignCommand is not a queued action.  It's just to make a different object than the one calling the script be considered the OBJECT_SELF of that command.  If it is delayed, and the character is not commandable at the time when the delay would run out, then nothing will happen.  It needs to be an Action to be put into the queue (before command is disabled) and be executed in turn (not delayed) while the character is not commandable.  Thus, if there is not already an Action version of the function you're trying to use, put it in an ActionDoCommand.



#9
Dann-J

Dann-J
  • Members
  • 3 161 messages

I like to delay things very slightly after ClearAllActions(), usually just 0.1 seconds. Whether it makes a difference or not is another question, but I do it just to be on the safe side.

 

Here's a function that's part of my camp fire resting script, that makes the party sit down and stay down after they've been arranged in a circle around the fire (using GroupSetCircleFormation). I use SetAssociateState(NW_ASC_MODE_STAND_GROUND, TRUE) to prevent their AI from ruining the arrangement (so they don't try to move closer to the PC). I also use SetCutsceneMode() to disable the GUI temporarily.

void SitDown()
{
	object oPC = GetFirstPC();
	object oPartyMember = GetFirstFactionMember(oPC, FALSE);

	while(GetIsObjectValid(oPartyMember) == TRUE)
	{
	SetBumpState(oPartyMember, 2);
	AssignCommand(oPartyMember, ClearAllActions(TRUE));
	AssignCommand(oPartyMember, DelayCommand(0.1, PlayCustomAnimationWrapper(oPartyMember, "sitgrounddown",0)));
	AssignCommand(oPartyMember, DelayCommand(1.85,PlayCustomAnimationWrapper(oPartyMember,"sitgroundidle",1)));
	oPartyMember = GetNextFactionMember(oPC, FALSE);
	}
}

  • GCoyote aime ceci

#10
kevL

kevL
  • Members
  • 4 056 messages

...  Thus, if there is not already an Action version of the function you're trying to use, put it in an ActionDoCommand.


as in,
 

AssignCommand(oTarget, ActionDoCommand(SetFacing(GetFacing(oPC))));

i guess it could be
 

DelayCommand(0.5f, AssignCommand(oTarget, ActionDoCommand(SetFacing(GetFacing(oPC)))));

:o

that's kinda the reason i was avoiding DelayCommands() and relying on the action-queue to line things up instead.



#11
Dann-J

Dann-J
  • Members
  • 3 161 messages

NEVER rely on the action queue to do what you think is logical. It defies logic at every opportunity.  :)

 

Some actions will assert their dominance and happen immediately, despite there being other actions waiting in the action queue. That puts the actions out of sequence, or you get several actions all trying to happen at once (resulting in some being ignored completely). I find you get more consistent results by first assigning and then delaying the actions:

  • AssignCommand(oTarget, DelayCommand(0.5, [do your thing]));

 

Then you can assign them in any order you want, since their delays will ensure they happen in the correct order regardless of their order in the action queue.



#12
psiiijay

psiiijay
  • Members
  • 258 messages

Results so far after trying some variations:

 

ActionDoCommand will not work with SetFacing at all - not even without delay. Compiles but does nothing.

 

AssignCommand Does work - but only when not delayed - if using DelayCommand in any way (before or after) it does not work..

Maybe I'm applying something not in the best way?

 

I tried these lately: 

AssignCommand(oTarget,  DelayCommand(0.6f, AssignCommand(oTarget, SetFacing(GetFacing(oPC)))));
AssignCommand(oTarget, DelayCommand(0.7, SetFacing(GetFacing(oPC))));
 
And same with Action do command
 
I really don't get what's going on..


#13
Tchos

Tchos
  • Members
  • 5 042 messages

Like I said, if it's a non-action being assigned or delayed to be assigned when the character is not commandable, it's not going to work, and it's not clear from your comments whether that's the case, but depending on which code you're using above, it is.  If you're using actions, then they all have to be assigned before the character is made uncommandable.  If you're using delays, then you'll have to precede each command with the function to make it commandable until after that delay and then make it uncommandable again, each time.



#14
Dann-J

Dann-J
  • Members
  • 3 161 messages

Indeed. I'd be queuing up the actions with the delay inside the AssignCommand() before setting the target to be uncommandable. The point of making them uncommandable is to stop anything from interfering with their action queue - that includes anything the script is trying to queue up as well.

 

I've used SetFacing() successfully without ActionDoCommand(), so the latter shouldn't be necessary. It takes time for the creature to revolve around its axis though. Any other actions that take effect before the creature is finished turning might interrupt the turning process.



#15
psiiijay

psiiijay
  • Members
  • 258 messages

Tchos - Got it - for some reason it will not respon.. <_<

Dann-J, It worked in a script with a DelayCommand inside? 

If yes please send me the entire script and I'll work something out to mesh it with what I have now:) For some reason It didn't do anything even when I left only the facing command alone in the script..



#16
kevL

kevL
  • Members
  • 4 056 messages
had a bit of intrigue this morning

updated. jic anyone decides to actually use something like this. Added a safety along with more tolerance to the PlayThrow() function loop. Removed some redundant stuff. Added standup animation. &tc

#17
psiiijay

psiiijay
  • Members
  • 258 messages

Wow!! This looks amazing! :o  :o  :o Gonna try it now!!



#18
kevL

kevL
  • Members
  • 4 056 messages
oops, my 20-iteration safety isn't safe. (iter rather needs to be set as a local_int)

interested to hear how it goes tho

#19
psiiijay

psiiijay
  • Members
  • 258 messages

The script is great but the animation is still a little off as the game is trying to compensate for not having animations between facing and proneB - it turns the object instead of making it appear turned (which creates a little unreal motion as everything happens too slow for a throw).. I'm trying to play with it a little to see what could be done.. maybe moving the objects location a little would do the trick and give a "swifter" look to the move..

 

I'll also add an attack check if the moves succeeds - If I get it right in the script if the size dif is less then 1 it would work 100% on any humanoid race right?  



#20
kevL

kevL
  • Members
  • 4 056 messages
if size diff is *greater* than -1 it goes 100% (see note*)

( and yes other checks need to be integrated )


*i get things like that reversed sometimes - think it through yourself and Test. Also, I listed those humanoids simply by looking at RACIAL_TYPES_* in nwscript.nss -- add & remove to taste

Note there *is* a hazard if a creature's model-base or attack** distance (Appearance.2da) is too large; that is, the script might get stuck in the PlayThrow() re-loop. (But if so i think Player could still successfully disengage the loop by clicking to cancel the behavior). This potential bug involves the "1.35/1.65m" ranges ...

**perspace/creperspace columns

#21
psiiijay

psiiijay
  • Members
  • 258 messages

actually for some reason if the pc wont get to the target on time and close the distance the script would still fire and throw the target from a distance.. 

I don't know why it ignores the spells.2da distance for the spell to be cast..

 

Btw, It looks nicer imo with the player using "deflect" animation - looks very aikido-like:)



#22
kevL

kevL
  • Members
  • 4 056 messages

actually for some reason if the pc wont get to the target on time and close the distance the script would still fire and throw the target from a distance..


that's governed by this line in main()
ActionDoCommand(PlayThrow(oPC, oTarget, fDur));
which puts PlayThrow() into the PC's action queue. It might have something to do with Dj's "don't trust the action queue" policy. ( depends how consistent/inconsistent it is, etc.)

In *any* case, however, the codeblock in PlayThrow() is what regulates whether & when the akido animations start:
if (GetDistanceToObject(oTarget) < 1.65f)
{
    PlayCustomAnimation(oPC, "throwarmsloop", FALSE);
    DelayCommand(0.3f, Fall(oPC, oTarget, fDur));
}
as it stands above, the distance from the center of the target's model-base to the center of the PC's model-base has to be less than 1.65m

(as I interpret things, at least)

So unless something significant has changed nothing much should happen until the distance has closed.


ps. yeh i'm sure there are better anims than "throwarmsloop" lul :)

 

I don't know why it ignores the spells.2da distance for the spell to be cast..


if you Post your spellscript between <code></code> tags (use square brackets) along with the entire row from Spells.2da ...