The following is the onplayerrest script I use in Age Of Mortals and it gives resting a realistic feeling. Log in to my roleplay server and press rest to test it out.
//::///////////////////////////////////////////////
//:: Custom Module OnPlayerRest Script
//:: Copyright © 2003
//:://////////////////////////////////////////////
//
// Purpose: To limit resting by a configurable amount of time. Provides ability to allow
// unlimited resting for users under a certain level, or allow unlimited resting
// in certain areas.
//
//:://////////////////////////////////////////////
//:: Created By: Diabolist
//:: Created On: June, 2003
//:://////////////////////////////////////////////
void main()
{
object oPC = GetLastPCRested();
// eBad is used to cycle through effects on the user, and remove the blind and deaf effects from resting
// I'm uncertain why I can't just do a RemoveEffect(oPC, EffectBlindness())...
effect eBad = GetFirstEffect(oPC);
// get the hour and day the user last rested
int nLastRestedHour = GetLocalInt(oPC, "LastRestedHour");
int nLastRestedDay = GetLocalInt(oPC, "LastRestedDay");
// Since nLastRestedHour will return 0 if it's NOT set, and 0 is a valid hour, we need another variable to check if the user has ever rested
int nHasRested = GetLocalInt(oPC, "HasRested");
// Time difference between last rest and last rest attempt
int nRestDelta;
// change nRestTimer to increase/decrease the wait time between resting (with default NWN game time, 5 equates to 10 minutes real-time)
int nRestTimer = 5;
int nHour = GetTimeHour();
int nDay = GetCalendarDay();
int bCanRest = FALSE;
// Get the area the PC is in, this can be used to allow unlimited resting in certain areas
string sArea = GetTag(GetAreaFromLocation(GetLocation(oPC)));
// change nPCMinLevel to allow users equal to, or less than, this value to rest without waiting
int nPCMinLevel = 5;
int nPCLevel = GetLevelByPosition(1, oPC) + GetLevelByPosition(2, oPC) + GetLevelByPosition(3, oPC);
// Used in output to change the word "hour" to "hours"
string sPlural = "";
// String to save the location of the player (so they can restart where they left off)
string sLocKey = "lLoc_" + GetPCPlayerName(oPC) + "_" + GetName(oPC);
location lLoc = GetLocation(oPC);
switch (GetLastRestEventType()) {
case REST_EVENTTYPE_REST_STARTED:
// Check if the player has rested this session and that the player is over nPCMinLevel
// If you want unlimited resting in certain areas, add them to this if statement, example:
// if ((!nHasRested && nPCLevel > nPCMinLevel)
// || sArea != "Flen"
// || sArea != "CITY_CORE"
// || sArea != "FOREST_REFUGEE_CAMP") {
// local variables will still be updated, but it will allow players a safe area they can flee to
'>
if ((nHasRested == 1 && nPCLevel > nPCMinLevel)) {
// Some simple calculation here to determine if we can rest, but we need to account for the "wrapping" effect of time
// if nHour is less than the last rest attempt, then we've moved into the next day...
if (nHour < nLastRestedHour) {
nRestDelta = 24 - nLastRestedHour + nHour;
// This check is a little more simple, since the rest attempt is larger than the last rest event, we just need to
// calculate the difference, we'll check later if it's the next day
} else if (nHour > nLastRestedHour) {
nRestDelta = nHour - nLastRestedHour;
// looks like they tried to rest in the same hour (same day or next day)
} else {
nRestDelta = 0;
}
// These next checks which allow the user to rest look a bit conveluted, but it's necessary to catch everything
// 1. Check if rest time is greater than the rest timer
// 2. Check if the last successfull rest day is two days earlier
// 3. Check if the user waited over 23 hours to rest
// 4. Check for day 28 anomoly (special situation of check #3)
if (nRestDelta >= nRestTimer
|| nLastRestedDay < nDay - 1
|| (nHour >= nLastRestedHour && nLastRestedDay < nDay)
|| (nHour >= nLastRestedHour && nLastRestedDay == 28 && nDay == 1)) {
bCanRest = TRUE;
}
// The player hasn't rested yet this session, they're a low level, or they're in a safe area... so set the rest flag to TRUE
} else {
bCanRest = TRUE;
}
if (!bCanRest) {
// can't rest yet, so let's tell the user how long to wait
nRestDelta = 5 - nRestDelta;
// quick trick to change the word "hour" to plural: "hours"
if (nLastRestedHour > 1) { sPlural = "s"; }
FloatingTextStringOnCreature("You must wait " + IntToString(nRestDelta) + " hour" + sPlural + " before resting again (" + IntToString(FloatToInt(HoursToSeconds(nRestDelta)/60)) + " minutes realtime)...", oPC, FALSE);
AssignCommand(oPC,ClearAllActions());
} else {
// user can rest, so set local int, and apply blind/deaf effects
SetLocalInt(oPC, "LastRestedHour", nHour);
SetLocalInt(oPC, "LastRestedDay", nDay);
SetLocalInt(oPC, "HasRested", 1);
PlayVoiceChat(VOICE_CHAT_REST, oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectBlindness(), oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectDeaf(), oPC);
SetLocalLocation(GetModule(), sLocKey, lLoc);
}
break;
case REST_EVENTTYPE_REST_CANCELLED:
// rest cancelled, remove effects... again, wish I could just use a simple RemoveEffect(oPC, EffectBlindness())...
while (GetIsEffectValid(eBad)) {
if (GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS ||
GetEffectType(eBad) == EFFECT_TYPE_DEAF) {
RemoveEffect(oPC, eBad);
}
eBad = GetNextEffect(oPC);
}
break;
case REST_EVENTTYPE_REST_FINISHED:
// Status quo...
while (GetIsEffectValid(eBad)) {
if (GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS ||
GetEffectType(eBad) == EFFECT_TYPE_DEAF) {
RemoveEffect(oPC, eBad);
}
eBad = GetNextEffect(oPC);
}
break;
}
}
Modifié par beirutnwn, 05 novembre 2011 - 03:30 .