Aller au contenu

Photo

Changing ambient behaviour via scripting


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

#1
sea-

sea-
  • Members
  • 264 messages
Has anyone managed to properly change an NPC's ambient behaviour using scripting?  I'd like certain ambient/idle NPCs to cower when the player begins fighting in the area, but the Ambient_Start command doesn't seem to be working too well for me - Ambient_Stop works just fine, however.

My script currently looks like this:

                //stops current ambient animations of various additional NPCs
                Ambient_Stop(oWaiter1);
                Ambient_Stop(oWaiter2);
                Ambient_Stop(oWaiter3);
                Ambient_Stop(oBarkeep);
                Ambient_Stop(oServant1);
                Ambient_Stop(oServant2);
                Ambient_Stop(oServant3);
                Ambient_Stop(oServant4);
                Ambient_Stop(oServant5);
               
                //tells the following NPCs to begin cowering
                Ambient_Start(oWaiter1, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oWaiter2, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oWaiter3, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oBarkeep, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oServant1, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oServant2, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oServant3, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oServant4, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);
                Ambient_Start(oServant5, 2, AMBIENT_MOVE_INVALID, AMBIENT_MOVE_PREFIX_NONE, 120, -1.0);

Anyone figured out a way to get this to behave?  The 120 animation (angry crowd) was just set to make the change more obvious at a glance in testing; I intend to use the cowering (int 99) routine if I can actually get this working properly.

#2
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
I'm not sure what's going on in your mod, but if the NPC enters combat mode (even if it's just to run away), won't their ambient AI get skipped? At that point I think it's more down to a custom AI.

It's been a while since I've checked, but my guess is something like that is what's going on. Maybe rules_core or thereabouts is where you can trace it for yourself.

Modifié par FollowTheGourd, 19 juin 2011 - 05:00 .


#3
sea-

sea-
  • Members
  • 264 messages
Sorry, I should clarify that the NPCs in question are non-interactive, non-combat and don't go hostile in this situation.

#4
Proleric

Proleric
  • Members
  • 2 346 messages
By default, ambient animation is suspended when the player is in combat, too.

You can override this by setting the AMBIENT_SYSTEM_ALWAYSON flag in the AMBIENT_SYSTEM_STATE.

Bioware says "this should rarely, if ever, be used". However, I suspect that's just reiterating the basic principle that performance can deteriorate if you have vast numbers of creatures in combat or animation.

When restarting animation, IIRC you also need to set the AMBIENT_SYSTEM_ENABLED flag.

So, for a looping animation, my reading is that the second parameter of Ambient_Start should be

AMBIENT_SYSTEM_ENABLED | AMBIENT_SYSTEM_SPAWNSTART | AMBIENT_SYSTEM_NOPLAYNEXT | AMBIENT_SYSTEM_ALWAYSON



#5
sea-

sea-
  • Members
  • 264 messages
Thanks so much for the detailed response! I actually had no idea before now that you could pass multiple values to the same parameter. I take it that is just in special cases, but still.

I kind of got it working. The ambient animations don't seem to play during combat, but afterwards they do play correctly. The animation routine itself needs work (turns out the cowering animation isn't so much a loop as it is one of those enter/exit things), but I'll play with the duration/time settings a bit and see what I can get.

#6
Proleric

Proleric
  • Members
  • 2 346 messages

sea- wrote...

...I actually had no idea before now that you could pass multiple values to the same parameter. I take it that is just in special cases, but still.

As it happens, this is a general technique, not a special case.

The | operator is a bitwise OR (a method for setting bits in an integer).

So. the parameter only has one value, but instead of a cryptic number, I've used an expression which makes it clear which flags are set.

In this instance, you could write (A + B) instead of (A | B). The latter is more robust, because it gives the correct result when A or B have more than one bit set.  

P.S. I'd be interested to know if you can make AMBIENT_SYSTEM_ALWAYSON work for combat. I had some problems with it when setting up guard patrols. It seems to work up to a point, but the NPC still freezes when very distant (which shouldn't be an issue in your situation).

Modifié par Proleric1, 19 juin 2011 - 05:27 .


#7
sea-

sea-
  • Members
  • 264 messages
Well, the ambient system is disabled at a certain distance due to performance reasons... isn't there a variable that's supposed to override that somehow? Unless you're saying it doesn't work.

As for the + and | operators, I didn't realise that the various ambient system states could be activated simultaneously - I figured it was just a binary choice between all of them.

#8
Craig Graff

Craig Graff
  • Members
  • 608 messages
The distant NPCs should still work if you have AMBIENT_SYSTEM_ALWAYSON flagged. But they get starved for AI updates. You may be able to work around this by using the CSERVERAIMASTER_* constants to bump up the AI level. The function to use is SetAILevel.

Example: 
SetAILevel(oCreature, CSERVERAIMASTER_AI_LEVEL_HIGH);

Edit: name corrections.

Modifié par Craig Graff, 23 juin 2011 - 05:48 .


#9
Proleric

Proleric
  • Members
  • 2 346 messages
Thanks, Craig.

As it happens, I already tried the highest AI level setting, with ambient behaviour "always on", but creatures still stop moving when very distant.

If the player approaches them, they start moving again shortly after becoming visible.