Core/Creatures: Fixed level 240 guards and updated scaling level calculation

Port From (https://github.com/TrinityCore/TrinityCore/commit/82b4ca3b7c2329e571d0a341b8a5ab366a5d26f4)
This commit is contained in:
hondacrx
2020-05-20 20:04:00 -04:00
parent 29991a2062
commit ea80678e9a
7 changed files with 68 additions and 35 deletions
@@ -75,7 +75,7 @@ namespace Framework.Database
PrepareStatement(WorldStatements.SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?");
PrepareStatement(WorldStatements.DEL_CREATURE, "DELETE FROM creature WHERE guid = ?");
PrepareStatement(WorldStatements.SEL_COMMANDS, "SELECT name, permission, help FROM command");
PrepareStatement(WorldStatements.SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?");
PrepareStatement(WorldStatements.SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, FadeRegionRadius, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?");
PrepareStatement(WorldStatements.SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?");
PrepareStatement(WorldStatements.SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?");
PrepareStatement(WorldStatements.SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_");
+29 -11
View File
@@ -1145,10 +1145,11 @@ namespace Game.Entities
CreatureTemplate cInfo = GetCreatureTemplate();
// level
byte minlevel = (byte)Math.Min(cInfo.Maxlevel, cInfo.Minlevel);
byte maxlevel = (byte)Math.Max(cInfo.Maxlevel, cInfo.Minlevel);
byte level = (byte)(minlevel == maxlevel ? minlevel : RandomHelper.URand(minlevel, maxlevel));
SetLevel(level);
var levels = cInfo.GetMinMaxLevel();
int minlevel = Math.Min(levels[0], levels[1]);
int maxlevel = Math.Max(levels[0], levels[1]);
int level = (minlevel == maxlevel ? minlevel : RandomHelper.IRand(minlevel, maxlevel));
SetLevel((uint)level);
CreatureLevelScaling scaling = cInfo.GetLevelScaling(GetMap().GetDifficultyID());
@@ -2362,7 +2363,7 @@ namespace Game.Entities
{
CreatureTemplate cInfo = GetCreatureTemplate();
CreatureLevelScaling scaling = cInfo.GetLevelScaling(GetMap().GetDifficultyID());
float baseHealth = Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureHealth, level, cInfo.HealthScalingExpansion, scaling.ContentTuningID, (Class)cInfo.UnitClass);
float baseHealth = Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureHealth, level, cInfo.GetHealthScalingExpansion(), scaling.ContentTuningID, (Class)cInfo.UnitClass);
return (ulong)(baseHealth * cInfo.ModHealth * cInfo.ModHealthExtra);
}
@@ -2382,7 +2383,7 @@ namespace Game.Entities
{
CreatureTemplate cInfo = GetCreatureTemplate();
CreatureLevelScaling scaling = cInfo.GetLevelScaling(GetMap().GetDifficultyID());
return Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureAutoAttackDps, level, cInfo.HealthScalingExpansion, scaling.ContentTuningID, (Class)cInfo.UnitClass);
return Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureAutoAttackDps, level, cInfo.GetHealthScalingExpansion(), scaling.ContentTuningID, (Class)cInfo.UnitClass);
}
public override float GetDamageMultiplierForTarget(WorldObject target)
@@ -2399,7 +2400,7 @@ namespace Game.Entities
{
CreatureTemplate cInfo = GetCreatureTemplate();
CreatureLevelScaling scaling = cInfo.GetLevelScaling(GetMap().GetDifficultyID());
float baseArmor = Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureArmor, level, cInfo.HealthScalingExpansion, scaling.ContentTuningID, (Class)cInfo.UnitClass);
float baseArmor = Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureArmor, level, cInfo.GetHealthScalingExpansion(), scaling.ContentTuningID, (Class)cInfo.UnitClass);
return baseArmor * cInfo.ModArmor;
}
@@ -2428,12 +2429,29 @@ namespace Game.Entities
// between UNIT_FIELD_SCALING_LEVEL_MIN and UNIT_FIELD_SCALING_LEVEL_MAX
if (HasScalableLevels())
{
int targetLevelWithDelta = (int)unitTarget.GetLevel() + m_unitData.ScalingLevelDelta;
int scalingLevelMin = m_unitData.ScalingLevelMin;
int scalingLevelMax = m_unitData.ScalingLevelMax;
int scalingLevelDelta = m_unitData.ScalingLevelDelta;
int scalingFactionGroup = m_unitData.ScalingFactionGroup;
int targetLevel = unitTarget.m_unitData.EffectiveLevel;
if (targetLevel == 0)
targetLevel = (int)unitTarget.GetLevel();
if (target.IsPlayer())
targetLevelWithDelta += target.ToPlayer().m_activePlayerData.ScalingPlayerLevelDelta;
int targetLevelDelta = 0;
return (uint)MathFunctions.RoundToInterval(ref targetLevelWithDelta, m_unitData.ScalingLevelMin, m_unitData.ScalingLevelMax);
Player playerTarget = target.ToPlayer();
if (playerTarget != null)
{
if (scalingFactionGroup != 0 && CliDB.FactionTemplateStorage.LookupByKey(CliDB.ChrRacesStorage.LookupByKey(playerTarget.GetRace()).FactionID).FactionGroup != scalingFactionGroup)
scalingLevelMin = scalingLevelMax;
int maxCreatureScalingLevel = playerTarget.m_activePlayerData.MaxCreatureScalingLevel;
targetLevelDelta = Math.Min(maxCreatureScalingLevel > 0 ? maxCreatureScalingLevel - targetLevel : 0, playerTarget.m_activePlayerData.ScalingPlayerLevelDelta);
}
int levelWithDelta = targetLevel + targetLevelDelta;
int level = MathFunctions.RoundToInterval(ref levelWithDelta, scalingLevelMin, scalingLevelMax) + scalingLevelDelta;
return (uint)MathFunctions.RoundToInterval(ref level, 1, SharedConst.MaxLevel + 3);
}
}
@@ -157,6 +157,20 @@ namespace Game.Entities
return CreatureModel.DefaultVisibleModel;
}
public int[] GetMinMaxLevel()
{
return new[]
{
HealthScalingExpansion != (int)Expansion.LevelCurrent ? Minlevel : Minlevel + SharedConst.MaxLevel,
HealthScalingExpansion != (int)Expansion.LevelCurrent ? Maxlevel : Maxlevel + SharedConst.MaxLevel
};
}
public int GetHealthScalingExpansion()
{
return HealthScalingExpansion == (int)Expansion.LevelCurrent ? (int)Expansion.WarlordsOfDraenor : HealthScalingExpansion;
}
public SkillType GetRequiredLootSkill()
{
if (TypeFlags.HasAnyFlag(CreatureTypeFlags.HerbSkinningSkill))
+1 -1
View File
@@ -489,7 +489,7 @@ namespace Game.Entities
CreatureBaseStats stats = Global.ObjectMgr.GetCreatureBaseStats(petlevel, cinfo.UnitClass);
CreatureLevelScaling scaling = cinfo.GetLevelScaling(GetMap().GetDifficultyID());
SetCreateHealth((uint)(Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureHealth, petlevel, cinfo.HealthScalingExpansion, scaling.ContentTuningID, (Class)cinfo.UnitClass) * cinfo.ModHealth * cinfo.ModHealthExtra));
SetCreateHealth((uint)(Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureHealth, petlevel, cinfo.GetHealthScalingExpansion(), scaling.ContentTuningID, (Class)cinfo.UnitClass) * cinfo.ModHealth * cinfo.ModHealthExtra));
SetCreateMana(stats.BaseMana);
+12 -21
View File
@@ -2527,14 +2527,14 @@ namespace Game
if (cInfo.DmgSchool != difficultyInfo.DmgSchool)
{
Log.outError(LogFilter.Sql, "Creature (Entry: {0}, `dmgschool`: {1}) has different `dmgschool` in difficulty {2} mode (Entry: {3}, `dmgschool`: {4}).",
Log.outError(LogFilter.Sql, "Creature (Entry: {0}, `dmgschool`: {1}) has different `dmgschool` in difficulty {2} mode (Entry: {3}, `dmgschool`: {4}).",
cInfo.Entry, cInfo.DmgSchool, diff + 1, cInfo.DifficultyEntry[diff], difficultyInfo.DmgSchool);
Log.outError(LogFilter.Sql, "Possible FIX: UPDATE `creature_template` SET `dmgschool`={0} WHERE `entry`={1};", cInfo.DmgSchool, cInfo.DifficultyEntry[diff]);
}
if (cInfo.UnitFlags2 != difficultyInfo.UnitFlags2)
{
Log.outError(LogFilter.Sql, "Creature (Entry: {0}, `unit_flags2`: {1}) has different `unit_flags2` in difficulty {2} mode (Entry: {3}, `unit_flags2`: {4}).",
Log.outError(LogFilter.Sql, "Creature (Entry: {0}, `unit_flags2`: {1}) has different `unit_flags2` in difficulty {2} mode (Entry: {3}, `unit_flags2`: {4}).",
cInfo.Entry, cInfo.UnitFlags2, diff + 1, cInfo.DifficultyEntry[diff], difficultyInfo.UnitFlags2);
Log.outError(LogFilter.Sql, "Possible FIX: UPDATE `creature_template` SET `unit_flags2`=`unit_flags2`^{0} WHERE `entry`={1};", cInfo.UnitFlags2 ^ difficultyInfo.UnitFlags2, cInfo.DifficultyEntry[diff]);
}
@@ -2565,7 +2565,7 @@ namespace Game
if (cInfo.RegenHealth != difficultyInfo.RegenHealth)
{
Log.outError(LogFilter.Sql, "Creature (Entry: {0}, RegenHealth: {1}) has different `RegenHealth` in difficulty {2} mode (Entry: {3}, RegenHealth: {4}).",
Log.outError(LogFilter.Sql, "Creature (Entry: {0}, RegenHealth: {1}) has different `RegenHealth` in difficulty {2} mode (Entry: {3}, RegenHealth: {4}).",
cInfo.Entry, cInfo.RegenHealth, diff + 1, cInfo.DifficultyEntry[diff], difficultyInfo.RegenHealth);
Log.outError(LogFilter.Sql, "Possible FIX: UPDATE `creature_template` SET `RegenHealth`={0} WHERE `entry`={1};", cInfo.RegenHealth, cInfo.DifficultyEntry[diff]);
}
@@ -2705,13 +2705,13 @@ namespace Game
cInfo.MovementType = (uint)MovementGeneratorType.Idle;
}
if (cInfo.HealthScalingExpansion < (int)Expansion.LevelCurrent || cInfo.HealthScalingExpansion > ((int)Expansion.Max - 1))
if (cInfo.HealthScalingExpansion < (int)Expansion.LevelCurrent || cInfo.HealthScalingExpansion >= (int)Expansion.Max)
{
Log.outError(LogFilter.Sql, "Table `creature_template` lists creature (Id: {0}) with invalid `HealthScalingExpansion` {1}. Ignored and set to 0.", cInfo.Entry, cInfo.HealthScalingExpansion);
cInfo.HealthScalingExpansion = 0;
}
if (cInfo.RequiredExpansion > (int)(Expansion.Max - 1))
if (cInfo.RequiredExpansion > (int)Expansion.Max)
{
Log.outError(LogFilter.Sql, "Table `creature_template` lists creature (Entry: {0}) with `RequiredExpansion` {1}. Ignored and set to 0.", cInfo.Entry, cInfo.RequiredExpansion);
cInfo.RequiredExpansion = 0;
@@ -2724,26 +2724,17 @@ namespace Game
cInfo.FlagsExtra &= CreatureFlagsExtra.DBAllowed;
}
// -1, as expansion, is used in CreatureDifficulty.db2 for
// auto-updating the levels of creatures having their expansion
// set to that value to the current expansion's max leveling level
if (cInfo.HealthScalingExpansion == (int)Expansion.LevelCurrent)
var levels = cInfo.GetMinMaxLevel();
if (levels[0] < 1 || levels[0] > SharedConst.StrongMaxLevel)
{
cInfo.Minlevel = (short)(WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) + cInfo.Minlevel);
cInfo.Maxlevel = (short)(WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) + cInfo.Maxlevel);
cInfo.HealthScalingExpansion = (int)Expansion.WarlordsOfDraenor;
Log.outError(LogFilter.Sql, $"Creature (ID: {cInfo.Entry}): Calculated minLevel {cInfo.Minlevel} is not within [1, 255], value has been set to {(cInfo.HealthScalingExpansion == (int)Expansion.LevelCurrent ? SharedConst.MaxLevel : 1)}.");
cInfo.Minlevel = (short)(cInfo.HealthScalingExpansion == (int)Expansion.LevelCurrent ? 0 : 1);
}
if (cInfo.Minlevel < 1 || cInfo.Minlevel > SharedConst.StrongMaxLevel)
if (levels[1] < 1 || levels[1] > SharedConst.StrongMaxLevel)
{
Log.outError(LogFilter.Sql, "Creature (ID: {0}): MinLevel {1} is not within [1, 255], value has been set to 1.", cInfo.Entry, cInfo.Minlevel);
cInfo.Minlevel = 1;
}
if (cInfo.Maxlevel < 1 || cInfo.Maxlevel > SharedConst.StrongMaxLevel)
{
Log.outError(LogFilter.Sql, "Creature (ID: {0}): MaxLevel {1} is not within [1, 255], value has been set to 1.", cInfo.Entry, cInfo.Maxlevel);
cInfo.Maxlevel = 1;
Log.outError(LogFilter.Sql, $"Creature (ID: {cInfo.Entry}): Calculated maxLevel {cInfo.Maxlevel} is not within [1, 255], value has been set to {(cInfo.HealthScalingExpansion == (int)Expansion.LevelCurrent ? SharedConst.MaxLevel : 1)}.");
cInfo.Maxlevel = (short)(cInfo.HealthScalingExpansion == (int)Expansion.LevelCurrent ? 0 : 1);
}
cInfo.ModDamage *= Creature._GetDamageMod(cInfo.Rank);
+1 -1
View File
@@ -154,7 +154,7 @@ namespace Game
if (gain != 0 && creature)
{
// Players get only 10% xp for killing creatures of lower expansion levels than himself
if ((creature.GetCreatureTemplate().HealthScalingExpansion < (int)GetExpansionForLevel(player.GetLevel())))
if ((creature.GetCreatureTemplate().GetHealthScalingExpansion() < (int)GetExpansionForLevel(player.GetLevel())))
gain = (uint)Math.Round(gain / 10.0f);
if (creature.IsElite())
@@ -0,0 +1,10 @@
UPDATE creature_template SET `minlevel`=0 WHERE `minlevel`=1 AND `HealthScalingExpansion`=-1 AND `BaseAttackTime`=0; -- no attack time means we have no data and minlevel value was also defaulted
UPDATE creature_template SET `maxlevel`=0 WHERE `maxlevel`=1 AND `HealthScalingExpansion`=-1 AND `BaseAttackTime`=0; -- no attack time means we have no data and maxlevel value was also defaulted
UPDATE creature_template SET `minlevel`=`minlevel`-90 WHERE `minlevel`>=90 AND `minlevel`<100 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `maxlevel`=`maxlevel`-90 WHERE `maxlevel`>=90 AND `maxlevel`<100 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `minlevel`=`minlevel`-100 WHERE `minlevel`>=100 AND `minlevel`<110 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `maxlevel`=`maxlevel`-100 WHERE `maxlevel`>=100 AND `maxlevel`<110 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `minlevel`=`minlevel`-110 WHERE `minlevel`>=110 AND `minlevel`<120 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `maxlevel`=`maxlevel`-110 WHERE `maxlevel`>=110 AND `maxlevel`<120 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `minlevel`=`minlevel`-120 WHERE `minlevel`>=120 AND `minlevel`<130 AND `HealthScalingExpansion`=-1;
UPDATE creature_template SET `maxlevel`=`maxlevel`-120 WHERE `maxlevel`>=120 AND `maxlevel`<130 AND `HealthScalingExpansion`=-1;