This worked very well in testing with a party of companions and associates. Note that I made the assumption that no-sleep triggers are tagged “RestTrigger”, warmth triggers are tagged “rest_warm”, and the food items have their localint “rest_food” set to 1.
// Place on the module's OnPlayerRest event.
/* 26/07/21 Kev. Deliverance modifications.
Desired results...
1. Player can rest freely, as long as they are not in a restricted zone (see d1_resting_restrict)
2. Any member of the party must possess a food item holding local var "rest_food"
3. Food item to be destroyed upon rest event
4. If resting creature is within a warmth trigger, apply well rested bonus: Full health/abilities restore, +1 fortitude until next rest.
5. If not resting in a warmth trigger, restore 75% health, restore all abilities.
*/
/* Travus 7/26/21 - Added code to check/remove one food item from the party when resting.
If resting in a warmth zone, the paty will heal fully and get a Fortitude bonus.
If resting outside a warmth zone, the party will heal only to 75% due the frigid weather.
Assumes all no-sleep triggers are tagged "RestTrigger".
Assumes all warmth triggers are tagged "rest_warm".
Assumes the food items have their localint "rest_food" set to 1.
*/
int TakeFood(object oPC)
{
object oFM = GetFirstFactionMember(oPC, FALSE);
object oItem;
while (GetIsObjectValid(oFM))
{
oItem = GetFirstItemInInventory(oFM);
while (GetIsObjectValid(oItem))
{
if (GetLocalInt(oItem, "rest_food"))
{
DestroyObject(oItem);
return TRUE;
}
oItem = GetNextItemInInventory(oFM);
}
oFM = GetNextFactionMember(oPC, FALSE);
}
return FALSE;
}
void ApplyEffectToParty(object oPC, int bWarm=FALSE)
{
int n;
effect eEffect = MagicalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, 1));
object oFM = GetFirstFactionMember(oPC, FALSE);
while (GetIsObjectValid(oFM))
{
if (bWarm) ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oFM);
else
{
n = GetMaxHitPoints(oFM) / 4;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(n, DAMAGE_TYPE_COLD), oFM);
}
oFM = GetNextFactionMember(oPC, FALSE);
}
}
void main()
{
object oPC = GetLastPCRested();
int nRestAllow = TRUE;
int nWarm;
int nRestEvent = GetLastRestEventType();
object oTrig = GetNearestObjectByTag("RestTrigger", oPC);
object oPers = GetFirstInPersistentObject(oTrig);
while (GetIsObjectValid(oPers))
{
if (oPers == oPC) nRestAllow = FALSE;
oPers = GetNextInPersistentObject(oTrig);
}
if (!nRestAllow && nRestEvent == REST_EVENTTYPE_REST_STARTED)
{
AssignCommand(oPC, ClearAllActions());
FloatingTextStringOnCreature("<color=red>It would be extremely dangerous to rest here!", oPC, FALSE);
}
else if (GetIsResting(oPC) && nRestEvent == REST_EVENTTYPE_REST_STARTED)
{
if (!TakeFood(oPC))
{
AssignCommand(oPC, ClearAllActions());
FloatingTextStringOnCreature("<color=yellow>You do not have enough food to rest!", oPC, FALSE);
}
else
{
object oIP = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_ipoint ", GetLocation(oPC));
// do not remove this space ^
string sYawn = "as_pl_snoringm1";
string sWake = "as_pl_yawningm1";
if (GetGender(oPC) == GENDER_FEMALE)
{
sYawn = "as_pl_snoringm1";
sWake = "as_pl_yawningf1";
}
// Playsound does not work on the same object while it is animating. So play it off of an ipoint.
DelayCommand(0.2f, AssignCommand(oIP, PlaySound(sYawn, TRUE)));
FadeToBlack(oPC, FADE_SPEED_SLOW, 7.0f);
DelayCommand(6.0f, AssignCommand(oPC, PlaySound(sWake, TRUE)));
SetPlotFlag(oIP, FALSE);
DestroyObject(oIP, 6.2f);
object oWTrig = GetNearestObjectByTag("rest_warm", oPC);
object oWPers = GetFirstInPersistentObject(oWTrig);
while (GetIsObjectValid(oWPers))
{
if (oWPers == oPC) SetLocalInt(oPC, "warm", TRUE);
oWPers = GetNextInPersistentObject(oWTrig);
}
}
}
if (GetLocalInt(oPC, "warm") && nRestEvent == REST_EVENTTYPE_REST_FINISHED)
{
DelayCommand(1.0f, ApplyEffectToParty(oPC, TRUE));
DelayCommand(2.0f, FloatingTextStringOnCreature("<color=lime>You are well-rested! (Fortitude Bonus)", oPC, FALSE));
DelayCommand(2.0f, DeleteLocalInt(oPC, "warm"));
}
else if (nRestEvent == REST_EVENTTYPE_REST_FINISHED)
{
DelayCommand(1.0f, ApplyEffectToParty(oPC));
DelayCommand(2.0f, FloatingTextStringOnCreature("<color=aqua>The frigid cold saps your soul!", oPC, FALSE));
}
}