SpeakString NPC on OnPlayerChat event

Hello everyone!

I have been thinking in a way of a more dinamic boss battles and i’m thinking ways to the boss give orders to his minions if certain conditions are meet. My idea is for a necromancer controlling his minions.

For example, if someone cast spells as wizard / sorcerer (With a certain delay or it may cause a spam…) make a SpeakString for the boss shouting " Attack the caster fools!!" then change the target of specified minions to the caster. The condition can be diferent just making an example.

My question is, does a npc using SpeakString trigger OnPlayerChat events? If not, the only way I can think is by seting a local variable in the area amd have those minions be controlled depending on the variables set there. Like SetLocalInt(oArea,“AttackCaster”,1) and have the minion read that variable with a delay… May be too complex.

Any other idea if it is posible?

Thank you all!

Okey reading arround I found that NPC dialogs never trigger this event.

Guess I have to work with local variables it seems.

You could do this by setting listening patterns on your minions and then having the boss shout to them. That’s what the functionality is for. Look in the general onspawn script. And maybe the lexicon for OnConversation etc.

Or if you know the minion objects you could send them userdefined events with SignalEvent() to control what they do.

This is a good advice. Another way to do it is to (ab)use OnSpellCastAt event handler of signal receiver creature (your minion), which:

  • allows passing an object, for example a signal sender - something that sadly isn’t available to user-defined events
  • is less CPU-intensive (no active listening), but probably marginal issue
  • may allow you to use no local variables if you care for that

Example:

SignalEvent(oReceiver, EventSpellCastAt(oCaster, -20, FALSE));

Second parameter is the spell ID, which in game must be positive. Using a negative number marks this “spell” as a special signal.

This could be therefore turned into something like:

SignalEvent(oMinion, EventSpellCastAt(oPC, SOMETHING_NASTY, FALSE));

oMinion would the interpret that as do SOMETHING_NASTY to oPC. Last parameter (via GetLastSpellHarmful) is also usable.

Oh wow thanks to both!

i never used signal events and should take a look there. When I have time will do some experiments to see how the work.

For the EventSpellCastAt(), the spell ID (signal) is the script attached to that number in the spells 2da?

Not a script. Spell ID - for actual spells - is simply their matching row in spells.2da. But you’re right you can obtain all spell data this way, including its impact script.

When a spell is cast on a creature, this spell’s impact script tells the target who did what to it, i.e. fireball:

// nw_s0_fireball, OBJECT_SELF = spellcaster
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_FIREBALL));

Target can react to this situation in its own OnSpellCastAt (one place for all spell events), which for standard creatures defaults to nw_c2_defaultb.

Standard reaction is: “Spell harmful? DetermineCombatRound()”. You can put your own script in its place. Something like this:

// OnSpellCastAt event handler
void main()
{
    int iCaster = GetLastSpellCaster();
    int iSpell = GetLastSpell();
    int iHarmful = GetLastSpellHarmful();

    if(iSpell >= 0)
    {
        // this is a normal spell
        ExecuteScript("nw_c2_defaultb", OBJECT_SELF);
        return;
    }

    // spell is a "signal" - your code here
}
1 Like

Wow thank you for the detailed explanation!

Gona check on that when i got a time to prepare all ^^