LoneWanderer

onDamaged() event doesn't trigger in TSL?

Recommended Posts

Has anyone tried working with the onDamaged() event in TSL? I overwrote onDamaged scripts for party members and PC, placed them in Override and noticed a problem.

Party members have k_hen_damage01 script attached to their onDamaged() events. It appears that the script for party members only fires when they are controlled by the AI.

For some reason the PC has k_def_damage01 script instead (checked this in pc.utc file, which is available during the game) and it doesn't trigger at all. For enemies and NPCs the script works just fine.

I wonder if this is a problem on my end only, a bug made by Obsidian or if KOTOR 1 had that behavior too?

 

Also, how to work with onUserDefine() event? If I write function SendMessageToPC() inside the script for onAttacked() event, then it works. But similar code inside k_def_userdef01 doesn't trigger. Example of code:

Spoiler

//:: k_def_userdef01
/*
    Default User Defined Events Script
*/
//:: Created By: Preston Watamaniuk
//:: Copyright (c) 2002 Bioware Corp.

#include "k_inc_generic"
#include "k_inc_debug"
#include "k_inc_utility"

void DebugMessage(string sText, int bTimestamp=FALSE);

void main()
{
    int nUser = GetUserDefinedEventNumber();

    if(nUser == 1001) //HEARTBEAT
    {
        DebugMessage("HEARTBEAT.", 1); 
    }
    else if(nUser == 1002) // PERCEIVE
    {

    }
    else if(nUser == 1003) // END OF COMBAT
    {

    }
    else if(nUser == 1004) // ON DIALOGUE
    {

    }
    else if(nUser == 1005) // ATTACKED
    {
         DebugMessage("ATTACKED.", 1); 
    }
    else if(nUser == 1006) // DAMAGED
    {
          DebugMessage("DAMAGED.", 1); 
    }
    else if(nUser == 1007) // DEATH
    {

    }
    else if(nUser == 1008) // DISTURBED
    {

    }
    else if(nUser == 1009) // BLOCKED
    {

    }
    else if(nUser == 1010) // SPELL CAST AT
    {

    }
    else if(nUser == 1011) //DIALOGUE END
    {
    
    }
    else if(nUser == HOSTILE_RETREAT)
    {
        UT_ReturnToBase();
    }
}

void DebugMessage(string sText, int bTimestamp=FALSE) {
	string sTimestamp = "";
	
	if (bTimestamp) {
		int nHour = GetTimeHour();
		int nMin  = GetTimeMinute(); // ST: Ingame-time! There are 2 min/hour.
		int nSec  = GetTimeSecond();
		int nMSec = GetTimeMillisecond();
		
		sTimestamp = (nHour < 10 ? "0" : "") + IntToString(nHour)
			 + ":" + (nMin  < 10 ? "0" : "") + IntToString(nMin)
			 + ":" + (nSec  < 10 ? "0" : "") + IntToString(nSec)
			 + ":" + GetSubString((nMSec  < 10 ? "0" : "") + IntToString(nMSec), 0, 2);	
			 
		sTimestamp += " - ";	
	}
	
	SendMessageToPC(GetPartyLeader(), sTimestamp + "DEBUG[" + GetName(OBJECT_SELF) + "] " + sText);
}

 

 

 

Share this post


Link to post
Share on other sites
On 9/25/2022 at 10:18 AM, LoneWanderer said:

Party members have k_hen_damage01 script attached to their onDamaged() events.

For some reason the PC has k_def_damage01 script instead

The some reason is that the hen in k_hen_damage01 is short for henchman. Henchmen from NWN evolved into the party members of KotOR, so party member scripts are marked hen. The def scripts, meanwhile, are the default scripts.

Anyway, this is normal behaviour for both games. Despite its potential for interesting effects the onDamage hook is basically only used for AI purposes so it's automatically skipped when the player controls them. Still good for having things happen when enemies are damaged though.

  • Like 2

Share this post


Link to post
Share on other sites

Thanks for the clarification!

From this topic I got the impression that it was possible to use onDamaged() script for the player's party.

So, I had an idea about creating new Force Power "Force Shell", that would absorb (technically, immediately regenerate) part of the received damage in onDamaged() script. There is a function GetTotalDamageDealt(), which returns received damage, but the problem is, the function returns correct value only when is called inside onDamaged() event (according to NWN Script wiki). Guess, the idea should be reconsidered.

Share this post


Link to post
Share on other sites

If you need something to trigger off a party member’s HP level you can use a Heartbeat. It’s not perfect but we go to war with the troops we have etc. I think the closest thing to your Force Shell would be a heartbeat that put up a weak shield every six seconds while it was active. Maybe scale the potency of the shield based on how low their HP was.

Share this post


Link to post
Share on other sites
On 9/28/2022 at 3:26 AM, TamerBill said:

I think the closest thing to your Force Shell would be a heartbeat that put up a weak shield every six seconds while it was active.

This is a clever idea and might've worked with some adjustments (strong shield absorbs all damage, then we apply part of the damage to PC), but looks like there is no function available to modders, that can get info about how much damage shield has already absorbed or how much shield HP left? The idea was that new Force Power would be able to block/absorb a dynamic amount of damage (for example, 50% of received damage), otherwise it would be too similar to Force Barrier and Energy Resistance.

With all scripting limitations, I'm thinking about just reading current player's HP and comparing it with the one from previous round in onHeartbeat(), but that'll require to take into consideration healing items and Force Heal.

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.