public void Revive(ReviveOptions option)
{
if (!this.IsDead)
return;
// Get and check exp penalty
// "Here" wil be disabled by the client if not enough exp are
// available, nothing else though, so we send an error message
// if creature doesn't have enough exp, instead of issuing a
// warning.
var expPenalty = this.DeadMenu.GetExpPenalty(this.Level, option);
var minExp = AuraData.ExpDb.GetTotalForNextLevel(this.Level - 2);
// Friday: Decrease in penalties if knocked unconscious.
// -5%, bonus is unofficial.
// TODO: Does the client subtract the bonus on its side?
// Check on Friday.
if (ErinnTime.Now.Month == ErinnMonth.AlbanElved)
expPenalty = (int)(expPenalty * 0.95f);
if (this.Exp - expPenalty < minExp)
{
// Unofficial
Send.Notice(this, NoticeType.MiddleSystem, Localization.Get("Insufficient EXP."));
Send.DeadFeather(this);
Send.Revived(this);
return;
}
switch (option)
{
case ReviveOptions.Town:
case ReviveOptions.TirChonaill:
case ReviveOptions.DungeonEntrance:
case ReviveOptions.BarriLobby:
case ReviveOptions.TirNaNog:
// 100% life and 50% injury recovery
this.Injuries -= this.Injuries * 0.50f;
this.Life = this.LifeMax;
break;
case ReviveOptions.Here:
// 5 life recovery and 50% additional injuries
this.Injuries += this.LifeInjured * 0.50f;
this.Life = 5;
break;
case ReviveOptions.HereNoPenalty:
// 100% life and 100% injury recovery
this.Injuries = 0;
this.Life = this.LifeMax;
break;
case ReviveOptions.ArenaLobby:
case ReviveOptions.ArenaWaitingRoom:
// 100% life, 100% injury, and 100% stamina recovery
this.Injuries = 0;
this.Life = this.LifeMax;
this.Stamina = this.StaminaMax;
break;
case ReviveOptions.ArenaSide:
// 50% life, 20% injury, and 50% stamina recovery
this.Injuries -= this.Injuries * 0.20f;
this.Life = this.LifeMax * 0.50f;
this.Stamina = this.StaminaMax * 0.50f;
break;
case ReviveOptions.InCamp:
case ReviveOptions.StatueOfGoddess:
// 25% life recovery and 10% additional injuries
this.Injuries = Math2.Clamp(0, this.LifeMax * 0.75f, this.Injuries + this.LifeMax * 0.10f);
this.Life = this.LifeMax * 0.25f;
break;
case ReviveOptions.PhoenixFeather:
// Only set life if life is not at max, since creatures
// will keep their life if they leveled up while dead.
if (this.Life < this.LifeMax)
{
// 10% additional injuries
this.Injuries += this.LifeInjured * 0.10f;
this.Life = 1;
}
break;
case ReviveOptions.WaitForRescue:
this.DeadMenu.Options ^= ReviveOptions.PhoenixFeather;
Send.DeadFeather(this);
Send.Revived(this);
return;
case ReviveOptions.NaoStone:
this.DeadMenu.Options = ReviveOptions.NaoStoneRevive;
Send.DeadFeather(this);
Send.NaoRevivalEntrance(this);
Send.Revived(this);
return;
case ReviveOptions.NaoStoneRevive:
// First try beginner stones, then normals
var item = this.Inventory.GetItem(a => a.HasTag("/notTransServer/nao_coupon/"), StartAt.BottomRight);
if (item == null)
{
item = this.Inventory.GetItem(a => a.HasTag("/nao_coupon/"), StartAt.BottomRight);
if (item == null)
{
Log.Error("Creature.Revive: Unable to remove Nao Soul Stone, none found.");
return;
}
}
// 100% life and 100% injury recovery
this.Injuries = 0;
this.Life = this.LifeMax;
// Blessing of all items
this.BlessAll();
// Remove Soul Stone
this.Inventory.Decrement(item);
Send.NaoRevivalExit(this);
break;
default:
Log.Warning("Creature.Revive: Unknown revive option: {0}", option);
// Fallback, set Life to something positive.
if (this.Life <= 1)
this.Life = 1;
break;
}
this.Deactivate(CreatureStates.Dead);
this.DeadMenu.Clear();
if (expPenalty != 0)
{
this.Exp = Math.Max(minExp, this.Exp - expPenalty);
Send.StatUpdate(this, StatUpdateType.Private, Stat.Experience);
}
Send.RemoveDeathScreen(this);
Send.StatUpdate(this, StatUpdateType.Private, Stat.Life, Stat.LifeInjured, Stat.LifeMax, Stat.LifeMaxMod, Stat.Stamina, Stat.Hunger);
Send.StatUpdate(this, StatUpdateType.Public, Stat.Life, Stat.LifeInjured, Stat.LifeMax, Stat.LifeMaxMod);
Send.RiseFromTheDead(this);
Send.DeadFeather(this);
Send.Revived(this);
}