Aller au contenu

Photo

PC penalty when swarmed by hostiles


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

#1
Terrorble

Terrorble
  • Members
  • 194 messages
I'm toying with the idea of a dodge AC penalty to PCs that are being attacked by 4 or more NPCs. It would account for dwarven defender levels and involve a tumble check.  Problem is, I can't think of how or where best to check if the player is surrounded.

#2
Squatting Monk

Squatting Monk
  • Members
  • 446 messages
The only thing I can think of is to put an AoE on the PC that increments a counter when hostiles enter and decrements it when they leave. If the counter rises to 4, apply your penalties.

#3
MagicalMaster

MagicalMaster
  • Members
  • 2 003 messages
Could just run it on the module heartbeat or a psuedo-heartbeat on the PC himself. Check every X enemies to see how many enemies are within Y yards or whatever.

#4
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
AoEs are no good unless you're single player, and somewhat dodgy even then - we generally replace them with psuedos. The problem is, pseudos are about 5x the overhead of a comparable heartbeat, and you'd only want them running during combat.

I think my inclination would be to run it off the monsters themselves, either in heartbeat or from endcombat. You get a different issue there, though, in that every critter is firing that same code (it'd have to be on all critters, in the default ai or a hook from it). So, you're then in a situation where you'd need to mark each critter as counted for a particular PC - you'd probably want both a timestamp and a local object var, to limit how often it's recalculated.

Long story short, if this is for a single-player or few-player mod, your best bet is probably the module heartbeat, doing a GetFirstPlayer (or looping through all if MP) and checking how many creatures are within x radius of them.

If you're expecting more than a few pcs on at once, though, you're probably going to want to check from encombat or creature heartbeat, which will be both more efficient, and more difficult to code properly.

Two questions:
1) SP or MP?
2) Are you using NWNX? If so, windows or linux?


Funky

Modifié par FunkySwerve, 22 novembre 2013 - 04:20 .


#5
Terrorble

Terrorble
  • Members
  • 194 messages
1. The module is setup for MP, but will unlikely see more than 3-4 players.
2. On Windows. No NWNX currently.

So, I've thrown this together on the module heartbeat. I track heartbeats (which has worked reliably so far), and this should fire every 2nd one. If it works, I'll give the numbers and the role of dwarven defender more thought later.

Of course, thanks for the replies.  Using an AoE didn't cross my mind.

if( nHB % 2 == 0 )

{

  while( GetIsObjectValid(oPC) )

  {

    if( GetIsInCombat(oPC) )

    {

      int iCount = 0;

      int n = 1;

      object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oPC,n);

      while( GetDistanceBetween(oPC,oEnemy) < 4.0 )

      {

        iCount++;

        n++;

      oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oPC,n);

      }

      if( iCount > 3 )

      {

        int nOppRoll = 10 + (iCount-2)*5;//the DC is at least 20

        int nMyRoll  = d20() + GetSkillRank(SKILL_TUMBLE,oPC);

        if( nMyRoll < nOppRoll )

        {

            effect eSwarm = EffectACDecrease(iCount-2);//Minimum AC decrease of 2

            eSwarm = SupernaturalEffect(eSwarm);

            effect eVis = EffectVisualEffect(VFX_IMP_HEAD_EVIL);

            ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC);

            ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSwarm,oPC,12.0);


            FloatingTextStringOnCreature("You are swarmed and unable to maneuver well.",oPC,FALSE);

        }

      }

    }

  oPC = GetNextPC();

  }

}

Modifié par Terrorble, 23 novembre 2013 - 06:15 .


#6
WhiZard

WhiZard
  • Members
  • 1 204 messages
You are counting the number of objects (not necessarily enemies) within 4.0 meters. It might be better to use your GetNearestCreature() function to simulate the loop by incrementing it until the creature reached is beyond 5.0 meters (or 4.0 meters not sure which one you are going for).

#7
Terrorble

Terrorble
  • Members
  • 194 messages
Thanks, WhiZard! You just saved me some time. I like the idea of using GetNearestCreature() instead of scanning objects in the shape. Besides, it will check for hostiles without me having to do that in a separate step anyway (which I clearly forgot to do the first time around). I edited the code above to reflect it.

Now, my hope is that some of my weaker NPCs (e.g. goblins, spiders) will be respected a little more for their numbers.

#8
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
GNC with reaction check is how I would've done it, yeah. The question about NWNX is moot, I think. I was asking mainly because being able to assign and check effect ids and durations would have made the more complex method somewhat easier.

Funky

#9
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Terrorble wrote...


      int iCount = 0;

      int n = 1;

      object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oPC,n);

      while( GetDistanceBetween(oPC,oEnemy) < 4.0 )

      {

        iCount++;

        n++;

      oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oPC,n);

      }

      if( iCount > 3 ) ...

      

 

I see no reason for a loop here.   all you need to do is find the 4th nearest enemy creature then find out if the is valid and check the distance.  

 
oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oPC,4);

if ( oEnemy != OBJECT_INVALID && GetDistanceBetween(oPC,oEnemy) < 4.0 ) ...

#10
Terrorble

Terrorble
  • Members
  • 194 messages
I'm very glad I posted this question, instead of mulling through it myself. Thanks for the insight.

There is one reason I may do the loop. If the total number of enemies within 4.0m determines the DC of the tumble check and the severity of the penalty, then I need to know how many there are. But even then, I think I could use this idea to optimize the loop, start at n = 4 and go up from there.