Author: Beseb
Author Website: http://masterofdragons.com/coa
Script Name: 3rd Edition Lich 
Description: This lich has 2 new behaviors. One, he will automatically respawn after a couple of minutes if his phylactery hasn't been destroyed.  Two, I have him summon a random number of critters every 3rd round that help him in combat and they don't disappear if he dies (this keeps the PC's there longer so the lich will then respawn).
Instructions on Use:
  1. Create a new lich template and add the following code into the appropriate places. The resref of the template must be gravelich otherwise you'll need to change the appropriate references.
    1. Input Script 1 below into the Lich's OnSpawn script
    2. Input Script 2 into the Lich's OnEndCombatRound script
    3. Input Script 3 into the Lich's OnDeath script
  2. Create a new bat template and tag it CryptBat, resref should be cryptbat.
  3. Input Script 4 into the Area OnHeartbeat script.  NOTE: In this case it is the area that the lich will respawn in. 
  4. Create a phylactery and add it's destroyed code.
    1. Input Script 5 into the phylacteries OnDeath script.  Ensure that the tag "LichThrone" is changed to the tag of your phylactery.

Script 1 (Lich - OnSpawn):

void main()
{
object oLich = OBJECT_SELF;
object oPC;

SetLocalInt(oLich,"BatCounter",1);
SetLocalInt(GetArea(oLich),"LichDestroyed",0);
SetLocalInt(GetArea(oLich),"spawnCounter",0);

// look for a pc to attack
oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC);
if(GetIsObjectValid(oPC))
SetIsTemporaryEnemy(oPC);

}

Script 2 (Lich - OnEndCombatRound):

OnEndCombatRound:

void main()
{

object oLich = OBJECT_SELF;
int counter = GetLocalInt(oLich,"BatCounter");
string s;

switch(d4()){
default:
case 1:
s="Fear me mortal!";
break;
case 2:
s="You are no match for me!";
break;
case 3:
s="Feel my wrath!";
break;
case 4:
s="I am immortal! You will fall before me!";
break;
}
SpeakString(s);

if(counter!=3){
++counter;
SetLocalInt(oLich,"BatCounter",counter);
return;
}

SetLocalInt(oLich,"BatCounter",1); // reset counter

location loc = GetLocation(oLich);
effect eSummon;

eSummon = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);

int i,rand;
rand = d6();
// create crypt bats
for(i=0;i<rand;i++){
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eSummon,loc);
CreateObject(OBJECT_TYPE_CREATURE,"cryptbat",loc);
}
}

Script 3 (OnDeath):

void main()
{

SetLocalInt(GetArea(OBJECT_SELF),"LichDestroyed",1);
SetLocalInt(GetArea(OBJECT_SELF),"spawnCounter",0);
effect eBoom = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eBoom,OBJECT_SELF);
}

Script 4 (Area OnHeartbeat):

void main()
{
int LichDead,ThroneDead,spawnCounter;

LichDead=GetLocalInt(OBJECT_SELF,"LichDestroyed");
ThroneDead = GetLocalInt(OBJECT_SELF,"ThroneDestroyed");

object oLich=GetNearestObjectByTag("GraveLich",GetObjectByTag("LichThrone"));
if(GetIsObjectValid(oLich))
return;

if(LichDead<0 || LichDead>1 || ThroneDead<0 || ThroneDead>1)
return;

if(LichDead==1 && ThroneDead==1)
return;
if(ThroneDead==1)
return;
spawnCounter=GetLocalInt(OBJECT_SELF,"spawnCounter");

if(spawnCounter<0 || spawnCounter>15)
return;

if(spawnCounter<15){
spawnCounter++;
SetLocalInt(OBJECT_SELF,"spawnCounter",spawnCounter);
return;
}
SetLocalInt(OBJECT_SELF,"spawnCounter",0);


CreateObject(OBJECT_TYPE_CREATURE,"gravelich",GetLocation(GetObjectByTag("LichThrone")),TRUE);

} 

Script 5 (Phylactery OnDeath):

void main()
{
PlaySound("as_cv_bldgcrumb1");
SetLocalInt(GetArea(OBJECT_SELF),"ThroneDestroyed",1);

SetTileMainLightColor(GetLocation(GetObjectByTag("LichThrone")),TILE_MAIN_LIGHT_COLOR_PURPLE,TILE_MAIN_LIGHT_C OLOR_BLACK);

SetTileSourceLightColor(GetLocation(GetObjectByTag("LichThrone")),TILE_MAIN_LIGHT_COLOR_DARK_PURPLE,TILE_MAIN_ LIGHT_COLOR_RED);
RecomputeStaticLighting(GetArea(OBJECT_SELF));

SetLocalInt(GetModule(),"ThroneDestroyed",1);

}