Hey guys, I’ve looked through Script Gens and the Archive but I can’t seem to find information on how to make an NPC give up when it’s about to be killed. Advice? Thank you!
You can use the built-in SurrenderToEnemies
function. Call it in OnDamaged when HP drops below a certain level. Making the creature immortal is also a good idea to prevent it from actually dying.
That’s right. Despite the comments in the Lexicon, SurrenderToEnemies seems to be permanent and affects all enemies, including associates. The code I use is
object oNPC = OBJECT_SELF;
SurrenderToEnemies();
ForceRest(oNPC); // Cancels spells in progress (and fully restores NPC)
AssignCommand(oPC, ClearAllActions(TRUE)); // Ensures PC can talk - conversation should be delayed by (say) 0.5 sec to allow this to take effect
Thank you both!
if((GetIsDead(OBJECT_SELF) == FALSE) && (nCurrHP <= 30) && GetLocalInt(OBJECT_SELF,“Generic_Surrender”) == 0)
Sorry I’m not sure where I’d list the HP marker. Trying to use the OC as an example but as I was told, it’s a bit of a mess. This is, “if not dead and HP at 30 get self and set a surrender variable at 0.” Are they just doing that for the dialogue tree?
The typical protocol (also used by OC) is as follows:
- NPC is set as immortal
- NPC talks and goes agro
- NPC gets beaten up by PC
- NPC surrenders (handled by its OnDamaged)
- NPC talks to PC, possibly going agro again (when it fights to death)
Variable you’re seeing in that snippet from OC (which has a bug by the way - classy BW) is set at stage 3 to ensure that specific (post-battle) dialogue tree is entered at stage 4.
Assuming you’re trying to achieve this, put this script as NPC’s OnDamaged script.
Click me.
// surrender at this fraction of HP (0 - 1)
const float SURRENDER_HP_FRACTION = 0.1;
// surrender dialogue variable
const string SURRENDER_VARIABLE = "i_give_up";
// OnDamaged event script
void main()
{
float fCurHP = IntToFloat(GetCurrentHitPoints());
float fMaxHP = IntToFloat(GetMaxHitPoints());
object oPC;
if(fCurHP / fMaxHP <= SURRENDER_HP_FRACTION &&
!GetLocalInt(OBJECT_SELF, SURRENDER_VARIABLE))
{
SetLocalInt(OBJECT_SELF, SURRENDER_VARIABLE, TRUE);
SurrenderToEnemies();
oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
ClearAllActions(TRUE);
AssignCommand(oPC, ClearAllActions(TRUE));
ActionStartConversation(oPC);
return;
}
ExecuteScript("nw_c2_default6", OBJECT_SELF);
}
Got it working, thanks again!
Just for accuracy what that code snippet actually says in English is -
If the calling object is NOT dead AND it’s current hitpoints are 30 OR less AND
the local variable “Generic_Surrender” set on the calling object is Zero/FALSE,
do the code that follows.
It could be written slightly less complicated like -
if(!GetIsDead(OBJECT_SELF) && (nCurrHP < 31) && !GetLocalInt(OBJECT_SELF, “Generic_Surrender”))
TR
This seems to be correct.
Lexicon also states that the 10 meter distance from function’s description is outdated. It says the value is now 50 m. I made a quick check and it seems to be 45.5 m (Lexicon says 54.5, which I guess is a typo).
This is indeed way beyond anyone’s vision range, but may be not enough if there are mobile creatures in the area. Making a NPC neutral towards everyone in such area isn’t a big problem though.