Change who inflicts damage from EffectDamage

I have a script I am building around religions shrines where, depending on who your Deity is, you could be buffed, healed, harmed or simply ignored.

When I use EffectDamage it displays as “Someone damage<>”. I would love for it to name the Deity if possible.

My google-fu isn’t helping me here. Any ideas?

place or create an invisible object with the name of the Deity … then do AssignCommand(object, subfunction())

where object is the invisible deity object
and subfunction() constructs and applies the damage effect <- that should result in “So-and-so damages …”

 
/untested, but worth a shot

if you need to choose among multiple deities, I think GetDeity() can get the target’s deity as a string … which could be used during pre-determinations, perhaps then applying the appropriate diety’s name (to the object) w/ SetFirst/LastName()

 
 
basically have an object with the name of the Deity apply the damage effect

ps. “Someone damages…” typically means the effect was applied by the module-object …

I was thinking something similar.

I created and invisible creature and wrote this … but it still says “Someone”

oDeity = GetObjectByTag("DeityTheSisters");
eVis = EffectDamage(iLevel*(iRoll+1),DAMAGE_TYPE_DIVINE);
AssignCommand(oDeity,ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5));

The GetObjectByTag is working though if I throw in a debug message to give me it’s name it’s gives the correct name. I tried it with the creature in a different area, then in the same area. Is there something I should be using instead of ApplyEffectToObject I wonder.

Tried this as well. Still no joy

AssignCommand(oDeity,ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5)));

you may have to construct the effect in a subfunction that’s assigned to the Deity-object …

// 'trigger_oe'

void magical(object oPc);

void main()
{
	object oPc = GetEnteringObject();
	SendMessageToPC(GetFirstPC(FALSE), "trigger_oe");

	AssignCommand(GetNearestObjectByTag("altar"), magical(oPc));
}

void magical(object oPc)
{
	SendMessageToPC(GetFirstPC(FALSE), ". " + GetName(OBJECT_SELF));
	effect e = EffectDamage(10, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_NORMAL, FALSE);
	ApplyEffectToObject(DURATION_TYPE_INSTANT, e, oPc);
}

I didn’t try from the module-object (if that’s what yer starting the script from). But above there’s a trigger behind the alter with that onEnter script, and it successfully shows the name of the Altar as the damager.

 
how are you starting the event, and what event, etc?

try a placeable ( invisible stuff might be hardcoded to say “someone” )

I have it on a trigger. So if they get close to the altar (about 7 meters) it fires off.

The script isn’t finished yet but here’s what I have. Right now it will always return a 0 so I am testing each implementation there before moving it to the right spot. I will try this though

#include "rest_inc"

void main()
{
    object oPC = GetEnteringObject();

    if (GetIsPC(oPC) == TRUE)
    {
        //This is a PC\
        string sDeity = GetDeity(oPC);
        string sShrine = GetTag(OBJECT_SELF);
        int iDuration = 2880;                           /*24 Hours Game time = 48 mins real time */
        int iPC =  GetLocalInt(oPC, sShrine);

        SendMessageToPC (oPC, "Entered Hold area at: " + IntToString(iPC));

        if (GetMinuteTimeZero() <= GetLocalInt(oPC, sShrine) + iDuration) // i_TI_LastRest is 0 when the player enters the module
        {
            // Nothing will happen
            SendMessageToPC (oPC, "MinZero Start: " + IntToString(iPC));
            SendMessageToPC (oPC, "MinZero: " + IntToString(GetMinuteTimeZero()) + " HourZero: " + IntToString(GetHourTimeZero()));
            SendMessageToPC (oPC, "You must wait " + IntToString(iDuration - (GetMinuteTimeZero() - iPC)) + " minutes(s) before this happens again.");
        }
        else
        {
            // Get the gods list
            //      0 = Dp Nothing
            //      1 = Heal
            //      2 = Buff
            //      3 = hurt
            //      4 = Debuff

            int iVi = GetLocalInt(OBJECT_SELF,"iVild");
            int iAr = GetLocalInt(OBJECT_SELF,"iArawin");
            int iGo = GetLocalInt(OBJECT_SELF,"iGofannon");
            int iBr = GetLocalInt(OBJECT_SELF,"iBreve");
            int iCe = GetLocalInt(OBJECT_SELF,"iCeridwen");
            int iRi = GetLocalInt(OBJECT_SELF,"iRigia");
            int iFl = GetLocalInt(OBJECT_SELF,"iFaithless");

            int iLevel = GetLevelByPosition(1,oPC) + GetLevelByPosition(2,oPC) + GetLevelByPosition(3,oPC);
            int iRoll = Random(4)+1;
            effect eVis;
            object oDeity;

            // Check if since the last bump more than <iDuration> mins have passed.
            SetLocalInt (oPC, sShrine, GetMinuteTimeZero());


            if (sDeity == "Faithless")
            {
                switch (iFl)
                {
                    case 1:     //Heal
                        SendMessageToPC (oPC, "You feel the glory of " + sDeity + " flow through you.");
                        eVis = EffectVisualEffect(VFX_DUR_AURA_PULSE_CYAN_WHITE,FALSE);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oPC,3.0);
                        if (iRoll <3)
                        {
                            eVis = EffectHeal(iLevel*(iRoll+1));
                            ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5);
                        }
                        break;
                    case 2:     //Buff
                        SendMessageToPC (oPC, "You feel the glory of " + sDeity + " flow through you.");
                        eVis = EffectVisualEffect(VFX_DUR_AURA_PULSE_CYAN_WHITE,FALSE);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oPC,3.0);
                        if (iRoll <3)
                        {
                            eVis = EffectSavingThrowIncrease(SAVING_THROW_ALL,iRoll,SAVING_THROW_TYPE_ALL);
                            ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oPC,300.0);
                        }
                    case 3:     //Hurt
                        SendMessageToPC (oPC, "You feel the disaproval of " + sDeity + " wash over you.");
                        eVis = EffectVisualEffect(VFX_DUR_AURA_PULSE_CYAN_BLACK,FALSE);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oPC,3.0);
                        if (iRoll <3)
                        {
                            eVis = EffectDamage(iLevel*(iRoll+1),DAMAGE_TYPE_DIVINE);
                            ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5);
                        }
                        break;
                    case 4:     //Debuff
                        break;
                    default:    //Do Nothing

                        eVis = EffectVisualEffect(VFX_DUR_AURA_PULSE_CYAN_RED,FALSE);
                        ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eVis,oPC,3.0);
                            oDeity = GetObjectByTag("DeityTheSisters");
                            eVis = EffectDamage(iLevel*(iRoll+1),DAMAGE_TYPE_DIVINE);

//ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5);
//AssignCommand(oDeity,ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5));
//AssignCommand(oDeity,ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5)));
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oPC,0.5));



                        SendMessageToPC (oPC, "DEBUG: Nothing happens.");
                        SendMessageToPC (oPC, "DEBUG: oDeity is: " + GetName(oDeity));
                        break;
                }
            }
        }
    }
    //Not a PC so go away I guess
}

/heh im on nwn2 but suspect the behavior is the same as 1

yeah, just write an effector function

void doDivine(int iDamage, object oPC)
{
    effect eVis = EffectDamage(iDamage, DAMAGE_TYPE_DIVINE);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
}

and call it

AssignCommand(oDeity, doDivine(iLevel*(iRoll+1), oPC));

(don’t forget to define oDeity in case 3 )

Thanks it works pretty good with an invisible creature but if I assign it to the Altar I am getting

Bad Strref as the damager unfortunately. I have defined the altar object properly though as my debug is giving the right name for it.

Gonna play around with that a bit as I really don’t want to have to create invisible creatures and put them with the altars. I might play with creating an invisible creature, hitting the PC and then despawning it as well. Gotta love scripting eh! Thanks for the help that wrapper did the trick, just seems silly you have to use one there but hey if it works it works!

Tried creating the creature, running the command and then destroying it but I think that I have some sort of operational order issue going on. Even with Delays it’s not working properly. I don’t want the creature to be there all the time because pressing TAB shows it even through it’s invisible.

If it’s not in the same area it doesn’t work
If it’s not in an area connected / near the PC it doesn’t appear to work.

sigh maybe I should just accept “Someone” doing the damage adderall. I have a several hours putzing around with what really is a minor flavour part of the world.

hm yeh sounds niggly,

it also sounds like it could work, with some more tweaks and ideas, like spawning/despawning a creature or placeable into an inaccessible region of the area … eg.

eg … a temp object can be despawned in the wrapper-funct w/ DestroyObject(oTemp, 0.5);

Since I don’t know specifics of your module i cant really say much; but i suspect someone has in fact solved this in Nwn1.

maybe one of the old pros will chime in,

Have you tried SetTlkOverrite() to overwrite the tlk entry used be the message? Would require latest EE build though. Could be done either by temporarily overwriting the whole message or just by overwriting that ‘Someone’ (StrRef 8349) with the name of the deity.

1 Like

But why a creature? Can’t an invisible placeable do this?

Assigning the command to an invisible object works for me.

It needs to be reasonably close to the PC - over some distance limit (40m, perhaps?) even a creature attack will say “Someone”.

The name of the damaging object is set in advance. I’d expect SetName to be instant - can’t imagine why it would BadStrRef - but maybe a slight delay before the effect would help?

In my examples, the command is assigned by the module, which I have found to be very reliable, but I doubt whether that matters here.

Final thought - for an instant effect, the last parameter of ApplyEffectToObject isn’t required - but again it shouldn’t matter.

1 Like

Hmmm.

I don’t get it at all. I tried stripping this down to the bare minimum. I created the Altar, put the trigger around it, the PC is literally less than 2 meters away from the altar when they enter the trigger.

This is my OnEnter Script for the trigger

void doDivine(int iDamage, object oPC)
{
effect eVis = EffectDamage(iDamage, DAMAGE_TYPE_DIVINE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
}

void main()
{
object oDeity = GetObjectByTag("DivineAltar");
object oPC = GetEnteringObject();
effect eVis = EffectDamage(1, DAMAGE_TYPE_DIVINE);

SendMessageToPC (oPC, "DEBUG: you entered the trigger.");
SendMessageToPC (oPC, "DEBUG: oDeity Name is: " + GetName(oDeity));
SendMessageToPC (oPC, "DEBUG: oDeity Tag is: " + GetTag(oDeity));


SendMessageToPC (oPC, "DEBUG: Try Dmg with Applyeffect");
doDivine(1,oPC);


SendMessageToPC (oPC, "DEBUG: Try Dmg with AssignCommand");
AssignCommand(oDeity,doDivine(1,oPC));


SendMessageToPC (oPC, "DEBUG: Try Dmg with DelayCommand then AssignCommand");
DelayCommand(1.0,AssignCommand(oDeity,doDivine(1,oPC)));
}

Entering into the trigger I get the debug messages as follows
DEBUG: you entered the trigger
DEBUG: oDeity Name is: Altar To The Sisters
DEBUG: oDeity Tag is: DivineAltar

all 3 damage effects read
Someone damages Seluna: 1 (1 Divine)

I know spawning the invisible creature will work but it also rolls initiative and feels really kludgy. @Proleric What version of NWN are you running. I am on NWN: EE.

Does my object maybe need to be configured a certain way? The Altar right now is just set as Static. It’s not Plot or Usable. Changing it to Plot and Usable didn’t make any difference though.

I wonder if it would work better if I made the altar usable and this was in it’s on used event. I could do that and still maintain the aesthetic I am going for.

I think it’s still the trigger that runs the script and that does the damage… thus ‘Someone’.
But if you’re building on EE anyway why don’t you just overwrite the tlk entry ‘Someone’?

SetTlkOverride(8349, GetName(oDeity));
doDivine(1, oPC);
SetTlkOverride(8349, ""); // maybe this has to be delayed 

I can’t find that in my toolset. I see that there is a lexicon entry SetTlkOverride(int, string) - NWN Lexicon

Looking at the tlk entiresI find the one I want to change is

#define STRREF_SOMEONE 8349

So I try
SetTlkOverride(8349,“The Sisters”);

I get the followin

_god_on_enter.nss(14): ERROR: UNDEFINED IDENTIFIER (SetTlkOverride)

So it seems my toolset isn’t finding it from what I am reading it’s part of the new Development Build 8193.21 and it might be exactly what I am looking for but it doesn’t look like it’s actually released yet, at least my steam install says it’s up to date and it’s not in my toolset. My toolset is showing Game version v1.82 Toolset version vts80 Playing my game shows version 82.8193.20.1 So I am juuuust out of date I guess.

Anyone have any idea when they will release 8193.21 on steam?

in nwn2 Static tends to shut objects down … → try false

No idea how it works in steam but on the beamdog client the deveolpment build is a different download.

Good news however is that it works:

 void main()
 {
     object oPC = GetEnteringObject();
     effect eVis = EffectDamage(2, DAMAGE_TYPE_DIVINE);
     SetTlkOverride(8349, "Altar To The Sisters");
     ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
     SetTlkOverride(8349, "");
 }

displays ‘Altar To The Sisters damages …’.

1 Like

@SiliconScout my method works in both EE and 1.69, with non-static objects which are assigned commands by the module.

Did you try a different damage type?

Updated to the beta build (pretty easy just go into properties on steam, beta tab and pick it from the drop down).

SetTlkOverride is a dream. Thanks everyone this seems like such a simple thing but good lord will this make such a difference!

1 Like