Constantly sitting NPC


#1

So I want to have an NPC (half-orc specifically) who’s constantly sitting on the floor. I tried “PlayAnimation(ANIMATION_LOOPING_SIT_CROSS);” on the OnSpawn handle, but it just does it once. Just curious, is there a way to do it without using the OnHeartBeat?


#2

When you script someone to play the animation, there’s two numbers you can enter for that command, so that the whole thing looks, for instance, like this:

ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0f, 100.0f);

The first number is the speed at which the animation will be played, and the second number is the duration. The longer this number, the longer the characters will keep on playing the animation.

I also like my characters to keep sitting, and not using heartbeat scripts, so I just put a ridiculously large number there, like 9999.0 or something. Though honestly I’m not 100% sure that’s the best way to do it. But it works.


#3

Hmm, I thought there was a more elegant way, but okay, I’ll try putting a ridiculously high number there and see how it functions. Thanks!

PS it’s for a PW


#4

And by the by, how do I make sure the sitting animation is not disturbed by a PC clicking them?


#5

For PWs, since it’s up for long periods of time, make sure you’re using a big enough number (something like 31557600.0 which is 1 year, 9999.0 is about 3 hours). Another solution is to put something like the following on the spawn script:

    ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0f, 6.0f);
    DelayCommand(3.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT, ExtraordinaryEffect(EffectCutsceneParalyze()), OBJECT_SELF));

That will lock the NPC into the sitting position but they won’t be able to do anything until you remove the Cutscene Paralysis. The extraordinary effect is there just in case a PC does something like cast dispel magic on the NPC (never know what those crazy PCs are going to do and how it could break your work). With this solution the NPC will ignore all clicks.

Yet another solution would be to put something like the following in NPC’s heartbeat:

    int iSit=GetLocalInt(OBJECT_SELF, "SitRounds");
    if (!iSit)
    {
        iSit=10+d6();
        SetLocalInt(OBJECT_SELF, "SitRounds", iSit);
        ClearAllActions();
        ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_TIRED, 1.0f, 3.0f);
        ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0f, RoundsToSeconds(iSit)+3.0f);
    }
    else SetLocalInt(OBJECT_SELF, "SitRounds", iSit-1);

This will have the NPC sit on the ground for most of the time, occasionally getting up before sitting down. This could be interrupted by someone clicking on the PC, but if you edit the OnConversation event script, you can avoid this interruption.

Within the OnConversation event script (by default nw_c2_default4.nss), the ClearActions and BeginConversation functions will both interrupt the NPC’s sitting animation. Once they are in a conversation you can script them to sit down using the, “actions taken,” script on the conversation nodes. Alternatively, if you use SpeakString instead of a conversation, it won’t interrupt the animation.


#6

I’ve had some success procuring a similar effect to the “cutscene paralyze” one by using SetCommandable(FALSE); (which was pure guesswork on my part, and I’m crazily proud of myself for it). But, come to think of it, I did not wait around to see what happens when the animation timer runs out - the NPC may still get up, because there’s no new command given to do that, just that the old one ends.
Food for thought!


#7
const int    HIGH             = 2147483647;                         // Largest possible integer
const float  FAR_AWAY         = 1000000000000.0;                    // One trillion metres
const float  FOREVER          = 1000000000000.0;                    // 1 trillion seconds = about 5000 years of gameplay

#8

Challenge accepted Proleric.

starts a test module with the highest possible float

Now, we wait.


#9

OK, my float values are arbitrary, but well in excess of any practical limit… and self-documenting (kinda).


#10

Well Cutscene Paralysis did the trick! What a useful command :slight_smile:
Appreciate it Wendigo!


#11

There is no largest possible integer :smile: But jokes aside, if anyone needed the maximum value an IEEE 754 32-bit float can hold, use this:

PrintFloat((2.0 - pow(2.0, -23.0)) * pow(2.0, 127.0), 0, 0);

which will print to the log: 340282346638528860000000000000000000000 (39 digits).

It also sucks that ActionPlayAnimation cannot accept infinity as duration, such as pow(100.0, 100.0) - no animation will be played.

It is however possible to use Inf and NaN as usual (but watch out for the last example)

float inf = pow(100.0, 100.0);
float nan = inf - inf;
float some_float = 32.0;

some_float < inf;  // TRUE
-inf < some_float; // TRUE
inf == inf;        // TRUE
some_float == nan; // FALSE
nan == nan;        // TRUE (IEEE 754 non-conformant)

#12

I have never made anything for NWN, so I might be talking nonsense. Could you make a phenotype with sitting as the only animation available?


#13

Hello all,
I had the same problem a few years ago with my NPC and I fixed it in his OnHeartBeat script
ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 7.0);
:wink:


#14

You’ve got to be careful with that because it can fill up the action queue for the NPC. I.e. every 6 heartbeats another action gets added to the queue. So after 36 seconds there is an additional action on the queue, after an hour there are 100 actions on the queue…


#15

Thx ! My NPC is standing drunk in a tavern by night, and he’s sit all day long in another place. I’ve never noticed a problem with his OnHeartBeat script, can it be a ressources problem ?


#16

If you had a ClearAllActions call before he moved to another location, or you despawned and respawned him, then the script is fine because that would clear his action queue. It’s only really a problem if he’s sitting continuously and the module is running for a long time.


#17

Well Cutscene Paralysis did the trick! What a useful command :slight_smile:
Appreciate it Wendigo!

FYI, I used this on a character in my module that’s supposed to be kneeling and praying constantly, and after a white they get up. They’re still unresponsive, but they stand up.


#18

It should freeze the animation indefinitely (similar to using a petrify effect to create NPC statues) Did you leave the area and re-enter it? or save and reload? Or did it just cancel by itself? I’ll see if I can recreate it on my end and come up with a fix.


#19

I re-visited the area several times, in fact, seeing as I’ve decided to make a decent run-through of it. But I’m not sure whether or not I’ve reloaded, sorry.


#20

Statue effects definitely need to be reapplied on module load.