On Rest Scripts

Hello all,

I’ve searched through Google and even these forums for anything pertaining to the NWN2 rest system and can’t find anything to give me a good idea of where to go. I did find ColorsFade’s guide to setting up the MotB rest system, but after following it I couldn’t get it to work. Now when I hit the R key my party kneels for a second, then stands back up. No change in the GUI, and no option to wait versus rest, etc. The party does have a rested effect though, as spells were replenished, but this wasn’t what was supposed to happen.

That’s neither here nor there though, I guess. I just want to be able to place triggers that allow the party to rest if they’re near a campfire or any kind of heat source (lots of snow and no shelter in most areas). But my attempts to use variables fell apart when I saw there were no real functions to check to see if a player is in the right area in order to then “allow rest”. I see only five functions related to resting and none of them do what I want. But I’m not a scripter and I’ve only learned what I have learned by modding these NWN games. So there’s probably a more creative way to get what I want. I just can’t figure it out. Any suggestions?

I’ve been through the “gui_rest” and “k_mod_load” and “k_player_rest” scripts and can’t make heads or tails of what to change in them. Lastly, my module currently uses the default “resting” gui after you hit R and you can rest as often as you like, wherever you like, with no repercussions. I don’t know where to go to tweak this behavior, but my guess is it’s one of those scripts I listed above.

Thanks for your help!

resting works through the module-level OnRest event

in the toolset: View|Module Properties|Scripts|On Player Rest Script

a script that’s slotted there handles nwn2’s OnRest event … there are 3 types of rest event, all handled in that script:

void main()
{
    switch (GetLastRestEventType())
    {
        case REST_EVENTTYPE_REST_STARTED:
            break;

        case REST_EVENTTYPE_REST_FINISHED:
            break;

        case REST_EVENTTYPE_REST_CANCELLED:
            break;
    }
}

( sometimes structured as if/else statements )

REST_EVENTTYPE_REST_STARTED is the most important one. Paint your trigger for allowing rest, and set a variable on the creature that enters the trigger (eg. canrest=1 ) in the trigger’s OnEnter script. Delete the variable on the creature that leaves the trigger in the trigger’s OnExit script. And check the variable on the creature in the OnRest script:

void main()
{
   object oRester = GetLastPCRested();

    switch (GetLastRestEventType())
    {
        case REST_EVENTTYPE_REST_STARTED:
            if (!GetLocalInt(oRester, "canrest"))
            {
                AssignCommand(oRester, ClearAllActions()); // prevent rest, i think that works
            }
            else
            {
                // do rest routine here
            }
            break;

        case REST_EVENTTYPE_REST_FINISHED:
            break;

        case REST_EVENTTYPE_REST_CANCELLED:
            break;
    }
}

Look at other rest scripts to see what other sorts of things should go in the rest script … this is just the basics, I just wanted to point you to the OnRest script and event

 
ps. the Nwn Lexicon is still our friend

1 Like

Thanks KevL_s!

I wrote this:

#include “wot_severing”
#include “wot_ft_effects”
void main()
{

	object oPC = GetLastPCRested();
	AjahChooseOnRest(oPC);
	DarkOnesHoundOnRest(oPC);
	ShadarLogothCurseOnRest(oPC);
	PresenceOnRest(oPC);
	ResolveCombatCastingOnRest(oPC);
	DefensiveBlowOnRest(oPC);
	WarderBondOnRest(oPC);
	WolfSpeechOnRest(oPC);
	WolfScentOnRest(oPC);
	WolfYellowEyesOnRest(oPC);
	WolfTrackByScentOnRest(oPC);
	WolfbrotherSurvivorOnRest(oPC);
	WolfGreatHealthOnRest(oPC);
	WolfKeenHearingOnRest(oPC);
	NobleCallInFavorOnRest(oPC);
	DanceTheSpearsOnRest(oPC);
	BrotherhoodContactsOnRest(oPC);
	PersuasiveOnRest(oPC);
	TrustworthyOnRest(oPC);
	MimicOnRest(oPC);
	SeveredOnRest(oPC);
	
	int nRestType = GetLastRestEventType();
	
	if((GetLocalInt(oPC, "SafeToRest") == 1) && (nRestType == REST_EVENTTYPE_REST_STARTED))
		{
		SendMessageToPC(oPC, "It is warm enough to rest here.");
		}
	else
		{
		AssignCommand(oPC, ClearAllActions());
		SendMessageToPC(oPC, "It is not warm enough to rest here.  Find some place with a heat source or shelter from the cold if you wish to rest.");
		} 

}

And it worked, but for some reason it would send the message “It is not warm enough…” just after I finished resting. But yes, it seems ClearAllActions was the right path. I suppose I should have tested more before asking for help. Still though, I’m going to try your script out and see if that doesn’t run as…well, clunky as mine.

I appreciate the help, and yes, I really do try to use the Lexicon when I can. But as I said, my only scripting experience is from these two games and I’m not very good at it so even that site is still very Greek to me. But every time I ask for help I learn something new, so maybe one day I’ll be able to whip out scripts like you seem to be able to do. Seriously, did you just write that off the top of your head? I have to write in the toolset and hit “save and compile” a lot just to help me find all of my errors. Nice work man.

Yes, your script worked perfect. No double messages or telling me it wasn’t warm enough after I had just rested. I sure appreciate it KevL!

np Lando :)

scripting (and coding in general) becomes easier with experience, the more you work in concepts and come to recognize ‘patterns’ that coders use over and over. Your intuition starts saying what’s possible, but then i often look up the functions and its args (on the Lexicon or in NwScript.nss, eg)

 
 
note that eventscripts usually have several very specific functions that can be used exclusively in their respective scripts – eg. GetLastRestEventType() and GetLastPCRested() for the OnRest event. The Lexicon lists those functs under Events … very handy,

1 Like

i think you’re getting the double rest message because of this:

if (GetLocalInt(oPC, "SafeToRest") == 1 && nRestType == REST_EVENTTYPE_REST_STARTED)
{
    //
}
else
{
    AssignCommand(oPC, ClearAllActions());
    SendMessageToPC(oPC, "It is not warm enough to rest here.");
}

The game fires the OnRest script twice automatically. First for REST_STARTED and again for REST_FINISHED (or REST_CANCELLED). OnRestStarted says not safe to rest, so the message appears. Then OnRestFinished says not rest started, so the message appears again.

->

if (nRestType == REST_EVENTTYPE_REST_STARTED)
{
    if (GetLocalInt(oPC, "SafeToRest") == 1)
    {
        //
    }
    else
    {
        AssignCommand(oPC, ClearAllActions());
        SendMessageToPC(oPC, "It is not warm enough to rest here.");
    }
}

Oh, I didn’t know that. You know, there are other scripts I’ve written where I’ve put a SendMessageToPC thing in there just to help me debug or see if the script actually fired and I’ve often seen that message fire two or even three times all at once, spamming the chat box. I’ll need to read more about when scripts fire like that. I had no idea they did such things. Thanks for looking it over and helping me learn!

2 Likes