How to get the mob into a fight

The folling situation is given: I met a group of baddies. The faction reputation to the PC is set to neutral. I have a nice chat with the boss which results in a battle.

To make the baddies hostile, I change the faction reputation of the PC to -100, which perfectly works. But then, those guys just stand there around, watching how I butcher the boss.

Is there an easy way to get them into fight at once? A single command line?

Something like

  //Shout Attack my target, only works with the On Spawn In setup
  SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);

  //MM: This obviously only works in the on_death script

Note: looping through all faction members nearby and issue the attack command is not the preferred solution.

The shout might work. I don’t know about the comment about the on_death script. That should be irrelevant. As long as they are in the same faction and are listening (on spawn setup) I’d think you could get them to attack.

Another approach would be to make them re-perceive the PC after the reputation change. This can be done by giving the PC a really short invisibility effect, for example.

Thanks for the input.

But it doesn’t work for me.

Btw, this is the script to intitiate combat:

#include "nw_i0_generic"

void main()
{
  object oPC = GetPCSpeaker();
  AdjustReputation(oPC, OBJECT_SELF, -100);
  SpeakString("NW_ATTACK_MY_TARGET", TALKVOLUME_SILENT_TALK);
  DetermineCombatRound (oPC);
}

Messed around with the talkvolume, tried TALKVOLUME_SILENT_SHOUT and TALKVOLUME_SHOUT, but it doesn’t help.

All the mobs use the default spawn in.

you need to tell them to attack.
there are many ways to manage this, depending on how you’ve set things up. here’s one way :

void attack(object mob, object pc)
{
        SendMessageToPC(pc, "Sending " + GetName(mob) + " to attack " + GetName(pc) + "!");
        // the faction change may be redundant.
        // if it isn't, comment it out to keep hostiles 'disguised' as friendly until last minute.
        ChangeToStandardFaction(mob, STANDARD_FACTION_HOSTILE);
        SetIsTemporaryEnemy(mob, pc);
        AssignCommand(mob, ActionAttack(pc));
}

void main()
{
    int nth;
    object pc = GetPCSpeaker();
    object leader = OBJECT_SELF;
    object mob = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, leader, ++nth);
    while (GetIsObjectValid(mob)) {
        attack(mob, pc);
        mob = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, leader, ++nth);
    }
    attack(leader, pc);
}

this script would be placed on the mob leader’s conversation at the point where you want the mobs to attack.

Right, but OP did say:

:slight_smile:

Thanks guys, and yes a loop is not what I’m looking for. Actually I already have a loop, a terrible sample of code which needs a lot of settings. I want just a simple single line. I’m still wondering why the shouting doesn’t work.

Meanwhile I tested temporary invisibility. It works in general, but not reliable enough in the given scenario.

@xorbaxian : Maybe the little doggie nearby, which has nothing to do with the conflict will bite me as well? :slight_smile: Only faction members of the boss should get the attack command. But you’ve given me an idea how to make my loop a little bit better.

maybe so, but i disagree.

you need to tell the creatures you target that you want them to act, otherwise they won’t act. silent shouts are often troublesome for several reasons : first (as you’ve seen) they may not work the way you want because your assumptions may not be valid ; the shout depends on factors you might not have taken into account. second, silent shouts are notoriously laggy, because you end up w/all your mobs shouting back and forth to each other any time one of them so much as stubs its little toe. you can see quantitatively how costly this is if you profile your scripts w/nwnx.

well, as i mentioned, there are lots of approaches to this. if you’ve taken the trouble to set your hostiles to a separate unique faction and all other creatures in the area don’t belong to that faction, then you can use GetFirstFactionMember/GetNextFactionMember, which aren’t nearly as costly as the various GetNearestx functions. however, if you’re still dead-set against using a loop and still want to use silent shouts, there are a few things you can check.

  • have you set appropriate flags on-spawn for your baddies? in order for them to react to silent shouts, you’ll need to have set SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET). this will allow other faction members to process the shout if they receive it.
  • have you set SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT) ? this will allow your in-spawned creature to react to OnDialog events it receives. you’ll need to write an event handler to get them to move their arses once they receive the event.
  • are all enemies near enough ? (i don’t remember how far apart they can be, but if they’re dispersed in a map whose size is greater than 4x4 i can tell you from personal experience that some will ‘miss’ the call for some arcane reason…).
  • have you called DetermineCombatRound ? the function is ridiculously messy, but it does set many many conditions that aren’t set w/a simple ActionAttack.

if you want the silent shout approach, let me take a look at this once i get home from work tonight and i’ll work something up for you.

Thanks for your friendly offer but no, I think, you’ve already helped me. Sometimes it’s just good to talk about things to get ideas.

I’ve made my loop a bit more simple and easy to use, as it previously was:

#include "nw_i0_generic"

 void main()
{
  object oPC = GetPCSpeaker();
  AdjustReputation(oPC, OBJECT_SELF, -100);
  DetermineCombatRound(oPC);

  location p = GetLocation (OBJECT_SELF);
  int r = GetLocalInt (OBJECT_SELF, "Radius");
  if (r == 0) r = 20;
  float d = IntToFloat(r);

  object o = GetFirstObjectInShape (SHAPE_SPHERE, d, p);
  while (GetIsObjectValid (o))
    {
      if (GetIsEnemy(oPC, o)) AssignCommand (o, DetermineCombatRound (oPC));
      o = GetNextObjectInShape (SHAPE_SPHERE, d, p);
    }
}

I guess I can live with it, it’s much more elegant as the thing I used in Blooodfeud 2. (And little doggie will not bite me. :slight_smile: )

Of course I need to use “DetermineCombatRound” , at least it prevents that casters within the mob go into melee immediately.

1 Like