Want script to fire upon PC picking item up

#1

I don’t know if anyone checks these forums anymore, but I have a problem I could use help solving…

I wanted a script that would change the environment to fire once the PC picked up a certain item, but the script is firing as soon as my tester enters the module. I changed the OnAcquiredItem script for the module and tried to make it check for the item before running the goblins_attack script, but it isn’t working.
On the bright side, the goblins_attack script appears to be working as intended.
Here is the OnAcquiredItem script (it’s going to be messy because I’m shaky with formatting on this site):

int IsItemPossesedByPC(object oTarget, string sTag){
object oObject = GetItemPossessedBy(oTarget, sTag);
if(oObject == OBJECT_INVALID)
return FALSE;

else
    return TRUE;

}
void main()
{
// Get the object which was acquired
object oItemAcquired = GetModuleItemAcquired();

if (oItemAcquired != OBJECT_INVALID)
{
    if (GetTag(oItemAcquired ) == "DryadBark")
    {
        // Get the object (player) who now possess the item
        object oPC = GetItemPossessor(oItemAcquired );
        if(IsItemPossesedByPC(oPC, "DryadBark")){
            // Change Environs to suit goblin attack
            ExecuteScript("goblins_attack", GetModule());
        }
        // Add an appropriate journal entry to his journal
        AddJournalQuestEntry ("Journal1", 3, oPC);
        // Change Quest progress variable
        SetLocalInt(GetModule(), "Quest_Progress", 3);
    }
}

}

#2

Nice t’meetcha, new person. :slight_smile: Forum’s decently active, I think.

Code formatting works like this:

[code]
// Put the code here.
[/code]

I think we can simplify that a bit. There’s a function for getting the object that picked up an item, thereby triggering the OnAcquireItem event, and at that point, it should just be a matter of aborting if they aren’t a PC, and then checking whether the tag of the acquired item is a match - and making sure that it can’t happen over and over again, forever, if the PC drops and then picks the item back up again. :open_mouth: Give this a try?

void main()
{
    // Get the object which was acquired
    object oItem = GetModuleItemAcquired();
    object oPC   = GetModuleItemAcquiredBy();
    object oMod  = GetModule();

    // This does not happen for non-PCs.
    if (!GetIsPC(oPC))
        return;

    // This does not happen more than once (if nothing can lower this variable again, anyway).
    if (GetLocalInt(oMod, "Quest_Progress") >= 3)
        return;

    if (GetTag(oItem) == "DryadBark")
        {
        // Change Environs to suit goblin attack
        ExecuteScript("goblins_attack", oMod);
        // Add an appropriate journal entry to his journal
        AddJournalQuestEntry ("Journal1", 3, oPC);
        // Change Quest progress variable
        SetLocalInt(oMod, "Quest_Progress", 3);
        }
}

Also, tag-based scripting is a great way to set up items with custom events. :slight_smile: Keeps the OnAcquireItem event clean. Linking Grimlar’s Introduction to Tag-Based Scripting.

1 Like
#3

Thank you so much for replying!
I’m going to try this when I get the chance, but while I have you here, I’m really only trying to trigger the goblin attack after a certain point in the main quest and using the item as the thing to trigger it. I know I could try placing a trigger, but there’s no guarantee the PC will hit it and the quest won’t be able to progress until they do. Do you know of an easier way to do something like that?
My main problem is I’ve been piecing everything together between online forums and the Wordbuilder Guide magazine because it’s been a loooong time since I last did programming of any kind.

1 Like
#4

De nada. :slight_smile: You’re definitely in the right place here. I’m fairly sure all the crazy scripterpeople lurk under the furniture hereabouts, waiting to grab the ankles of unwary passersbys, shrieking something to the effect of “WOULD YOU LIKE TO LEARN NWSCRIPT?”. Some amount of “One of us… one of us…”-chanting may also be involved.

:thinking: I’m not sure I know how to rank the ways to trigger events by difficulty. One thing you could do is start a pseudoheartbeat on module load, which keeps checking whether a script is currently queued for execution, and then queue the goblin attack script for execution when the main quest reaches the appropriate state. Hold up, writin’ ya a thing.

Here, for OnModuleLoad:

void MODHB_Events(int nSecond=0)
{
    // Increment the seconds counter on the module, to be able to read it from within other scripts.
    SetLocalInt(OBJECT_SELF, "CURRENT_SECOND", nSecond);

    // Check whether a script is supposed to be executed on the current second.
    string sScript = GetLocalString(OBJECT_SELF, "QUEUED_SCRIPT_"+IntToString(nSecond));
    // If there is something supposed to happen during this second...
    if (sScript != "")
        // ... do TEH MAGICS!
        ExecuteScript(sScript, OBJECT_SELF);

    // After 1 second, repeat all of this, incrementing the seconds counter by 1.
    DelayCommand(1.0, MODHB_Events(++nSecond));
}

void main()
{
    // Kick off the pseudoheartbeat.
    MODHB_Events();
}
1 Like
#5

Does the module count all items possessed by creatures at the start of the module as acquired items? If that’s the case, it might’ve just been that it saw the dryad herself had some dryad bark and fired based on that.

#6

I’m not sure, but I can confirm that NPCs do trigger the OnAcquireItem event. :open_mouth: If it’s been firing on it’s own, then that sounds like a very likely explanation.

#7

I tried your code and it solved the problem! I think it was counting the dryad herself as the possessor of the dryad bark, so it would fire as soon as the module loaded. Thank you so much. It was driving me crazy lol

1 Like
#8

No prob. :smiley: Shout when the next issue comes up! THEY ARE LURKING EVERYWHERE, TRYING TO EAT OUR TOES. x_x

1 Like