Author Topic: Set oTarget to Immobile?  (Read 594 times)

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Set oTarget to Immobile?
« on: March 28, 2012, 02:40:54 am »


               What function would I use to set a target's movement speed to Immobile?
I've tried EffectMovementSpeedDecrease(99) but that's not immobile, and it doesn't go up to 100%. I've searched the Lexicon for Movement and Immobile but I found options for oPC camera/cutscene, not the movement speed on the npc.
               
               

               
            

Legacy_Fester Pot

  • Hero Member
  • *****
  • Posts: 1698
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #1 on: March 28, 2012, 02:43:09 am »


               

effect eFreeze = EffectCutsceneImmobilize();
AssignCommand( OBJECT_SELF, ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFreeze, OBJECT_SELF, 30.0)));


Change 30.0 for the duration you need to keep the NPC from moving about.

FP!
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #2 on: March 28, 2012, 02:44:29 am »


               // Returns an effect that when applied will paralyze the target's legs, rendering
// them unable to walk but otherwise unpenalized. This effect cannot be resisted.
effect EffectCutsceneImmobilize()
               
               

               
            

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #3 on: March 28, 2012, 03:43:05 am »


               Thanks guys, though the cutscene effect 'freezes' the monster, the mob doesn't go agressive. I've added damage and AssignCommand(oTarget, ActionAttack(oPC)) to try and get the mob to attack me while i'm within melle range, but no go.

I'm trying to duplicate the Root spell found in other games, and the closest I can see that in nwn is to switch the npc's movement to Immobilize. This allows range attacks to occur and for them to wack on the player if they are within range. Suggestions?
               
               

               
            

Legacy_wyldhunt1

  • Sr. Member
  • ****
  • Posts: 443
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #4 on: March 28, 2012, 04:36:04 am »


               That may be related to a bug wherein an NPC with a speed set to immobile in the toolset won't reliably attack either.
You could probably add a check to the AI script to see if they have your spell effect on them and run a custom AI if they do. You'd have to code a bit to check for enemies within melee distance, else switch to a ranged weapon or cast. Just don't add any options that would involve moving or running.

EffectCutsceneImmobilize() really should work though...
I've just never tested it with the combat AI.
<Wonders if there's some check in the default AI that cancels out if the NPC is immobile>
I think that the AI does a few checks to see if the NPC shouldn't be able to attack and cancels out if it returns true. I'm fairly sure that it checks for stuff like paralyze, petrify, sleep, etc... I'll have to take a look at that when I get a chance.
It may be as simple as adjusting a check in the AI somewhere.
               
               

               


                     Modifié par wyldhunt1, 28 mars 2012 - 03:37 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #5 on: March 28, 2012, 11:20:13 am »


               If you're using NWNX, you can do this with SetMovementRate. Otherwise, I know of no way to do this save Immobilize. Here's a sample of our new Viscid Glob spell, which uses this method, and which radically slows the target while they are affected:


#include "hg_inc"
#include "ac_spell_inc"

void CheckGlobMoveRate(object oTarget, int nDC, effect eEff, int nCount = 1) {

    if (!GetIsObjectValid(oTarget))
        return;

    int nRate = GetLocalInt(oTarget, "BaseMoveRate");
    if (!GetHasSpecificEffect(eEff, oTarget)) {

        SetMovementRate(oTarget, nRate);
        return;

    } else if (!(nCount%3)) {

        nDC -= 5;
        if (GetSkillCheckResult(SKILL_DISCIPLINE, oTarget, nDC) <= 0) {
            RemoveEffect(oTarget, eEff);
            SetMovementRate(oTarget, nRate);
            return;
        }
    }

    nCount++;

    DelayCommand(6.0, CheckGlobMoveRate(oTarget, nDC, eEff, nCount));
}

void ApplyNPCMovementRateChange(object oTarget, int nMoveRate) {
    int nBaseRate = GetLocalInt(oTarget, "BaseMoveRate");
    if (!nBaseRate) {
        nBaseRate = GetMovementRate(oTarget);
        SetLocalInt(oTarget, "BaseMoveRate", nBaseRate);
    }
    SetMovementRate(oTarget, nMoveRate);
}

void main() {
    struct SpellInfo si = GetSpellInfo();
    if (si.id < 0)
        return;

    si.dc = si.clevel*2;
    si.dc = (si.dc > 120 ? 120 : si.dc);

    float fDur = MetaDuration(si, si.clevel / 2, DURATION_IN_ROUNDS);

    if (GetIsSpellTarget(si)) {
        SignalEvent(si.target, EventSpellCastAt(si.caster, si.id));

        if (!GetSpellResisted(si)                                           &&
            !GetIsImmune(si.target, IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE)  &&
            GetSkillCheckResult(SKILL_DISCIPLINE, si.target, si.dc) <= 0) {

            ApplyVisualToObject(VFX_FNF_GAS_EXPLOSION_ACID, si.target);
            effect eLink = EffectSpellImmunity(HGSPELL_UNUSED);
            eLink = EffectLinkEffects(EffectVisualEffect(CEPVFX_AOE_FOG_STINK), eLink);
            SetEffectSpellId(eLink, HGSPELL_VISCID_GLOB);


            if (GetIsPC(si.target))  {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, si.target, fDur);
                RecalculateMovementRate(si.target);
            } else {
                if (!GetHasSpellEffect(si.id, si.target)) {
                    //change this to a Recalc analogue if we add a second rate setter
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, si.target, fDur);
                    ApplyNPCMovementRateChange(si.target, MOVEMENT_RATE_GLACIAL);
                    AssignCommand(GetArea(si.target), DelayCommand(6.0, CheckGlobMoveRate(si.target, si.dc, eLink)));
                } else  //block double application to prevent dur bugging
                    FloatingTextStringOnCreature("Only one Viscid Glob may be put on a creature at once!", si.caster, FALSE);
            }
        }
    }
}

Funky
               
               

               


                     Modifié par FunkySwerve, 28 mars 2012 - 10:23 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #6 on: March 28, 2012, 10:34:52 pm »


               

FunkySwerve wrote...

If you're using NWNX, you can do this with SetMovementRate. Otherwise, I know of no way to do this save Immobilize.


Well you can add a line to appearance.2da with the immobile speed "NOMOVE" used instead and then use the script SetAppearance() to immobilize.  But as has previously been said, speed of 0.0 itself has problems in allowing NPC to make use of their AI effectively, just like EffectCutsceneImmobility().

Here are some alternatives to look at:
Defensive Stance (does not work with ranged weapons or spell casting).
Define a new movement speed (such 0.01) that is slightly faster than immobility.
               
               

               


                     Modifié par WhiZard, 28 mars 2012 - 09:39 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #7 on: March 29, 2012, 01:07:34 am »


               

WhiZard wrote...
 But as has previously been said, speed of 0.0 itself has problems in allowing NPC to make use of their AI effectively, just like EffectCutsceneImmobility().


We use movespeed GLACIAL, rather than immobilizing them. From our (modified) creaturespeed.2da:

2DA V2.0
     Label       Name   2DAName  WALKRATE RUNRATE
0    PC_Movement ****   PLAYER     2.00      4.00
1    Immobile    2319   NOMOVE     0.00      0.00
2    Very_Slow   2320   VSLOW      0.75      1.50
3    Slow        2321   SLOW       1.25      2.50
4    Normal      2322   NORM       1.75      3.50
5    Fast        2323   FAST       2.25      4.50
6    Very_Fast   2324   VFAST      2.75      5.50
7    Default     6614   DEFAULT    0.00      0.00
8    DM_Fast     6893   DFAST      5.50     11.00
9    Faster      690    FASTER     2.50      5.00
10   Extra_Fast  725    EFAST      3.00      6.00
11   Super_Fast  687    SFAST      3.25      6.50
12   Hyper_Fast  684    HFAST      3.50      7.00
13   Light_Fast  1026   XFAST      3.75      7.50
14   Ridic_Fast  1014   YFAST      4.00      8.00
15   Ludic_Fast  2214   ZFAST      4.25      8.50
16   Relaxed     2275   RELAXED    1.60      3.20
17   Extra_Slow  5137   ESLOW      0.50      1.00
18   Super_Slow  5138   SSLOW      0.25      0.50
19   Glacial     5139   GLACIAL    0.10      0.20

That is PRECISELY why I suggested this approach. The very same you yourself suggest in your last sentence. Did you not read my post?

Funky
               
               

               


                     Modifié par FunkySwerve, 29 mars 2012 - 12:09 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #8 on: March 29, 2012, 02:52:09 am »


               

FunkySwerve wrote...

That is PRECISELY why I suggested this approach. The very same you yourself suggest in your last sentence. Did you not read my post?

Funky


You didn't specificly say you ADDED a line to creaturespeed.2da.  My assumption was that you reset the speed to a previously existing line.  But you did say that this can be only achieved through NWNX, and I did mention that adding lines to appearance.2da would allow SetCreatureAppearance() to make use of the speeds defined there (even for extra lines added to creaturespeed.2da).  My post was there to show that there is a non-NWNX alternative, not to say that your method doesn't work or has problems.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #9 on: March 29, 2012, 03:07:50 am »


               

WhiZard wrote...

FunkySwerve wrote...

That is PRECISELY why I suggested this approach. The very same you yourself suggest in your last sentence. Did you not read my post?

Funky


You didn't specificly say you ADDED a line to creaturespeed.2da.


No, I didn't. It's obvious from the code, which Sets moverate to a value not found in nwscript. I also made it explicit that it 'radically slows' the target, rather than immobilizing it, which renders your expressed concerns about this technique completely irrelevant. If you're going to reply to my posts, please take the time to read them. Doing otherwise wastes both our time and risks confusing the issue for the OP.

Funky
               
               

               


                     Modifié par FunkySwerve, 29 mars 2012 - 02:09 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #10 on: March 29, 2012, 03:37:23 am »


               

FunkySwerve wrote...

WhiZard wrote...

FunkySwerve wrote...

That is PRECISELY why I suggested this approach. The very same you yourself suggest in your last sentence. Did you not read my post?

Funky


You didn't specificly say you ADDED a line to creaturespeed.2da.


No, I didn't. It's obvious from the code, which Sets moverate to a value not found in nwscript. I also made it explicit that it 'radically slows' the target, rather than immobilizing it, which renders your expressed concerns about this technique completely irrelevant. If you're going to reply to my posts, please take the time to read them. Doing otherwise wastes both our time and risks confusing the issue for the OP.

Funky


Since you want to throw down the guantlet, tell me where I interpreted that your glacial constant couldn't possibly mean very slow movement with run disabled.  You have already told me that I have interpreted your words specifically to mean immobile speed.  Show me where I said that.
               
               

               
            

Legacy_DMSelena

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #11 on: March 29, 2012, 09:28:47 am »


               Hey you know what song I'm listening to now? This one:

Relax, fellas. Testaserone levels are making it smell like a gym sock around here, yo. ;-D
               
               

               


                     Modifié par DMSelena, 29 mars 2012 - 08:33 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #12 on: March 30, 2012, 03:19:55 am »


               

DMSelena wrote...

Hey you know what song I'm listening to now? This one:

Relax, fellas. Testaserone levels are making it smell like a gym sock around here, yo. ;-D


Lolz, that was my response to that post as well. Fallen, here's the part of your where you offer a critique of my suggestion with no apparent awareness that I'm suggesting setting a very slow, rather than immobile movement speed, despite my having made that abundantly clear in my post:

But as has previously been said, speed of 0.0 itself has problems in
allowing NPC to make use of their AI effectively, just like
EffectCutsceneImmobility().

At no point did I suggest setting a speed of 0.0, making that a pretty bizarre nonsequitor at best. If you actually took the time to read my post and reply to it, without grasping that concept, I can only suggest you avoid future remark on my posts, as you simply won't be able to add anything useful to the conversation. If you simply skimmed it, as I suspect, then I can only repeat my above suggestion - be a little more attentive to what you're replying to, in order to save everyone some pointless typing.

Funky
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #13 on: March 30, 2012, 05:45:26 am »


               

FunkySwerve wrote...

DMSelena wrote...

Hey you know what song I'm listening to now? This one:

Relax, fellas. Testaserone levels are making it smell like a gym sock around here, yo. ;-D


Lolz, that was my response to that post as well. Fallen, here's the part of your where you offer a critique of my suggestion with no apparent awareness that I'm suggesting setting a very slow, rather than immobile movement speed, despite my having made that abundantly clear in my post:

But as has previously been said, speed of 0.0 itself has problems in
allowing NPC to make use of their AI effectively, just like
EffectCutsceneImmobility().

At no point did I suggest setting a speed of 0.0, making that a pretty bizarre nonsequitor at best.

0.0 is the speed of "NOMOVE" from appearance.2da which was in the prior sentence.  I don't see how you are getting it to refer to the glacial constant which I did not mention at all.
               
               

               
            

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Set oTarget to Immobile?
« Reply #14 on: March 30, 2012, 05:51:15 pm »


               Is it possible to add glacial to the appearance.2da and call it without nxnx (or with basic nwn +cep)?