Skip to content

Reapplying Status Effects after Rest

So I'm currently helping a friend with an item. Its main purpose is to restore spell casts during fights, however to my knowledge that requires a rest, so you will have to restore their hit points to what it was before the rest as well as reapplying any status effects. I can manage to restore their health to what it was before the rest, but I've hit a snag in reapplying status effects. Here's what I've managed so far:
#include "x2_inc_switches"
#include "nw_i0_spells"
#include "x0_i0_match"
#include "nw_o0_itemmaker"

void TrySavingHPWithoutTempHP(object oPC, int OldHP);
int FindStatuses(object oPC);
void main()
{
	int nEvent = GetUserDefinedItemEventNumber();

	if (nEvent == X2_ITEM_EVENT_ACTIVATE) 
	{
		object oPC = GetItemActivator();
		int OldHP = GetCurrentHitPoints(oPC);	//Save Current hitpoints with Temp. HP
		if (GetHasEffect(EFFECT_TYPE_TEMPORARY_HITPOINTS, oPC) == TRUE)	//Only do when there is Temp. HP
		{
			effect THP = EffectTemporaryHitpoints(1);
			ApplyEffectToObject(DURATION_TYPE_TEMPORARY, THP, oPC, 0.1);	//Apply Temp. HP for a short amount of time
			DelayCommand(1.3, TrySavingHPWithoutTempHP(oPC, OldHP));	//Should trigger after Temp. HP wears off
		}
		else
		{
			TrySavingHPWithoutTempHP(oPC, OldHP);
		}
	}
	SetExecutedScriptReturnValue(X2_EXECUTE_SCRIPT_END);
}

void TrySavingHPWithoutTempHP(object oPC, int OldHP)
{
	int OldHP_T = GetCurrentHitPoints(oPC);	//Saves hitpoints with Temp. HP
	int OldTHP = OldHP - OldHP_T;	//Gets previous Temp. HP
	int NumberStatus = FindStatuses(oPC);	//Finds total number of Statuses on character
	int StatusNum = 1;
	effect eEffect = GetFirstEffect(oPC);
	while (GetIsEffectValid(eEffect))
	{
		SetLocalArrayInt(oPC, "DurType", StatusNum, GetEffectDurationType(eEffect));	//Arrays for various variables needed later
		SetLocalArrayInt(oPC, "SubType", StatusNum, GetEffectSubType(eEffect));
		SetLocalArrayInt(oPC, "DurRem", StatusNum, GetEffectDurationRemaining(eEffect));
		StatusNum += 1;
		RemoveEffect(oPC, eEffect);	//Removes effects - don't want to double stack
		SupernaturalEffect(eEffect);
		ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);	//Applies effect back on to character - should persist through rest
		eEffect = GetNextEffect(oPC);
	}
	ForceRest(oPC);
	StatusNum = 1;
	eEffect = GetFirstEffect(oPC);
	while (StatusNum <= NumberStatus)
	{
		RemoveEffect(oPC,eEffect);	//Removes previously applied supernatural effect
		if (GetLocalArrayInt(oPC,"SubType",StatusNum) == 8)	//Is Magical
		{
			if (GetLocalArrayInt(oPC,"DurType",StatusNum) == 1)	//Is Temporary
			{
				MagicalEffect(eEffect);
				ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eEffect,oPC,IntToFloat(GetLocalArrayInt(oPC,"DurRem",StatusNum)));
			}
			else
			{
				MagicalEffect(eEffect);
				ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
			}
		}
		else if (GetLocalArrayInt(oPC,"SubType",StatusNum) == 16)	//Is Supernatural
		{
			if (GetLocalArrayInt(oPC,"DurType",StatusNum) == 1)
			{
				SupernaturalEffect(eEffect);
				ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eEffect,oPC,IntToFloat(GetLocalArrayInt(oPC,"DurRem",StatusNum)));
			}
			else
			{
				SupernaturalEffect(eEffect);
				ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
			}
		}
		else if (GetLocalArrayInt(oPC,"SubType",StatusNum) == 24)	//Is Extraordinary
		{
			if (GetLocalArrayInt(oPC,"DurType",StatusNum) == 1)
			{
				ExtraordinaryEffect(eEffect);
				ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eEffect,oPC,IntToFloat(GetLocalArrayInt(oPC,"DurRem",StatusNum)));
			}
			else
			{
				ExtraordinaryEffect(eEffect);
				ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
			}
		}
		else
		{
			if (GetLocalArrayInt(oPC,"DurType",StatusNum) == 1)
			{
				ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eEffect,oPC,IntToFloat(GetLocalArrayInt(oPC,"DurRem",StatusNum)));
			}
			else
			{
				ApplyEffectToObject(DURATION_TYPE_PERMANENT,eEffect,oPC);
			}
		}
		StatusNum += 1;
		eEffect = GetNextEffect(oPC);
	}
	SetCurrentHitPoints(oPC, OldHP_T);	//Sets hitpoints to what they were previously
	if (OldTHP != 0)	//Previously had Temp. HP
	{
		effect THP = EffectTemporaryHitpoints(OldTHP);
		ApplyEffectToObject(DURATION_TYPE_PERMANENT, THP, oPC);	//Applies previous Temp. HP
	}
}

int FindStatuses(object oPC)
{
	int NumStatuses = 0;
	effect eEffect = GetFirstEffect(oPC);
	while (GetIsEffectValid(eEffect))
	{
		NumStatuses += 1;
		eEffect = GetNextEffect(oPC);
	}
	return NumStatuses;
}

Comments

  • ForSeriousForSerious Member Posts: 466
    What happens if you remove the effect after applying the supernatural effect?
    I'm trying to remember if the new effect overrides the old effect or gets ignored because the effect is already applied.

    Also, I just realized, this gets more complicated if you want to include popular buffs like Greater Magic Weapon and other effects that get placed on items.
  • ShonguShongu Member Posts: 3
    Okay, so I've modified my script, and through testing I've found that it will properly save the information on the effects. The unfortunate part is that ForceRest(oPC); seems to get rid of even permanent supernatural effects making it so that I can't reapply them. I tested code that only force rested the PC and tried applying a permanent Supernatural effect. It disappeared after the PC was Force Rested.

    It seems that with ForceRest(); removing every status effect this is a lost cause.
  • ForSeriousForSerious Member Posts: 466
    Since they decided to give each effect its own constructor, it looks like the easiest way to reapply them, would be to cast all the spells again. You can get the spell ID from the effect. You lose the duration of the spells though, and maybe caster level if another player cast the spell.
    The only other way I can think of is to make a giant switch case, basically copying all the buff and debuff spell scripts, but applying the effects with the duration left.
  • NeverwinterWightsNeverwinterWights Member Posts: 339
    edited March 2022
    The unfortunate part is that ForceRest(oPC); seems to get rid of even permanent supernatural effects making it so that I can't reapply them

    This definitely should not be the case. In testing, I added several supernatural effects followed by a ForceRest and all SupernaturalEffects remained. If they are permanent SupernaturalEffects that is.
  • ShonguShongu Member Posts: 3
    edited March 2022
    EDIT: I think I know what I did wrong.
Sign In or Register to comment.