Bit of scripting help and a couple of ( hopefully) simple questions

I’m looking for a script that would trigger an area transition only if the PC has an item equipped. I’m absolutely no scripter although I’m starting to recognise the odd phrase !

Anyway, I’ve been looking for scripts to do this and came across this one. I could be completely wrong but I reckon its close to what I want but needs some changes. If I’ve learned anything about scripting its that there’ll probably be another 5 or 6 steps I need to add !

void main()
{
// Assign the variables.
object oPC = GetEnteringObject();
object oWP = GetWaypointByTag("dt_cliffstoice");
object oWP1 = GetWaypointByTag("dt_icetocliffs");
int iVar1 = GetLocalInt(GetModule(), "iVar");
// Now we test to make sure at iVar1 is what you need to
// go into the new area. If it isn't, you go to the old.
if (iVar1 != number)
{
    AssignCommand(oPC, JumpToObject(oWP1));
}
else
{
    AssignCommand(oPC, JumpToObject(oWP));
}
}

I reckon the script goes into the OnEnter box in the trigger and I think the line I need help on is this -

int iVar1 = GetLocalInt(GetModule(), “iVar”);

However, I’m stumped with what to do next. I know I need it to check for an item in the inventory. Had a look at the Script Generator but couldn’t figure out how to work it. Any help with getting this script done there would probably save me coming back for more help later :grinning:

My other quick questions aren’t worth starting new posts on as they’re specific to working with a class. Apologies if I need to start new posts for both. I wasn’t sure. I’ve had a look round and there doesn’t seem to be an answer for either and maybe not a solution either.

  1. When demoing a module on a projector for kids any tiles comes across as very dark. Even at the risk of ruining the atmosphere what is the best way of boosting area lighting? I’ve tried rural which seems to be the brightest but once in the game even that goes darker. Clear day in area lighting doesn’t hack it and I’m not sure where to go with customising environment.

  2. Is there a (very) easy way to just end a module by fading to black? I want to create a teaser for the kids where they get a drawbridge down then hear an evil voice ( well, see it spoken above their head !) and it just fades to black.

Thanks for any help offered. Edit: Sorry, forgot to credit the script I used. It was NWN wiki and I think the author was Trinity.

#include "x0_i0_partywide"

void JumpParty(object oPartyMember, object oDestination);

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

	if (!GetIsObjectValid(oLeader)) //Not a PC-faction
		return;

	object oWP = GetWaypointByTag("wp_tag");
	int bCheck = GetIsItemPossessedByParty(oPC, "item_tag");

	if (bCheck == TRUE)
		JumpParty(oPC, oWP);
}

void JumpParty(object oPartyMember, object oDestination)
{
	object oJumper = GetFirstFactionMember(oPartyMember, FALSE);
	while (GetIsObjectValid(oJumper))
	{
		AssignCommand(oJumper, JumpToObject(oDestination));
		oJumper = GetNextFactionMember(oPartyMember, FALSE);
	}
}

I think something like that will acomplish your task.

2 Likes

To clarify, do you want to check whether the PC speaker has an item in their inventory, or whether they are equipping it in a specific slot?

If it’s for an item that oPC is equipping in a specific slot, you want GetItemInSlot:

   // Check whether the tag of the item that is equipped
   // in the right-hand slot of oPC matches a given string.
   object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
   if (GetTag(oItem) == "cookie")
        {
        // Do things here.
        }

If the item may be anywhere in oPC’s inventory, not necessarily being equipped, GetItemPossessedBy is your friend.

    object oItem = GetItemPossessedBy("cookie", oPC);
    if (oItem != OBJECT_INVALID)
        {
        // Do things here.
        }

Whereas, if you’re checking whether any PC member of oPC’s party possesses an item with this tag, then @Aqvilinus 's method with x0_i0_partywide and GetIsItemPossessedByParty could be the thing for you.

In all three of these cases, you’d be checking whether the tag of the item is a match. If you want it to not be case-sensitive, you can also lowercase it first:

    string sTag = GetTag(oItem);
    if (GetStringLowerCase(sTag) == "cookie")

That aside, FadeToBlack is a function to fade the screen to black, EndGame is a function for ending the module, and SpeakString (or ActionSpeakString) is for making objects speak.

    // Clear oPC's action queue.
    AssignCommand(oPC, ClearAllActions());
    // Assign actions to oPC.
    AssignCommand(oPC, ActionSpeakString("*Evil laughter rings in your head...*"));
    AssignCommand(oPC, ActionWait(2.0));
    AssignCommand(oPC, ActionSpeakString("*A voice speaks...* Well, well, well... now what do we have here?"));
    // Locks oPC's action queue.
    // Note: UNLESS YOU UNLOCK IT AGAIN,
    // THEY WILL REMAIN UNABLE TO ACT. FOREVER!
    DelayCommand(0.1, SetCommandable(FALSE, oPC));

    // Fade to black.
    DelayCommand(3.0, FadeToBlack(oPC, FADE_SPEED_SLOWEST));
    //DelayCommand(5.0, EndGame("")); // Commented out; but would end the module.

You can also set Ambient and Diffuse lighting color to pure white, and possibly set the fog color lighter, too, but I think that’s about as bright as things’re gonna get. :thinking: AFAIK the game doesn’t have gamma/brightness sliders.

image

1 Like

Thanks, Aqvilinus. That’s brilliant. It’s for SP but the whole party bit is fine. Tried it and it works. Unfortunately, I had already put in a transition and forgot to take it out so will need to try the transition without that to see if it was the script that did the deed and whether it fails to activate the transition without it.

Yeah, it could have been either but I see the difference in the scripts. It was a particular item they had to get so I think I’ll make it slot specific.

Thanks for offering those three. I already knew the third ( cough . . ) but the others are interesting. I’ll go try them out. I need to get this demo module finished by tomorrow for the class on Friday. I’m going to let them play it to learn the game, hopefully be impressed (!) then tell them we’re gonna build it.

Will try both endings. Just curious but why have you used the DELAY command rather than the float we used before as both are time intervals?

Hmm, slight problem. Took my area transition out of the transition trigger, took the object out of the inventory and it still works.

#include "x0_i0_partywide"

void JumpParty(object oPartyMember, object oDestination);

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

    if (!GetIsObjectValid(oLeader)) //Not a PC-faction
        return;

    object oWP = GetWaypointByTag("dt_cliffstochess");
    int bCheck = GetIsItemPossessedByParty(oPC, "it_lairamulet");

    if (bCheck == TRUE)
        JumpParty(oPC, oWP);
}

void JumpParty(object oPartyMember, object oDestination)
{
    object oJumper = GetFirstFactionMember(oPartyMember, FALSE);
    while (GetIsObjectValid(oJumper))
    {
        AssignCommand(oJumper, JumpToObject(oDestination));
        oJumper = GetNextFactionMember(oPartyMember, FALSE);
    }
}

I just know I’m doing something daft again . . .

No real reason aside from “I didn’t feel like writing out the AssignCommand(oPC, ActionDoCommand(bleghblub()))”-shenanigans at that moment. I think you could probably also add the fade to the action queue:

    // Clear oPC's action queue.
    AssignCommand(oPC, ClearAllActions());
    // Assign actions to oPC.
    AssignCommand(oPC, ActionSpeakString("*Evil laughter rings in your head...*"));
    AssignCommand(oPC, ActionWait(2.0));
    AssignCommand(oPC, ActionSpeakString("*A voice speaks...* Well, well, well... now what do we have here?"));
    AssignCommand(oPC, ActionWait(1.0));    
    AssignCommand(oPC, ActionDoCommand(FadeToBlack(oPC, FADE_SPEED_SLOWEST)));
    AssignCommand(oPC, ActionWait(10.0)); 
    AssignCommand(oPC, ActionDoCommand(EndGame("")));
    // Locks oPC's action queue.
    // Note: UNLESS YOU UNLOCK IT AGAIN,
    // THEY WILL REMAIN UNABLE TO ACT. FOREVER!
    DelayCommand(0.1, SetCommandable(FALSE, oPC));

:thinking:

I’m not spotting anything obviously wrong about the script you posted, there.

1 Like

Ok, its in the other bits I did then.

Made an area transition trigger on a chessboard square. (Thought occurs, should it have been a WP)?
Gave it tag. does it matter what I call it or is that only for the return journey?
Put a WP in the new area
In chess square trigger/ OnEnter I put Aqvilinus’ script, changed the WP destination to the WP tag in new area and the object item to its tag.
Saved as trg_enter_send" and compiled with no errors.

If I don’t have the item in my inventory should I even see the trigger?
Would I see it but just not go anywhere?

Counterquestion: Do you want the trigger to be visible/clickable? :thinking: Giving it a brief test - if there is no destination specified and no OnClick event script, then the area transition trigger doesn’t visibly show up for me at all.

Note that the script does not use area transitions, per se. It does the travel-jump “manually”, without referencing the trigger’s travel destination. If you use the same script for the way back, then the tag of the trigger doesn’t matter, but you’d want to place down a unique waypoint at the location the player should jump to on the way back.

The visibility of the trigger is not being affected by whether or not you have the item. Whether or not any PC party member of the entering object has the item is currently only being checked for when the script runs (so, when something enters the trigger).

2 Likes

Aha, solved, although I’m not sure how. I deleted everything, rebuilt it without putting in area transitions and played the game with the object in the inventory and it worked !

It doesn’t show as a trigger at all for me until it sends me off to the load screen but that’s okay. Just need to make it a bit more obvious where they need to look for it.

Thanks again !

1 Like

Nearly there ! Transition solved but end of game fade to black etc. throwing up error.

It’s line 2 apparently but I’m not sure why.

I take it that we don’t need the “Void all” at the top here with appropriate brackets or were you assuming I’d be clever enough to add it ? :see_no_evil:

The reason for the error is that there is no void main() function. The compiler thinks that you are trying to declare functions for use later in the script instead of calling them.

They need to be in -

void main()
{
    //put that code here
}

TR

1 Like

Thanks Tarot. I thought that was it !

Nope, still not working. . .

‘oPC’ is a variable, what “type” of variable is it? eg.

object, int, float, location,
etc etc

so, declare it:

object oPC;

then, define it:

oPC = GetObjectByTag("tag");

alternately, do it all at once:

object oPC = GetObjectByTag("tag");

 
note: I don’t know what ‘oPC’ should represent; GetObjectByTag() is just an example way to get an object. Other possibilities are OBJECT_SELF, GetEnteringObject() for triggers, and the list goes on …

1 Like

Thanks. That makes sense to me. However, I’m not sure either, other than its the PC we want it to refer to. I remember in a previous script for the PC to speak to self we began

object oPC = GetEnteringObject();
string sIdentifier = ObjectToString(oPC);

Sorry, I’ve also posted this in the wrong place. Should be in Toolset, Scripting , methinks.

I think you can move it to Nwn1|Scripting … before a certain date

 
“the PC” is a bit ambiguous

describe what’s firing the script and that’ll help establish a robust ‘oPC’

Thread moved !

I’m using an OnEnter script on a generic trigger to allow the PC to have a self conversation which appears above his head. The conversation leads to the end of the module or possibly fading to black.

try this at the top of the script

object oPC = GetEnteringObject();
if (!GetIsPC(oPC))
   return;

// then do the actions ...
1 Like

Probably the script wants to be the action taken script for that node of the conversation. In that case use:

object oPC = GetPCSpeaker();

1 Like