Untold Tales of Tolkien Series - Developments Thread

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));
	}
}
2 Likes