#include "mn_i_rebornrst" // *** Tarashon adding for itembuffs to disapear on rest *** // #include "prc_x2_itemprop" // *** Tarashon done for now *** // //:://///////////////////////////////////////////// //:: Custom Module OnPlayerRest Script //:: Copyright (c) 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(); // *** Tarashon adds to clear temporary powers from natural and worn weapons *** // object oItem; oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC); if(GetIsObjectValid(oItem)) IPRemoveAllItemProperties(oItem, DURATION_TYPE_TEMPORARY); oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC); if(GetIsObjectValid(oItem)) IPRemoveAllItemProperties(oItem, DURATION_TYPE_TEMPORARY); oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oPC); if(GetIsObjectValid(oItem)) IPRemoveAllItemProperties(oItem, DURATION_TYPE_TEMPORARY); oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC); if(GetIsObjectValid(oItem)) IPRemoveAllItemProperties(oItem, DURATION_TYPE_TEMPORARY); oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC); if(GetIsObjectValid(oItem)) IPRemoveAllItemProperties(oItem, DURATION_TYPE_TEMPORARY); // *** Tarashon done clearing worn and natural weapons of temporary powers *** // // 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 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 = 2; 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) ble string sLocKey = "lLoc_" + GetPCPlayerName(oPC) + "_" + GetName(oPC); location lLoc = GetLocation(oPC); int nRestTimer = (nPCLevel/4)-1; if (nRestTimer > 8) nRestTimer = 8; 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 != "TheAdventurersRest" // || sArea != "AislasPlateau" // || 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 = nRestTimer - 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); } // Reset reborn powers for reborns object reborn = GetItemPossessedBy( oPC, "MN_REBORN" ); if (reborn != OBJECT_INVALID) { ResetReborn( reborn ); SendMessageToPC( oPC, "reset item" ); } break; } }