Aller au contenu

Photo

[Question] Disabling Actions of PC/Followers


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

#1
Challseus

Challseus
  • Members
  • 1 032 messages
All.

So, I am attempting to figure out how to disable all actions of the PC/Followers through script. For reference, there is already a function called EffectRoot(), which sort of does what I want. Whoever it is cast on, they cannot move, cannot attack, cannot use tactics (except for stopping sustained abilities), cannot mess with their equipment, etc. It also makes them loop through this really cool animation, where they are struggling to free themselves from what looks like, roots Posted Image

While I played through the entire game, my hero was a Warrior, so I did not mess with a lot of spells. Someone here may know the corresponding spell that does this. Is there a Root spell/talent? I certainly didn't see one in the corresponding spell_ scripts, but I could have missed it.

At any rate, does anyone know of any current scripts that can be used for this? In NWN (and presumably NWN2), we have the function, SetCommandable(int bCommandable = TRUE). There is already a DA function, SetControllable(object oFollower, int nIsControllable), but that actually makes it so that I cannot even select the party member in question. Remember, I want to be able to select them, just not be able to do anything with them.

Any ideas?

#2
Craig Graff

Craig Graff
  • Members
  • 608 messages
Does this help?



int Effects_HandleApplyEffectRoot(effect eEffect)

{

// increment stationary counter

int nStationaryFlag = GetLocalInt(OBJECT_SELF, AI_FLAG_STATIONARY);

LogTrace(LOG_CHANNEL_EFFECTS, "Stationary AI Flag = " + ToString(nStationaryFlag), OBJECT_SELF);

nStationaryFlag += 2;

LogTrace(LOG_CHANNEL_EFFECTS, "Altered Stationary AI Flag = " + ToString(nStationaryFlag), OBJECT_SELF);

SetLocalInt(OBJECT_SELF, AI_FLAG_STATIONARY, nStationaryFlag);



return TRUE;

}

#3
Challseus

Challseus
  • Members
  • 1 032 messages
Hi Craig.

Yeah, I should have pointed out I already tried that earlier when I was looking at effect_root_h.nss. When I set that flag on the target, they are still able to run around and do stuff. I am really, really hoping that whatever is getting that functionality I need isn't somewhere in the engine code itself Posted Image

While I have you here, I might as well ask you something else... Another thought I had was that whenever this particular functionality I want is in effect (it's triggered by a sustained spell), I could just override any actions events of the target (I already have a script that overrides player_core.nss). I'm thinking, movement, item use, ability use, attacking, and equipment changing. I found the following event in rules_core.nss and thought it might be useful:

        // --------------------------------------------------------------------
        // COMMAND_PENDING - Deal with pending commands issued either by the AI
        //                   or by player input
        // Params:
        //          obj(0)  - Command Owner
        //          obj(1)  - Command Target
        //          obj(2)  - varies by command.
        //          int(0)  - The command id (COMMAND_TYPE_* constant)
        //          int(1)  - The command subtype:
        //                    COMMAND_TYPE_ATTACK  - # of attacks
        //                    COMMAND_TYPE_ABILITY - ABILITY_TYPE constant *
        //
        //  Note: Ranged Attacks always send one attack, never two.
        //
        // --------------------------------------------------------------------
        case EVENT_TYPE_COMMAND_PENDING:

Some of the command types that interest me are COMMAND_TYPE_MOVE_TO_LOCATION, COMMAND_TYPE_MOVE_TO_OBJECT, COMMAND_TYPE_ATTACK, & COMMAND_TYPE_USE_ABILITY. My idea was to catch these events in my custom script, and then do nothing. I am having some issues with actually catching any EVENT_TYPE_COMMAND_PENDING events, but it may be something I am doing wrong on my end.
 
Before I waste too much time on this:

a) Is my understanding of this event correct. It is thrown when any action is attempted, but before it is completed?
B) Are these events even being thrown (I have seen some commented out events, so maybe this one was forgotten?)?

Thanks again for your time.

#4
Craig Graff

Craig Graff
  • Members
  • 608 messages
EVENT_TYPE_COMMAND_PENDING and EVENT_TYPE_COMMAND_COMPLETE are both redirected to rules_core via events.xls.

Modifié par Craig Graff, 24 novembre 2009 - 06:14 .


#5
Challseus

Challseus
  • Members
  • 1 032 messages
Thanks, Craig. I just overrided rules_core.nss, but I am not getting what I want... I can stop the player from using abilities and items and such, but they are still allowed to move around. In fact, EVENT_TYPE_COMMAND_PENDING isn't even called when attempting to walk/run. However, EVENT_TYPE_COMMAND_COMPLETE is...

I have found something else that is interesting however... I was looking at some of the core modal spell scripts, and came across this line for the Combat Magic implementation. In it, there is a comment from Georg stating that they are disabling the use of the function, SetEffectFlags. Here's a snippet:

        case ABILITY_SPELL_COMBAT_MAGIC:
        {
            eEffects[0] = EffectModifyProperty(PROPERTY_ATTRIBUTE_ATTACK, COMBAT_MAGIC_ATTACK_BONUS + MaxF(GetCreatureSpellPower(stEvent.oCaster)/5.0,0.0) );
            // -----------------------------------------------------------------
            // Georg: One of the earlier designs for the spell called for it
            //        to disable spellcasting. This was found not working well
            //        so instead we're now balancing through increased fatigue
            // -----------------------------------------------------------------
            // eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_SPELLS);
            eEffects[0] = SetEffectEngineInteger(eEffects[0], EFFECT_INTEGER_VFX, Ability_GetImpactObjectVfxId(stEvent.nAbility));
        }

I never even knew of this SetEffectFlags function. I of course started to look up the various flags, and tried adding it to my code. Here is a snippet (this code essentially increases the spellpower of the user):

            //apply effect
            eEffects[0] = EffectModifyProperty(PROPERTY_ATTRIBUTE_SPELLPOWER, 100.0);
            eEffects[0] = SetEffectEngineInteger(eEffects[0], EFFECT_INTEGER_VFX, Ability_GetImpactObjectVfxId(stEvent.nAbility));
            //eEffects[1] = EffectRoot();   
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_MOVEMENT);   
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_COMBAT);
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_INPUT);
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_ITEMS);
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_SKILLS);
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_SPELLS);
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_TALENTS);   
            eEffects[0] = SetEffectFlags(eEffects[0], EFFECT_FLAG_DISABLE_TURNING);

So, the spellpower addition works just as before. When I try to use a spell, I can click on the target, but nothing happens. I assume it would be the same for skills/talents. However, I am still able to move around and such. Is there anything I am missing? Is there some other local/global variable that has to be set in order to make these flags work?

Thanks.

Modifié par Challseus, 25 novembre 2009 - 04:36 .


#6
Challseus

Challseus
  • Members
  • 1 032 messages
Well, I have finally found a workaround. I probably should have originally stated what I wanted. Essentially, I wanted to force a PC/Follower to have all their actions disabled, while performing an animation.

I will still be using the function, EffectRoot(). However, after some more digging around, I have discovered a function called SetEffectAnimation(). Using this little code snippet, I can override the existing animation associated with the root effect:

effect eEffect = EffectRoot();
eEffect = SetEffectAnimation(eEffect, 244);

So now, instead of grabbing at their feet, the creature performs a casting animation. Definitely cleaner than trying to override core events. I'm still curious as to how those flags work, but this will do for the moment.