Create the collide where the alState is 0, so it triggers its function on both exiting and entering the area.
In your callback, put
if(alState == 1) {
SetLocalVarInt("areacheck", 1);
SetLocalVarFloat("defaultsanity", GetPlayerSanity());
}
if(alState == -1) Set LocalVarInt("areacheck", -1);
SetLocalVarInt("damage", 0);
if(GetLocalVarInt("areacheck") == 1) {
for(int s=1;s<100;s++) AddTimer("drain"+s, 1.0, "SanityDrain");
}
if(GetLocalVarInt("areacheck") == -1) RestoreDrainedSanity();
void SanityDrain(string &in asTimer)
{
GiveSanityDamage(5, false);
AddLocalVarInt("damage", 5); //I suggest not using effects. This may turn out to be very annoying
}
void RestoreDrainedSanity()
{
SetPlayerSanity(GetPlayerSanity() + GetLocalVarFloat("defaultsanity"))
for(int s=1;s<100;s++) RemoveTimer("drain"+s);
}
I'll give this a test later; tied up at the moment. If you want the sanity to instantly be reduced to a set amount, use SetPlayerSanity() as suggested in above posts, as opposed to draining it. Drain would probably be smoother gameplay-wise.
Good luck!