Startingconditional for checking PC item's variable

Super related to my previous post: Update Object variable via OnEnter Trigger

I’ve spent a few hours now trying to make the conversation check the PCs item’s (non equipped) variable int.

I know I’m way off. I think there’s a way to basically merge what I’m trying to do. I just don’t know how and I haven’t been coming across any similar examples. I assumed I could tweak NWShacker’s code but I’m botching the formatting.

int StartingConditional()
{
GetItemPossessedBy(oPC, "worldstoneshard")== OBJECT_INVALID) return;
if (GetLocalInt(oItem, "bwwp") != 1) return TRUE;

}
int StartingConditional()
{
   object oPC = GetPCSpeaker();
   object oItem = GetItemPossessedBy(oPC, "worldstoneshard");
   if (!GetIsObjectValid(oItem)
   {
      return FALSE;
   }
   return (GetLocalInt(oItem, "bwwp") != 1); 
}

Change last line to

return (GetLocalInt(oItem, "bwwp") == 1);

if script should return TRUE when the value of local int “bwwp” is 1.

@Beleghost Your main problem is the first line. Because you aren’t asking if the item is valid by using an if(), the script doesn’t get passed there.

@Kamiryn You missed a closing bracket on the line with your if() statement so you would get a syntax error there. This gives me an excuse to slightly re-write your code to ensure there is only a single exit point from the function -

int StartingConditional()
{
    object oPC = GetPCSpeaker();
    object oItem = GetItemPossessedBy(oPC, "worldstoneshard");
    int iReturnMe = FALSE;
    
    if(GetIsObjectValid(oItem))
        iReturnMe = (GetLocalInt(oItem, "bwwp") != 1);

    return iReturnMe; 
}

TR

I think this works, just testing it out today.

Does the integer I’m trying to update/check on the item in the PC inventory need to have the existing integer already on it for it to be set? Or should the ‘setlocalint’ (from another script) create the new variable if it’s not there?

Also thank you both for the replies. This community rocks.

It will be created but there’s no reason not to create the variable in the toolset either.

TR

Something isn’t working right for me on this.

Player spawns in module and receives the ‘worldstoneshard’ from a NPC conversation that also sends them off into the world.

Player walks into the trigger area that should be setting the local variable ‘bwwp’ on the item via a onenter script:

void main()
{
    object oPC;
    object oItem;

    oPC = GetEnteringObject();

    if(!GetIsPC(oPC))
    {
        return;
    }

    oItem = GetItemPossessedBy(oPC, "worldstoneshard");

    if(GetIsObjectValid(oItem))
    {
        SetLocalInt(oItem, "bwwp", 1);
    }
    else
    {
        SendMessageToPC(oPC, "You are missing something.");
    }
}

Then after entering the area, the player can select the portal object that kicks off a conversation, with a list of areas the player can travel too. Areas the player has not yet been too, are hidden via the variables.

Conversation Text Appears When…:

int StartingConditional()
{
    object oPC = GetPCSpeaker();
    object oItem = GetItemPossessedBy(oPC, "worldstoneshard");
    int iReturnMe = FALSE;

    if(GetIsObjectValid(oItem))
        iReturnMe = (GetLocalInt(oItem, "bwwp") != 1);

    return iReturnMe;
}

I went ahead and set the variables so they preexist on the item with values of 0.

Doesn’t seem to work for me.

Upon the first conversation with another portal using the same scripts, it displays the options that should be hidden, the variable on item is by default 0. But when I go to the location of the portal with the trigger that should allow the text in conversation, it is not visible.

This is unnecessary. Calling GetLocalInt() on an unset or deleted variable (or invalid target) always yields 0. Same goes for other GetLocal*()s with their respective “null” values.

You may want to write point by point what you’re trying to achieve. How many portals, what’s the difference between them, does the item need to be “activated” just once, etc.

Also put your code between [code] and [/code] (in new lines) so it gets syntax-hilighted.

You are setting it to 1 but then returning TRUE only if it’s not equal to 1.

1 Like

Point by point. Trying to develop the start of a portal system. Where the player can’t use a portal to jump to another portal they have never been too. Somewhat like diablo’s waypoint system but not requiring use of the portal to unlock location, instead coming within proximity of it (via area trigger).

I don’t have a full count of the portals I will end up with. I was hoping once this starts working I could copy/paste and make minor changes - if even needed - for additional city/location portals in the future. Even going so far as allowing the player to set three points anywhere that they can portal too… <— that step is not important right now.

In total right now there are 3 “portals”.
City 1 (player starts here and this is always visible in the portal conversation)
City 2 (player needs to visit the portal at City 2 before it’s available to select in portal conversation.
Worldstone (when a player dies, they return to the worldstone - which is just a portal that uses the same conversation as the other two portals. Allowing the PC to jump back to a city near their death location.

So the idea is the player obtains a shard of the worldstone and that allows them to use the portals. And only where the portal has been visited (visiting City 2 portal), is where the player can teleport too. I wanted to use local variables on the worldstoneshard item in the PC inventory because I may have the PC lose the stone in the future or during certain events/quests - requiring them to obtain a new one, and revisit locations to be able to travel to them again. So plugging the VARs into the PCs undroppable worldstoneshard item seemed to be the right directions in my mind.

Step 1:
Create worldstoneshard in PC inventory:

This comes from a One Time conversation the player has with a NPC that sends them into the world.

/*   Script generated by
    Lilac Soul's NWN Script Generator, v. 2.3

    For download info, please visit:
    http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625    */

    //Put this on action taken in the conversation editor
    void main()
    {

    object oPC = GetPCSpeaker();

    CreateItemOnObject("worldstoneshard", oPC);
    SetLocalInt(oPC, "virgin", 1);

    }

Now the PC has the item and is teleported to City1.

PC talks to a unrelated NPC that charges 800gp to sail them to City2.

PC pays the gold and arrives at City2 docks, makes way into city2 and comes within proximity of the portal. There is a Area Trigger surrounding the portal area that the PC would need to enter before clicking on the portal.

Upon entering the trigger area around the undiscovered portal in City2, the PC’s worldstoneshard item’s local variable called ‘bwwp’ is updated to 1, meaning the portal is discovered.

Trigger Area OnEnter script:

void main()
{
    object oPC;
    object oItem;

    oPC = GetEnteringObject();

    if(!GetIsPC(oPC))
    {
        return;
    }

    oItem = GetItemPossessedBy(oPC, "worldstoneshard");

    if(GetIsObjectValid(oItem))
    {
        SetLocalInt(oItem, "bwwp", 1);
    }
    else
    {
        SendMessageToPC(oPC, "You are missing something.");
    }
}

This script kicks off the conversation when PC uses the portal:

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625    */

//Put this script OnUsed
void main()
{

object oPC = GetLastUsedBy();

if (!GetIsPC(oPC)) return;

object oTarget;
oTarget = GetObjectByTag("bwwp");

AssignCommand(oTarget, ActionStartConversation(oPC, "wordlstone"));

}

I’m aware of the spelling mistake with ‘Wordlstone’ above.

On the portals conversation “text appears when…” check the City2 option should now be visible and the PC teleported when clicking it.

Conversation Script:

int StartingConditional()
{
    object oPC = GetPCSpeaker();
    object oItem = GetItemPossessedBy(oPC, "worldstoneshard");
    int iReturnMe = FALSE;

    if(GetIsObjectValid(oItem))
        iReturnMe = (GetLocalInt(oItem, "bwwp") != 1);

    return iReturnMe;
}

That’s all I’m trying to do. I’m probably making it far more complicated than it should be.

City1 Portal Script:

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625    */

//Put this on action taken in the conversation editor
void main()
{

object oPC = GetPCSpeaker();

object oTarget;
location lTarget;
oTarget = GetWaypointByTag("BeleghostPortal");

lTarget = GetLocation(oTarget);

//only do the jump if the location is valid.
//though not flawless, we just check if it is in a valid area.
//the script will stop if the location isn't valid - meaning that
//nothing put after the teleport will fire either.
//the current location won't be stored, either

if (GetAreaFromLocation(lTarget)==OBJECT_INVALID) return;

AssignCommand(oPC, ClearAllActions());

DelayCommand(3.0, AssignCommand(oPC, ActionJumpToLocation(lTarget)));

oTarget = oPC;

//Visual effects can't be applied to waypoints, so if it is a WP
//the VFX will be applied to the WP's location instead

int nInt;
nInt = GetObjectType(oTarget);

if (nInt != OBJECT_TYPE_WAYPOINT) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_UNSUMMON), oTarget);
else ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_UNSUMMON), GetLocation(oTarget));

}

City2 Portal Script:

/*   Script generated by
Lilac Soul's NWN Script Generator, v. 2.3

For download info, please visit:
http://nwvault.ign.com/View.php?view=Other.Detail&id=4683&id=625    */

//Put this on action taken in the conversation editor
void main()
{

object oPC = GetPCSpeaker();

object oTarget;
location lTarget;
oTarget = GetWaypointByTag("bwwp");

lTarget = GetLocation(oTarget);

//only do the jump if the location is valid.
//though not flawless, we just check if it is in a valid area.
//the script will stop if the location isn't valid - meaning that
//nothing put after the teleport will fire either.
//the current location won't be stored, either

if (GetAreaFromLocation(lTarget)==OBJECT_INVALID) return;

AssignCommand(oPC, ClearAllActions());

DelayCommand(3.0, AssignCommand(oPC, ActionJumpToLocation(lTarget)));

oTarget = oPC;

//Visual effects can't be applied to waypoints, so if it is a WP
//the VFX will be applied to the WP's location instead

int nInt;
nInt = GetObjectType(oTarget);

if (nInt != OBJECT_TYPE_WAYPOINT) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_UNSUMMON), oTarget);
else ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_UNSUMMON), GetLocation(oTarget));

}

Hopefully this is in a decent order.
-missed the trigger onenter script, added.

OK. This is a fairly common concept. Have you tried some of the “portal” projects we have on the Vault? I can’t vouch for any of them, but for sure it will be implemented in in one.

Now that you wrote it, it seems that @meaglyn has good point. In:

iReturnMe = (GetLocalInt(oItem, "bwwp") != 1);

You return TRUE (meaning show jump destination convo line) only when the stone is not activated.

[edit]Too slow…[/edit]

I’ll grab the projects tonight and run through them. I don’t recall seeing them so I didn’t think to look there for someone’s demo or project.

Pops up as one of early results when searching for “portal”:

Simple Portal System | The Neverwinter Vault

It could be a demo or be inflexible, but is a start.

No my man, you got it!

== fixed it and it works correctly now.

I should have tried that 15hours ago when you first suggested it. Sorry about that.

Thank you!

For visability since he edited his answer,

Kamiryn suggested:

Change last line of the conditional to:

return (GetLocalInt(oItem, "bwwp") == 1);

changing != to ==.

Right… nevermind. @Kamiryn pointed that out in the second post.

Actually I told him in the post#2 already ;).

2 Likes

Right you are! I missed that… it was so far back :slight_smile: One is left wondering why all those other posts even happened…

1 Like

That would be my fault…