Two NPCs training against one another?

Is this possible? I would like a room where two gnolls are wrestling with each other without any of them dying. I guess it has to do with choosing different factions for them and maybe make them both immortal? Is this complicated? My understanding of scripting is somewhat improved since the last couple of months when I was a complete noob, but I still have ALOT to learn…

I saw in some module that there was a custom animation playing in the heartbeat script of the creature. Maybe one could use something like that…I tried using the Animation Viewer plugin and tried saving an animation from there. That created an xml file. However in the module with the custom animation it was some kind of string that was called with PlayCustomAnimation…urrghh…does anybody know how you do this?

Yes, you can do it that way, although I think it will be a brawl rather than a wrestling match. Just make sure their mutual factions aren’t hostile to other factions in the area. If you do a custom animation version, you would need to keep them facing each other or it will look a bit stupid.

There’s a list of custom animation names here:

However, if the creatures aren’t player races then you won’t necessarily get all of the possible animations.

an example of humans doing mock battle is in OC, module 0_Tutorial, area 0000_west_harbor. There are several pre-placed “brawlers” that have modified OnSpawn scripts, that use

SetCombatOverrides()

and they don’t have OnDamaged or OnSpellCastAt scripts.

I’m not saying it’s a good example, but at least it’s an example (ie, you’d likely have to tweak the cr*p out of it to make it work…)

in fact, iirc I did a fix for it in “nwn2fixes” …

maybe stuff like, use SetCombatOverrides() to not actually do any damage, and use their OnHeartbeat scripts to call ActionAttack(), etc

note there are also functions that can change their AI-handlers on the fly if they need to stop brawling and become genuine threats, (ie. don’t hesitate to wipe their AI-event slots if they get in the way.)

… the brawlers can be the same faction, since this type of combat is purely a mock-up

&npsb;
personally your guys’ idea of simply using PlayCustomAnimation() [ + SetFacingPoint() ] is more appealing …

And, uh yeh, create a custom-faction for them that’s neutral to other factions & vice versa.

Thanks for the answers you guys! I tried with doing a script like this (it’s actually taken from the module Bad Habits, I just modified it):

void main()
{
int nRandom = Random(2);

if (nRandom == 0)
	{
	PlayCustomAnimation(OBJECT_SELF,"UnA_1attack01",1);
	}
else
	{
	PlayCustomAnimation(OBJECT_SELF,"UnA_1attack02",1);
	}
}

that I placed on the two gnolls fighting each other. It looks ok I guess. However, a new idea came to my mind that the reason for this brawl or fight could be that the PC could bet on who of the two would win the fight, and then there could be a rematch and the PC could bet again. Just as a bit of a side quest. But that would require an animation for one of the guys to go down, and then maybe it would be easier to do a real fight between them and create a custom faction for them both (which I have never done and don’t know yet how to do). And then when each match is done one could maybe revive them or respawn them back…or something… I’ll have to think about this. Maybe I should check the OC…

flag both critters Immortal - means they stop losing health at 1 hp - and let them go hostile on each other. in their OnDamaged scripts

    if (GetCurrentHitPoints(oSelf) == 1)
    {
        // do what it takes to stop combat:
        // set their factions to Commoner, eg.
        // and assign ClearAllActions(TRUE) on both critters.
    }

 
There’d also be a fair bit of stuff required to handle betting / winning / losing / payouts

ps. really should look at the FactionTable, it’s not that complicated (except this is nwn2 so bugs and redundancies could throw a monkey wrench at ya).

Thanks for the reply kevL_s! I’ll try what you suggested.

I have now created two new factions that are only hostile towards each other. I’ll see how that looks and works in the game. When reading Kartinas NWN2 Toolset Guide she talked about that you have to create Faction Pigs. I found a Faction Pig under Blueprints/Creatures. Question: Do you just copy this blueprint to the module and thus making two new ones that I rename with new tag and all that? Or is there some other way you’re supposed to do this? I mean, if I am going to change faction on them to Commoner when one of the reaches 1 hp it seems that I have to have Faction Pigs…

Ok. So far so good. The OnDamaged scripts for both the gnolls looks like this right now:

void main()
{

object oSelf = (OBJECT_SELF);


if (GetCurrentHitPoints(oSelf) == 1)
    {
        // do what it takes to stop combat:
		object oGnoll = GetObjectByTag("l_gnollwrestler");
		ChangeToStandardFaction(oSelf, STANDARD_FACTION_COMMONER);
		ChangeToStandardFaction(oGnoll, STANDARD_FACTION_COMMONER);
		AssignCommand(oGnoll, ClearAllActions(TRUE));
		AssignCommand(oSelf, ClearAllActions(TRUE));
		PlayCustomAnimation(OBJECT_SELF,"UnA_death01",0);
	
        // set their factions to Commoner, eg.
        // and assign ClearAllActions(TRUE) on both critters.
    }
}

and like this:

void main()
{

object oSelf = (OBJECT_SELF);


if (GetCurrentHitPoints(oSelf) == 1)
    {
        // do what it takes to stop combat:
		object oGnoll = GetObjectByTag("l_gnollwrestler2");
		ChangeToStandardFaction(oSelf, STANDARD_FACTION_COMMONER);
		ChangeToStandardFaction(oGnoll, STANDARD_FACTION_COMMONER);
		AssignCommand(oGnoll, ClearAllActions(TRUE));
		AssignCommand(oSelf, ClearAllActions(TRUE));
		PlayCustomAnimation(OBJECT_SELF,"UnA_death01",0);
	
        // set their factions to Commoner, eg.
        // and assign ClearAllActions(TRUE) on both critters.
    }
}

Everything works and they stop fighting. However when using the PlayCustomAnimation one of them just “dies” and then rises up instantly (and I suspected this would happen) and if you loop the animation it’s just up-and-down-you-go. Is there a way to make the one with only 1 hp to fall down and stay down?

Tried this instead, but when doing this nothing happens when one of them dies, apart from them stopping the fight.

void main()
{

object oSelf = (OBJECT_SELF);


if (GetCurrentHitPoints(oSelf) == 1)
    {
        // do what it takes to stop combat:
		object oGnoll = GetObjectByTag("l_gnollwrestler");
		ChangeToStandardFaction(oSelf, STANDARD_FACTION_COMMONER);
		ChangeToStandardFaction(oGnoll, STANDARD_FACTION_COMMONER);
		AssignCommand(oGnoll, ClearAllActions(TRUE));
		AssignCommand(oSelf, ClearAllActions(TRUE));
		EffectDeath(TRUE,TRUE,TRUE,TRUE);
		//PlayCustomAnimation(OBJECT_SELF,"UnA_death01",0);
	
        // set their factions to Commoner, eg.
        // and assign ClearAllActions(TRUE) on both critters.
    }
}

I guess it has to do with telling, in the script, which creature it is that is supposed to die, but I couldn’t find that in the function.

Set an ‘Immortal’ flag on both the gnolls before the training. You can then remove it in the OnDamaged-script when the training is over.

// Set a creature's immortality flag.
// -oCreature: creature affected
// -bImmortal: TRUE = creature is immortal and cannot be killed (but still takes damage)
//             FALSE = creature is not immortal and is damaged normally.
void SetImmortal(object oCreature, int bImmortal);

NOTE: Most hostile spell effects stop working if the enemy is immortal, but the gnolls don’t use any spells against each other, I guess, so it’s not the problem here.

Thanks for the reply Aqvilinus!

I don’t think I was clear about what I wanted to do though. None of the gnolls are supposed to die, just fall down so that it looks like it was knocked out or “died”, so it’s clear for the player which of the ones were victorious in the brawling- or fighting match.

So my question right now is: How do you make the EffectDeath to work? Or is that not the way to do it perhaps?

Ah, I see :slight_smile:

Try this:

	AssignCommand(oGnoll, ClearAllActions(TRUE));
	AssignCommand(oSelf, ClearAllActions(TRUE));
	DelayCommand(0.1f, PlayCustomAnimation(OBJECT_SELF,"UnA_death01",0));

Mmm, yes, but I tried PlayCustomAnimation already and he just rises up directly after dying. I want him to stay down, at least for a few seconds.

But you didn’t use DelayCommand, so the animation was cleared by the ClearAllActions command, I believe.

Ok…does that really make a difference in this case? :astonished: Ok, I’ll test it in game.

Strange…I get an error when trying to compile the script. I can’t see what’s wrong.

My bad. PlayCustomAnimation returns int. You can use only void functions inside DelayCommand.
So you simply need to create the wrapper for this action:

void PlayDeathAnimation()
{
	PlayCustomAnimation(OBJECT_SELF,"UnA_death01",0);
}

And the use it inside DelayCommand:

DelayCommand(0.1f, PlayDeathAnimation());

I just tested it in game, but I’m sorry to say the result is the same. He falls down but rises instantly, just as before.

Ok, here’s another try:

AssignCommand(oGnoll, ClearAllActions(TRUE));
AssignCommand(oSelf, ClearAllActions(TRUE));
PlayCustomAnimation(oSelf, "UnA_death01", 0);
AssignCommand(oSelf, ActionWait(3.0f));   //duration of the animation, ex: 3.0 seconds
AssignCommand(oSelf, ActionDoCommand(SetCommandable(TRUE)));
SetCommandable(FALSE, oSelf);

That’s because you didn’t actually apply the death effect to the gnoll.

ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(TRUE,TRUE,TRUE,TRUE), oSelf);