public void GiveExp(long val)
{
this.Exp += val;
var levelStats = AuraData.StatsLevelUpDb.Find(this.RaceId, this.Age);
if (levelStats == null)
{
if ((levelStats = AuraData.StatsLevelUpDb.Find(10000, 17)) == null)
{
Log.Error("Creature.GiveExp: No valid level up stats found for race {0}, age {1}.", this.RaceId, this.Age);
}
else
{
// Only warn when creature was a player, we'll let NPCs fall
// back to Human 17 silently, until we know if they
// have specific level up stats.
//if (this.IsPlayer)
// Log.Warning("Creature.GiveExp: Level up stats missing for race {0}, age {1}. Falling back to Human 17.", this.RaceId, this.Age);
// Don't warn anymore, as that would put out a warning for
// every kill as an RP monster, since only normal
// characters and pets have level up stats.
}
}
var prevLevel = this.Level;
float ap = this.AbilityPoints;
float life = this.LifeMaxBase;
float mana = this.ManaMaxBase;
float stamina = this.StaminaMaxBase;
float str = this.StrBase;
float int_ = this.IntBase;
float dex = this.DexBase;
float will = this.WillBase;
float luck = this.LuckBase;
while (this.Level < AuraData.ExpDb.MaxLevel && this.Exp >= AuraData.ExpDb.GetTotalForNextLevel(this.Level))
{
this.Level++;
this.TotalLevel++;
if (levelStats == null)
continue;
var addAp = levelStats.AP;
// Add global bonus
float bonusMultiplier;
string bonuses;
if (ChannelServer.Instance.GameEventManager.GlobalBonuses.GetBonusMultiplier(GlobalBonusStat.LevelUpAp, out bonusMultiplier, out bonuses))
addAp = (int)(addAp * bonusMultiplier);
// Add conf
addAp = (int)(addAp * ChannelServer.Instance.Conf.World.LevelApRate);
this.AbilityPoints += (short)addAp;
this.LifeMaxBase += levelStats.Life;
this.ManaMaxBase += levelStats.Mana;
this.StaminaMaxBase += levelStats.Stamina;
this.StrBase += levelStats.Str;
this.IntBase += levelStats.Int;
this.DexBase += levelStats.Dex;
this.WillBase += levelStats.Will;
this.LuckBase += levelStats.Luck;
this.PlayPoints += 5;
}
// Only notify on level up
if (prevLevel < this.Level)
{
this.FullHeal();
Send.StatUpdateDefault(this);
Send.LevelUp(this);
// Only send aquire if stat crosses the X.0 border.
// Eg, 50.9 -> 51.1
float diff = 0;
if ((diff = (this.AbilityPoints - (int)ap)) >= 1) Send.SimpleAcquireInfo(this, "ap", diff);
if ((diff = (this.LifeMaxBase - (int)life)) >= 1) Send.SimpleAcquireInfo(this, "life", diff);
if ((diff = (this.ManaMaxBase - (int)mana)) >= 1) Send.SimpleAcquireInfo(this, "mana", diff);
if ((diff = (this.StaminaMaxBase - (int)stamina)) >= 1) Send.SimpleAcquireInfo(this, "stamina", diff);
if ((diff = (this.StrBase - (int)str)) >= 1) Send.SimpleAcquireInfo(this, "str", diff);
if ((diff = (this.IntBase - (int)int_)) >= 1) Send.SimpleAcquireInfo(this, "int", diff);
if ((diff = (this.DexBase - (int)dex)) >= 1) Send.SimpleAcquireInfo(this, "dex", diff);
if ((diff = (this.WillBase - (int)will)) >= 1) Send.SimpleAcquireInfo(this, "will", diff);
if ((diff = (this.LuckBase - (int)luck)) >= 1) Send.SimpleAcquireInfo(this, "luck", diff);
ChannelServer.Instance.Events.OnCreatureLevelUp(this);
this.LeveledUp.Raise(this, prevLevel);
}
else
Send.StatUpdate(this, StatUpdateType.Private, Stat.Experience);
}