While setting creature as plot is one way to do it, I recommend against it. Immortal flag is indeed better here (in communication at least).
Rationale: players may be confused why they cannot damage the target and may assume there is something wrong with the module (i.e. builder forgot to clear the plot status when combat started). They will also see incorrect messages, such as the target being immune to critical hits when it isn’t, etc.
I suggest making the creature immortal in toolset or OnSpawn, then check in its OnDamage whether the attacker has the specific item:
- no item - full heal
- item - turn immortality off
This has the benefit of being applied when the hit lands and allows the creature to play VFX and taunt the attacker.
Give PC an emerald to “dispel” the “invulnerability” permanently:
// OnDamage
void main()
{
object oDamager = GetLastDamager();
// I am immortal (set this flag to on elsewhere, i.e. on spawn)
if(GetImmortal())
{
// but attacker got the item (item is not consumed)
if(GetIsObjectValid(GetItemPossessedBy(
oDamager, "NW_IT_GEM012"))) // emerald
{
SpeakString("I am now vulnerable!");
SetImmortal(OBJECT_SELF, FALSE);
}
else
{
// or maybe not
SpeakString("You cannot hurt me!");
ApplyEffectToObject(DURATION_TYPE_INSTANT,
EffectHeal(GetMaxHitPoints()),
OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_INSTANT,
EffectVisualEffect(VFX_IMP_MAGIC_PROTECTION),
OBJECT_SELF);
}
}
// execute default script now
ExecuteScript("nw_c2_default6", OBJECT_SELF);
}
You may need to duplicate this code for OnSpellCastAt.
If you need however the creature to become invulnerable again, try this instead:
// OnDamage
void main()
{
object oDamager = GetLastDamager();
int iDamage = GetTotalDamageDealt();
// attacker got the item (item is not consumed)
if(GetIsObjectValid(GetItemPossessedBy(oDamager, "NW_IT_GEM012")))
{
SpeakString("I am vulnerable!");
SetImmortal(OBJECT_SELF, FALSE);
DelayCommand(0.0, SetImmortal(OBJECT_SELF, TRUE));
}
else
{
// attacker has no item
SpeakString("You cannot hurt me!");
ApplyEffectToObject(DURATION_TYPE_INSTANT,
EffectHeal(iDamage),
OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_INSTANT,
EffectVisualEffect(VFX_IMP_MAGIC_PROTECTION),
OBJECT_SELF);
}
// execute default script now
ExecuteScript("nw_c2_default6", OBJECT_SELF);
}
The trick here is to re-enable immortality right after damage is dealt, so only those who carry the emerald can actually hurt the creature. Or if you prefer - it will absorb their damage and convert it into HP.