You can put an ondeath script on those objects to check if the other objects are alive. If none of them is alive set the Flag on the creature in that same script.
here’s my take on this. NWShacker had the same approach in mind that i chose.
the following script is fairly flexible ; setting a few variables on the creatures and placeables will allow you to designate precisely how many objects of what type will render which creature vulnerable.
kill_me_now.nss
// require n objects to be destroyed before an invulnerable creature is
// rendered vulnerable.
// to use :
// - place this script in the 'on death' event for all objects that will be destroyed,
// - set a string variable named 'target' on all objects that will be destroyed,
// where the value of the variable is the tag of the invulnerable creature.
// - on the invulnerable creature, set an integer variable named 'killmenow'
// whose value is the number of objects that must be destroyed before the
// creature is rendered vulnerable.
void main()
{
string tag = GetLocalString(OBJECT_SELF, "target");
object target = GetNearestObjectByTag(tag);
if (!GetIsObjectValid(target)) {
PrintString("oh noze! can't find a target whose tag is '" + tag + "'!");
return;
}
int counter = GetLocalInt(target, "killmenow");
if (counter > 1) {
SetLocalInt(target, "killmenow", counter - 1);
AssignCommand(target, SpeakString("* Arghhh! *")); // optional... ;)
return;
}
SetImmortal(target, FALSE);
}
Sorry. I wasn’t at home when I sent that. I couldn’t post my code.
Xorbaxian, your script helped wonderfully. I was trying to do some kind of heartbeat loop with a fifth object to check to see if they were destroyed… it was a mess. This is much more elegant, Thank you.
So I figured maybe someone would want to try something like this in their own modules. Here’s the code. I tend to almost over note my scripts. Thanks again everyone.
#include "nw_i0_spells"
///////////////////////////////////////////////////////////////////////////////
// The Mad Poet - Lich Boss Script
// Assistance from: xorbaxian
//
// This script is used on the boss fight in the Forgotten Estate. Players
// must destroy four phylacteries before the lich can be destroyed.
//
///////////////////////////////////////////////////////////////////////////////
void main()
{
//Put the string variable 'target' on each object to be destroyed. The value of
//the string should be the tag of the boss creature.
string sTag = GetLocalString(OBJECT_SELF, "target");
object oTarget = GetNearestObjectByTag("lich_boss");
string sLine;
effect eVFX;
//In case something goes wrong
if (!GetIsObjectValid(oTarget)) {
PrintString("oh noze! can't find a target whose tag is '" + sTag + "'!");
return;
}
//Make sure to put an int variable on the boss. Name:killmenow, Value: Number of
//placeables you are going to have the player destroy
int counter = GetLocalInt(oTarget, "killmenow");
//Decrease the counter
if (counter > 1) {
SetLocalInt(oTarget, "killmenow", counter - 1);
//These are random lines the boss will say as the placeables are destroyed. Edit
//to say whatever you want.
switch (Random(6)+1)
{
case 1: sLine = "What?"; break;
case 2: sLine = "You will not succeed!"; break;
case 3: sLine = "Stop! You must stop!"; break;
case 4: sLine = "I will destroy you for that!"; break;
case 5: sLine = "Death is too swify for you!"; break;
case 6: sLine = "Arrrgh!"; break;
}
//These are VFX to apply when a placeable is destroyed. I'm going for a lich
//so I used evil burst.
AssignCommand(oTarget, SpeakString(sLine));
eVFX = EffectVisualEffect(VFX_FNF_SCREEN_SHAKE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
eVFX = EffectVisualEffect(VFX_FNF_LOS_EVIL_30);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
return;
}
//Alright, placeables are destroyed. Remove the immortality, make it obvious
//with some VFX, and then just blurt it out at the player. Hopefully they understand
//they did a good thing!
SetImmortal(oTarget, FALSE);
eVFX = EffectVisualEffect(VFX_FNF_PWKILL);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oTarget);
FloatingTextStringOnCreature(" With the destruction of the last phylactery the Lich loses its immortality. *", GetLastKiller(), TRUE);
}
For some reason, your code (both of you) has no syntax highlight. Anyway,
You could set it right here too. If counter is zero, it means it has not been set yet, so set it to the total number of placeables to destroy. Then business as usual. TBH, using vars in this case is most useful when there is N targets, but you need to destroy just M < N of them, or if their number is unknown or changes.
Other, simpler (no vars) approach - as @Baireswolf said - would be to just check if there are no more other placeables with the same tag:
if(!GetIsObjectValid(GetNearestObjectByTag(GetTag(OBJECT_SELF))))
{ /* TRUE if caller is the only placeable with this tag here */ }
From narrative perspective, you may also want the boss say its lines with a slight delay.
We considered that with @niv but eventually opted against it because it would force nwscript on all other code types. Highlight.js used by Discourse has a built-in code type detector and I gave the nwscript keywords some strong weights in mine (our) lexer, so they get spotted fairly accurately apart from some tiny snippets. However:
They didn’t use any of them. Explanation below.
I looked at your post’s source and now see why. The thing is that if you have anything in the post with code-like indentation, it is automatically rendered by Discourse with mono font.
So this:
4 spaces + text
tab + text
becomes this:
4 spaces + text
tab + text
This means you don’t need to use ``` or [code] to get the formatting, but then the code is not treated as a code, so no syntax highlighting.
BTW, to post preformatted text with no colors, I prefer to use this method to force no highlighting when the auto-detector is trying too hard:
apologies, @NWNShacker, i missed this one in the deluge of comments to this thread.
i agree, for the most part. however, this is actually the OP’s use case. the OP is scripting for a PW ; while the easiest solution may work fine for this particular encounter, or for a SP module w/a fixed number of quests, on a PW, where you’re constantly developing new quests all the time, it’s important to script w/re-use in mind. on the PW i write for, we’ve currently got well over 6,000 scripts, even paying close attention to script re-use. that’s over 12,000 resources – in a system where the ceiling is 16,000. if we used a cookie-cutter approach instead of writing for re-use, i’m sure we’d already have exploded that limit.
long-winded example
as an example, imagine the developers of the OP’s PW decide to create a situation where the lich somehow comes back… as an arch demi-lich. the demi-lich has summoned 4 elemental princes of evil and feeds off their life energy [i.e., they have to be killed before the Big Bad can be killed]. each of the elemental princes is in turn protected by 4 elemental gateways, all of which must be destroyed before the princes can be killed. this scenario may seem more complicated than the original, but it’s fundamentally the same problem, and while a cookie-cutter approach w/hard-coded tags would be faster, it would also result in up to 16 additional script resources, while the approach i proposed is flexible enough to handle the whole thing – and other problems w/this use case – w/just one script.
i’m not implying my suggestion is ‘One Script to Rule Them All’, but i think in this case the additional level of complexity is warranted. while i think most often ‘simple is better’, it’s sometimes better to write for the general case, especially if the added complexity isn’t significant and the gains are. [just my 2¢]
I get where you were going. EX: I have one script to open every merchant in the game which comes off of one conversation every merchant uses. Hence my Universal Item Quest.