What I've done is fire the OnPlayerRest event once for the PC that initiated the rest. The rest event then cycles through the initiating PC's faction members who are PCs and applies the ForceRest() function to them. At the same time that block of code checks if the resting faction member is a Wizard and if they have their spellbook (if not, spell uses are decremented to pre-rest values).
I went this route because using ActionRest() was firing the rest event for each PC and creating an infinite resting loop that crashed the game - in addition to other undesireable effects (like indexing the clock each time). Heres the final script:
//::///////////////////////////////////////////////
//:: Name: x2_onrest
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
The generic wandering monster system
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: June 9/03
//:://////////////////////////////////////////////
//:: Modified By: Deva Winblood
//:: Modified Date: January 28th, 2008
//:://////////////////////////////////////////////
#include "x2_inc_restsys"
#include "x2_inc_switches"
#include "x3_inc_horse"
void main()
{
object oPC = GetLastPCRested();
object oMount;
if (!GetLocalInt(GetModule(),"X3_MOUNT_NO_REST_DISMOUNT"))
{ // make sure not mounted
/* Deva, Jan 17, 2008
Do not allow a mounted PC to rest
*/
if (HorseGetIsMounted(oPC))
{ // cannot mount
if (GetLocalInt(oPC,"X3_REST_CANCEL_MESSAGE_SENT"))
{ // cancel message already played
DeleteLocalInt(oPC,"X3_REST_CANCEL_MESSAGE_SENT");
} // cancel message already played
else
{ // play cancel message
FloatingTextStrRefOnCreature(112006,oPC,FALSE);
SetLocalInt(oPC,"X3_REST_CANCEL_MESSAGE_SENT",TRUE); // sentinel
// value to prevent message played a 2nd time on canceled rest
} // play cancel message
AssignCommand(oPC,ClearAllActions(TRUE));
return;
} // cannot mount
} // make sure not mounted
if (!GetLocalInt(GetModule(),"X3_MOUNT_NO_REST_DESPAWN"))
{ // if there is a paladin mount despawn it
oMount=HorseGetPaladinMount(oPC);
if (!GetIsObjectValid(oMount)) oMount=GetLocalObject(oPC,"oX3PaladinMount");
if (GetIsObjectValid(oMount))
{ // paladin mount exists
if (oMount==oPC||!GetIsObjectValid(GetMaster(oMount))) AssignCommand(oPC,HorseUnsummonPaladinMount());
else { AssignCommand(GetMaster(oMount),HorseUnsummonPaladinMount()); }
} // paladin mount exists
} // if there is a paladin mount despawn it
if (GetModuleSwitchValue(MODULE_SWITCH_USE_XP2_RESTSYSTEM) == TRUE)
{
/* Georg, August 11, 2003
Added this code to allow the designer to specify a variable on the module
Instead of using a OnAreaEnter script. Nice new toolset feature!
Basically, the first time a player rests, the area is scanned for the
encounter table string and will set it up.
*/
object oArea = GetArea (oPC);
string sTable = GetLocalString(oArea,"X2_WM_ENCOUNTERTABLE") ;
if (sTable != "" )
{
int nDoors = GetLocalInt(oArea,"X2_WM_AREA_USEDOORS");
int nDC = GetLocalInt(oArea,"X2_WM_AREA_LISTENCHECK");
WMSetAreaTable(oArea,sTable,nDoors,nDC);
//remove string to indicate we are set up
DeleteLocalString(oArea,"X2_WM_ENCOUNTERTABLE");
}
/* Brent, July 2 2003
- If you rest and are a low level character at the beginning of the module.
You will trigger the first dream cutscene
*/
if (GetLocalInt(GetModule(), "X2_G_LOWLEVELSTART") == 10)
{
AssignCommand(oPC, ClearAllActions());
if (GetHitDice(oPC) >= 12)
{
ExecuteScript("bk_sleep", oPC);
return;
}
else
{
FloatingTextStrRefOnCreature(84141 , oPC);
return;
}
}
/*
Pstemarie, 11 August 2011
Force the remaining party members to rest
*/
object oPartyMember = GetFirstFactionMember(oPC);
while(GetIsObjectValid(oPartyMember) == TRUE)
{
AssignCommand(oPartyMember, ClearAllActions());
SendMessageToPC(oPartyMember, "You rest with the other members of your party.");
//Check spellbook
if (GetLevelByclass(class_TYPE_WIZARD, oPartyMember) > 0)
{
if (GetItemPossessedBy(oPartyMember, "m1_it_spellbk001") == OBJECT_INVALID)
{
//Store pre-rest values for all memorized spells
int nSpell, nUses, nStored;
for (nSpell = 0; nSpell < 599; nSpell ++)
{
nUses = GetHasSpell(nSpell, oPC);
if (nUses > 0)
{
SetLocalInt(oPartyMember, IntToString(nSpell), nUses);
}
}
ForceRest(oPartyMember);
//Reset spells to their pre-rest values
for (nSpell = 0; nSpell < 599; nSpell ++)
{
nUses = GetHasSpell(nSpell, oPartyMember);
nStored = GetLocalInt(oPartyMember, IntToString(nSpell));
nStored = nUses - nStored;
for (nUses = 0; nUses < nStored; nUses ++)
{
DecrementRemainingSpellUses(oPartyMember, nSpell);
}
DeleteLocalInt(oPartyMember, IntToString(nSpell));
}
SendMessageToPC(oPartyMember, "You cannot regain spells without a spellbook.");
}
else
{
ForceRest(oPartyMember);
}
}
//Check spellbook
else
{
ForceRest(oPartyMember);
}
oPartyMember = GetNextFactionMember(oPC);
}
if (GetLastRestEventType()==REST_EVENTTYPE_REST_STARTED)
{
if (!WMStartPlayerRest(oPC))
{
// The resting system has objections against resting here and now
// Probably because there is an ambush already in progress
FloatingTextStrRefOnCreature(84142 ,oPC);
AssignCommand(oPC,ClearAllActions());
}
if (WMCheckForWanderingMonster(oPC))
{
//This script MUST be run or the player won't be able to rest again ...
ExecuteScript("x2_restsys_ambus",oPC);
}
//Check spellbook
/*
Pstemarie, 11 August 2011
Do not allow a wizard to regain spells without a spellbook
Step 1 - Store remaining uses for memorized spells
*/
if (GetLevelByclass(class_TYPE_WIZARD, oPC) > 0)
{
if (GetItemPossessedBy(oPC, "m1_it_spellbk001") == OBJECT_INVALID)
{
//Store pre-rest values for all memorized spells
int nSpell, nUses;
for (nSpell = 0; nSpell < 599; nSpell ++)
{
nUses = GetHasSpell(nSpell, oPC);
if (nUses > 0)
{
SetLocalInt(oPC, IntToString(nSpell), nUses);
}
}
}
}
//Check spellbook
}
else if (GetLastRestEventType()==REST_EVENTTYPE_REST_CANCELLED)
{
// No longer used but left in for the community
// WMFinishPlayerRest(oPC,TRUE); // removes sleep effect, etc
}
else if (GetLastRestEventType()==REST_EVENTTYPE_REST_FINISHED)
{
// No longer used but left in for the community
// WMFinishPlayerRest(oPC); // removes sleep effect, etc
//Check spellbook
/*
Pstemarie, 11 August 2011
Do not allow a wizard to regain spells without a spellbook
Step 2 - Reset remaining uses for memorized spells
*/
if (GetLevelByclass(class_TYPE_WIZARD, oPC) > 0)
{
if (GetItemPossessedBy(oPC, "m1_it_spellbk001") == OBJECT_INVALID)
{
//Reset spells to their pre-rest values
int nSpell, nUses, nStored;
for (nSpell = 0; nSpell < 599; nSpell ++)
{
nUses = GetHasSpell(nSpell, oPC);
nStored = GetLocalInt(oPC, IntToString(nSpell));
nStored = nUses - nStored;
for (nUses = 0; nUses < nStored; nUses ++)
{
DecrementRemainingSpellUses(oPC, nSpell);
}
DeleteLocalInt(oPC, IntToString(nSpell));
}
SendMessageToPC(oPC, "You cannot regain spells without a spellbook.");
}
}
//Check spellbook
//Advance game clock
/*
Pstemarie, 11 August 2011
Advance the game clock 8 hours when a player rests
*/
int nHour = GetTimeHour();
int nMin = GetTimeMinute();
int nSec = GetTimeSecond();
int nMSec = GetTimeMillisecond();
nHour += 8;
SetTime(nHour, nMin, nSec, nMSec);
//Advance game clock
}
}
}
Modifié par Pstemarie, 12 août 2011 - 10:14 .