Sign in to follow this  
Salk

[KotOR Scripting] OnDeath() for henchmen

Recommended Posts

Hello!

Does anyone know whether the OnDeath() script triggers for party members that are incapacitated during combat or if they do need to be "properly" killed?

Share this post


Link to post
Share on other sites

You'll probably need to edit k_hen_damage01 and do a HP check. They don't have an OUD or OnDeath script assigned aside from Canderous, who has an OUD with an OnDeath event for his regen.

  • Like 1

Share this post


Link to post
Share on other sites

Alright.

Thanks for the advice!

Do you see a problem with my revised k_hen_damage01 script, @DarthParametric?

The goal is to have Mission gain some bonus once the other two party members are down and remove the bonus once combat is over (feat.2da and globalcat.2da have been modified accordingly, of course).

void FeatStreetwise()
{
    if (GetHasFeat(129, OBJECT_SELF))
    {
        if (GetPartyMemberByIndex(1) != OBJECT_INVALID && GetPartyMemberByIndex(2) != OBJECT_INVALID)
        {            
            object oFirstPM;
            object oSecondPM;
            
            if (GetPartyMemberByIndex(0) == OBJECT_SELF)
            {
                oFirstPM = GetPartyMemberByIndex(1);
                oSecondPM = GetPartyMemberByIndex(2);
            }
            else if (GetPartyMemberByIndex(1) == OBJECT_SELF)
            {
                oFirstPM = GetPartyMemberByIndex(0);
                oSecondPM = GetPartyMemberByIndex(2);
            }
            else if (GetPartyMemberByIndex(2) == OBJECT_SELF)
            {
                oFirstPM = GetPartyMemberByIndex(0);
                oSecondPM = GetPartyMemberByIndex(1);
            }
            
            if ((GetCurrentHitPoints(oFirstPM) < 1) && (GetCurrentHitPoints(oSecondPM) < 1) && (!GetGlobalBoolean("STREETWISE")))            
            {
        SetGlobalBoolean("STREETWISE", TRUE);

                effect eACUp = EffectACIncrease(1, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
        effect eSTUp = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_ALL);
                
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eACUp, OBJECT_SELF);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eSTUp, OBJECT_SELF);
            }
            
        }
    }
}

void main()
{

    object oMission = GetObjectByTag("Mission");

    if (IsNPCPartyMember(NPC_MISSION)) {
      if ((GetGlobalBoolean("STREETWISE")) && (!GetIsInCombat(oMission))) {
        SetGlobalBoolean("STREETWISE", FALSE);
        AssignCommand(oMission, ClearAllEffects());
      }
      if ((!GetGlobalBoolean("STREETWISE")) && (GetIsInCombat(oMission)) && (GetCurrentHitPoints(oMission) > 0)) {
        AssignCommand(oMission, FeatStreetwise());
      }
    }
    
    ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_HENCH_EVENT_ON_DAMAGE);
}

 

Share this post


Link to post
Share on other sites

DURATION_TYPE_TEMPORARY sounds ideal but I have never seen it used anywhere.

But other than duration type, would you say things should work?

I am unsure about the effect being applied on the player controlled party member and that's my main concern.

Share this post


Link to post
Share on other sites

Since you clear it out of combat, you could just go with permanent. Something you'll need to test I guess.

Another thing that springs to mind is that you'll probably need a GetIsDead check in addition to or as opposed to the GetIsObjectValid check, much like that Xor mooks issue for K1CP. Especially with party members, they presumably remain a valid object after death, since they resurrect after combat is over.

Share this post


Link to post
Share on other sites

One more thing I realize now is that my code wouldn't work when there are only two party members (unlikely to happen but surely possible).

I'll have to remedy that.

 

Share this post


Link to post
Share on other sites
4 hours ago, DarthParametric said:

You'll probably need to edit k_hen_damage01 and do a HP check. They don't have an OUD or OnDeath script assigned aside from Canderous, who has an OUD with an OnDeath event for his regen.

This works, but also you could just give her an onDeath. Her file needs to be edited anyway to add the feat.

 

4 hours ago, Salk said:

DURATION_TYPE_INSTANT

I assume you're looking at my Last Stand for reference? DURATION_TYPE_INSTANT is used for effects with no duration, like the heals I used there. For an AC bonus it needs to be either TEMPORARY with a set duration or PERMANENT to work.

 

4 hours ago, Salk said:

if (IsNPCPartyMember(NPC_MISSION)) {
      if ((GetGlobalBoolean("STREETWISE")) && (!GetIsInCombat(oMission))) {
        SetGlobalBoolean("STREETWISE", FALSE);
        AssignCommand(oMission, ClearAllEffects());

 

If this is in  k_hen_damage01 it's only going to get called when they take damage. So it won't wear off when combat ends, it'll wear off only when someone takes damage out of combat.

Share this post


Link to post
Share on other sites
5 minutes ago, TamerBill said:

you could just give her an onDeath

He's checking for when the rest of the party is dead while Mission is still alive, so that would require adding OnDeaths to everyone else.

Share this post


Link to post
Share on other sites
4 minutes ago, DarthParametric said:

He's checking for when the rest of the party is dead while Mission is still alive, so that would require adding OnDeaths to everyone else.

Yeah, I was just coming back to edit that >.<

But the mod involves giving feats to multiple party members, so it's still not unreasonable.

Share this post


Link to post
Share on other sites

Hello again!

1 hour ago, TamerBill said:

I assume you're looking at my Last Stand for reference?

I was just looking at that as reference (although now I changed a few things around).

1 hour ago, TamerBill said:

If this is in  k_hen_damage01 it's only going to get called when they take damage. So it won't wear off when combat ends, it'll wear off only when someone takes damage out of combat.

Very true.

I have moved that part to the henchmen's heartbeat.

I actually moved everything to the henchmen's heartbeat because my testing was not successful when trying to apply the bonus via k_hen_damage01 while it did work using the heartbeat. I don't like it because of the delay (I think the worst case scenario is the bonus being applied 6 seconds after the death of the other party members) so I am open to alternate solutions.

This is the code I introduced in the henchmen's heartbeat:
 

void BuffUp(object oSelf)
{
  SetGlobalBoolean("STREETWISE", TRUE);

  effect eACUp = EffectACIncrease(1, AC_DODGE_BONUS, AC_VS_DAMAGE_TYPE_ALL);
  effect eSTUp = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_ALL);
                
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, eACUp, oSelf);
  ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSTUp, oSelf);

  BarkString(oSelf, 36946);

}

void FeatStreetwise() {
    if (GetHasFeat(129, OBJECT_SELF)) {

    object oFirstPM;
    object oSecondPM;

    if (GetPartyMemberCount() == 3) {
      if (GetPartyMemberByIndex(0) == OBJECT_SELF) {
        oFirstPM = GetPartyMemberByIndex(1);
        oSecondPM = GetPartyMemberByIndex(2);
      }
      else if (GetPartyMemberByIndex(1) == OBJECT_SELF) {
        oFirstPM = GetPartyMemberByIndex(0);
        oSecondPM = GetPartyMemberByIndex(2);
      }
      else {
        oFirstPM = GetPartyMemberByIndex(0);
        oSecondPM = GetPartyMemberByIndex(1);
      }
      if ((GetCurrentHitPoints(oFirstPM) < 1) && (GetCurrentHitPoints(oSecondPM) < 1) && (!GetGlobalBoolean("STREETWISE")))    {
        BuffUp(OBJECT_SELF);
      }
        }
    else if (GetPartyMemberCount() == 2) {
      if (GetPartyMemberByIndex(0) == OBJECT_SELF) {
        oFirstPM = GetPartyMemberByIndex(1);
      }
      else {
        oFirstPM = GetPartyMemberByIndex(0);
      }
      if ((GetCurrentHitPoints(oFirstPM) < 1) && (!GetGlobalBoolean("STREETWISE"))) {
        BuffUp(OBJECT_SELF);
      }
    }
    }
}

void main() {
  object oLeader = GetPartyMemberByIndex(0);
  object oNPC1 = GetPartyMemberByIndex(1);
  object oNPC2 = GetPartyMemberByIndex(2);

 (...)


  if (IsNPCPartyMember(NPC_MISSION)) {
    if ((GetGlobalBoolean("STREETWISE")) && (!GetIsInCombat(oMission))) {
      AssignCommand(oMission, ClearAllEffects());
      SetGlobalBoolean("STREETWISE", FALSE);
    }
    if ((!GetGlobalBoolean("STREETWISE")) && (GetIsInCombat(oMission)) && (GetCurrentHitPoints(oMission) > 0)) {
      if (GetIsObjectValid(oNPC2)) {
        if (GetCurrentHitPoints(oLeader) < 1 || GetCurrentHitPoints(oNPC1) < 1 || GetCurrentHitPoints(oNPC2) < 1) {
          AssignCommand(oMission, FeatStreetwise());
        }
      }
      else if (GetIsObjectValid(oNPC1)) {
        if (GetCurrentHitPoints(oLeader) < 1 || GetCurrentHitPoints(oNPC1) < 1) {
          AssignCommand(oMission, FeatStreetwise());
        }
      }
    }
  }

(...)

}

By the way, do you know if BarkString() plays .wav files associated with the string called? And if not, how do I play a sound that is in the Streamsounds folder of the game?

Would Playsound("p_mission_bat4") work?

Thanks!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this